Skip to content

Add --for-client flag for client transfer store creation#7280

Open
tizmagik wants to merge 3 commits intojg/store-create-commandfrom
jg/store-create-for-client
Open

Add --for-client flag for client transfer store creation#7280
tizmagik wants to merge 3 commits intojg/store-create-commandfrom
jg/store-create-for-client

Conversation

@tizmagik
Copy link
Copy Markdown

Summary

Stacked on #7218.

Adds --for-client flag to shopify store create for creating client transfer stores (stores built by partners for their clients, on the affiliate plan).

  • shopify store create --for-client --org <id> — calls Organizations API createClientDevelopmentShop mutation
  • --org is required with --for-client (Partner organization ID)
  • Uses Business Platform token auth (different from Signups API path used by trial/dev stores)
  • No server-side changes needed — uses existing Organizations API mutation

Flag validation

  • --for-client and --dev are mutually exclusive
  • --subdomain is not supported with --for-client
  • --org is required with --for-client

Test plan

  • pnpm vitest run passes (41 tests total, 10 new for client transfer + validation)
  • pnpm tsc --noEmit passes
  • Manual test: shopify store create --for-client --org <id> --name "Client Store"

🤖 Generated with Claude Code

@tizmagik tizmagik requested review from a team as code owners April 13, 2026 21:07
@tizmagik tizmagik force-pushed the jg/store-create-command branch from 07f69f7 to a8f6fab Compare April 13, 2026 21:20
@tizmagik tizmagik force-pushed the jg/store-create-for-client branch from cb11b50 to d714122 Compare April 13, 2026 21:21
@tizmagik tizmagik force-pushed the jg/store-create-command branch from 5b90ed5 to 0513e3d Compare April 13, 2026 21:34
tizmagik and others added 3 commits April 13, 2026 17:34
Enables creating Shopify stores directly from the CLI via Core's Signups
GraphQL API. Supports both trial stores (`shopify store create`) and
development stores (`shopify store create --dev`) using the StoreCreate
and AppDevelopmentStoreCreate mutations respectively.

The CLI authenticates with Identity via PKCE and sends the bearer token
directly to the Signups API (no application token exchange needed).

Flags: --name, --subdomain, --country (default: US), --dev, --json

Prerequisites:
- Core PR shop/world#586779 (authorizes CLI on Signups API)
- Identity scope grant for `shop.create`
- `app_development_store_create` approval scope for --dev flag

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Enables creating Shopify stores directly from the CLI via Core's Signups
GraphQL API. Supports both trial stores (`shopify store create`) and
development stores (`shopify store create --dev`) using the StoreCreate
and AppDevelopmentStoreCreate mutations respectively.

The CLI authenticates with Identity via PKCE and sends the bearer token
directly to the Signups API (no application token exchange needed).

Flags: --name, --subdomain, --country (default: US), --dev, --json

Prerequisites:
- Core PR shop/world#586779 (authorizes CLI on Signups API)
- Identity scope grant for `shop.create`
- `app_development_store_create` approval scope for --dev flag

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds support for creating client transfer stores via the Organizations
API `createClientDevelopmentShop` mutation. These are stores built by
partners for their clients, on the affiliate plan.

Usage: shopify store create --for-client --org <org-id> --name "Store"

The --org flag is required with --for-client and provides the Partner
organization ID. Uses Business Platform token auth via the Organizations
API (different from the Signups API path used by trial/dev stores).

Also adds flag validation:
- --for-client and --dev are mutually exclusive
- --subdomain is not supported with --for-client
- --org is required with --for-client

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tizmagik tizmagik force-pushed the jg/store-create-for-client branch from d714122 to 28caff1 Compare April 13, 2026 21:34
@github-actions
Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

packages/cli-kit/dist/public/node/api/signups.d.ts
import { GraphQLVariables } from './graphql.js';
/**
 * Executes a GraphQL query against the Signups API.
 * Uses the Identity bearer token directly (no application token exchange).
 *
 * @param query - GraphQL query to execute.
 * @param token - Identity access token.
 * @param variables - GraphQL variables to pass to the query.
 * @returns The response of the query of generic type <T>.
 */
export declare function signupsRequest<T>(query: string, token: string, variables?: GraphQLVariables): Promise<T>;

Existing type declarations

packages/cli-kit/dist/private/node/session.d.ts
@@ -41,6 +41,15 @@ interface BusinessPlatformAPIOAuthOptions {
     /** List of scopes to request permissions for. */
     scopes: BusinessPlatformScope[];
 }
+/**
+ * A scope supported by the Signups API.
+ * The Signups API uses the Identity bearer token directly (no application token exchange).
+ */
+export type SignupsScope = 'shop-create';
+interface SignupsAPIOAuthOptions {
+    /** List of scopes to request permissions for. */
+    scopes: SignupsScope[];
+}
 /**
  * It represents the authentication requirements and
  * is the input necessary to trigger the authentication
@@ -52,6 +61,7 @@ export interface OAuthApplications {
     partnersApi?: PartnersAPIOAuthOptions;
     businessPlatformApi?: BusinessPlatformAPIOAuthOptions;
     appManagementApi?: AppManagementAPIOauthOptions;
+    signupsApi?: SignupsAPIOAuthOptions;
 }
 export interface OAuthSession {
     admin?: AdminSession;
@@ -59,6 +69,7 @@ export interface OAuthSession {
     storefront?: string;
     businessPlatform?: string;
     appManagement?: string;
+    identity?: string;
     userId: string;
 }
 type AuthMethod = 'partners_token' | 'device_auth' | 'theme_access_token' | 'custom_app_token' | 'none';
packages/cli-kit/dist/public/node/session.d.ts
@@ -1,4 +1,4 @@
-import { AdminAPIScope, AppManagementAPIScope, BusinessPlatformScope, EnsureAuthenticatedAdditionalOptions, PartnersAPIScope, StorefrontRendererScope } from '../../private/node/session.js';
+import { AdminAPIScope, AppManagementAPIScope, BusinessPlatformScope, EnsureAuthenticatedAdditionalOptions, PartnersAPIScope, SignupsScope, StorefrontRendererScope } from '../../private/node/session.js';
 /**
  * Session Object to access the Admin API, includes the token and the store FQDN.
  */
@@ -116,6 +116,19 @@ export declare function ensureAuthenticatedThemes(store: string, password: strin
  * @returns The access token for the Business Platform API.
  */
 export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPlatformScope[]): Promise<string>;
+/**
+ * Ensure that we have a valid session to access the Signups API.
+ * The Signups API uses the Identity bearer token directly (no application token exchange).
+ *
+ * @param scopes - Optional array of extra scopes to authenticate with.
+ * @param env - Optional environment variables to use.
+ * @param options - Optional extra options to use.
+ * @returns The Identity access token and user ID.
+ */
+export declare function ensureAuthenticatedSignups(scopes?: SignupsScope[], env?: NodeJS.ProcessEnv, options?: EnsureAuthenticatedAdditionalOptions): Promise<{
+    token: string;
+    userId: string;
+}>;
 /**
  * Logout from Shopify.
  *
packages/cli-kit/dist/public/node/context/fqdn.d.ts
@@ -37,6 +37,12 @@ export declare function developerDashboardFqdn(): Promise<string>;
  * @returns Fully-qualified domain of the partners service we should interact with.
  */
 export declare function businessPlatformFqdn(): Promise<string>;
+/**
+ * It returns the Signups API service we should interact with.
+ *
+ * @returns Fully-qualified domain of the Signups service we should interact with.
+ */
+export declare function signupsFqdn(): Promise<string>;
 /**
  * It returns the Identity service we should interact with.
  *

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant