diff --git a/.changeset/wet-bats-glow.md b/.changeset/wet-bats-glow.md new file mode 100644 index 00000000000..5cb48f8ffa2 --- /dev/null +++ b/.changeset/wet-bats-glow.md @@ -0,0 +1,14 @@ +--- +'@shopify/cli-kit': patch +'@shopify/theme': patch +'@shopify/app': patch +--- + +Updated the environment flag to support glob patterns + +For commands that support multiple environments you can now use glob patterns +to specify the environments, e.g. `--environment "*-production"`. It's important +to wrap any glob patterns in quotes to ensure your shell does not expand the +value before passing it to the CLI. + +This comes with a side effect that environments will be deduplicated. diff --git a/bin/shadowenv/p b/bin/shadowenv/p index 885a204f325..a767a62c506 100755 --- a/bin/shadowenv/p +++ b/bin/shadowenv/p @@ -2,4 +2,4 @@ set -e printf "\033[0;32mNote that p is an alias for pnpm activated by shadowenv in the CLI repository\n\033[0m" -pnpm $@ +pnpm "$@" diff --git a/docs-shopify.dev/commands/interfaces/theme-check.interface.ts b/docs-shopify.dev/commands/interfaces/theme-check.interface.ts index 41a0493b342..16cd27e1de6 100644 --- a/docs-shopify.dev/commands/interfaces/theme-check.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-check.interface.ts @@ -16,7 +16,7 @@ export interface themecheck { '-C, --config '?: string /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-console.interface.ts b/docs-shopify.dev/commands/interfaces/theme-console.interface.ts index c9d81358925..4198564308e 100644 --- a/docs-shopify.dev/commands/interfaces/theme-console.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-console.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface themeconsole { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-delete.interface.ts b/docs-shopify.dev/commands/interfaces/theme-delete.interface.ts index 6890abc352a..67b858d1709 100644 --- a/docs-shopify.dev/commands/interfaces/theme-delete.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-delete.interface.ts @@ -7,7 +7,7 @@ export interface themedelete { '-d, --development'?: '' /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-dev.interface.ts b/docs-shopify.dev/commands/interfaces/theme-dev.interface.ts index 749065eb303..be7d8290ae4 100644 --- a/docs-shopify.dev/commands/interfaces/theme-dev.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-dev.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface themedev { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-duplicate.interface.ts b/docs-shopify.dev/commands/interfaces/theme-duplicate.interface.ts index 2e3a5ae3d6b..234a37295f7 100644 --- a/docs-shopify.dev/commands/interfaces/theme-duplicate.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-duplicate.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface themeduplicate { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-info.interface.ts b/docs-shopify.dev/commands/interfaces/theme-info.interface.ts index 55245759eac..cace0a34b4b 100644 --- a/docs-shopify.dev/commands/interfaces/theme-info.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-info.interface.ts @@ -7,7 +7,7 @@ export interface themeinfo { '-d, --development'?: '' /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-list.interface.ts b/docs-shopify.dev/commands/interfaces/theme-list.interface.ts index 38781b99713..0d017293513 100644 --- a/docs-shopify.dev/commands/interfaces/theme-list.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-list.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface themelist { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-metafields-pull.interface.ts b/docs-shopify.dev/commands/interfaces/theme-metafields-pull.interface.ts index ac3708129fa..11eee519b54 100644 --- a/docs-shopify.dev/commands/interfaces/theme-metafields-pull.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-metafields-pull.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface thememetafieldspull { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-open.interface.ts b/docs-shopify.dev/commands/interfaces/theme-open.interface.ts index a13ccdd69d5..8cdb6d63c28 100644 --- a/docs-shopify.dev/commands/interfaces/theme-open.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-open.interface.ts @@ -13,7 +13,7 @@ export interface themeopen { '-E, --editor'?: '' /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-profile.interface.ts b/docs-shopify.dev/commands/interfaces/theme-profile.interface.ts index 93a66fd02f3..20b0f607614 100644 --- a/docs-shopify.dev/commands/interfaces/theme-profile.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-profile.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface themeprofile { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-publish.interface.ts b/docs-shopify.dev/commands/interfaces/theme-publish.interface.ts index 26f8b4b5a50..ed22c399087 100644 --- a/docs-shopify.dev/commands/interfaces/theme-publish.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-publish.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface themepublish { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-pull.interface.ts b/docs-shopify.dev/commands/interfaces/theme-pull.interface.ts index 235a5456cb9..e16c1686fdf 100644 --- a/docs-shopify.dev/commands/interfaces/theme-pull.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-pull.interface.ts @@ -7,7 +7,7 @@ export interface themepull { '-d, --development'?: '' /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-push.interface.ts b/docs-shopify.dev/commands/interfaces/theme-push.interface.ts index 26d656ce04e..5b4e3fc8251 100644 --- a/docs-shopify.dev/commands/interfaces/theme-push.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-push.interface.ts @@ -13,7 +13,7 @@ export interface themepush { '-d, --development'?: '' /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-rename.interface.ts b/docs-shopify.dev/commands/interfaces/theme-rename.interface.ts index e7343cd649e..47e670a0a4d 100644 --- a/docs-shopify.dev/commands/interfaces/theme-rename.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-rename.interface.ts @@ -7,7 +7,7 @@ export interface themerename { '-d, --development'?: '' /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/commands/interfaces/theme-share.interface.ts b/docs-shopify.dev/commands/interfaces/theme-share.interface.ts index c4ad87bc9e7..6a33b6ede3e 100644 --- a/docs-shopify.dev/commands/interfaces/theme-share.interface.ts +++ b/docs-shopify.dev/commands/interfaces/theme-share.interface.ts @@ -1,7 +1,7 @@ // This is an autogenerated file. Don't edit this file manually. export interface themeshare { /** - * The environment to apply to the current command. + * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards. * @environment SHOPIFY_FLAG_ENVIRONMENT */ '-e, --environment '?: string diff --git a/docs-shopify.dev/generated/generated_docs_data.json b/docs-shopify.dev/generated/generated_docs_data.json index e0cfeec8247..40b1e4bd3bc 100644 --- a/docs-shopify.dev/generated/generated_docs_data.json +++ b/docs-shopify.dev/generated/generated_docs_data.json @@ -4828,7 +4828,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -4851,7 +4851,7 @@ "environmentValue": "SHOPIFY_FLAG_VERSION" } ], - "value": "export interface themecheck {\n /**\n * Automatically fix offenses\n * @environment SHOPIFY_FLAG_AUTO_CORRECT\n */\n '-a, --auto-correct'?: ''\n\n /**\n * Use the config provided, overriding .theme-check.yml if present\n Supports all theme-check: config values, e.g., theme-check:theme-app-extension,\n theme-check:recommended, theme-check:all\n For backwards compatibility, :theme_app_extension is also supported \n * @environment SHOPIFY_FLAG_CONFIG\n */\n '-C, --config '?: string\n\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Minimum severity for exit with error code\n * @environment SHOPIFY_FLAG_FAIL_LEVEL\n */\n '--fail-level '?: string\n\n /**\n * Generate a .theme-check.yml file\n * @environment SHOPIFY_FLAG_INIT\n */\n '--init'?: ''\n\n /**\n * List enabled checks\n * @environment SHOPIFY_FLAG_LIST\n */\n '--list'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * The output format to use\n * @environment SHOPIFY_FLAG_OUTPUT\n */\n '-o, --output '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Output active config to STDOUT\n * @environment SHOPIFY_FLAG_PRINT\n */\n '--print'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n\n /**\n * Print Theme Check version\n * @environment SHOPIFY_FLAG_VERSION\n */\n '-v, --version'?: ''\n}" + "value": "export interface themecheck {\n /**\n * Automatically fix offenses\n * @environment SHOPIFY_FLAG_AUTO_CORRECT\n */\n '-a, --auto-correct'?: ''\n\n /**\n * Use the config provided, overriding .theme-check.yml if present\n Supports all theme-check: config values, e.g., theme-check:theme-app-extension,\n theme-check:recommended, theme-check:all\n For backwards compatibility, :theme_app_extension is also supported \n * @environment SHOPIFY_FLAG_CONFIG\n */\n '-C, --config '?: string\n\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Minimum severity for exit with error code\n * @environment SHOPIFY_FLAG_FAIL_LEVEL\n */\n '--fail-level '?: string\n\n /**\n * Generate a .theme-check.yml file\n * @environment SHOPIFY_FLAG_INIT\n */\n '--init'?: ''\n\n /**\n * List enabled checks\n * @environment SHOPIFY_FLAG_LIST\n */\n '--list'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * The output format to use\n * @environment SHOPIFY_FLAG_OUTPUT\n */\n '-o, --output '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Output active config to STDOUT\n * @environment SHOPIFY_FLAG_PRINT\n */\n '--print'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n\n /**\n * Print Theme Check version\n * @environment SHOPIFY_FLAG_VERSION\n */\n '-v, --version'?: ''\n}" } } } @@ -4947,7 +4947,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -4961,7 +4961,7 @@ "environmentValue": "SHOPIFY_FLAG_STORE" } ], - "value": "export interface themeconsole {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password '?: string\n\n /**\n * The url to be used as context\n * @environment SHOPIFY_FLAG_URL\n */\n '--url '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themeconsole {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password '?: string\n\n /**\n * The url to be used as context\n * @environment SHOPIFY_FLAG_URL\n */\n '--url '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -5057,7 +5057,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -5089,7 +5089,7 @@ "environmentValue": "SHOPIFY_FLAG_THEME_ID" } ], - "value": "export interface themedelete {\n /**\n * Delete your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip confirmation.\n * @environment SHOPIFY_FLAG_FORCE\n */\n '-f, --force'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Include others development themes in theme list.\n * @environment SHOPIFY_FLAG_SHOW_ALL\n */\n '-a, --show-all'?: ''\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themedelete {\n /**\n * Delete your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip confirmation.\n * @environment SHOPIFY_FLAG_FORCE\n */\n '-f, --force'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Include others development themes in theme list.\n * @environment SHOPIFY_FLAG_SHOW_ALL\n */\n '-a, --show-all'?: ''\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -5239,7 +5239,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -5289,7 +5289,7 @@ "environmentValue": "SHOPIFY_FLAG_IGNORE" } ], - "value": "export interface themedev {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Controls the visibility of the error overlay when an theme asset upload fails:\n- silent Prevents the error overlay from appearing.\n- default Displays the error overlay.\n \n * @environment SHOPIFY_FLAG_ERROR_OVERLAY\n */\n '--error-overlay '?: string\n\n /**\n * Set which network interface the web server listens on. The default value is 127.0.0.1.\n * @environment SHOPIFY_FLAG_HOST\n */\n '--host '?: string\n\n /**\n * Skip hot reloading any files that match the specified pattern.\n * @environment SHOPIFY_FLAG_IGNORE\n */\n '-x, --ignore '?: string\n\n /**\n * The live reload mode switches the server behavior when a file is modified:\n- hot-reload Hot reloads local changes to CSS and sections (default)\n- full-page Always refreshes the entire page\n- off Deactivate live reload\n * @environment SHOPIFY_FLAG_LIVE_RELOAD\n */\n '--live-reload '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Prevents files from being deleted in the remote theme when a file has been deleted locally. This applies to files that are deleted while the command is running, and files that have been deleted locally before the command is run.\n * @environment SHOPIFY_FLAG_NODELETE\n */\n '-n, --nodelete'?: ''\n\n /**\n * The file path or URL. The file path is to a file that you want updated on idle. The URL path is where you want a webhook posted to report on file changes.\n * @environment SHOPIFY_FLAG_NOTIFY\n */\n '--notify '?: string\n\n /**\n * Hot reload only files that match the specified pattern.\n * @environment SHOPIFY_FLAG_ONLY\n */\n '-o, --only '?: string\n\n /**\n * Automatically launch the theme preview in your default web browser.\n * @environment SHOPIFY_FLAG_OPEN\n */\n '--open'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Local port to serve theme preview from.\n * @environment SHOPIFY_FLAG_PORT\n */\n '--port '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Synchronize Theme Editor updates in the local theme files.\n * @environment SHOPIFY_FLAG_THEME_EDITOR_SYNC\n */\n '--theme-editor-sync'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themedev {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Controls the visibility of the error overlay when an theme asset upload fails:\n- silent Prevents the error overlay from appearing.\n- default Displays the error overlay.\n \n * @environment SHOPIFY_FLAG_ERROR_OVERLAY\n */\n '--error-overlay '?: string\n\n /**\n * Set which network interface the web server listens on. The default value is 127.0.0.1.\n * @environment SHOPIFY_FLAG_HOST\n */\n '--host '?: string\n\n /**\n * Skip hot reloading any files that match the specified pattern.\n * @environment SHOPIFY_FLAG_IGNORE\n */\n '-x, --ignore '?: string\n\n /**\n * The live reload mode switches the server behavior when a file is modified:\n- hot-reload Hot reloads local changes to CSS and sections (default)\n- full-page Always refreshes the entire page\n- off Deactivate live reload\n * @environment SHOPIFY_FLAG_LIVE_RELOAD\n */\n '--live-reload '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Prevents files from being deleted in the remote theme when a file has been deleted locally. This applies to files that are deleted while the command is running, and files that have been deleted locally before the command is run.\n * @environment SHOPIFY_FLAG_NODELETE\n */\n '-n, --nodelete'?: ''\n\n /**\n * The file path or URL. The file path is to a file that you want updated on idle. The URL path is where you want a webhook posted to report on file changes.\n * @environment SHOPIFY_FLAG_NOTIFY\n */\n '--notify '?: string\n\n /**\n * Hot reload only files that match the specified pattern.\n * @environment SHOPIFY_FLAG_ONLY\n */\n '-o, --only '?: string\n\n /**\n * Automatically launch the theme preview in your default web browser.\n * @environment SHOPIFY_FLAG_OPEN\n */\n '--open'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Local port to serve theme preview from.\n * @environment SHOPIFY_FLAG_PORT\n */\n '--port '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Synchronize Theme Editor updates in the local theme files.\n * @environment SHOPIFY_FLAG_THEME_EDITOR_SYNC\n */\n '--theme-editor-sync'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -5358,7 +5358,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -5408,7 +5408,7 @@ "environmentValue": "SHOPIFY_FLAG_THEME_ID" } ], - "value": "export interface themeduplicate {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Force the duplicate operation to run without prompts or confirmations.\n * @environment SHOPIFY_FLAG_FORCE\n */\n '-f, --force'?: ''\n\n /**\n * Output the result as JSON.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Name of the newly duplicated theme.\n * @environment SHOPIFY_FLAG_NAME\n */\n '-n, --name '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themeduplicate {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Force the duplicate operation to run without prompts or confirmations.\n * @environment SHOPIFY_FLAG_FORCE\n */\n '-f, --force'?: ''\n\n /**\n * Output the result as JSON.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Name of the newly duplicated theme.\n * @environment SHOPIFY_FLAG_NAME\n */\n '-n, --name '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -5495,7 +5495,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -5527,7 +5527,7 @@ "environmentValue": "SHOPIFY_FLAG_THEME_ID" } ], - "value": "export interface themeinfo {\n /**\n * Retrieve info from your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Output the result as JSON.\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 * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themeinfo {\n /**\n * Retrieve info from your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Output the result as JSON.\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 * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -5771,7 +5771,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -5794,7 +5794,7 @@ "environmentValue": "SHOPIFY_FLAG_STORE" } ], - "value": "export interface themelist {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Only list theme with the given ID.\n * @environment SHOPIFY_FLAG_ID\n */\n '--id '?: string\n\n /**\n * Output the result as JSON.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Only list themes that contain the given name.\n * @environment SHOPIFY_FLAG_NAME\n */\n '--name '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Only list themes with the given role.\n * @environment SHOPIFY_FLAG_ROLE\n */\n '--role '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themelist {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Only list theme with the given ID.\n * @environment SHOPIFY_FLAG_ID\n */\n '--id '?: string\n\n /**\n * Output the result as JSON.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Only list themes that contain the given name.\n * @environment SHOPIFY_FLAG_NAME\n */\n '--name '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Only list themes with the given role.\n * @environment SHOPIFY_FLAG_ROLE\n */\n '--role '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -5872,7 +5872,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -5886,7 +5886,7 @@ "environmentValue": "SHOPIFY_FLAG_STORE" } ], - "value": "export interface thememetafieldspull {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface thememetafieldspull {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -5982,7 +5982,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -6014,7 +6014,7 @@ "environmentValue": "SHOPIFY_FLAG_THEME_ID" } ], - "value": "export interface themeopen {\n /**\n * Open your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * Open the theme editor for the specified theme in the browser.\n * @environment SHOPIFY_FLAG_EDITOR\n */\n '-E, --editor'?: ''\n\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Open your live (published) theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themeopen {\n /**\n * Open your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * Open the theme editor for the specified theme in the browser.\n * @environment SHOPIFY_FLAG_EDITOR\n */\n '-E, --editor'?: ''\n\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Open your live (published) theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -6175,7 +6175,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -6207,7 +6207,7 @@ "environmentValue": "SHOPIFY_FLAG_THEME_ID" } ], - "value": "export interface themeprofile {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Output the result as JSON.\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 * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * The url to be used as context\n * @environment SHOPIFY_FLAG_URL\n */\n '--url '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themeprofile {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Output the result as JSON.\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 * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * The password for storefronts with password protection.\n * @environment SHOPIFY_FLAG_STORE_PASSWORD\n */\n '--store-password '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * The url to be used as context\n * @environment SHOPIFY_FLAG_URL\n */\n '--url '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -6285,7 +6285,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -6317,7 +6317,7 @@ "environmentValue": "SHOPIFY_FLAG_THEME_ID" } ], - "value": "export interface themepublish {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip confirmation.\n * @environment SHOPIFY_FLAG_FORCE\n */\n '-f, --force'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themepublish {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip confirmation.\n * @environment SHOPIFY_FLAG_FORCE\n */\n '-f, --force'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -6404,7 +6404,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -6463,7 +6463,7 @@ "environmentValue": "SHOPIFY_FLAG_IGNORE" } ], - "value": "export interface themepull {\n /**\n * Pull theme files from your remote development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip downloading the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_IGNORE\n */\n '-x, --ignore '?: string\n\n /**\n * Pull theme files from your remote live theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Prevent deleting local files that don't exist remotely.\n * @environment SHOPIFY_FLAG_NODELETE\n */\n '-n, --nodelete'?: ''\n\n /**\n * Download only the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ONLY\n */\n '-o, --only '?: string\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themepull {\n /**\n * Pull theme files from your remote development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip downloading the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_IGNORE\n */\n '-x, --ignore '?: string\n\n /**\n * Pull theme files from your remote live theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Prevent deleting local files that don't exist remotely.\n * @environment SHOPIFY_FLAG_NODELETE\n */\n '-n, --nodelete'?: ''\n\n /**\n * Download only the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ONLY\n */\n '-o, --only '?: string\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -6568,7 +6568,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -6654,7 +6654,7 @@ "environmentValue": "SHOPIFY_FLAG_IGNORE" } ], - "value": "export interface themepush {\n /**\n * Allow push to a live theme.\n * @environment SHOPIFY_FLAG_ALLOW_LIVE\n */\n '-a, --allow-live'?: ''\n\n /**\n * Push theme files from your remote development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip uploading the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_IGNORE\n */\n '-x, --ignore '?: string\n\n /**\n * Output the result as JSON.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Push theme files from your remote live theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Prevent deleting remote files that don't exist locally.\n * @environment SHOPIFY_FLAG_NODELETE\n */\n '-n, --nodelete'?: ''\n\n /**\n * Upload only the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ONLY\n */\n '-o, --only '?: string\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Publish as the live theme after uploading.\n * @environment SHOPIFY_FLAG_PUBLISH\n */\n '-p, --publish'?: ''\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Require theme check to pass without errors before pushing. Warnings are allowed.\n * @environment SHOPIFY_FLAG_STRICT_PUSH\n */\n '--strict'?: ''\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Create a new unpublished theme and push to it.\n * @environment SHOPIFY_FLAG_UNPUBLISHED\n */\n '-u, --unpublished'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themepush {\n /**\n * Allow push to a live theme.\n * @environment SHOPIFY_FLAG_ALLOW_LIVE\n */\n '-a, --allow-live'?: ''\n\n /**\n * Push theme files from your remote development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Skip uploading the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_IGNORE\n */\n '-x, --ignore '?: string\n\n /**\n * Output the result as JSON.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Push theme files from your remote live theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Prevent deleting remote files that don't exist locally.\n * @environment SHOPIFY_FLAG_NODELETE\n */\n '-n, --nodelete'?: ''\n\n /**\n * Upload only the specified files (Multiple flags allowed). Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ONLY\n */\n '-o, --only '?: string\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Publish as the live theme after uploading.\n * @environment SHOPIFY_FLAG_PUBLISH\n */\n '-p, --publish'?: ''\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Require theme check to pass without errors before pushing. Warnings are allowed.\n * @environment SHOPIFY_FLAG_STRICT_PUSH\n */\n '--strict'?: ''\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Create a new unpublished theme and push to it.\n * @environment SHOPIFY_FLAG_UNPUBLISHED\n */\n '-u, --unpublished'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -6741,7 +6741,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -6782,7 +6782,7 @@ "environmentValue": "SHOPIFY_FLAG_THEME_ID" } ], - "value": "export interface themerename {\n /**\n * Rename your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Rename your remote live theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * The new name for the theme.\n * @environment SHOPIFY_FLAG_NEW_NAME\n */\n '-n, --name '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themerename {\n /**\n * Rename your development theme.\n * @environment SHOPIFY_FLAG_DEVELOPMENT\n */\n '-d, --development'?: ''\n\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Rename your remote live theme.\n * @environment SHOPIFY_FLAG_LIVE\n */\n '-l, --live'?: ''\n\n /**\n * The new name for the theme.\n * @environment SHOPIFY_FLAG_NEW_NAME\n */\n '-n, --name '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Theme ID or name of the remote theme.\n * @environment SHOPIFY_FLAG_THEME_ID\n */\n '-t, --theme '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } @@ -6860,7 +6860,7 @@ "syntaxKind": "PropertySignature", "name": "-e, --environment ", "value": "string", - "description": "The environment to apply to the current command.", + "description": "The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_ENVIRONMENT" }, @@ -6874,7 +6874,7 @@ "environmentValue": "SHOPIFY_FLAG_STORE" } ], - "value": "export interface themeshare {\n /**\n * The environment to apply to the current command.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface themeshare {\n /**\n * The environment to apply to the current command. Wrap the value in double quotes if you're using wildcards.\n * @environment SHOPIFY_FLAG_ENVIRONMENT\n */\n '-e, --environment '?: string\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Password generated from the Theme Access app.\n * @environment SHOPIFY_CLI_THEME_TOKEN\n */\n '--password '?: string\n\n /**\n * The path where you want to run the command. Defaults to the current working directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com).\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store '?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } } } diff --git a/packages/cli-kit/src/public/node/base-command.test.ts b/packages/cli-kit/src/public/node/base-command.test.ts index 54677ce00de..86ff9b39ab4 100644 --- a/packages/cli-kit/src/public/node/base-command.test.ts +++ b/packages/cli-kit/src/public/node/base-command.test.ts @@ -203,12 +203,19 @@ describe('applying environments', async () => { outputMock.clear() // When - await MockCommand.run(['--path', tmpDir, '--environment', 'validEnvironment', '--environment', 'validEnvironment']) + await MockCommand.run([ + '--path', + tmpDir, + '--environment', + 'validEnvironment', + '--environment', + 'environmentWithPassword', + ]) // Then expect(testResult).toEqual({ path: resolvePath(tmpDir), - environment: ['validEnvironment', 'validEnvironment'], + environment: ['validEnvironment', 'environmentWithPassword'], someStringWithDefault: 'default stringy', }) expect(outputMock.info()).toEqual('') diff --git a/packages/cli-kit/src/public/node/base-command.ts b/packages/cli-kit/src/public/node/base-command.ts index 0269efed6df..83db9f22726 100644 --- a/packages/cli-kit/src/public/node/base-command.ts +++ b/packages/cli-kit/src/public/node/base-command.ts @@ -1,5 +1,5 @@ import {errorHandler, registerCleanBugsnagErrorsFromWithinPlugins} from './error-handler.js' -import {loadEnvironment, environmentFilePath} from './environments.js' +import {loadEnvironment, environmentFilePath, expandEnvironmentPatterns} from './environments.js' import {isDevelopment} from './context/local.js' import {addPublicMetadata} from './metadata.js' import {AbortError} from './error.js' @@ -146,19 +146,32 @@ This flag is required in non-interactive terminal environments, such as a CI env const environmentFileExists = await environmentFilePath(environmentsFileName, {from: flags.path}) // Handle both string and array cases for environment flag - let environments: string[] = [] + let environmentPatterns: string[] = [] if (flags.environment) { - environments = Array.isArray(flags.environment) ? flags.environment : [flags.environment] + environmentPatterns = Array.isArray(flags.environment) ? flags.environment : [flags.environment] } - const environmentSpecified = environments.length > 0 + const environmentSpecified = environmentPatterns.length > 0 // Noop if no environment file exists and none was specified if (!environmentFileExists && !environmentSpecified) return originalResult + // Theme commands can have environment names with glob patterns, in order + // to check if there are multiple environments being specified we need to + // expand them before continuing even if other commands might not support + // multi environment behaviour. + const environments = await expandEnvironmentPatterns(environmentPatterns, environmentsFileName, { + from: flags.path, + silent: true, + }) + // Noop if multiple environments were specified (let commands handle this) if (environmentSpecified && environments.length > 1) return originalResult + // If no environments matched but one was specified we should return now and + // avoid loading a default environment + if (environments.length === 0 && environmentSpecified) return originalResult + const {environment, isDefaultEnvironment} = await this.loadEnvironmentForCommand( flags.path, environmentsFileName, diff --git a/packages/cli-kit/src/public/node/environments.test.ts b/packages/cli-kit/src/public/node/environments.test.ts index 888ae04d58a..e5e4557a595 100644 --- a/packages/cli-kit/src/public/node/environments.test.ts +++ b/packages/cli-kit/src/public/node/environments.test.ts @@ -132,3 +132,199 @@ describe('loading environments', async () => { }) }) }) + +describe('getEnvironmentNames', () => { + test('returns all environment names', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const filePath = joinPath(tmpDir, fileName) + await writeFile(filePath, tomlEncode({environments: {environment1, environment2}})) + + // When + const names = await environments.getEnvironmentNames(fileName, {from: tmpDir}) + + // Then + expect(names).toEqual(['environment1', 'environment2']) + }) + }) + + describe('when no environment file exists', () => { + test('returns empty array', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // When + const names = await environments.getEnvironmentNames(fileName, {from: tmpDir}) + + // Then + expect(names).toEqual([]) + }) + }) + }) + + describe('when environment file is empty', () => { + test('returns empty array', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const filePath = joinPath(tmpDir, fileName) + await writeFile(filePath, '# no content') + + // When + const names = await environments.getEnvironmentNames(fileName, {from: tmpDir}) + + // Then + expect(names).toEqual([]) + }) + }) + }) +}) + +describe('expandEnvironmentPatterns', () => { + test('returns dedeuplicated environment names', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const filePath = joinPath(tmpDir, fileName) + await writeFile( + filePath, + tomlEncode({ + environments: { + 'us-production': {store: 'us-store'}, + 'ca-production': {store: 'ca-store'}, + }, + }), + ) + + // When + const expanded = await environments.expandEnvironmentPatterns(['us-production', 'us-production'], fileName, { + from: tmpDir, + }) + + // Then + expect(expanded).toEqual(['us-production']) + }) + }) + + describe('when the pattern contains glob characters', () => { + test('expands glob pattern to return multiple environments', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const filePath = joinPath(tmpDir, fileName) + await writeFile( + filePath, + tomlEncode({ + environments: { + 'us-production': {store: 'us-store'}, + 'ca-production': {store: 'ca-store'}, + 'de-production': {store: 'de-store'}, + 'us-staging': {store: 'us-staging-store'}, + }, + }), + ) + + // When + const expanded = await environments.expandEnvironmentPatterns(['*-production'], fileName, {from: tmpDir}) + + // Then + expect(expanded.sort()).toEqual(['ca-production', 'de-production', 'us-production']) + }) + }) + + test('supports question mark glob patterns', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const filePath = joinPath(tmpDir, fileName) + await writeFile( + filePath, + tomlEncode({ + environments: { + 'us-production': {store: 'us-store'}, + 'uk-production': {store: 'uk-store'}, + 'usa-production': {store: 'usa-store'}, + }, + }), + ) + + // When + const expanded = await environments.expandEnvironmentPatterns(['u?-production'], fileName, {from: tmpDir}) + + // Then + expect(expanded.sort()).toEqual(['uk-production', 'us-production']) + }) + }) + + test('supports square bracket glob patterns', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const filePath = joinPath(tmpDir, fileName) + await writeFile( + filePath, + tomlEncode({ + environments: { + 'us-production': {store: 'us-store'}, + 'uk-production': {store: 'uk-store'}, + 'usa-production': {store: 'usa-store'}, + }, + }), + ) + + // When + const expanded = await environments.expandEnvironmentPatterns(['u[a-z]-production'], fileName, {from: tmpDir}) + + // Then + expect(expanded.sort()).toEqual(['uk-production', 'us-production']) + }) + }) + + test('supports curly bracket glob patterns', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const filePath = joinPath(tmpDir, fileName) + await writeFile( + filePath, + tomlEncode({ + environments: { + 'us-production': {store: 'us-store'}, + 'uk-production': {store: 'uk-store'}, + 'usa-production': {store: 'usa-store'}, + }, + }), + ) + + // When + const expanded = await environments.expandEnvironmentPatterns(['{uk,us}-production'], fileName, {from: tmpDir}) + + // Then + expect(expanded.sort()).toEqual(['uk-production', 'us-production']) + }) + }) + }) + + test('renders a warning if no match is found', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + const outputMock = mockAndCaptureOutput() + outputMock.clear() + const filePath = joinPath(tmpDir, fileName) + await writeFile( + filePath, + tomlEncode({ + environments: { + 'us-production': {store: 'us-store'}, + }, + }), + ) + + // When + const expanded = await environments.expandEnvironmentPatterns(['nonexistent'], fileName, {from: tmpDir}) + + // Then + expect(expanded).toEqual([]) + expect(outputMock.warn()).toMatchInlineSnapshot(` + "╭─ warning ────────────────────────────────────────────────────────────────────╮ + │ │ + │ Could not find any environments matching \`nonexistent\` │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────╯ + " + `) + }) + }) +}) diff --git a/packages/cli-kit/src/public/node/environments.ts b/packages/cli-kit/src/public/node/environments.ts index 2555f7cc775..89509db729f 100644 --- a/packages/cli-kit/src/public/node/environments.ts +++ b/packages/cli-kit/src/public/node/environments.ts @@ -4,6 +4,7 @@ import {cwd} from './path.js' import * as metadata from './metadata.js' import {renderWarning} from './ui.js' import {JsonMap} from '../../private/common/json.js' +import {minimatch} from 'minimatch' export interface Environments { [name: string]: JsonMap @@ -27,30 +28,21 @@ function renderWarningIfNeeded(message: Parameters[0], sil /** * Loads environments from a file. - * @param dir - The file path to load environments from. - * @returns The loaded environments. + * @param environmentName - The name of the environment. + * @param fileName - The file name to load environments from. + * @param options - Optional configuration for loading. + * @returns The loaded environment. */ export async function loadEnvironment( environmentName: string, fileName: string, options?: LoadEnvironmentOptions, ): Promise { - const filePath = await environmentFilePath(fileName, options) - if (!filePath) { - renderWarningIfNeeded({body: 'Environment file not found.'}, options?.silent) - return undefined - } - const environmentsJson = decodeToml(await readFile(filePath)) as Environments - const environments = environmentsJson.environments + const environments = await decodeEnvironments(fileName, options) if (!environments) { - renderWarningIfNeeded( - { - body: ['No environments found in', {command: filePath}, {char: '.'}], - }, - options?.silent, - ) return undefined } + const environment = environments[environmentName] as JsonMap | undefined if (!environment) { @@ -80,3 +72,76 @@ export async function environmentFilePath( type: 'file', }) } + +async function decodeEnvironments(fileName: string, options?: LoadEnvironmentOptions): Promise { + const filePath = await environmentFilePath(fileName, options) + + if (!filePath) { + renderWarningIfNeeded({body: 'Environment file not found.'}, options?.silent) + return undefined + } + + const environmentsJson = decodeToml(await readFile(filePath)) as Environments + const environments = environmentsJson.environments + + if (!environments) { + renderWarningIfNeeded( + { + body: ['No environments found in', {command: filePath}, {char: '.'}], + }, + options?.silent, + ) + return undefined + } + + return environments +} + +/** + * Gets all available environment names from a file. + * @param fileName - The file name to load environments from. + * @param options - Optional configuration for loading. + * @returns Array of environment names, or empty array if none found. + */ +export async function getEnvironmentNames(fileName: string, options?: LoadEnvironmentOptions): Promise { + const environments = await decodeEnvironments(fileName, options) + + if (!environments) { + return [] + } + + return Object.keys(environments) +} + +/** + * Expands environment patterns (including globs) to actual environment names. + * @param patterns - Array of environment names or glob patterns. + * @param fileName - The file name to load environments from. + * @param options - Optional configuration for loading. + * @returns Array of matched environment names. + */ +export async function expandEnvironmentPatterns( + patterns: string[], + fileName: string, + options?: LoadEnvironmentOptions, +): Promise { + const allEnvironments = await getEnvironmentNames(fileName, options) + const matchedEnvironments = new Set() + + for (const pattern of patterns) { + const matches = allEnvironments.filter((env) => minimatch(env, pattern)) + + if (matches.length === 0) { + renderWarningIfNeeded( + { + body: [`Could not find any environments matching`, {command: pattern}], + }, + options?.silent, + ) + } + + matches.forEach((match) => matchedEnvironments.add(match)) + } + + return Array.from(matchedEnvironments) +} diff --git a/packages/cli/README.md b/packages/cli/README.md index b07c04cb033..e97386bd403 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -1714,7 +1714,8 @@ FLAGS theme-check:recommended, theme-check:all For backwards compatibility, :theme_app_extension is also supported -a, --auto-correct Automatically fix offenses - -e, --environment=... The environment to apply to the current command. + -e, --environment=... The environment to apply to the current command. Wrap the value in double quotes if + you're using wildcards. -o, --output=