Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/preview-store-create-production.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@shopify/cli': minor
'@shopify/store': minor
---

Add `shopify store create preview` to create preview stores and persist their Admin API token in local store auth.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This is an autogenerated file. Don't edit this file manually.
/**
* The following flags are available for the `store create preview` command:
* @publicDocs
*/
export interface storecreatepreview {
/**
* Two-letter ISO 3166-1 alpha-2 country code for the store, such as US, CA, or GB.
* @environment SHOPIFY_FLAG_PREVIEW_STORE_COUNTRY
*/
'--country <value>'?: string

/**
* Output the result as JSON. Automatically disables color output.
* @environment SHOPIFY_FLAG_JSON
*/
'-j, --json'?: ''

/**
* The name of the store.
* @environment SHOPIFY_FLAG_PREVIEW_STORE_NAME
*/
'--name <value>'?: string

/**
* Disable color output.
* @environment SHOPIFY_FLAG_NO_COLOR
*/
'--no-color'?: ''

/**
* Increase the verbosity of the output.
* @environment SHOPIFY_FLAG_VERBOSE
*/
'--verbose'?: ''
}
56 changes: 56 additions & 0 deletions docs-shopify.dev/generated/generated_docs_data_v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -4184,6 +4184,62 @@
"value": "export interface storeauth {\n /**\n * Output the result as JSON. Automatically disables color output.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Comma-separated Admin API scopes to request for the app.\n * @environment SHOPIFY_FLAG_SCOPES\n */\n '--scopes <value>': string\n\n /**\n * The myshopify.com domain of the store.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <value>': string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}"
}
},
"storecreatepreview": {
"docs-shopify.dev/commands/interfaces/store-create-preview.interface.ts": {
"filePath": "docs-shopify.dev/commands/interfaces/store-create-preview.interface.ts",
"name": "storecreatepreview",
"description": "The following flags are available for the `store create preview` command:",
"isPublicDocs": true,
"members": [
{
"filePath": "docs-shopify.dev/commands/interfaces/store-create-preview.interface.ts",
"syntaxKind": "PropertySignature",
"name": "--country <value>",
"value": "string",
"description": "Two-letter ISO 3166-1 alpha-2 country code for the store, such as US, CA, or GB.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_PREVIEW_STORE_COUNTRY"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-create-preview.interface.ts",
"syntaxKind": "PropertySignature",
"name": "--name <value>",
"value": "string",
"description": "The name of the store.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_PREVIEW_STORE_NAME"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-create-preview.interface.ts",
"syntaxKind": "PropertySignature",
"name": "--no-color",
"value": "''",
"description": "Disable color output.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_NO_COLOR"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-create-preview.interface.ts",
"syntaxKind": "PropertySignature",
"name": "--verbose",
"value": "''",
"description": "Increase the verbosity of the output.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_VERBOSE"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-create-preview.interface.ts",
"syntaxKind": "PropertySignature",
"name": "-j, --json",
"value": "''",
"description": "Output the result as JSON. Automatically disables color output.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_JSON"
}
],
"value": "export interface storecreatepreview {\n /**\n * Two-letter ISO 3166-1 alpha-2 country code for the store, such as US, CA, or GB.\n * @environment SHOPIFY_FLAG_PREVIEW_STORE_COUNTRY\n */\n '--country <value>'?: string\n\n /**\n * Output the result as JSON. Automatically disables color output.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * The name of the store.\n * @environment SHOPIFY_FLAG_PREVIEW_STORE_NAME\n */\n '--name <value>'?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}"
}
},
"storeexecute": {
"docs-shopify.dev/commands/interfaces/store-execute.interface.ts": {
"filePath": "docs-shopify.dev/commands/interfaces/store-execute.interface.ts",
Expand Down
31 changes: 31 additions & 0 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
* [`shopify plugins update`](#shopify-plugins-update)
* [`shopify search [query]`](#shopify-search-query)
* [`shopify store auth`](#shopify-store-auth)
* [`shopify store create preview`](#shopify-store-create-preview)
* [`shopify store execute`](#shopify-store-execute)
* [`shopify store info`](#shopify-store-info)
* [`shopify theme check`](#shopify-theme-check)
Expand Down Expand Up @@ -2131,6 +2132,36 @@ EXAMPLES
$ shopify store auth --store shop.myshopify.com --scopes read_products,write_products --json
```

## `shopify store create preview`

Create a preview Shopify store.

```
USAGE
$ shopify store create preview [--country <value>] [-j] [--name <value>] [--no-color] [--verbose]

FLAGS
-j, --json [env: SHOPIFY_FLAG_JSON] Output the result as JSON. Automatically disables color output.
--country=<value> [env: SHOPIFY_FLAG_PREVIEW_STORE_COUNTRY] Two-letter ISO 3166-1 alpha-2 country code for the
store, such as US, CA, or GB.
--name=<value> [env: SHOPIFY_FLAG_PREVIEW_STORE_NAME] The name of the store.
--no-color [env: SHOPIFY_FLAG_NO_COLOR] Disable color output.
--verbose [env: SHOPIFY_FLAG_VERBOSE] Increase the verbosity of the output.

DESCRIPTION
Create a preview Shopify store.

Creates a new preview Shopify store for a merchant who wants to try Shopify without needing to immediately create an
account.

EXAMPLES
$ shopify store create preview --name "Lavender Candles"

$ shopify store create preview --name "Lavender Candles" --country US

$ shopify store create preview --name "Lavender Candles" --json
```

## `shopify store execute`

Execute GraphQL queries and mutations on a store.
Expand Down
136 changes: 136 additions & 0 deletions packages/cli/oclif.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5812,6 +5812,142 @@
"strict": true,
"summary": "Create a new development store."
},
"store:auth": {
"aliases": [
],
"args": {
},
"customPluginName": "@shopify/store",
"description": "Authenticates the app against the specified store for store commands and stores an online access token for later reuse.\n\nRe-run this command if the stored token is missing, expires, or no longer has the scopes you need.",
"descriptionWithMarkdown": "Authenticates the app against the specified store for store commands and stores an online access token for later reuse.\n\nRe-run this command if the stored token is missing, expires, or no longer has the scopes you need.",
"examples": [
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products",
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products --json"
],
"flags": {
"json": {
"allowNo": false,
"char": "j",
"description": "Output the result as JSON. Automatically disables color output.",
"env": "SHOPIFY_FLAG_JSON",
"hidden": false,
"name": "json",
"type": "boolean"
},
"no-color": {
"allowNo": false,
"description": "Disable color output.",
"env": "SHOPIFY_FLAG_NO_COLOR",
"hidden": false,
"name": "no-color",
"type": "boolean"
},
"scopes": {
"description": "Comma-separated Admin API scopes to request for the app.",
"env": "SHOPIFY_FLAG_SCOPES",
"hasDynamicHelp": false,
"multiple": false,
"name": "scopes",
"required": true,
"type": "option"
},
"store": {
"char": "s",
"description": "The myshopify.com domain of the store.",
"env": "SHOPIFY_FLAG_STORE",
"hasDynamicHelp": false,
"multiple": false,
"name": "store",
"required": true,
"type": "option"
},
"verbose": {
"allowNo": false,
"description": "Increase the verbosity of the output.",
"env": "SHOPIFY_FLAG_VERBOSE",
"hidden": false,
"name": "verbose",
"type": "boolean"
}
},
"hasDynamicHelp": false,
"hiddenAliases": [
],
"id": "store:auth",
"pluginAlias": "@shopify/cli",
"pluginName": "@shopify/cli",
"pluginType": "core",
"strict": true,
"summary": "Authenticate an app against a store for store commands."
},
"store:create:preview": {
"aliases": [
],
"args": {
},
"customPluginName": "@shopify/store",
"description": "Creates a new preview Shopify store for a merchant who wants to try Shopify without needing to immediately create an account.",
"descriptionWithMarkdown": "Creates a new preview Shopify store for a merchant who wants to try Shopify without needing to immediately create an account.",
"examples": [
"<%= config.bin %> <%= command.id %> --name \"Lavender Candles\"",
"<%= config.bin %> <%= command.id %> --name \"Lavender Candles\" --country US",
"<%= config.bin %> <%= command.id %> --name \"Lavender Candles\" --json"
],
"flags": {
"country": {
"description": "Two-letter ISO 3166-1 alpha-2 country code for the store, such as US, CA, or GB.",
"env": "SHOPIFY_FLAG_PREVIEW_STORE_COUNTRY",
"hasDynamicHelp": false,
"multiple": false,
"name": "country",
"required": false,
"type": "option"
},
"json": {
"allowNo": false,
"char": "j",
"description": "Output the result as JSON. Automatically disables color output.",
"env": "SHOPIFY_FLAG_JSON",
"hidden": false,
"name": "json",
"type": "boolean"
},
"name": {
"description": "The name of the store.",
"env": "SHOPIFY_FLAG_PREVIEW_STORE_NAME",
"hasDynamicHelp": false,
"multiple": false,
"name": "name",
"required": false,
"type": "option"
},
"no-color": {
"allowNo": false,
"description": "Disable color output.",
"env": "SHOPIFY_FLAG_NO_COLOR",
"hidden": false,
"name": "no-color",
"type": "boolean"
},
"verbose": {
"allowNo": false,
"description": "Increase the verbosity of the output.",
"env": "SHOPIFY_FLAG_VERBOSE",
"hidden": false,
"name": "verbose",
"type": "boolean"
}
},
"hasDynamicHelp": false,
"hiddenAliases": [
],
"id": "store:create:preview",
"pluginAlias": "@shopify/cli",
"pluginName": "@shopify/cli",
"pluginType": "core",
"strict": true,
"summary": "Create a preview Shopify store."
},
"store:execute": {
"aliases": [
],
Expand Down
2 changes: 2 additions & 0 deletions packages/e2e/data/snapshots/commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@
├─ search
├─ store
│ ├─ auth
│ ├─ create
│ │ └─ preview
│ ├─ execute
│ └─ info
├─ theme
Expand Down
45 changes: 45 additions & 0 deletions packages/store/src/cli/commands/store/create/preview.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import StoreCreatePreview from './preview.js'
import {createPreviewStoreCommand} from '../../../services/store/create/preview/index.js'
import {writeCreatePreviewStoreResult} from '../../../services/store/create/preview/result.js'
import {renderSingleTask} from '@shopify/cli-kit/node/ui'
import {describe, expect, test, vi} from 'vitest'

vi.mock('../../../services/store/create/preview/index.js')
vi.mock('../../../services/store/create/preview/result.js')
vi.mock('@shopify/cli-kit/node/ui', async () => {
const actual = await vi.importActual<typeof import('@shopify/cli-kit/node/ui')>('@shopify/cli-kit/node/ui')
return {...actual, renderSingleTask: vi.fn(async ({task}) => task())}
})

describe('store create preview command', () => {
test('passes parsed flags through to the service', async () => {
const result = {
status: 'success' as const,
message: 'Your preview store is ready.',
store: {
id: '123',
name: 'Lavender Candles',
subdomain: 'x.myshopify.com',
accessUrl: 'https://app.shopify.com/auth/preview-store?token=access-token',
requestedCountry: 'US',
},
nextSteps: [],
}
vi.mocked(createPreviewStoreCommand).mockResolvedValueOnce(result)

await StoreCreatePreview.run(['--name', 'Lavender Candles', '--country', 'us', '--json'])

expect(renderSingleTask).toHaveBeenCalledWith({
title: expect.objectContaining({value: 'Creating store…'}),
task: expect.any(Function),
})
expect(createPreviewStoreCommand).toHaveBeenCalledWith({name: 'Lavender Candles', country: 'US'})
expect(writeCreatePreviewStoreResult).toHaveBeenCalledWith(result, 'json')
})

test('rejects invalid country codes before calling the service', async () => {
await expect(StoreCreatePreview.run(['--country', 'USA'])).rejects.toThrow('process.exit unexpectedly called')

expect(createPreviewStoreCommand).not.toHaveBeenCalled()
})
})
Loading
Loading