Conversation
80db198 to
c3be9fc
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a new non-interactive shopify store create trial command in @shopify/store, backed by the Signups API storeCreate mutation, and adds the necessary cli-kit auth + API foundations to call Signups using an Identity bearer token.
Changes:
- Add
shopify store create trialcommand + service layer to create a trial store and optionally output JSON. - Add cli-kit Signups support:
shop-createscope transform,signupsApiauth path (ensureAuthenticatedSignups),signupsFqdn(), andsignupsRequest()helper. - Regenerate CLI manifests/docs/snapshots to expose the new command.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/store/src/index.ts | Registers the new store:create:trial command. |
| packages/store/src/cli/services/store/create/index.ts | Implements Signups storeCreate call + error handling. |
| packages/store/src/cli/services/store/create/index.test.ts | Adds unit coverage for store creation service behavior and error cases. |
| packages/store/src/cli/commands/store/create/trial.ts | Adds the CLI command/flags and output behavior (--json vs UI). |
| packages/store/src/cli/commands/store/create/trial.test.ts | Adds unit tests for flag plumbing and output paths. |
| packages/e2e/data/snapshots/commands.txt | Updates command tree snapshot to include store create trial. |
| packages/cli/oclif.manifest.json | Adds the new command to the generated oclif manifest. |
| packages/cli/README.md | Documents the new command usage and flags. |
| packages/cli-kit/src/public/node/session.ts | Adds ensureAuthenticatedSignups() for Signups API auth. |
| packages/cli-kit/src/public/node/context/fqdn.ts | Adds signupsFqdn() resolver for Signups service routing. |
| packages/cli-kit/src/public/node/api/signups.ts | Adds signupsRequest() GraphQL helper targeting /services/signups/graphql. |
| packages/cli-kit/src/public/node/api/signups.test.ts | Adds unit tests ensuring correct graphqlRequest wiring for Signups. |
| packages/cli-kit/src/private/node/session/scopes.ts | Adds shop-create → https://api.shopify.com/auth/shop.create transform. |
| packages/cli-kit/src/private/node/session/scopes.test.ts | Adds test for the new scope transform. |
| packages/cli-kit/src/private/node/session.ts | Adds signupsApi application handling and exposes identity token when requested. |
| docs-shopify.dev/commands/store-create-trial.doc.ts | Adds autogenerated public docs entry for the command. |
| docs-shopify.dev/commands/interfaces/store-create-trial.interface.ts | Adds autogenerated flags interface for docs generation. |
| docs-shopify.dev/commands/examples/store-create-trial.example.sh | Adds autogenerated example snippet. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export async function ensureAuthenticatedSignups( | ||
| scopes: SignupsScope[] = ['shop-create'], | ||
| env = process.env, | ||
| options: EnsureAuthenticatedAdditionalOptions = {}, | ||
| ): Promise<{token: string; userId: string}> { | ||
| outputDebug(outputContent`Ensuring that the user is authenticated with the Signups API with the following scopes: | ||
| ${outputToken.json(scopes)} | ||
| `) | ||
| const tokens = await ensureAuthenticated({signupsApi: {scopes}}, env, options) | ||
| if (!tokens.identity) { | ||
| throw new BugError('No identity token found after ensuring authenticated') | ||
| } | ||
| return {token: tokens.identity, userId: tokens.userId} | ||
| } |
There was a problem hiding this comment.
Add unit tests for ensureAuthenticatedSignups similar to the existing ensureAuthenticatedPartners/ensureAuthenticatedAdmin tests. This function introduces new authentication behavior (default scopes, token selection, and the No identity token found... error path) but currently has no direct coverage in packages/cli-kit/src/public/node/session.test.ts.
There was a problem hiding this comment.
Added ensureAuthenticatedSignups coverage in session.test.ts: default scope, custom scope passthrough, success, and the No identity token error path.
| export async function signupsFqdn(): Promise<string> { | ||
| const environment = serviceEnvironment() | ||
| const productionFqdn = 'shopify.com' | ||
| switch (environment) { | ||
| case 'local': | ||
| return new DevServerCore().host('shopify') | ||
| default: | ||
| return productionFqdn | ||
| } |
There was a problem hiding this comment.
Add coverage for signupsFqdn() in fqdn.test.ts (local vs production), like the existing tests for partnersFqdn, adminFqdn, etc. Without a direct test, regressions in the Signups FQDN routing (especially the local dev-server host mapping) may go unnoticed.
There was a problem hiding this comment.
Added a describe('signupsFqdn') block in fqdn.test.ts covering local + production environments, matching the pattern used by partnersFqdn / adminFqdn.
Adds a programmatic way to create a Shopify trial store from the CLI, backed by the Signups API's StoreCreate mutation. - Registers `store:create:trial` in @shopify/store with flags for --name, --subdomain, --country (default US), and --json. - Adds cli-kit Signups foundation: `shop-create` OAuth scope, `signupsApi` application + `ensureAuthenticatedSignups`, `signupsFqdn()`, and `signupsRequest` API helper. - Regenerates oclif manifest, README, dev docs, and e2e snapshot. Supersedes #7218.
c3be9fc to
4ca00ba
Compare
Differences in type declarationsWe 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:
New type declarationspackages/cli-kit/dist/public/node/api/signups.d.tsimport { 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 declarationspackages/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.
*
|
Summary
shopify store create trial— a non-interactive way to create a Shopify trial store from the CLI, backed by the Signups APIStoreCreatemutation.shop-createOAuth scope,signupsApiapplication +ensureAuthenticatedSignups,signupsFqdn(), and asignupsRequestAPI helper.@shopify/store(picks up the recent extraction).Supersedes #7218, which targeted the pre-extraction layout and used a flag-based shape (
store create --dev). This PR uses the subcommand shape (store create trial) so sibling commands (e.g. dev stores) can slot in as additional subcommands.Command shape
All flags have env-var equivalents (
SHOPIFY_FLAG_STORE_NAME,SHOPIFY_FLAG_STORE_SUBDOMAIN,SHOPIFY_FLAG_STORE_COUNTRY).--countrydefaults toUS.Test plan
pnpm --filter @shopify/store vitest run— all new unit tests pass (15 tests across command + service)pnpm build— monorepo builds cleanly (cli-kit → store → cli)./packages/cli/bin/run store create trial --name "Plan Test Store"creates a trial store and prints next steps./packages/cli/bin/run store create trial --jsonemits parseable JSON on stdout./packages/cli/bin/run store create trial --subdomain takensurfaces user errors from the Signups APIcommands.txtsnapshot all regenerated from a cold install🤖 Generated with Claude Code