@shopify/create-app 3.89.0 → 3.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8,14 +8,14 @@ import {
8
8
  errorHandler,
9
9
  registerCleanBugsnagErrorsFromWithinPlugins,
10
10
  require_end_of_stream
11
- } from "./chunk-6MAOIPCN.js";
11
+ } from "./chunk-2DEP3RXL.js";
12
12
  import {
13
13
  postRunHookHasCompleted
14
- } from "./chunk-PH7SQKY6.js";
14
+ } from "./chunk-GWY4CBLA.js";
15
15
  import {
16
16
  setCurrentCommandId,
17
17
  showNotificationsIfNeeded
18
- } from "./chunk-G547J43X.js";
18
+ } from "./chunk-7YUNOVUI.js";
19
19
  import {
20
20
  CLI_KIT_VERSION,
21
21
  ClientError,
@@ -94,7 +94,7 @@ import {
94
94
  setPathValue,
95
95
  shopifyFetch,
96
96
  z
97
- } from "./chunk-2MJWCH3V.js";
97
+ } from "./chunk-2HKUDD5O.js";
98
98
  import "./chunk-XD3LXUGW.js";
99
99
  import {
100
100
  LocalStorage,
@@ -116,7 +116,7 @@ import {
116
116
  usesWorkspaces,
117
117
  versionSatisfies,
118
118
  writePackageJSON
119
- } from "./chunk-SDSP6YZX.js";
119
+ } from "./chunk-6J45DHE7.js";
120
120
  import {
121
121
  AbortController as AbortController2,
122
122
  AbortError,
@@ -257,6 +257,7 @@ import {
257
257
  rmdir,
258
258
  runWithTimer,
259
259
  shouldDisplayColors,
260
+ skipLocalDevConsole,
260
261
  sleep,
261
262
  slugify,
262
263
  source_default,
@@ -283,7 +284,7 @@ import {
283
284
  username,
284
285
  writeFile,
285
286
  writeFileSync
286
- } from "./chunk-OVQTCKQU.js";
287
+ } from "./chunk-RGJ4BXIY.js";
287
288
  import {
288
289
  require_brace_expansion,
289
290
  require_commonjs,
@@ -326393,6 +326394,8 @@ var MAX_EXTENSION_HANDLE_LENGTH = 50, MAX_UID_LENGTH = 250, MetafieldSchema = z.
326393
326394
  api_access: z.boolean().optional(),
326394
326395
  collect_buyer_consent: CollectBuyerConsentCapabilitySchema.optional(),
326395
326396
  iframe: IframeCapabilitySchema.optional()
326397
+ }), SupportedFeaturesSchema = z.object({
326398
+ offline_mode: z.boolean().optional()
326396
326399
  }), ExtensionsArraySchema = z.object({
326397
326400
  type: z.string().optional(),
326398
326401
  extensions: z.array(z.any()).optional()
@@ -326436,6 +326439,7 @@ var MAX_EXTENSION_HANDLE_LENGTH = 50, MAX_UID_LENGTH = 250, MetafieldSchema = z.
326436
326439
  api_version: ApiVersionSchema.optional(),
326437
326440
  extension_points: z.any().optional(),
326438
326441
  capabilities: CapabilitiesSchema.optional(),
326442
+ supported_features: SupportedFeaturesSchema.optional(),
326439
326443
  settings: SettingsSchema.optional()
326440
326444
  }), BaseSchemaWithHandle = BaseSchema.extend({
326441
326445
  handle: HandleSchema
@@ -328221,6 +328225,7 @@ var dependency2 = "@shopify/checkout-ui-extensions", CheckoutSchema = BaseSchema
328221
328225
  deployConfig: async (config2, directory) => ({
328222
328226
  extension_points: config2.extension_points,
328223
328227
  capabilities: config2.capabilities,
328228
+ supported_features: config2.supported_features,
328224
328229
  metafields: config2.metafields ?? [],
328225
328230
  name: config2.name,
328226
328231
  settings: config2.settings,
@@ -329584,7 +329589,6 @@ var dependency5 = "@shopify/checkout-ui-extensions", validatePoints = (config2)
329584
329589
  }
329585
329590
  };
329586
329591
  return {
329587
- tools: targeting.tools,
329588
329592
  target: targeting.target,
329589
329593
  module: targeting.module,
329590
329594
  metafields: targeting.metafields ?? config2.metafields ?? [],
@@ -329592,7 +329596,9 @@ var dependency5 = "@shopify/checkout-ui-extensions", validatePoints = (config2)
329592
329596
  urls: targeting.urls ?? {},
329593
329597
  capabilities: targeting.capabilities,
329594
329598
  preloads: targeting.preloads ?? {},
329595
- build_manifest: buildManifest
329599
+ build_manifest: buildManifest,
329600
+ tools: targeting.tools,
329601
+ instructions: targeting.instructions
329596
329602
  };
329597
329603
  });
329598
329604
  return { ...config2, extension_points: extensionPoints };
@@ -329612,6 +329618,7 @@ var dependency5 = "@shopify/checkout-ui-extensions", validatePoints = (config2)
329612
329618
  api_version: config2.api_version,
329613
329619
  extension_points: transformedExtensionPoints,
329614
329620
  capabilities: config2.capabilities,
329621
+ supported_features: config2.supported_features,
329615
329622
  name: config2.name,
329616
329623
  description: config2.description,
329617
329624
  settings: config2.settings,
@@ -329622,13 +329629,8 @@ var dependency5 = "@shopify/checkout-ui-extensions", validatePoints = (config2)
329622
329629
  let shouldIncludeShopifyExtend = isRemoteDomExtension(config2), extensionPoints = config2.extension_points || [], main = extensionPoints.map(({ target, module: module2 }, index) => shouldIncludeShopifyExtend ? `import Target_${index} from '${module2}';shopify.extend('${target}', (...args) => Target_${index}(...args));` : `import '${module2}';`).join(`
329623
329630
  `), assets = {};
329624
329631
  extensionPoints.forEach((extensionPoint) => {
329625
- Object.entries(extensionPoint.build_manifest.assets).forEach(([identifier, asset]) => {
329626
- identifier !== AssetIdentifier.Main && (asset.static && asset.module || (assets[identifier] = {
329627
- identifier,
329628
- outputFileName: asset.filepath,
329629
- content: shouldIncludeShopifyExtend ? `import shouldRender from '${asset.module}';shopify.extend('${getShouldRenderTarget(extensionPoint.target)}', (...args) => shouldRender(...args));` : `import '${asset.module}'`
329630
- }));
329631
- });
329632
+ let shouldRenderAsset = buildShouldRenderAsset(extensionPoint, shouldIncludeShopifyExtend);
329633
+ shouldRenderAsset && (assets[AssetIdentifier.ShouldRender] = shouldRenderAsset);
329632
329634
  });
329633
329635
  let assetsArray = Object.values(assets);
329634
329636
  return {
@@ -329637,7 +329639,7 @@ var dependency5 = "@shopify/checkout-ui-extensions", validatePoints = (config2)
329637
329639
  };
329638
329640
  },
329639
329641
  copyStaticAssets: async (config2, directory, outputPath) => {
329640
- isRemoteDomExtension(config2) && await Promise.all(config2.extension_points.map((extensionPoint) => "build_manifest" in extensionPoint ? Object.entries(extensionPoint.build_manifest.assets).map(([_2, asset]) => {
329642
+ isRemoteDomExtension(config2) && await Promise.all(config2.extension_points.flatMap((extensionPoint) => "build_manifest" in extensionPoint ? Object.entries(extensionPoint.build_manifest.assets).map(([_2, asset]) => {
329641
329643
  if (asset.static && asset.module) {
329642
329644
  let sourceFile = joinPath(directory, asset.module), outputFilePath = joinPath(dirname(outputPath), asset.filepath);
329643
329645
  return copyFile(sourceFile, outputFilePath).catch((error) => {
@@ -329645,7 +329647,7 @@ var dependency5 = "@shopify/checkout-ui-extensions", validatePoints = (config2)
329645
329647
  });
329646
329648
  }
329647
329649
  return Promise.resolve();
329648
- }) : Promise.resolve()));
329650
+ }) : []));
329649
329651
  },
329650
329652
  hasExtensionPointTarget: (config2, requestedTarget) => config2.extension_points?.find((extensionPoint) => extensionPoint.target === requestedTarget) !== void 0,
329651
329653
  contributeToSharedTypeFile: async (extension, typeDefinitionsByFile) => {
@@ -329769,6 +329771,15 @@ function isRemoteDomExtension(config2) {
329769
329771
  function getShouldRenderTarget(target) {
329770
329772
  return target.replace(/\.render$/, ".should-render");
329771
329773
  }
329774
+ function buildShouldRenderAsset(extensionPoint, shouldIncludeShopifyExtend) {
329775
+ let shouldRenderAsset = extensionPoint.build_manifest.assets[AssetIdentifier.ShouldRender];
329776
+ if (shouldRenderAsset)
329777
+ return {
329778
+ identifier: AssetIdentifier.ShouldRender,
329779
+ outputFileName: shouldRenderAsset.filepath,
329780
+ content: shouldIncludeShopifyExtend ? `import shouldRender from '${shouldRenderAsset.module}';shopify.extend('${getShouldRenderTarget(extensionPoint.target)}', (...args) => shouldRender(...args));` : `import '${shouldRenderAsset.module}'`
329781
+ };
329782
+ }
329772
329783
  var ui_extension_default = uiExtensionSpec;
329773
329784
 
329774
329785
  // ../app/dist/cli/models/extensions/specifications/web_pixel_extension.js
@@ -330259,7 +330270,7 @@ function loadFwConfigFile(rootPath, fwConfigFileName, fwConfigFiles = {}) {
330259
330270
 
330260
330271
  // ../cli-kit/dist/public/node/toml.js
330261
330272
  init_cjs_shims();
330262
- var toml = __toESM(require_toml(), 1);
330273
+ var toml = __toESM(require_toml());
330263
330274
  function decodeToml(input) {
330264
330275
  let normalizedInput = input.replace(/\r\n$/g, `
330265
330276
  `);
@@ -332350,6 +332361,71 @@ function organizationBetaFlagsQuery(flags) {
332350
332361
  }`;
332351
332362
  }
332352
332363
 
332364
+ // ../app/dist/cli/api/graphql/business-platform-organizations/generated/organization_exp_flags.js
332365
+ init_cjs_shims();
332366
+ var OrganizationExpFlags = {
332367
+ kind: "Document",
332368
+ definitions: [
332369
+ {
332370
+ kind: "OperationDefinition",
332371
+ operation: "query",
332372
+ name: { kind: "Name", value: "OrganizationExpFlags" },
332373
+ variableDefinitions: [
332374
+ {
332375
+ kind: "VariableDefinition",
332376
+ variable: { kind: "Variable", name: { kind: "Name", value: "organizationId" } },
332377
+ type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "OrganizationID" } } }
332378
+ },
332379
+ {
332380
+ kind: "VariableDefinition",
332381
+ variable: { kind: "Variable", name: { kind: "Name", value: "flagHandles" } },
332382
+ type: {
332383
+ kind: "NonNullType",
332384
+ type: {
332385
+ kind: "ListType",
332386
+ type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } }
332387
+ }
332388
+ }
332389
+ }
332390
+ ],
332391
+ selectionSet: {
332392
+ kind: "SelectionSet",
332393
+ selections: [
332394
+ {
332395
+ kind: "Field",
332396
+ name: { kind: "Name", value: "organization" },
332397
+ arguments: [
332398
+ {
332399
+ kind: "Argument",
332400
+ name: { kind: "Name", value: "organizationId" },
332401
+ value: { kind: "Variable", name: { kind: "Name", value: "organizationId" } }
332402
+ }
332403
+ ],
332404
+ selectionSet: {
332405
+ kind: "SelectionSet",
332406
+ selections: [
332407
+ { kind: "Field", name: { kind: "Name", value: "id" } },
332408
+ {
332409
+ kind: "Field",
332410
+ name: { kind: "Name", value: "enabledFlags" },
332411
+ arguments: [
332412
+ {
332413
+ kind: "Argument",
332414
+ name: { kind: "Name", value: "flagHandles" },
332415
+ value: { kind: "Variable", name: { kind: "Name", value: "flagHandles" } }
332416
+ }
332417
+ ]
332418
+ },
332419
+ { kind: "Field", name: { kind: "Name", value: "__typename" } }
332420
+ ]
332421
+ }
332422
+ }
332423
+ ]
332424
+ }
332425
+ }
332426
+ ]
332427
+ };
332428
+
332353
332429
  // ../app/dist/cli/api/graphql/business-platform-destinations/generated/organizations.js
332354
332430
  init_cjs_shims();
332355
332431
  var ListOrganizations = {
@@ -332427,6 +332503,11 @@ var DevSessionCreate = {
332427
332503
  kind: "VariableDefinition",
332428
332504
  variable: { kind: "Variable", name: { kind: "Name", value: "assetsUrl" } },
332429
332505
  type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } }
332506
+ },
332507
+ {
332508
+ kind: "VariableDefinition",
332509
+ variable: { kind: "Variable", name: { kind: "Name", value: "websocketUrl" } },
332510
+ type: { kind: "NamedType", name: { kind: "Name", value: "String" } }
332430
332511
  }
332431
332512
  ],
332432
332513
  selectionSet: {
@@ -332445,6 +332526,11 @@ var DevSessionCreate = {
332445
332526
  kind: "Argument",
332446
332527
  name: { kind: "Name", value: "assetsUrl" },
332447
332528
  value: { kind: "Variable", name: { kind: "Name", value: "assetsUrl" } }
332529
+ },
332530
+ {
332531
+ kind: "Argument",
332532
+ name: { kind: "Name", value: "websocketUrl" },
332533
+ value: { kind: "Variable", name: { kind: "Name", value: "websocketUrl" } }
332448
332534
  }
332449
332535
  ],
332450
332536
  selectionSet: {
@@ -334734,7 +334820,7 @@ var TEMPLATE_JSON_URL = "https://cdn.shopify.com/static/cli/extensions/templates
334734
334820
  "This likely means a problem with your internet connection."
334735
334821
  ]);
334736
334822
  }
334737
- let counter = 0, filteredTemplates = (await allowedTemplates(templates2, async (betaFlags) => this.organizationBetaFlags(organizationId, betaFlags))).map((template) => ({ ...template, sortPriority: counter++ })), groupOrder = [];
334823
+ let counter = 0, filteredTemplates = (await allowedTemplates(templates2, async (betaFlags) => this.organizationBetaFlags(organizationId, betaFlags), async (expFlags) => this.organizationExpFlags(organizationId, expFlags))).map((template) => ({ ...template, sortPriority: counter++ })), groupOrder = [];
334738
334824
  for (let template of templates2)
334739
334825
  template.group && !groupOrder.includes(template.group) && groupOrder.push(template.group);
334740
334826
  return {
@@ -335077,12 +335163,12 @@ var TEMPLATE_JSON_URL = "https://cdn.shopify.com/static/cli/extensions/templates
335077
335163
  async appDeepLink({ id, organizationId }) {
335078
335164
  return appDeepLink({ id, organizationId });
335079
335165
  }
335080
- async devSessionCreate({ appId, assetsUrl, shopFqdn }) {
335166
+ async devSessionCreate({ appId, assetsUrl, shopFqdn, websocketUrl }) {
335081
335167
  let appIdNumber = String(numberFromGid(appId));
335082
335168
  return this.appDevRequest({
335083
335169
  query: DevSessionCreate,
335084
335170
  shopFqdn,
335085
- variables: { appId: appIdNumber, assetsUrl: assetsUrl ?? "" },
335171
+ variables: { appId: appIdNumber, assetsUrl: assetsUrl ?? "", websocketUrl },
335086
335172
  requestOptions: { requestMode: "slow-request" }
335087
335173
  });
335088
335174
  }
@@ -335123,6 +335209,21 @@ var TEMPLATE_JSON_URL = "https://cdn.shopify.com/static/cli/extensions/templates
335123
335209
  result[flag] = !!flagsResult.organization[`flag_${flag}`];
335124
335210
  }), result;
335125
335211
  }
335212
+ async organizationExpFlags(organizationId, allExpFlags) {
335213
+ let variables = {
335214
+ organizationId: encodedGidFromOrganizationIdForBP(organizationId),
335215
+ flagHandles: allExpFlags
335216
+ }, flagsResult = await businessPlatformOrganizationsRequestDoc({
335217
+ query: OrganizationExpFlags,
335218
+ token: await this.businessPlatformToken(),
335219
+ organizationId,
335220
+ variables,
335221
+ unauthorizedHandler: this.createUnauthorizedHandler()
335222
+ }), result = {}, enabledFlags = flagsResult.organization?.enabledFlags ?? [];
335223
+ return allExpFlags.forEach((flag, index) => {
335224
+ result[flag] = !!enabledFlags[index];
335225
+ }), result;
335226
+ }
335126
335227
  async appManagementRequest(options) {
335127
335228
  return appManagementRequestDoc({
335128
335229
  ...options,
@@ -335236,11 +335337,14 @@ function diffAppModules({ currentModules, selectedVersionModules }) {
335236
335337
  let currentModuleUids = currentModules.map((mod) => mod.userIdentifier), selectedVersionModuleUids = selectedVersionModules.map((mod) => mod.userIdentifier), added = selectedVersionModules.filter((mod) => !currentModuleUids.includes(mod.userIdentifier)), removed = currentModules.filter((mod) => !selectedVersionModuleUids.includes(mod.userIdentifier)), removedUids = removed.map((mod) => mod.userIdentifier), updated = currentModules.filter((mod) => !removedUids.includes(mod.userIdentifier));
335237
335338
  return { added, removed, updated };
335238
335339
  }
335239
- async function allowedTemplates(templates2, betaFlagsFetcher, version = CLI_KIT_VERSION) {
335240
- let allBetaFlags = Array.from(new Set(templates2.map((ext) => ext.organizationBetaFlags ?? []).flat())), enabledBetaFlags = await betaFlagsFetcher(allBetaFlags);
335340
+ async function allowedTemplates(templates2, betaFlagsFetcher, expFlagsFetcher, version = CLI_KIT_VERSION) {
335341
+ let allBetaFlags = Array.from(new Set(templates2.map((ext) => ext.organizationBetaFlags ?? []).flat())), allExpFlags = Array.from(new Set(templates2.map((ext) => ext.organizationExpFlags ?? []).flat())), [enabledBetaFlags, enabledExpFlags] = await Promise.all([
335342
+ allBetaFlags.length > 0 ? betaFlagsFetcher(allBetaFlags) : Promise.resolve({}),
335343
+ allExpFlags.length > 0 ? expFlagsFetcher(allExpFlags) : Promise.resolve({})
335344
+ ]);
335241
335345
  return templates2.filter((ext) => {
335242
- let hasAnyNeededBetas = !ext.organizationBetaFlags || ext.organizationBetaFlags.every((flag) => enabledBetaFlags[flag]), satisfiesMinCliVersion = !ext.minimumCliVersion || versionSatisfies(version, `>=${ext.minimumCliVersion}`), satisfiesDeprecatedFromCliVersion = !ext.deprecatedFromCliVersion || versionSatisfies(version, `<${ext.deprecatedFromCliVersion}`), satisfiesVersion = satisfiesMinCliVersion && satisfiesDeprecatedFromCliVersion, satisfiesPreReleaseVersion = isPreReleaseVersion(version) && ext.deprecatedFromCliVersion === void 0;
335243
- return hasAnyNeededBetas && (satisfiesVersion || satisfiesPreReleaseVersion);
335346
+ let hasNeededBetaFlags = !ext.organizationBetaFlags || ext.organizationBetaFlags.every((flag) => enabledBetaFlags[flag]), hasNeededExpFlags = !ext.organizationExpFlags || ext.organizationExpFlags.every((flag) => enabledExpFlags[flag]), satisfiesMinCliVersion = !ext.minimumCliVersion || versionSatisfies(version, `>=${ext.minimumCliVersion}`), satisfiesDeprecatedFromCliVersion = !ext.deprecatedFromCliVersion || versionSatisfies(version, `<${ext.deprecatedFromCliVersion}`), satisfiesVersion = satisfiesMinCliVersion && satisfiesDeprecatedFromCliVersion, satisfiesPreReleaseVersion = isPreReleaseVersion(version) && ext.deprecatedFromCliVersion === void 0;
335347
+ return hasNeededBetaFlags && hasNeededExpFlags && (satisfiesVersion || satisfiesPreReleaseVersion);
335244
335348
  });
335245
335349
  }
335246
335350
  function experience(identifier) {
@@ -337293,7 +337397,7 @@ init_cjs_shims();
337293
337397
  init_cjs_shims();
337294
337398
  import { fileURLToPath as fileURLToPath2 } from "node:url";
337295
337399
  async function launchCLI(options) {
337296
- let { errorHandler: errorHandler2 } = await import("./error-handler-RTPIFBDU.js"), { isDevelopment: isDevelopment2 } = await import("./local-ORZXOPNB.js"), oclif = await import("./lib-IF6LVQLE.js"), { ShopifyConfig } = await import("./custom-oclif-loader-27AG3IED.js");
337400
+ let { errorHandler: errorHandler2 } = await import("./error-handler-TTBMK4H6.js"), { isDevelopment: isDevelopment2 } = await import("./local-XJBENDBD.js"), oclif = await import("./lib-IF6LVQLE.js"), { ShopifyConfig } = await import("./custom-oclif-loader-2UXWLT7G.js");
337297
337401
  isDevelopment2() && (oclif.default.settings.debug = !0);
337298
337402
  try {
337299
337403
  let config2 = new ShopifyConfig({ root: fileURLToPath2(options.moduleURL) });
@@ -337308,7 +337412,7 @@ var import_core3 = __toESM(require_lib2());
337308
337412
  async function exitIfOldNodeVersion(versions2 = process.versions) {
337309
337413
  let nodeVersion = versions2.node, nodeMajorVersion = Number(nodeVersion.split(".")[0]);
337310
337414
  if (nodeMajorVersion < 18) {
337311
- let { renderError: renderError2 } = await import("./ui-3NSS425V.js");
337415
+ let { renderError: renderError2 } = await import("./ui-NL6F4FZE.js");
337312
337416
  renderError2({
337313
337417
  headline: "Upgrade to a supported Node version now.",
337314
337418
  body: [
@@ -337335,7 +337439,7 @@ async function runCLI(options, launchCLI2 = launchCLI, argv = process.argv, env
337335
337439
  return setupEnvironmentVariables(options, argv, env), options.runInCreateMode && await addInitToArgvWhenRunningCreateCLI(options, argv), forceNoColor(argv, env), await exitIfOldNodeVersion(versions2), launchCLI2({ moduleURL: options.moduleURL });
337336
337440
  }
337337
337441
  async function addInitToArgvWhenRunningCreateCLI(options, argv = process.argv) {
337338
- let { findUpAndReadPackageJson: findUpAndReadPackageJson2 } = await import("./node-package-manager-LZE3IXBU.js"), { moduleDirectory: moduleDirectory2 } = await import("./path-COZT77T2.js"), name = (await findUpAndReadPackageJson2(moduleDirectory2(options.moduleURL))).content.name.replace("@shopify/create-", "");
337442
+ let { findUpAndReadPackageJson: findUpAndReadPackageJson2 } = await import("./node-package-manager-5CRVMYIH.js"), { moduleDirectory: moduleDirectory2 } = await import("./path-COZT77T2.js"), name = (await findUpAndReadPackageJson2(moduleDirectory2(options.moduleURL))).content.name.replace("@shopify/create-", "");
337339
337443
  if (argv.findIndex((arg) => arg.includes("init")) === -1) {
337340
337444
  let initIndex2 = argv.findIndex((arg) => arg.match(new RegExp(`bin(\\/|\\\\)+(create-${name}|dev|run)`))) + 1;
337341
337445
  argv.splice(initIndex2, 0, "init");
@@ -337562,13 +337666,16 @@ async function prepareAppStoreContext(flags) {
337562
337666
  }
337563
337667
  async function prepareExecuteContext(flags) {
337564
337668
  let query;
337565
- if (flags.query)
337669
+ if (flags.query !== void 0) {
337670
+ if (!flags.query.trim())
337671
+ throw new AbortError("The --query flag value is empty. Please provide a valid GraphQL query or mutation.");
337566
337672
  query = flags.query;
337567
- else if (flags["query-file"]) {
337673
+ } else if (flags["query-file"]) {
337568
337674
  let queryFile = flags["query-file"];
337569
337675
  if (!await fileExists(queryFile))
337570
337676
  throw new AbortError(outputContent`Query file not found at ${outputToken.path(queryFile)}. Please check the path and try again.`);
337571
- query = await readFile(queryFile, { encoding: "utf8" });
337677
+ if (query = await readFile(queryFile, { encoding: "utf8" }), !query.trim())
337678
+ throw new AbortError(outputContent`Query file at ${outputToken.path(queryFile)} is empty. Please provide a valid GraphQL query or mutation.`);
337572
337679
  }
337573
337680
  if (!query)
337574
337681
  throw new BugError("Query should have been provided via --query or --query-file flags due to exactlyOne constraint. This indicates the oclif flag validation failed.");
@@ -339719,7 +339826,8 @@ Deploy.flags = {
339719
339826
  hidden: !1,
339720
339827
  description: "Creates a version but doesn't release it - it's not made available to merchants. With this flag, a user confirmation is not required.",
339721
339828
  env: "SHOPIFY_FLAG_NO_RELEASE",
339722
- default: !1
339829
+ default: !1,
339830
+ exclusive: ["allow-updates", "allow-deletes"]
339723
339831
  }),
339724
339832
  "no-build": import_core8.Flags.boolean({
339725
339833
  description: "Use with caution: Skips building any elements of the app that require building. You should ensure your app has been prepared in advance, such as by running `shopify app build` or by caching build artifacts.",
@@ -345586,7 +345694,7 @@ function pollThemeEditorChanges(targetTheme, session, remoteChecksum, localFileS
345586
345694
  });
345587
345695
  }
345588
345696
  async function pollRemoteJsonChanges(targetTheme, currentSession, remoteChecksums, localFileSystem, options) {
345589
- let previousChecksums = applyFileFilters(remoteChecksums, localFileSystem), latestChecksums = await fetchChecksums(targetTheme.id, currentSession).then((checksums) => applyFileFilters(checksums, localFileSystem)), changedAssets = getAssetsChangedOnRemote(previousChecksums, latestChecksums), deletedAssets = getAssetsDeletedFromRemote(latestChecksums, previousChecksums);
345697
+ let currentUnsyncedKeys = new Set(localFileSystem.unsyncedFileKeys), previousChecksums = applyFileFilters(remoteChecksums, localFileSystem, currentUnsyncedKeys), latestChecksums = await fetchChecksums(targetTheme.id, currentSession).then((checksums) => applyFileFilters(checksums, localFileSystem, currentUnsyncedKeys)), changedAssets = getAssetsChangedOnRemote(previousChecksums, latestChecksums), deletedAssets = getAssetsDeletedFromRemote(latestChecksums, previousChecksums);
345590
345698
  return await abortIfMultipleSourcesChange(localFileSystem, changedAssets), await syncChangedAssets(targetTheme, currentSession, localFileSystem, changedAssets), await deleteRemovedAssets(localFileSystem, deletedAssets, options), latestChecksums;
345591
345699
  }
345592
345700
  function getAssetsDeletedFromRemote(latestChecksums, previousChecksums) {
@@ -345625,8 +345733,8 @@ async function abortIfMultipleSourcesChange(localFileSystem, assetsChangedOnRemo
345625
345733
  throw new PollingError(`Detected changes to the file '${asset.key}' on both local and remote sources. Aborting...`);
345626
345734
  }
345627
345735
  }
345628
- function applyFileFilters(files, localThemeFileSystem) {
345629
- return localThemeFileSystem.applyIgnoreFilters(files).filter((file) => file.key.endsWith(".json")).filter((file) => !localThemeFileSystem.unsyncedFileKeys.has(file.key));
345736
+ function applyFileFilters(files, localThemeFileSystem, unsyncedKeys) {
345737
+ return localThemeFileSystem.applyIgnoreFilters(files).filter((file) => file.key.endsWith(".json")).filter((file) => !unsyncedKeys.has(file.key));
345630
345738
  }
345631
345739
 
345632
345740
  // ../theme/dist/cli/utilities/theme-environment/theme-reconciliation.js
@@ -351656,6 +351764,9 @@ async function getUIExtensionPayload(extension, bundlePath, options) {
351656
351764
  lastUpdated: await fileLastUpdatedTimestamp(extensionOutputPath) ?? 0
351657
351765
  }
351658
351766
  },
351767
+ supportedFeatures: {
351768
+ offlineMode: extension.configuration.supported_features?.offline_mode ?? !1
351769
+ },
351659
351770
  capabilities: {
351660
351771
  blockProgress: extension.configuration.capabilities?.block_progress ?? !1,
351661
351772
  networkAccess: extension.configuration.capabilities?.network_access ?? !1,
@@ -351702,34 +351813,43 @@ async function getUIExtensionPayload(extension, bundlePath, options) {
351702
351813
  async function getExtensionPoints(extension, url) {
351703
351814
  let extensionPoints = extension.configuration.extension_points;
351704
351815
  return extension.type === "checkout_post_purchase" && (extensionPoints = [{ target: "purchase.post.render" }]), isNewExtensionPointsSchema(extensionPoints) ? Promise.all(extensionPoints.map(async (extensionPoint) => {
351705
- let { target, resource } = extensionPoint;
351706
- return {
351816
+ let { target, resource } = extensionPoint, payload = {
351707
351817
  ...extensionPoint,
351708
- ...extensionPoint.build_manifest ? { assets: await extractAssetsFromBuildManifest(extensionPoint.build_manifest, url, extension) } : {},
351709
351818
  surface: getExtensionPointTargetSurface(target),
351710
351819
  root: {
351711
351820
  url: `${url}/${target}`
351712
351821
  },
351713
351822
  resource: resource || { url: "" }
351714
351823
  };
351824
+ return "build_manifest" in extensionPoint ? {
351825
+ ...payload,
351826
+ ...await mapBuildManifestToPayload(extensionPoint.build_manifest, extensionPoint, url, extension)
351827
+ } : payload;
351715
351828
  })) : extensionPoints;
351716
351829
  }
351717
- async function extractAssetsFromBuildManifest(buildManifest, url, extension) {
351718
- if (!buildManifest?.assets)
351719
- return {};
351720
- let assets = {};
351721
- for (let [name, asset] of Object.entries(buildManifest.assets))
351722
- assets[name] = {
351723
- name,
351724
- url: `${url}${joinPath("/assets/", asset.filepath)}`,
351725
- // eslint-disable-next-line no-await-in-loop
351726
- lastUpdated: await fileLastUpdatedTimestamp(joinPath(dirname(extension.outputPath), asset.filepath)) ?? 0
351727
- };
351728
- return assets;
351830
+ async function defaultAssetMapper({ identifier, asset, url, extension }) {
351831
+ let payload = await getAssetPayload(identifier, asset, url, extension);
351832
+ return {
351833
+ assets: { [payload.name]: payload }
351834
+ };
351835
+ }
351836
+ async function mapBuildManifestToPayload(buildManifest, _extensionPoint, url, extension) {
351837
+ return buildManifest?.assets ? (await Promise.all(Object.entries(buildManifest.assets).map(async ([identifier, asset]) => defaultAssetMapper({ identifier, asset, url, extension })))).reduce((acc, result) => ({
351838
+ ...acc,
351839
+ ...result,
351840
+ assets: { ...acc.assets, ...result.assets }
351841
+ }), {}) : {};
351729
351842
  }
351730
351843
  function isNewExtensionPointsSchema(extensionPoints) {
351731
351844
  return Array.isArray(extensionPoints) && extensionPoints.every((extensionPoint) => typeof extensionPoint == "object");
351732
351845
  }
351846
+ async function getAssetPayload(name, asset, url, extension) {
351847
+ return {
351848
+ name,
351849
+ url: `${url}${joinPath("/assets/", asset.filepath)}`,
351850
+ lastUpdated: await fileLastUpdatedTimestamp(joinPath(dirname(extension.outputPath), asset.filepath)) ?? 0
351851
+ };
351852
+ }
351733
351853
 
351734
351854
  // ../app/dist/cli/utilities/app/app-url.js
351735
351855
  init_cjs_shims();
@@ -352603,7 +352723,7 @@ function getExtensionPayloadMiddleware({ devOptions, getExtensions: getExtension
352603
352723
  url: new URL("/extensions", devOptions.url).toString()
352604
352724
  },
352605
352725
  socket: {
352606
- url: getWebsocketUrl(devOptions)
352726
+ url: getWebSocketUrl(devOptions.url)
352607
352727
  },
352608
352728
  devConsole: {
352609
352729
  url: new URL("/extensions/dev-console", devOptions.url).toString()
@@ -352635,10 +352755,6 @@ function getExtensionPointMiddleware({ devOptions, getExtensions: getExtensions2
352635
352755
  await sendRedirect(response.event, url, 307);
352636
352756
  };
352637
352757
  }
352638
- function getWebsocketUrl(devOptions) {
352639
- let socket = new URL("/extensions", devOptions.url);
352640
- return socket.protocol = "wss:", socket.toString();
352641
- }
352642
352758
 
352643
352759
  // ../app/dist/cli/services/dev/extension/server.js
352644
352760
  import { createServer as createServer4 } from "http";
@@ -353312,7 +353428,7 @@ function graphiqlTemplate({ apiVersion, apiVersions, appName, appUrl, key, store
353312
353428
  {query: "{%if query.preface %}{{query.preface}}\\n{% endif %}{{query.query}}", variables: "{{query.variables}}"},
353313
353429
  {%endfor%}
353314
353430
  ],
353315
- isHeadersEditorEnabled: false,
353431
+ isHeadersEditorEnabled: true,
353316
353432
  }),
353317
353433
  document.getElementById('graphiql-explorer'),
353318
353434
  )
@@ -353536,6 +353652,35 @@ var import_react6 = __toESM(require_react(), 1), import_server8 = __toESM(requir
353536
353652
  </html>
353537
353653
  `;
353538
353654
 
353655
+ // ../app/dist/cli/services/dev/graphiql/utilities.js
353656
+ init_cjs_shims();
353657
+ var BLOCKED_HEADERS = /* @__PURE__ */ new Set([
353658
+ // Hop-by-hop headers (RFC 7230 Section 6.1)
353659
+ "connection",
353660
+ "keep-alive",
353661
+ "proxy-authenticate",
353662
+ "proxy-authorization",
353663
+ "te",
353664
+ "trailer",
353665
+ "transfer-encoding",
353666
+ "upgrade",
353667
+ // Headers the proxy controls
353668
+ "host",
353669
+ "content-length",
353670
+ "content-type",
353671
+ "accept",
353672
+ "user-agent",
353673
+ "authorization",
353674
+ "cookie",
353675
+ "x-shopify-access-token"
353676
+ ]);
353677
+ function filterCustomHeaders(headers) {
353678
+ let customHeaders = {};
353679
+ for (let [key, value] of Object.entries(headers))
353680
+ !BLOCKED_HEADERS.has(key.toLowerCase()) && typeof value == "string" && (customHeaders[key] = value);
353681
+ return customHeaders;
353682
+ }
353683
+
353539
353684
  // ../app/dist/cli/services/dev/graphiql/server.js
353540
353685
  var import_express = __toESM(require_express2(), 1), import_body_parser = __toESM(require_body_parser(), 1);
353541
353686
  import { createRequire as createRequire2 } from "module";
@@ -353629,8 +353774,9 @@ function setupGraphiQLServer({ stdout, port, appName, appUrl, apiKey, apiSecret,
353629
353774
  return;
353630
353775
  let graphqlUrl = adminUrl(storeFqdn, req.query.api_version);
353631
353776
  try {
353632
- let reqBody = JSON.stringify(req.body), runRequest = async () => {
353777
+ let reqBody = JSON.stringify(req.body), customHeaders = filterCustomHeaders(req.headers), runRequest = async () => {
353633
353778
  let headers = {
353779
+ ...customHeaders,
353634
353780
  Accept: "application/json",
353635
353781
  "Content-Type": "application/json",
353636
353782
  "X-Shopify-Access-Token": await token(),
@@ -353961,10 +354107,11 @@ var DevSession = class _DevSession {
353961
354107
  /**
353962
354108
  * Update the preview URL, it only changes if we move between a non-previewable state and a previewable state.
353963
354109
  * (i.e. if we go from a state with no extensions to a state with ui-extensions or vice versa)
354110
+ * Skip the dev console only when BOTH: SHOPIFY_CLI_1P_DEV is NOT enabled AND SHOPIFY_SKIP_LOCAL_DEV_CONSOLE is set.
353964
354111
  * @param event - The app event
353965
354112
  */
353966
354113
  updatePreviewURL(event) {
353967
- let newPreviewURL = event.app.allExtensions.filter((ext) => ext.isPreviewable).length > 0 ? this.options.appLocalProxyURL : this.options.appPreviewURL;
354114
+ let hasPreview = event.app.allExtensions.filter((ext) => ext.isPreviewable).length > 0, newPreviewURL = !(!firstPartyDev() && skipLocalDevConsole()) && hasPreview ? this.options.appLocalProxyURL : this.options.appPreviewURL;
353968
354115
  this.statusManager.updateStatus({ previewURL: newPreviewURL });
353969
354116
  }
353970
354117
  /**
@@ -353986,14 +354133,25 @@ var DevSession = class _DevSession {
353986
354133
  */
353987
354134
  async bundleExtensionsAndUpload(appEvent) {
353988
354135
  try {
353989
- let { manifest, inheritedModuleUids, assets } = await this.createManifest(appEvent), signedURL = await this.uploadAssetsIfNeeded(assets, !this.statusManager.status.isReady), payload = {
353990
- shopFqdn: this.options.storeFqdn,
353991
- appId: this.options.appId,
353992
- assetsUrl: signedURL,
353993
- manifest,
353994
- inheritedModuleUids
353995
- };
353996
- return this.statusManager.status.isReady ? this.devSessionUpdateWithRetry(payload) : this.devSessionCreateWithRetry(payload);
354136
+ let { manifest, inheritedModuleUids, assets } = await this.createManifest(appEvent), signedURL = await this.uploadAssetsIfNeeded(assets, !this.statusManager.status.isReady), websocketUrl = getWebSocketUrl(this.options.url);
354137
+ if (this.statusManager.status.isReady) {
354138
+ let payload = {
354139
+ shopFqdn: this.options.storeFqdn,
354140
+ appId: this.options.appId,
354141
+ assetsUrl: signedURL,
354142
+ manifest,
354143
+ inheritedModuleUids
354144
+ };
354145
+ return this.devSessionUpdateWithRetry(payload);
354146
+ } else {
354147
+ let payload = {
354148
+ shopFqdn: this.options.storeFqdn,
354149
+ appId: this.options.appId,
354150
+ assetsUrl: signedURL,
354151
+ websocketUrl
354152
+ };
354153
+ return this.devSessionCreateWithRetry(payload);
354154
+ }
353997
354155
  } catch (error) {
353998
354156
  if (error.statusCode === 401)
353999
354157
  throw new Error("Unauthorized");
@@ -354723,7 +354881,7 @@ function match(rules, req, websocket = !1) {
354723
354881
 
354724
354882
  // ../app/dist/cli/services/dev/processes/setup-dev-processes.js
354725
354883
  async function setupDevProcesses({ localApp, remoteAppUpdated, developerPlatformClient, remoteApp, storeFqdn, storeId, commandOptions, network, graphiqlPort, graphiqlKey }) {
354726
- let apiKey = remoteApp.apiKey, apiSecret = remoteApp.apiSecretKeys[0]?.secret ?? "", appPreviewUrl = buildAppURLForWeb(storeFqdn, apiKey), env = getEnvironmentVariables(), shouldRenderGraphiQL = !isTruthy(env[environmentVariableNames.disableGraphiQLExplorer]), reloadedApp = await reloadApp(localApp), appWatcher = new AppEventWatcher(reloadedApp, network.proxyUrl), anyPreviewableExtensions = reloadedApp.allExtensions.some((ext) => ext.isPreviewable), devConsoleURL = `${network.proxyUrl}/extensions/dev-console`, previewURL = anyPreviewableExtensions ? devConsoleURL : appPreviewUrl, graphiqlURL = shouldRenderGraphiQL ? `http://localhost:${graphiqlPort}/graphiql${graphiqlKey ? `?key=${graphiqlKey}` : ""}` : void 0, devSessionStatusManager = new DevSessionStatusManager({ isReady: !1, previewURL, graphiqlURL }), processes = [
354884
+ let apiKey = remoteApp.apiKey, apiSecret = remoteApp.apiSecretKeys[0]?.secret ?? "", appPreviewUrl = buildAppURLForWeb(storeFqdn, apiKey), env = getEnvironmentVariables(), shouldRenderGraphiQL = !isTruthy(env[environmentVariableNames.disableGraphiQLExplorer]), reloadedApp = await reloadApp(localApp), appWatcher = new AppEventWatcher(reloadedApp, network.proxyUrl), anyPreviewableExtensions = reloadedApp.allExtensions.some((ext) => ext.isPreviewable), devConsoleURL = `${network.proxyUrl}/extensions/dev-console`, previewURL = !(!firstPartyDev() && skipLocalDevConsole()) && anyPreviewableExtensions ? devConsoleURL : appPreviewUrl, graphiqlURL = shouldRenderGraphiQL ? `http://localhost:${graphiqlPort}/graphiql${graphiqlKey ? `?key=${graphiqlKey}` : ""}` : void 0, devSessionStatusManager = new DevSessionStatusManager({ isReady: !1, previewURL, graphiqlURL }), processes = [
354727
354885
  ...await setupWebProcesses({
354728
354886
  webs: reloadedApp.webs,
354729
354887
  proxyUrl: network.proxyUrl,
@@ -356940,8 +357098,7 @@ var StagedUploadsCreate = {
356940
357098
 
356941
357099
  // ../app/dist/cli/services/bulk-operations/stage-file.js
356942
357100
  async function stageFile(options) {
356943
- let { adminSession, variablesJsonl } = options, buffer = Buffer.from(variablesJsonl ? `${variablesJsonl}
356944
- ` : "", "utf-8"), filename = "bulk-variables.jsonl", size = buffer.length, response = await requestStagedUpload(adminSession, filename, size), target = validateStagedUploadResponse(response);
357101
+ let { adminSession, variablesJsonl } = options, buffer = Buffer.from(variablesJsonl ?? "", "utf-8"), filename = "bulk-variables.jsonl", size = buffer.length, response = await requestStagedUpload(adminSession, filename, size), target = validateStagedUploadResponse(response);
356945
357102
  return await uploadFileToStagedUrl(buffer, target.url, target.parameters, filename), target.stagedUploadKey;
356946
357103
  }
356947
357104
  async function requestStagedUpload(adminSession, filename, size) {
@@ -357246,7 +357403,11 @@ async function executeBulkOperation(input) {
357246
357403
  }) : await renderBulkOperationResult(operation, outputFile);
357247
357404
  } else {
357248
357405
  let operation = await shortBulkOperationPoll(adminSession, createdOperation.id);
357249
- await renderBulkOperationResult(operation, outputFile);
357406
+ ["FAILED", "CANCELED", "EXPIRED"].includes(operation.status) ? await renderBulkOperationResult(operation, outputFile) : renderSuccess({
357407
+ headline: "Bulk operation is running.",
357408
+ body: statusCommandHelpMessage(operation.id),
357409
+ customSections: [{ body: [{ list: { items: [outputContent`ID: ${outputToken.cyan(operation.id)}`.value] } }] }]
357410
+ });
357250
357411
  }
357251
357412
  else
357252
357413
  throw renderWarning({
@@ -357307,6 +357468,8 @@ function resultsContainUserErrors(results) {
357307
357468
  });
357308
357469
  }
357309
357470
  function validateBulkOperationVariables(graphqlOperation, variablesJsonl) {
357471
+ if (isMutation(graphqlOperation) && !variablesJsonl)
357472
+ throw new AbortError(outputContent`Bulk mutations require variables. Provide a JSONL file with ${outputToken.yellow("--variable-file")} or individual JSON objects with ${outputToken.yellow("--variables")}.`);
357310
357473
  if (!isMutation(graphqlOperation) && variablesJsonl)
357311
357474
  throw new AbortError(outputContent`The ${outputToken.yellow("--variables")} and ${outputToken.yellow("--variable-file")} flags can only be used with mutations, not queries.`);
357312
357475
  }
@@ -19,8 +19,9 @@ import {
19
19
  isVerbose,
20
20
  macAddress,
21
21
  opentelemetryDomain,
22
+ skipLocalDevConsole,
22
23
  themeToken
23
- } from "./chunk-OVQTCKQU.js";
24
+ } from "./chunk-RGJ4BXIY.js";
24
25
  import "./chunk-V7OWCSFT.js";
25
26
  import "./chunk-UMUTXITN.js";
26
27
  import "./chunk-Y2JP6WFP.js";
@@ -51,6 +52,7 @@ export {
51
52
  isVerbose,
52
53
  macAddress,
53
54
  opentelemetryDomain,
55
+ skipLocalDevConsole,
54
56
  themeToken
55
57
  };
56
- //# sourceMappingURL=local-ORZXOPNB.js.map
58
+ //# sourceMappingURL=local-XJBENDBD.js.map