@shopify/cli-kit 4.9.5 → 5.0.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/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.d.ts +5 -0
- package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js +22 -0
- package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js.map +1 -1
- package/dist/private/node/api/graphql.d.ts +2 -1
- package/dist/private/node/api/graphql.js +12 -1
- package/dist/private/node/api/graphql.js.map +1 -1
- package/dist/private/node/api.d.ts +2 -0
- package/dist/private/node/api.js +49 -22
- package/dist/private/node/api.js.map +1 -1
- package/dist/private/node/command-json-schema.js +1 -0
- package/dist/private/node/command-json-schema.js.map +1 -1
- package/dist/private/node/constants.d.ts +1 -0
- package/dist/private/node/constants.js +1 -0
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/dev-instance-output.d.ts +47 -0
- package/dist/private/node/dev-instance-output.js +143 -0
- package/dist/private/node/dev-instance-output.js.map +1 -0
- package/dist/private/node/json-error.d.ts +1 -15
- package/dist/private/node/json-error.js +4 -98
- package/dist/private/node/json-error.js.map +1 -1
- package/dist/private/node/output-context.d.ts +8 -0
- package/dist/private/node/output-context.js +10 -0
- package/dist/private/node/output-context.js.map +1 -0
- package/dist/private/node/output.test.js +4 -4
- package/dist/private/node/output.test.js.map +1 -1
- package/dist/private/node/session/automation-token.d.ts +50 -0
- package/dist/private/node/session/automation-token.js +77 -0
- package/dist/private/node/session/automation-token.js.map +1 -0
- package/dist/private/node/session/exchange.d.ts +2 -1
- package/dist/private/node/session/exchange.js +5 -3
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/permanent-store-domain.d.ts +21 -0
- package/dist/private/node/session/permanent-store-domain.js +72 -0
- package/dist/private/node/session/permanent-store-domain.js.map +1 -0
- package/dist/private/node/session.d.ts +3 -2
- package/dist/private/node/session.js +12 -3
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/themes/trust-challenge.d.ts +31 -0
- package/dist/private/node/themes/trust-challenge.js +143 -0
- package/dist/private/node/themes/trust-challenge.js.map +1 -0
- package/dist/private/node/ui/alert.js +1 -1
- package/dist/private/node/ui/alert.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +2 -7
- package/dist/private/node/ui/components/ConcurrentOutput.js +4 -8
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/LoadingBar.js +9 -15
- package/dist/private/node/ui/components/LoadingBar.js.map +1 -1
- package/dist/private/node/ui/components/LoadingBar.test.js +45 -107
- package/dist/private/node/ui/components/LoadingBar.test.js.map +1 -1
- package/dist/private/node/ui/components/LoadingIndicator.d.ts +7 -0
- package/dist/private/node/ui/components/LoadingIndicator.js +22 -0
- package/dist/private/node/ui/components/LoadingIndicator.js.map +1 -0
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/api/admin.js +13 -0
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/graphql.js +38 -7
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/archiver.js +13 -6
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.d.ts +6 -0
- package/dist/public/node/base-command.js +97 -16
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/dev-instance.d.ts +138 -0
- package/dist/public/node/dev-instance.js +365 -0
- package/dist/public/node/dev-instance.js.map +1 -0
- package/dist/public/node/environment.d.ts +6 -3
- package/dist/public/node/environment.js +11 -4
- package/dist/public/node/environment.js.map +1 -1
- package/dist/public/node/error/index.js +2 -1
- package/dist/public/node/error/index.js.map +1 -1
- package/dist/public/node/error/schema.d.ts +24 -24
- package/dist/public/node/error/serialization.d.ts +8 -0
- package/dist/public/node/error/serialization.js +103 -0
- package/dist/public/node/error/serialization.js.map +1 -0
- package/dist/public/node/graphiql/server.js +18 -2
- package/dist/public/node/graphiql/server.js.map +1 -1
- package/dist/public/node/is-global.js +2 -1
- package/dist/public/node/is-global.js.map +1 -1
- package/dist/public/node/notifications-system.d.ts +6 -6
- package/dist/public/node/path.d.ts +19 -3
- package/dist/public/node/path.js +21 -3
- package/dist/public/node/path.js.map +1 -1
- package/dist/public/node/session.d.ts +36 -2
- package/dist/public/node/session.js +48 -4
- package/dist/public/node/session.js.map +1 -1
- package/dist/public/node/system.d.ts +4 -0
- package/dist/public/node/system.js +39 -9
- package/dist/public/node/system.js.map +1 -1
- package/dist/public/node/themes/api.d.ts +9 -0
- package/dist/public/node/themes/api.js +50 -22
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/public/node/themes/theme-manager.d.ts +8 -1
- package/dist/public/node/themes/theme-manager.js +1 -1
- package/dist/public/node/themes/theme-manager.js.map +1 -1
- package/dist/public/node/tree-kill.js +12 -2
- package/dist/public/node/tree-kill.js.map +1 -1
- package/dist/public/node/ui/components.d.ts +1 -0
- package/dist/public/node/ui/components.js +1 -0
- package/dist/public/node/ui/components.js.map +1 -1
- package/dist/public/node/ui.d.ts +24 -4
- package/dist/public/node/ui.js +41 -18
- package/dist/public/node/ui.js.map +1 -1
- package/dist/public/node/upgrade/output.d.ts +17 -0
- package/dist/public/node/upgrade/output.js +51 -0
- package/dist/public/node/upgrade/output.js.map +1 -0
- package/dist/public/node/upgrade/result.d.ts +8 -0
- package/dist/public/node/upgrade/result.js +21 -0
- package/dist/public/node/upgrade/result.js.map +1 -0
- package/dist/public/node/upgrade/types.d.ts +61 -0
- package/dist/public/node/upgrade/types.js +46 -0
- package/dist/public/node/upgrade/types.js.map +1 -0
- package/dist/public/node/upgrade.d.ts +8 -0
- package/dist/public/node/upgrade.js +57 -22
- package/dist/public/node/upgrade.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/private/node/ui/components/TextAnimation.d.ts +0 -10
- package/dist/private/node/ui/components/TextAnimation.js +0 -56
- package/dist/private/node/ui/components/TextAnimation.js.map +0 -1
- package/dist/private/node/ui/components/TextAnimation.test.d.ts +0 -1
- package/dist/private/node/ui/components/TextAnimation.test.js +0 -73
- package/dist/private/node/ui/components/TextAnimation.test.js.map +0 -1
|
@@ -10,16 +10,17 @@ import { GetThemeFileBodies } from '../../../cli/api/graphql/admin/generated/get
|
|
|
10
10
|
import { GetThemeFileChecksums } from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js';
|
|
11
11
|
import { ThemeFilesUpsert, } from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js';
|
|
12
12
|
import { ThemeFilesDelete } from '../../../cli/api/graphql/admin/generated/theme_files_delete.js';
|
|
13
|
-
import { MetafieldDefinitionsByOwnerType } from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js';
|
|
13
|
+
import { MetafieldDefinitionsByOwnerType, } from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js';
|
|
14
14
|
import { GetThemes } from '../../../cli/api/graphql/admin/generated/get_themes.js';
|
|
15
15
|
import { GetTheme } from '../../../cli/api/graphql/admin/generated/get_theme.js';
|
|
16
16
|
import { FindDevelopmentThemeByName } from '../../../cli/api/graphql/admin/generated/find_development_theme_by_name.js';
|
|
17
17
|
import { OnlineStorePasswordProtection } from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js';
|
|
18
|
+
import { extractGraphQLErrors } from '../../../private/node/api/graphql.js';
|
|
19
|
+
import { TrustChallengeError, withTrustChallengeRetry } from '../../../private/node/themes/trust-challenge.js';
|
|
18
20
|
import { adminRequestDoc } from '../api/admin.js';
|
|
19
21
|
import { AbortError } from '../error.js';
|
|
20
22
|
import { outputDebug } from '../output.js';
|
|
21
23
|
import { recordTiming, recordEvent, recordError } from '../analytics.js';
|
|
22
|
-
import { ClientError } from 'graphql-request';
|
|
23
24
|
const SkeletonThemeCdn = 'https://cdn.shopify.com/static/online-store/theme-skeleton.zip';
|
|
24
25
|
const THEME_API_NETWORK_BEHAVIOUR = {
|
|
25
26
|
useNetworkLevelRetry: true,
|
|
@@ -194,7 +195,7 @@ export async function deleteThemeAssets(id, filenames, session) {
|
|
|
194
195
|
for (let i = 0; i < filenames.length; i += batchSize) {
|
|
195
196
|
const batch = filenames.slice(i, i + batchSize);
|
|
196
197
|
// eslint-disable-next-line no-await-in-loop
|
|
197
|
-
const { themeFilesDelete } = await
|
|
198
|
+
const { themeFilesDelete } = await requestThemeAdminDoc({
|
|
198
199
|
query: ThemeFilesDelete,
|
|
199
200
|
session,
|
|
200
201
|
variables: {
|
|
@@ -268,7 +269,7 @@ function prepareFilesForUpload(assets) {
|
|
|
268
269
|
});
|
|
269
270
|
}
|
|
270
271
|
async function uploadFiles(themeId, files, session) {
|
|
271
|
-
return
|
|
272
|
+
return requestThemeAdminDoc({
|
|
272
273
|
query: ThemeFilesUpsert,
|
|
273
274
|
session,
|
|
274
275
|
variables: { themeId: themeGid(themeId), files },
|
|
@@ -338,7 +339,7 @@ export async function themeUpdate(id, params, session) {
|
|
|
338
339
|
input.name = name;
|
|
339
340
|
}
|
|
340
341
|
recordEvent('theme-api:update-theme');
|
|
341
|
-
const { themeUpdate } = await
|
|
342
|
+
const { themeUpdate } = await requestThemeAdminDoc({
|
|
342
343
|
query: ThemeUpdate,
|
|
343
344
|
session,
|
|
344
345
|
variables: { id: composeThemeGid(id), input },
|
|
@@ -365,7 +366,7 @@ export async function themeUpdate(id, params, session) {
|
|
|
365
366
|
}
|
|
366
367
|
export async function themePublish(id, session) {
|
|
367
368
|
recordEvent('theme-api:publish-theme');
|
|
368
|
-
const { themePublish } = await
|
|
369
|
+
const { themePublish } = await requestThemeAdminDoc({
|
|
369
370
|
query: ThemePublish,
|
|
370
371
|
session,
|
|
371
372
|
variables: { id: composeThemeGid(id) },
|
|
@@ -392,7 +393,7 @@ export async function themePublish(id, session) {
|
|
|
392
393
|
}
|
|
393
394
|
export async function themeDelete(id, session) {
|
|
394
395
|
recordEvent('theme-api:delete-theme');
|
|
395
|
-
const { themeDelete } = await
|
|
396
|
+
const { themeDelete } = await requestThemeAdminDoc({
|
|
396
397
|
query: ThemeDelete,
|
|
397
398
|
session,
|
|
398
399
|
variables: { id: composeThemeGid(id) },
|
|
@@ -416,7 +417,7 @@ export async function themeDelete(id, session) {
|
|
|
416
417
|
export async function themeDuplicate(id, name, session) {
|
|
417
418
|
let requestId;
|
|
418
419
|
recordEvent('theme-api:duplicate-theme');
|
|
419
|
-
const { themeDuplicate } = await
|
|
420
|
+
const { themeDuplicate } = await requestThemeAdminDoc({
|
|
420
421
|
query: ThemeDuplicate,
|
|
421
422
|
session,
|
|
422
423
|
variables: { id: composeThemeGid(id), name },
|
|
@@ -465,12 +466,24 @@ export async function themeDuplicate(id, name, session) {
|
|
|
465
466
|
}
|
|
466
467
|
export async function metafieldDefinitionsByOwnerType(type, session) {
|
|
467
468
|
recordEvent('theme-api:fetch-metafield-definitions');
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
469
|
+
const definitions = [];
|
|
470
|
+
let after = null;
|
|
471
|
+
while (true) {
|
|
472
|
+
// eslint-disable-next-line no-await-in-loop
|
|
473
|
+
const { metafieldDefinitions } = await adminRequestDoc({
|
|
474
|
+
query: MetafieldDefinitionsByOwnerType,
|
|
475
|
+
session,
|
|
476
|
+
variables: { ownerType: type, after },
|
|
477
|
+
});
|
|
478
|
+
definitions.push(...metafieldDefinitions.nodes);
|
|
479
|
+
if (!metafieldDefinitions.pageInfo.hasNextPage)
|
|
480
|
+
break;
|
|
481
|
+
const endCursor = metafieldDefinitions.pageInfo.endCursor;
|
|
482
|
+
if (!endCursor || endCursor === after)
|
|
483
|
+
unexpectedGraphQLError('Failed to paginate metafield definitions');
|
|
484
|
+
after = endCursor;
|
|
485
|
+
}
|
|
486
|
+
return definitions.map((definition) => ({
|
|
474
487
|
key: definition.key,
|
|
475
488
|
namespace: definition.namespace,
|
|
476
489
|
name: definition.name,
|
|
@@ -496,9 +509,20 @@ export async function passwordProtected(session) {
|
|
|
496
509
|
function unexpectedGraphQLError(message) {
|
|
497
510
|
throw recordError(new AbortError(message));
|
|
498
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* Whether the error ends a Trust Battery challenge on a theme request. A caller that
|
|
514
|
+
* retries theme requests must rethrow it, or the user is asked to verify again for
|
|
515
|
+
* each attempt.
|
|
516
|
+
*
|
|
517
|
+
* @param error - The error to check.
|
|
518
|
+
* @returns True when the error ends a Trust Battery challenge.
|
|
519
|
+
*/
|
|
520
|
+
export function isTrustChallengeError(error) {
|
|
521
|
+
return error instanceof TrustChallengeError;
|
|
522
|
+
}
|
|
499
523
|
async function requestThemeAdminDoc(options) {
|
|
500
524
|
try {
|
|
501
|
-
const response = await adminRequestDoc(options);
|
|
525
|
+
const response = await withTrustChallengeRetry(() => adminRequestDoc(options));
|
|
502
526
|
return response;
|
|
503
527
|
}
|
|
504
528
|
catch (error) {
|
|
@@ -507,8 +531,6 @@ async function requestThemeAdminDoc(options) {
|
|
|
507
531
|
}
|
|
508
532
|
}
|
|
509
533
|
function abortIfMissingThemeAccessScope(error) {
|
|
510
|
-
if (!(error instanceof ClientError))
|
|
511
|
-
return;
|
|
512
534
|
const requiredAccess = getThemeAccessRequirementForAccessDeniedError(error);
|
|
513
535
|
if (!requiredAccess)
|
|
514
536
|
return;
|
|
@@ -533,9 +555,18 @@ function abortIfMissingThemeAccessScope(error) {
|
|
|
533
555
|
[
|
|
534
556
|
'For',
|
|
535
557
|
{ command: 'theme push' },
|
|
536
|
-
'
|
|
558
|
+
{ char: ',' },
|
|
537
559
|
{ command: 'theme dev' },
|
|
538
560
|
{ char: ',' },
|
|
561
|
+
{ command: 'theme publish' },
|
|
562
|
+
{ char: ',' },
|
|
563
|
+
{ command: 'theme delete' },
|
|
564
|
+
{ char: ',' },
|
|
565
|
+
{ command: 'theme rename' },
|
|
566
|
+
{ char: ',' },
|
|
567
|
+
'and',
|
|
568
|
+
{ command: 'theme duplicate' },
|
|
569
|
+
{ char: ',' },
|
|
539
570
|
'add both the',
|
|
540
571
|
{ command: 'read_themes' },
|
|
541
572
|
'and',
|
|
@@ -554,10 +585,7 @@ function abortIfMissingThemeAccessScope(error) {
|
|
|
554
585
|
throw recordError(new AbortError(`The authenticated account or access token is missing ${requiredAccess}.`, undefined, nextSteps));
|
|
555
586
|
}
|
|
556
587
|
function getThemeAccessRequirementForAccessDeniedError(error) {
|
|
557
|
-
const
|
|
558
|
-
if (!Array.isArray(graphQLErrors))
|
|
559
|
-
return undefined;
|
|
560
|
-
const accessDeniedError = graphQLErrors.find((graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED');
|
|
588
|
+
const accessDeniedError = extractGraphQLErrors(error).find((graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED');
|
|
561
589
|
if (!accessDeniedError)
|
|
562
590
|
return undefined;
|
|
563
591
|
const requiredAccess = accessDeniedError.extensions?.requiredAccess;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {Result, Checksum, Key, Theme, ThemeAsset, Operation} from './types.js'\nimport {buildTheme} from './factories.js'\nimport {composeThemeGid, parseGid, DEVELOPMENT_THEME_ROLE} from './utils.js'\nimport {ThemeUpdate} from '../../../cli/api/graphql/admin/generated/theme_update.js'\nimport {ThemeDelete} from '../../../cli/api/graphql/admin/generated/theme_delete.js'\nimport {ThemeDuplicate} from '../../../cli/api/graphql/admin/generated/theme_duplicate.js'\nimport {ThemePublish} from '../../../cli/api/graphql/admin/generated/theme_publish.js'\nimport {ThemeCreate} from '../../../cli/api/graphql/admin/generated/theme_create.js'\nimport {GetThemeFileBodies} from '../../../cli/api/graphql/admin/generated/get_theme_file_bodies.js'\nimport {GetThemeFileChecksums} from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js'\nimport {\n ThemeFilesUpsert,\n ThemeFilesUpsertMutation,\n} from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js'\nimport {ThemeFilesDelete} from '../../../cli/api/graphql/admin/generated/theme_files_delete.js'\nimport {\n OnlineStoreThemeFileBodyInputType,\n OnlineStoreThemeFilesUpsertFileInput,\n MetafieldOwnerType,\n ThemeRole,\n} from '../../../cli/api/graphql/admin/generated/types.js'\nimport {MetafieldDefinitionsByOwnerType} from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js'\nimport {GetThemes} from '../../../cli/api/graphql/admin/generated/get_themes.js'\nimport {GetTheme} from '../../../cli/api/graphql/admin/generated/get_theme.js'\nimport {FindDevelopmentThemeByName} from '../../../cli/api/graphql/admin/generated/find_development_theme_by_name.js'\nimport {OnlineStorePasswordProtection} from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js'\nimport {RequestModeInput} from '../http.js'\nimport {adminRequestDoc, type AdminRequestOptions} from '../api/admin.js'\nimport {AdminSession} from '../session.js'\nimport {AbortError} from '../error.js'\nimport {outputDebug} from '../output.js'\nimport {recordTiming, recordEvent, recordError} from '../analytics.js'\nimport {ClientError, type Variables} from 'graphql-request'\nimport type {InlineToken, TokenItem} from '../ui.js'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing' | 'src'>>\nexport type AssetParams = Pick<ThemeAsset, 'key'> & Partial<Pick<ThemeAsset, 'value' | 'attachment'>>\nconst SkeletonThemeCdn = 'https://cdn.shopify.com/static/online-store/theme-skeleton.zip'\nconst THEME_API_NETWORK_BEHAVIOUR: RequestModeInput = {\n useNetworkLevelRetry: true,\n useAbortSignal: false,\n maxRetryTimeMs: 90 * 1000,\n recordCommandRetries: true,\n}\nconst DEFAULT_THEME_ACCESS_REQUIREMENT = 'the required theme access scope'\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const gid = composeThemeGid(id)\n recordEvent('theme-api:fetch-theme')\n\n try {\n const {theme} = await adminRequestDoc({\n query: GetTheme,\n session,\n variables: {id: gid},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (theme) {\n return buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n }\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n /**\n * Consumers of this and other theme APIs in this file expect either a theme\n * or `undefined`.\n *\n * Error handlers should not inspect GraphQL error messages directly, as\n * they are internationalized.\n */\n recordError(error)\n outputDebug(`Error fetching theme with ID: ${id}`)\n }\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const themes: Theme[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-themes')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemes,\n session,\n variables: {after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n const {nodes, pageInfo} = response.themes\n nodes.forEach((theme) => {\n const t = buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n if (t) {\n themes.push(t)\n }\n })\n if (!pageInfo.hasNextPage) {\n return themes\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function findDevelopmentThemeByName(name: string, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:find-development-theme-by-name')\n\n const {themes} = await requestThemeAdminDoc({\n query: FindDevelopmentThemeByName,\n session,\n variables: {name},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n\n if (themes.nodes.length > 1) {\n throw recordError(new AbortError(`More than one development theme is named \"${name}\"`))\n }\n\n if (themes.nodes.length === 1) {\n const {id, processing, role, name} = themes.nodes[0]!\n\n return buildTheme({\n id: parseGid(id),\n processing,\n role: role.toLowerCase(),\n name,\n })\n }\n}\n\nexport async function themeCreate(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const themeSource = params.src ?? SkeletonThemeCdn\n recordEvent('theme-api:create-theme')\n const {themeCreate} = await requestThemeAdminDoc({\n query: ThemeCreate,\n session,\n variables: {\n name: params.name ?? '',\n source: themeSource,\n role: (params.role ?? DEVELOPMENT_THEME_ROLE).toUpperCase() as ThemeRole,\n },\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeCreate) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n const {theme, userErrors} = themeCreate\n if (userErrors.length) {\n const userErrors = themeCreate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]> {\n const assets: ThemeAsset[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-assets')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileBodies,\n session,\n variables: {id: themeGid(id), filenames, after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.theme?.files?.nodes || !response.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n unexpectedGraphQLError(`Error fetching assets: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n assets.push(\n // eslint-disable-next-line no-await-in-loop\n ...(await Promise.all(\n nodes.map(async (file) => {\n const {attachment, value} = await parseThemeFileContent(file.body)\n return {\n attachment,\n key: file.filename,\n checksum: file.checksumMd5 as string,\n value,\n }\n }),\n )),\n )\n\n if (!pageInfo.hasNextPage) {\n return assets\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function deleteThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<Result[]> {\n const batchSize = 50\n const results: Result[] = []\n recordEvent('theme-api:delete-assets')\n\n for (let i = 0; i < filenames.length; i += batchSize) {\n const batch = filenames.slice(i, i + batchSize)\n // eslint-disable-next-line no-await-in-loop\n const {themeFilesDelete} = await adminRequestDoc({\n query: ThemeFilesDelete,\n session,\n variables: {\n themeId: composeThemeGid(id),\n files: batch,\n },\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeFilesDelete) {\n unexpectedGraphQLError('Failed to delete theme assets')\n }\n\n const {deletedThemeFiles, userErrors} = themeFilesDelete\n\n if (deletedThemeFiles) {\n deletedThemeFiles.forEach((file) => {\n results.push({key: file.filename, success: true, operation: Operation.Delete})\n })\n }\n\n if (userErrors.length > 0) {\n userErrors.forEach((error) => {\n if (error.filename) {\n recordError(`Asset deletion failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Delete,\n errors: {asset: [error.message]},\n })\n } else {\n unexpectedGraphQLError(`Failed to delete theme assets: ${error.message}`)\n }\n })\n }\n }\n\n return results\n}\n\nexport async function bulkUploadThemeAssets(\n id: number,\n assets: AssetParams[],\n session: AdminSession,\n): Promise<Result[]> {\n const results: Result[] = []\n recordEvent('theme-api:bulk-upload-assets')\n for (let i = 0; i < assets.length; i += 50) {\n const chunk = assets.slice(i, i + 50)\n const files = prepareFilesForUpload(chunk)\n\n recordTiming('theme-api:upload-files')\n // eslint-disable-next-line no-await-in-loop\n const uploadResults = await uploadFiles(id, files, session)\n recordTiming('theme-api:upload-files')\n\n results.push(...processUploadResults(uploadResults))\n }\n return results\n}\n\nfunction prepareFilesForUpload(assets: AssetParams[]): OnlineStoreThemeFilesUpsertFileInput[] {\n return assets.map((asset) => {\n if (asset.attachment) {\n return {\n filename: asset.key,\n body: {\n type: 'BASE64' as const,\n value: asset.attachment,\n },\n }\n } else {\n return {\n filename: asset.key,\n body: {\n type: 'TEXT' as const,\n value: asset.value ?? '',\n },\n }\n }\n })\n}\n\nasync function uploadFiles(\n themeId: number,\n files: {filename: string; body: {type: OnlineStoreThemeFileBodyInputType; value: string}}[],\n session: AdminSession,\n): Promise<ThemeFilesUpsertMutation> {\n return adminRequestDoc({\n query: ThemeFilesUpsert,\n session,\n variables: {themeId: themeGid(themeId), files},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n}\n\nfunction processUploadResults(uploadResults: ThemeFilesUpsertMutation): Result[] {\n const {themeFilesUpsert} = uploadResults\n\n if (!themeFilesUpsert) {\n unexpectedGraphQLError('Failed to upload theme files')\n }\n\n const {upsertedThemeFiles, userErrors} = themeFilesUpsert\n\n const results: Result[] = []\n\n upsertedThemeFiles?.forEach((file) => {\n results.push({\n key: file.filename,\n success: true,\n operation: Operation.Upload,\n })\n })\n\n userErrors.forEach((error) => {\n if (!error.filename) {\n unexpectedGraphQLError(`Error uploading theme files: ${error.message}`)\n }\n recordError(`Asset upload failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Upload,\n errors: {asset: [error.message]},\n })\n })\n\n return results\n}\n\nexport async function fetchChecksums(id: number, session: AdminSession): Promise<Checksum[]> {\n const checksums: Checksum[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-checksums')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileChecksums,\n session,\n variables: {id: themeGid(id), after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response?.theme?.files?.nodes || !response?.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n throw recordError(new AbortError(`Failed to fetch checksums for: ${userErrors}`))\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n checksums.push(\n ...nodes.map((file) => ({\n key: file.filename,\n checksum: file.checksumMd5 as string,\n })),\n )\n\n if (!pageInfo.hasNextPage) {\n return checksums\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const name = params.name\n const input: Record<string, string> = {}\n if (name) {\n input.name = name\n }\n recordEvent('theme-api:update-theme')\n\n const {themeUpdate} = await adminRequestDoc({\n query: ThemeUpdate,\n session,\n variables: {id: composeThemeGid(id), input},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeUpdate) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themeUpdate\n if (userErrors.length) {\n const userErrors = themeUpdate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themePublish(id: number, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:publish-theme')\n const {themePublish} = await adminRequestDoc({\n query: ThemePublish,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themePublish) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themePublish\n if (userErrors.length) {\n const userErrors = themePublish.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themeDelete(id: number, session: AdminSession): Promise<boolean | undefined> {\n recordEvent('theme-api:delete-theme')\n const {themeDelete} = await adminRequestDoc({\n query: ThemeDelete,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeDelete) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {deletedThemeId, userErrors} = themeDelete\n if (userErrors.length) {\n const userErrors = themeDelete.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!deletedThemeId) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return true\n}\n\nexport interface ThemeDuplicateResult {\n theme?: Theme\n userErrors: {field?: string[] | null; message: string}[]\n requestId?: string\n}\n\nexport async function themeDuplicate(\n id: number,\n name: string | undefined,\n session: AdminSession,\n): Promise<ThemeDuplicateResult> {\n let requestId: string | undefined\n recordEvent('theme-api:duplicate-theme')\n\n const {themeDuplicate} = await adminRequestDoc({\n query: ThemeDuplicate,\n session,\n variables: {id: composeThemeGid(id), name},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n responseOptions: {\n onResponse: (response) => {\n requestId = response.headers.get('x-request-id') ?? undefined\n },\n },\n })\n\n if (!themeDuplicate) {\n // An unexpected error occurred during the GraphQL request execution\n recordError('Failed to duplicate theme')\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const {newTheme, userErrors} = themeDuplicate\n\n if (userErrors.length > 0) {\n return {\n theme: undefined,\n userErrors,\n requestId,\n }\n }\n\n if (!newTheme) {\n // An unexpected error if neither theme nor userErrors are returned\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const theme = buildTheme({\n id: parseGid(newTheme.id),\n name: newTheme.name,\n role: newTheme.role.toLowerCase(),\n })\n\n return {\n theme,\n userErrors: [],\n requestId,\n }\n}\n\nexport async function metafieldDefinitionsByOwnerType(type: MetafieldOwnerType, session: AdminSession) {\n recordEvent('theme-api:fetch-metafield-definitions')\n const {metafieldDefinitions} = await adminRequestDoc({\n query: MetafieldDefinitionsByOwnerType,\n session,\n variables: {ownerType: type},\n })\n\n return metafieldDefinitions.nodes.map((definition) => ({\n key: definition.key,\n namespace: definition.namespace,\n name: definition.name,\n description: definition.description,\n type: {\n name: definition.type.name,\n category: definition.type.category,\n },\n }))\n}\n\nexport async function passwordProtected(session: AdminSession): Promise<boolean> {\n recordEvent('theme-api:check-password-protection')\n const {onlineStore} = await adminRequestDoc({\n query: OnlineStorePasswordProtection,\n session,\n })\n if (!onlineStore) {\n unexpectedGraphQLError(\"Unable to get details about the storefront's password protection\")\n }\n\n const {passwordProtection} = onlineStore\n\n return passwordProtection.enabled\n}\n\nfunction unexpectedGraphQLError(message: string): never {\n throw recordError(new AbortError(message))\n}\n\nasync function requestThemeAdminDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n try {\n const response = await adminRequestDoc(options)\n return response\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n throw error\n }\n}\n\nfunction abortIfMissingThemeAccessScope(error: unknown): void {\n if (!(error instanceof ClientError)) return\n\n const requiredAccess = getThemeAccessRequirementForAccessDeniedError(error)\n if (!requiredAccess) return\n\n const nextSteps: TokenItem<InlineToken>[] = [\n [\n 'If you authenticated with an Admin API access token, update the app or integration that issued the token to include the required theme access scopes, then reauthorize it or generate a new token.',\n ],\n [\n 'For',\n {command: 'theme pull'},\n {char: ','},\n {command: 'theme list'},\n {char: ','},\n 'and',\n {command: 'theme info'},\n {char: ','},\n 'add the',\n {command: 'read_themes'},\n 'scope',\n {char: '.'},\n ],\n [\n 'For',\n {command: 'theme push'},\n 'and',\n {command: 'theme dev'},\n {char: ','},\n 'add both the',\n {command: 'read_themes'},\n 'and',\n {command: 'write_themes'},\n 'scopes',\n {char: '.'},\n ],\n [\n 'If you authenticated with your Shopify account, make sure your staff or collaborator account can access Online Store themes, then run',\n {command: 'shopify auth logout'},\n 'and try again',\n {char: '.'},\n ],\n ['See', {link: {label: 'Shopify access scopes', url: 'https://shopify.dev/api/usage/access-scopes'}}, {char: '.'}],\n ]\n\n throw recordError(\n new AbortError(`The authenticated account or access token is missing ${requiredAccess}.`, undefined, nextSteps),\n )\n}\n\nfunction getThemeAccessRequirementForAccessDeniedError(error: ClientError): string | undefined {\n const graphQLErrors = error.response.errors\n if (!Array.isArray(graphQLErrors)) return undefined\n\n const accessDeniedError = graphQLErrors.find((graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED')\n if (!accessDeniedError) return undefined\n\n const requiredAccess = accessDeniedError.extensions?.requiredAccess\n if (typeof requiredAccess !== 'string') return DEFAULT_THEME_ACCESS_REQUIREMENT\n\n return formatThemeAccessRequirement(requiredAccess)\n}\n\nfunction formatThemeAccessRequirement(requiredAccess: string): string {\n const requirement = requiredAccess\n .trim()\n .replace(/\\.$/, '')\n .replace(/^The user needs\\s+/i, '')\n\n return requirement || DEFAULT_THEME_ACCESS_REQUIREMENT\n}\n\nfunction themeGid(id: number): string {\n return `gid://shopify/OnlineStoreTheme/${id}`\n}\n\ntype OnlineStoreThemeFileBody =\n | {__typename: 'OnlineStoreThemeFileBodyBase64'; contentBase64: string}\n | {__typename: 'OnlineStoreThemeFileBodyText'; content: string}\n | {__typename: 'OnlineStoreThemeFileBodyUrl'; url: string}\n\nexport async function parseThemeFileContent(\n body: OnlineStoreThemeFileBody,\n): Promise<{value?: string; attachment?: string}> {\n switch (body.__typename) {\n case 'OnlineStoreThemeFileBodyText':\n return {value: body.content}\n case 'OnlineStoreThemeFileBodyBase64':\n return {attachment: body.contentBase64}\n case 'OnlineStoreThemeFileBodyUrl':\n try {\n // eslint-disable-next-line no-restricted-globals\n const response = await fetch(body.url)\n\n const arrayBuffer = await response.arrayBuffer()\n return {attachment: Buffer.from(arrayBuffer).toString('base64')}\n } catch (error) {\n // Raise error if we can't download the file\n throw recordError(new AbortError(`Error downloading content from URL: ${body.url}`))\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,SAAS,EAAC,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAC,UAAU,EAAC,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAE,sBAAsB,EAAC,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAC,WAAW,EAAC,MAAM,0DAA0D,CAAA;AACpF,OAAO,EAAC,WAAW,EAAC,MAAM,0DAA0D,CAAA;AACpF,OAAO,EAAC,cAAc,EAAC,MAAM,6DAA6D,CAAA;AAC1F,OAAO,EAAC,YAAY,EAAC,MAAM,2DAA2D,CAAA;AACtF,OAAO,EAAC,WAAW,EAAC,MAAM,0DAA0D,CAAA;AACpF,OAAO,EAAC,kBAAkB,EAAC,MAAM,mEAAmE,CAAA;AACpG,OAAO,EAAC,qBAAqB,EAAC,MAAM,sEAAsE,CAAA;AAC1G,OAAO,EACL,gBAAgB,GAEjB,MAAM,gEAAgE,CAAA;AACvE,OAAO,EAAC,gBAAgB,EAAC,MAAM,gEAAgE,CAAA;AAO/F,OAAO,EACL,+BAA+B,GAEhC,MAAM,iFAAiF,CAAA;AACxF,OAAO,EAAC,SAAS,EAAC,MAAM,wDAAwD,CAAA;AAChF,OAAO,EAAC,QAAQ,EAAC,MAAM,uDAAuD,CAAA;AAC9E,OAAO,EAAC,0BAA0B,EAAC,MAAM,4EAA4E,CAAA;AACrH,OAAO,EAAC,6BAA6B,EAAC,MAAM,8EAA8E,CAAA;AAC1H,OAAO,EAAC,oBAAoB,EAAC,MAAM,sCAAsC,CAAA;AACzE,OAAO,EAAC,mBAAmB,EAAE,uBAAuB,EAAC,MAAM,iDAAiD,CAAA;AAE5G,OAAO,EAAC,eAAe,EAA2B,MAAM,iBAAiB,CAAA;AAEzE,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAA;AACtC,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAA;AACxC,OAAO,EAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAC,MAAM,iBAAiB,CAAA;AAMtE,MAAM,gBAAgB,GAAG,gEAAgE,CAAA;AACzF,MAAM,2BAA2B,GAAqB;IACpD,oBAAoB,EAAE,IAAI;IAC1B,cAAc,EAAE,KAAK;IACrB,cAAc,EAAE,EAAE,GAAG,IAAI;IACzB,oBAAoB,EAAE,IAAI;CAC3B,CAAA;AACD,MAAM,gCAAgC,GAAG,iCAAiC,CAAA;AAE1E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAU,EAAE,OAAqB;IAChE,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,CAAC,CAAA;IAC/B,WAAW,CAAC,uBAAuB,CAAC,CAAA;IAEpC,IAAI,CAAC;QACH,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,eAAe,CAAC;YACpC,KAAK,EAAE,QAAQ;YACf,OAAO;YACP,SAAS,EAAE,EAAC,EAAE,EAAE,GAAG,EAAC;YACpB,eAAe,EAAE,EAAC,YAAY,EAAE,KAAK,EAAC;YACtC,kBAAkB,EAAE,2BAA2B;SAChD,CAAC,CAAA;QAEF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,UAAU,CAAC;gBAChB,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;gBAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CAAA;QACJ,CAAC;QAED,qDAAqD;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8BAA8B,CAAC,KAAK,CAAC,CAAA;QACrC;;;;;;WAMG;QACH,WAAW,CAAC,KAAK,CAAC,CAAA;QAClB,WAAW,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAA;IACpD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAqB;IACrD,MAAM,MAAM,GAAY,EAAE,CAAA;IAC1B,IAAI,KAAK,GAAkB,IAAI,CAAA;IAC/B,WAAW,CAAC,wBAAwB,CAAC,CAAA;IAErC,OAAO,IAAI,EAAE,CAAC;QACZ,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC;YAC1C,KAAK,EAAE,SAAS;YAChB,OAAO;YACP,SAAS,EAAE,EAAC,KAAK,EAAC;YAClB,eAAe,EAAE,EAAC,YAAY,EAAE,KAAK,EAAC;YACtC,kBAAkB,EAAE,2BAA2B;SAChD,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;QAClD,CAAC;QACD,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAC,GAAG,QAAQ,CAAC,MAAM,CAAA;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACtB,MAAM,CAAC,GAAG,UAAU,CAAC;gBACnB,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;gBAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CAAA;YACF,IAAI,CAAC,EAAE,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAChB,CAAC;QACH,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAA;QACf,CAAC;QAED,KAAK,GAAG,QAAQ,CAAC,SAAmB,CAAA;IACtC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,IAAY,EAAE,OAAqB;IAClF,WAAW,CAAC,0CAA0C,CAAC,CAAA;IAEvD,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,oBAAoB,CAAC;QAC1C,KAAK,EAAE,0BAA0B;QACjC,OAAO;QACP,SAAS,EAAE,EAAC,IAAI,EAAC;QACjB,eAAe,EAAE,EAAC,YAAY,EAAE,KAAK,EAAC;QACtC,kBAAkB,EAAE,2BAA2B;KAChD,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,6CAA6C,IAAI,GAAG,CAAC,CAAC,CAAA;IACzF,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,EAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAA;QAErD,OAAO,UAAU,CAAC;YAChB,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC;YAChB,UAAU;YACV,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE;YACxB,IAAI;SACL,CAAC,CAAA;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAmB,EAAE,OAAqB;IAC1E,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,IAAI,gBAAgB,CAAA;IAClD,WAAW,CAAC,wBAAwB,CAAC,CAAA;IACrC,MAAM,EAAC,WAAW,EAAC,GAAG,MAAM,oBAAoB,CAAC;QAC/C,KAAK,EAAE,WAAW;QAClB,OAAO;QACP,SAAS,EAAE;YACT,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;YACvB,MAAM,EAAE,WAAW;YACnB,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,sBAAsB,CAAC,CAAC,WAAW,EAAe;SACzE;QACD,eAAe,EAAE,EAAC,YAAY,EAAE,KAAK,EAAC;QACtC,kBAAkB,EAAE,2BAA2B;KAChD,CAAC,CAAA;IAEF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,EAAC,KAAK,EAAE,UAAU,EAAC,GAAG,WAAW,CAAA;IACvC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClF,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,UAAU,CAAC;QAChB,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;KAC/B,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAU,EAAE,SAAgB,EAAE,OAAqB;IACxF,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,IAAI,KAAK,GAAkB,IAAI,CAAA;IAC/B,WAAW,CAAC,wBAAwB,CAAC,CAAA;IAErC,OAAO,IAAI,EAAE,CAAC;QACZ,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC;YAC1C,KAAK,EAAE,kBAAkB;YACzB,OAAO;YACP,SAAS,EAAE,EAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAC;YAC/C,eAAe,EAAE,EAAC,YAAY,EAAE,KAAK,EAAC;YACtC,kBAAkB,EAAE,2BAA2B;SAChD,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YACtE,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC9F,sBAAsB,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAA;QAChE,CAAC;QAED,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAA;QAE9C,MAAM,CAAC,IAAI;QACT,4CAA4C;QAC5C,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CACnB,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,EAAC,UAAU,EAAE,KAAK,EAAC,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClE,OAAO;gBACL,UAAU;gBACV,GAAG,EAAE,IAAI,CAAC,QAAQ;gBAClB,QAAQ,EAAE,IAAI,CAAC,WAAqB;gBACpC,KAAK;aACN,CAAA;QACH,CAAC,CAAC,CACH,CAAC,CACH,CAAA;QAED,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAA;QACf,CAAC;QAED,KAAK,GAAG,QAAQ,CAAC,SAAmB,CAAA;IACtC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EAAU,EAAE,SAAgB,EAAE,OAAqB;IACzF,MAAM,SAAS,GAAG,EAAE,CAAA;IACpB,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,WAAW,CAAC,yBAAyB,CAAC,CAAA;IAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAA;QAC/C,4CAA4C;QAC5C,MAAM,EAAC,gBAAgB,EAAC,GAAG,MAAM,oBAAoB,CAAC;YACpD,KAAK,EAAE,gBAAgB;YACvB,OAAO;YACP,SAAS,EAAE;gBACT,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC;gBAC5B,KAAK,EAAE,KAAK;aACb;YACD,kBAAkB,EAAE,2BAA2B;SAChD,CAAC,CAAA;QAEF,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,sBAAsB,CAAC,+BAA+B,CAAC,CAAA;QACzD,CAAC;QAED,MAAM,EAAC,iBAAiB,EAAE,UAAU,EAAC,GAAG,gBAAgB,CAAA;QAExD,IAAI,iBAAiB,EAAE,CAAC;YACtB,iBAAiB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBACjC,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,EAAC,CAAC,CAAA;YAChF,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC3B,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACnB,WAAW,CAAC,6BAA6B,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;oBAC5E,OAAO,CAAC,IAAI,CAAC;wBACX,GAAG,EAAE,KAAK,CAAC,QAAQ;wBACnB,OAAO,EAAE,KAAK;wBACd,SAAS,EAAE,SAAS,CAAC,MAAM;wBAC3B,MAAM,EAAE,EAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAC;qBACjC,CAAC,CAAA;gBACJ,CAAC;qBAAM,CAAC;oBACN,sBAAsB,CAAC,kCAAkC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC3E,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,EAAU,EACV,MAAqB,EACrB,OAAqB;IAErB,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,WAAW,CAAC,8BAA8B,CAAC,CAAA;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAA;QACrC,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;QAE1C,YAAY,CAAC,wBAAwB,CAAC,CAAA;QACtC,4CAA4C;QAC5C,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAC3D,YAAY,CAAC,wBAAwB,CAAC,CAAA;QAEtC,OAAO,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAqB;IAClD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;gBACL,QAAQ,EAAE,KAAK,CAAC,GAAG;gBACnB,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAiB;oBACvB,KAAK,EAAE,KAAK,CAAC,UAAU;iBACxB;aACF,CAAA;QACH,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,QAAQ,EAAE,KAAK,CAAC,GAAG;gBACnB,IAAI,EAAE;oBACJ,IAAI,EAAE,MAAe;oBACrB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;iBACzB;aACF,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,OAAe,EACf,KAA2F,EAC3F,OAAqB;IAErB,OAAO,oBAAoB,CAAC;QAC1B,KAAK,EAAE,gBAAgB;QACvB,OAAO;QACP,SAAS,EAAE,EAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAC;QAC9C,kBAAkB,EAAE,2BAA2B;KAChD,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,aAAuC;IACnE,MAAM,EAAC,gBAAgB,EAAC,GAAG,aAAa,CAAA;IAExC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,sBAAsB,CAAC,8BAA8B,CAAC,CAAA;IACxD,CAAC;IAED,MAAM,EAAC,kBAAkB,EAAE,UAAU,EAAC,GAAG,gBAAgB,CAAA;IAEzD,MAAM,OAAO,GAAa,EAAE,CAAA;IAE5B,kBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACnC,OAAO,CAAC,IAAI,CAAC;YACX,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,SAAS,CAAC,MAAM;SAC5B,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3B,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpB,sBAAsB,CAAC,gCAAgC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACzE,CAAC;QACD,WAAW,CAAC,2BAA2B,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAC1E,OAAO,CAAC,IAAI,CAAC;YACX,GAAG,EAAE,KAAK,CAAC,QAAQ;YACnB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,SAAS,CAAC,MAAM;YAC3B,MAAM,EAAE,EAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAC;SACjC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EAAU,EAAE,OAAqB;IACpE,MAAM,SAAS,GAAe,EAAE,CAAA;IAChC,IAAI,KAAK,GAAkB,IAAI,CAAA;IAC/B,WAAW,CAAC,2BAA2B,CAAC,CAAA;IAExC,OAAO,IAAI,EAAE,CAAC;QACZ,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC;YAC1C,KAAK,EAAE,qBAAqB;YAC5B,OAAO;YACP,SAAS,EAAE,EAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,KAAK,EAAC;YACpC,eAAe,EAAE,EAAC,YAAY,EAAE,KAAK,EAAC;YACtC,kBAAkB,EAAE,2BAA2B;SAChD,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YACxE,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC9F,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC,CAAA;QACnF,CAAC;QAED,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAA;QAE9C,SAAS,CAAC,IAAI,CACZ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtB,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,QAAQ,EAAE,IAAI,CAAC,WAAqB;SACrC,CAAC,CAAC,CACJ,CAAA;QAED,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC1B,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,KAAK,GAAG,QAAQ,CAAC,SAAmB,CAAA;IACtC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU,EAAE,MAAmB,EAAE,OAAqB;IACtF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;IACxB,MAAM,KAAK,GAA2B,EAAE,CAAA;IACxC,IAAI,IAAI,EAAE,CAAC;QACT,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;IACnB,CAAC;IACD,WAAW,CAAC,wBAAwB,CAAC,CAAA;IAErC,MAAM,EAAC,WAAW,EAAC,GAAG,MAAM,oBAAoB,CAAC;QAC/C,KAAK,EAAE,WAAW;QAClB,OAAO;QACP,SAAS,EAAE,EAAC,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC,EAAE,KAAK,EAAC;QAC3C,kBAAkB,EAAE,2BAA2B;KAChD,CAAC,CAAA;IACF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,oEAAoE;QACpE,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,EAAC,KAAK,EAAE,UAAU,EAAC,GAAG,WAAW,CAAA;IACvC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClF,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,mEAAmE;QACnE,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,UAAU,CAAC;QAChB,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;KAC/B,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EAAU,EAAE,OAAqB;IAClE,WAAW,CAAC,yBAAyB,CAAC,CAAA;IACtC,MAAM,EAAC,YAAY,EAAC,GAAG,MAAM,oBAAoB,CAAC;QAChD,KAAK,EAAE,YAAY;QACnB,OAAO;QACP,SAAS,EAAE,EAAC,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC,EAAC;QACpC,kBAAkB,EAAE,2BAA2B;KAChD,CAAC,CAAA;IACF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,oEAAoE;QACpE,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,EAAC,KAAK,EAAE,UAAU,EAAC,GAAG,YAAY,CAAA;IACxC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnF,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,mEAAmE;QACnE,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,UAAU,CAAC;QAChB,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;KAC/B,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU,EAAE,OAAqB;IACjE,WAAW,CAAC,wBAAwB,CAAC,CAAA;IACrC,MAAM,EAAC,WAAW,EAAC,GAAG,MAAM,oBAAoB,CAAC;QAC/C,KAAK,EAAE,WAAW;QAClB,OAAO;QACP,SAAS,EAAE,EAAC,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC,EAAC;QACpC,kBAAkB,EAAE,2BAA2B;KAChD,CAAC,CAAA;IACF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,oEAAoE;QACpE,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,EAAC,cAAc,EAAE,UAAU,EAAC,GAAG,WAAW,CAAA;IAChD,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClF,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,mEAAmE;QACnE,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAU,EACV,IAAwB,EACxB,OAAqB;IAErB,IAAI,SAA6B,CAAA;IACjC,WAAW,CAAC,2BAA2B,CAAC,CAAA;IAExC,MAAM,EAAC,cAAc,EAAC,GAAG,MAAM,oBAAoB,CAAC;QAClD,KAAK,EAAE,cAAc;QACrB,OAAO;QACP,SAAS,EAAE,EAAC,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC,EAAE,IAAI,EAAC;QAC1C,kBAAkB,EAAE,2BAA2B;QAC/C,eAAe,EAAE;YACf,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACvB,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAA;YAC/D,CAAC;SACF;KACF,CAAC,CAAA;IAEF,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,oEAAoE;QACpE,WAAW,CAAC,2BAA2B,CAAC,CAAA;QACxC,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,CAAC,EAAC,OAAO,EAAE,2BAA2B,EAAC,CAAC;YACpD,SAAS;SACV,CAAA;IACH,CAAC;IAED,MAAM,EAAC,QAAQ,EAAE,UAAU,EAAC,GAAG,cAAc,CAAA;IAE7C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,UAAU;YACV,SAAS;SACV,CAAA;IACH,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,mEAAmE;QACnE,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,CAAC,EAAC,OAAO,EAAE,2BAA2B,EAAC,CAAC;YACpD,SAAS;SACV,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC;QACvB,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE;KAClC,CAAC,CAAA;IAEF,OAAO;QACL,KAAK;QACL,UAAU,EAAE,EAAE;QACd,SAAS;KACV,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,IAAwB,EAAE,OAAqB;IACnG,WAAW,CAAC,uCAAuC,CAAC,CAAA;IACpD,MAAM,WAAW,GAA0E,EAAE,CAAA;IAC7F,IAAI,KAAK,GAAkB,IAAI,CAAA;IAC/B,OAAO,IAAI,EAAE,CAAC;QACZ,4CAA4C;QAC5C,MAAM,EAAC,oBAAoB,EAAC,GAAyC,MAAM,eAAe,CAAC;YACzF,KAAK,EAAE,+BAA+B;YACtC,OAAO;YACP,SAAS,EAAE,EAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAC;SACpC,CAAC,CAAA;QACF,WAAW,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;QAC/C,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,WAAW;YAAE,MAAK;QACrD,MAAM,SAAS,GAA8B,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAA;QACpF,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,KAAK;YAAE,sBAAsB,CAAC,0CAA0C,CAAC,CAAA;QACzG,KAAK,GAAG,SAAS,CAAA;IACnB,CAAC;IAED,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACtC,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,IAAI,EAAE;YACJ,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI;YAC1B,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ;SACnC;KACF,CAAC,CAAC,CAAA;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAqB;IAC3D,WAAW,CAAC,qCAAqC,CAAC,CAAA;IAClD,MAAM,EAAC,WAAW,EAAC,GAAG,MAAM,eAAe,CAAC;QAC1C,KAAK,EAAE,6BAA6B;QACpC,OAAO;KACR,CAAC,CAAA;IACF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,sBAAsB,CAAC,kEAAkE,CAAC,CAAA;IAC5F,CAAC;IAED,MAAM,EAAC,kBAAkB,EAAC,GAAG,WAAW,CAAA;IAExC,OAAO,kBAAkB,CAAC,OAAO,CAAA;AACnC,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe;IAC7C,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;AAC5C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,OAAO,KAAK,YAAY,mBAAmB,CAAA;AAC7C,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAAiD;IAEjD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAA;QAC9E,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8BAA8B,CAAC,KAAK,CAAC,CAAA;QACrC,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,8BAA8B,CAAC,KAAc;IACpD,MAAM,cAAc,GAAG,6CAA6C,CAAC,KAAK,CAAC,CAAA;IAC3E,IAAI,CAAC,cAAc;QAAE,OAAM;IAE3B,MAAM,SAAS,GAA6B;QAC1C;YACE,oMAAoM;SACrM;QACD;YACE,KAAK;YACL,EAAC,OAAO,EAAE,YAAY,EAAC;YACvB,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,EAAC,OAAO,EAAE,YAAY,EAAC;YACvB,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,KAAK;YACL,EAAC,OAAO,EAAE,YAAY,EAAC;YACvB,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,SAAS;YACT,EAAC,OAAO,EAAE,aAAa,EAAC;YACxB,OAAO;YACP,EAAC,IAAI,EAAE,GAAG,EAAC;SACZ;QACD;YACE,KAAK;YACL,EAAC,OAAO,EAAE,YAAY,EAAC;YACvB,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,EAAC,OAAO,EAAE,WAAW,EAAC;YACtB,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,EAAC,OAAO,EAAE,eAAe,EAAC;YAC1B,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,EAAC,OAAO,EAAE,cAAc,EAAC;YACzB,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,EAAC,OAAO,EAAE,cAAc,EAAC;YACzB,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,KAAK;YACL,EAAC,OAAO,EAAE,iBAAiB,EAAC;YAC5B,EAAC,IAAI,EAAE,GAAG,EAAC;YACX,cAAc;YACd,EAAC,OAAO,EAAE,aAAa,EAAC;YACxB,KAAK;YACL,EAAC,OAAO,EAAE,cAAc,EAAC;YACzB,QAAQ;YACR,EAAC,IAAI,EAAE,GAAG,EAAC;SACZ;QACD;YACE,uIAAuI;YACvI,EAAC,OAAO,EAAE,qBAAqB,EAAC;YAChC,eAAe;YACf,EAAC,IAAI,EAAE,GAAG,EAAC;SACZ;QACD,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,uBAAuB,EAAE,GAAG,EAAE,6CAA6C,EAAC,EAAC,EAAE,EAAC,IAAI,EAAE,GAAG,EAAC,CAAC;KACnH,CAAA;IAED,MAAM,WAAW,CACf,IAAI,UAAU,CAAC,wDAAwD,cAAc,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,CAChH,CAAA;AACH,CAAC;AAED,SAAS,6CAA6C,CAAC,KAAc;IACnE,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC,IAAI,CACxD,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,KAAK,eAAe,CACpE,CAAA;IACD,IAAI,CAAC,iBAAiB;QAAE,OAAO,SAAS,CAAA;IAExC,MAAM,cAAc,GAAG,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAA;IACnE,IAAI,OAAO,cAAc,KAAK,QAAQ;QAAE,OAAO,gCAAgC,CAAA;IAE/E,OAAO,4BAA4B,CAAC,cAAc,CAAC,CAAA;AACrD,CAAC;AAED,SAAS,4BAA4B,CAAC,cAAsB;IAC1D,MAAM,WAAW,GAAG,cAAc;SAC/B,IAAI,EAAE;SACN,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAA;IAErC,OAAO,WAAW,IAAI,gCAAgC,CAAA;AACxD,CAAC;AAED,SAAS,QAAQ,CAAC,EAAU;IAC1B,OAAO,kCAAkC,EAAE,EAAE,CAAA;AAC/C,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA8B;IAE9B,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;QACxB,KAAK,8BAA8B;YACjC,OAAO,EAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAC,CAAA;QAC9B,KAAK,gCAAgC;YACnC,OAAO,EAAC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAC,CAAA;QACzC,KAAK,6BAA6B;YAChC,IAAI,CAAC;gBACH,iDAAiD;gBACjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBAEtC,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;gBAChD,OAAO,EAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAC,CAAA;YAClE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,4CAA4C;gBAC5C,MAAM,WAAW,CAAC,IAAI,UAAU,CAAC,uCAAuC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YACtF,CAAC;IACL,CAAC;AACH,CAAC","sourcesContent":["import {Result, Checksum, Key, Theme, ThemeAsset, Operation} from './types.js'\nimport {buildTheme} from './factories.js'\nimport {composeThemeGid, parseGid, DEVELOPMENT_THEME_ROLE} from './utils.js'\nimport {ThemeUpdate} from '../../../cli/api/graphql/admin/generated/theme_update.js'\nimport {ThemeDelete} from '../../../cli/api/graphql/admin/generated/theme_delete.js'\nimport {ThemeDuplicate} from '../../../cli/api/graphql/admin/generated/theme_duplicate.js'\nimport {ThemePublish} from '../../../cli/api/graphql/admin/generated/theme_publish.js'\nimport {ThemeCreate} from '../../../cli/api/graphql/admin/generated/theme_create.js'\nimport {GetThemeFileBodies} from '../../../cli/api/graphql/admin/generated/get_theme_file_bodies.js'\nimport {GetThemeFileChecksums} from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js'\nimport {\n ThemeFilesUpsert,\n ThemeFilesUpsertMutation,\n} from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js'\nimport {ThemeFilesDelete} from '../../../cli/api/graphql/admin/generated/theme_files_delete.js'\nimport {\n OnlineStoreThemeFileBodyInputType,\n OnlineStoreThemeFilesUpsertFileInput,\n MetafieldOwnerType,\n ThemeRole,\n} from '../../../cli/api/graphql/admin/generated/types.js'\nimport {\n MetafieldDefinitionsByOwnerType,\n type MetafieldDefinitionsByOwnerTypeQuery,\n} from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js'\nimport {GetThemes} from '../../../cli/api/graphql/admin/generated/get_themes.js'\nimport {GetTheme} from '../../../cli/api/graphql/admin/generated/get_theme.js'\nimport {FindDevelopmentThemeByName} from '../../../cli/api/graphql/admin/generated/find_development_theme_by_name.js'\nimport {OnlineStorePasswordProtection} from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js'\nimport {extractGraphQLErrors} from '../../../private/node/api/graphql.js'\nimport {TrustChallengeError, withTrustChallengeRetry} from '../../../private/node/themes/trust-challenge.js'\nimport {RequestModeInput} from '../http.js'\nimport {adminRequestDoc, type AdminRequestOptions} from '../api/admin.js'\nimport {AdminSession} from '../session.js'\nimport {AbortError} from '../error.js'\nimport {outputDebug} from '../output.js'\nimport {recordTiming, recordEvent, recordError} from '../analytics.js'\nimport {type Variables} from 'graphql-request'\nimport type {InlineToken, TokenItem} from '../ui.js'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing' | 'src'>>\nexport type AssetParams = Pick<ThemeAsset, 'key'> & Partial<Pick<ThemeAsset, 'value' | 'attachment'>>\nconst SkeletonThemeCdn = 'https://cdn.shopify.com/static/online-store/theme-skeleton.zip'\nconst THEME_API_NETWORK_BEHAVIOUR: RequestModeInput = {\n useNetworkLevelRetry: true,\n useAbortSignal: false,\n maxRetryTimeMs: 90 * 1000,\n recordCommandRetries: true,\n}\nconst DEFAULT_THEME_ACCESS_REQUIREMENT = 'the required theme access scope'\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const gid = composeThemeGid(id)\n recordEvent('theme-api:fetch-theme')\n\n try {\n const {theme} = await adminRequestDoc({\n query: GetTheme,\n session,\n variables: {id: gid},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (theme) {\n return buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n }\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n /**\n * Consumers of this and other theme APIs in this file expect either a theme\n * or `undefined`.\n *\n * Error handlers should not inspect GraphQL error messages directly, as\n * they are internationalized.\n */\n recordError(error)\n outputDebug(`Error fetching theme with ID: ${id}`)\n }\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const themes: Theme[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-themes')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemes,\n session,\n variables: {after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n const {nodes, pageInfo} = response.themes\n nodes.forEach((theme) => {\n const t = buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n if (t) {\n themes.push(t)\n }\n })\n if (!pageInfo.hasNextPage) {\n return themes\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function findDevelopmentThemeByName(name: string, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:find-development-theme-by-name')\n\n const {themes} = await requestThemeAdminDoc({\n query: FindDevelopmentThemeByName,\n session,\n variables: {name},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n\n if (themes.nodes.length > 1) {\n throw recordError(new AbortError(`More than one development theme is named \"${name}\"`))\n }\n\n if (themes.nodes.length === 1) {\n const {id, processing, role, name} = themes.nodes[0]!\n\n return buildTheme({\n id: parseGid(id),\n processing,\n role: role.toLowerCase(),\n name,\n })\n }\n}\n\nexport async function themeCreate(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const themeSource = params.src ?? SkeletonThemeCdn\n recordEvent('theme-api:create-theme')\n const {themeCreate} = await requestThemeAdminDoc({\n query: ThemeCreate,\n session,\n variables: {\n name: params.name ?? '',\n source: themeSource,\n role: (params.role ?? DEVELOPMENT_THEME_ROLE).toUpperCase() as ThemeRole,\n },\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeCreate) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n const {theme, userErrors} = themeCreate\n if (userErrors.length) {\n const userErrors = themeCreate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]> {\n const assets: ThemeAsset[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-assets')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileBodies,\n session,\n variables: {id: themeGid(id), filenames, after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.theme?.files?.nodes || !response.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n unexpectedGraphQLError(`Error fetching assets: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n assets.push(\n // eslint-disable-next-line no-await-in-loop\n ...(await Promise.all(\n nodes.map(async (file) => {\n const {attachment, value} = await parseThemeFileContent(file.body)\n return {\n attachment,\n key: file.filename,\n checksum: file.checksumMd5 as string,\n value,\n }\n }),\n )),\n )\n\n if (!pageInfo.hasNextPage) {\n return assets\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function deleteThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<Result[]> {\n const batchSize = 50\n const results: Result[] = []\n recordEvent('theme-api:delete-assets')\n\n for (let i = 0; i < filenames.length; i += batchSize) {\n const batch = filenames.slice(i, i + batchSize)\n // eslint-disable-next-line no-await-in-loop\n const {themeFilesDelete} = await requestThemeAdminDoc({\n query: ThemeFilesDelete,\n session,\n variables: {\n themeId: composeThemeGid(id),\n files: batch,\n },\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeFilesDelete) {\n unexpectedGraphQLError('Failed to delete theme assets')\n }\n\n const {deletedThemeFiles, userErrors} = themeFilesDelete\n\n if (deletedThemeFiles) {\n deletedThemeFiles.forEach((file) => {\n results.push({key: file.filename, success: true, operation: Operation.Delete})\n })\n }\n\n if (userErrors.length > 0) {\n userErrors.forEach((error) => {\n if (error.filename) {\n recordError(`Asset deletion failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Delete,\n errors: {asset: [error.message]},\n })\n } else {\n unexpectedGraphQLError(`Failed to delete theme assets: ${error.message}`)\n }\n })\n }\n }\n\n return results\n}\n\nexport async function bulkUploadThemeAssets(\n id: number,\n assets: AssetParams[],\n session: AdminSession,\n): Promise<Result[]> {\n const results: Result[] = []\n recordEvent('theme-api:bulk-upload-assets')\n for (let i = 0; i < assets.length; i += 50) {\n const chunk = assets.slice(i, i + 50)\n const files = prepareFilesForUpload(chunk)\n\n recordTiming('theme-api:upload-files')\n // eslint-disable-next-line no-await-in-loop\n const uploadResults = await uploadFiles(id, files, session)\n recordTiming('theme-api:upload-files')\n\n results.push(...processUploadResults(uploadResults))\n }\n return results\n}\n\nfunction prepareFilesForUpload(assets: AssetParams[]): OnlineStoreThemeFilesUpsertFileInput[] {\n return assets.map((asset) => {\n if (asset.attachment) {\n return {\n filename: asset.key,\n body: {\n type: 'BASE64' as const,\n value: asset.attachment,\n },\n }\n } else {\n return {\n filename: asset.key,\n body: {\n type: 'TEXT' as const,\n value: asset.value ?? '',\n },\n }\n }\n })\n}\n\nasync function uploadFiles(\n themeId: number,\n files: {filename: string; body: {type: OnlineStoreThemeFileBodyInputType; value: string}}[],\n session: AdminSession,\n): Promise<ThemeFilesUpsertMutation> {\n return requestThemeAdminDoc({\n query: ThemeFilesUpsert,\n session,\n variables: {themeId: themeGid(themeId), files},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n}\n\nfunction processUploadResults(uploadResults: ThemeFilesUpsertMutation): Result[] {\n const {themeFilesUpsert} = uploadResults\n\n if (!themeFilesUpsert) {\n unexpectedGraphQLError('Failed to upload theme files')\n }\n\n const {upsertedThemeFiles, userErrors} = themeFilesUpsert\n\n const results: Result[] = []\n\n upsertedThemeFiles?.forEach((file) => {\n results.push({\n key: file.filename,\n success: true,\n operation: Operation.Upload,\n })\n })\n\n userErrors.forEach((error) => {\n if (!error.filename) {\n unexpectedGraphQLError(`Error uploading theme files: ${error.message}`)\n }\n recordError(`Asset upload failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Upload,\n errors: {asset: [error.message]},\n })\n })\n\n return results\n}\n\nexport async function fetchChecksums(id: number, session: AdminSession): Promise<Checksum[]> {\n const checksums: Checksum[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-checksums')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileChecksums,\n session,\n variables: {id: themeGid(id), after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response?.theme?.files?.nodes || !response?.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n throw recordError(new AbortError(`Failed to fetch checksums for: ${userErrors}`))\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n checksums.push(\n ...nodes.map((file) => ({\n key: file.filename,\n checksum: file.checksumMd5 as string,\n })),\n )\n\n if (!pageInfo.hasNextPage) {\n return checksums\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const name = params.name\n const input: Record<string, string> = {}\n if (name) {\n input.name = name\n }\n recordEvent('theme-api:update-theme')\n\n const {themeUpdate} = await requestThemeAdminDoc({\n query: ThemeUpdate,\n session,\n variables: {id: composeThemeGid(id), input},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeUpdate) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themeUpdate\n if (userErrors.length) {\n const userErrors = themeUpdate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themePublish(id: number, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:publish-theme')\n const {themePublish} = await requestThemeAdminDoc({\n query: ThemePublish,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themePublish) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themePublish\n if (userErrors.length) {\n const userErrors = themePublish.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themeDelete(id: number, session: AdminSession): Promise<boolean | undefined> {\n recordEvent('theme-api:delete-theme')\n const {themeDelete} = await requestThemeAdminDoc({\n query: ThemeDelete,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeDelete) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {deletedThemeId, userErrors} = themeDelete\n if (userErrors.length) {\n const userErrors = themeDelete.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!deletedThemeId) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return true\n}\n\nexport interface ThemeDuplicateResult {\n theme?: Theme\n userErrors: {field?: string[] | null; message: string}[]\n requestId?: string\n}\n\nexport async function themeDuplicate(\n id: number,\n name: string | undefined,\n session: AdminSession,\n): Promise<ThemeDuplicateResult> {\n let requestId: string | undefined\n recordEvent('theme-api:duplicate-theme')\n\n const {themeDuplicate} = await requestThemeAdminDoc({\n query: ThemeDuplicate,\n session,\n variables: {id: composeThemeGid(id), name},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n responseOptions: {\n onResponse: (response) => {\n requestId = response.headers.get('x-request-id') ?? undefined\n },\n },\n })\n\n if (!themeDuplicate) {\n // An unexpected error occurred during the GraphQL request execution\n recordError('Failed to duplicate theme')\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const {newTheme, userErrors} = themeDuplicate\n\n if (userErrors.length > 0) {\n return {\n theme: undefined,\n userErrors,\n requestId,\n }\n }\n\n if (!newTheme) {\n // An unexpected error if neither theme nor userErrors are returned\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const theme = buildTheme({\n id: parseGid(newTheme.id),\n name: newTheme.name,\n role: newTheme.role.toLowerCase(),\n })\n\n return {\n theme,\n userErrors: [],\n requestId,\n }\n}\n\nexport async function metafieldDefinitionsByOwnerType(type: MetafieldOwnerType, session: AdminSession) {\n recordEvent('theme-api:fetch-metafield-definitions')\n const definitions: MetafieldDefinitionsByOwnerTypeQuery['metafieldDefinitions']['nodes'] = []\n let after: string | null = null\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const {metafieldDefinitions}: MetafieldDefinitionsByOwnerTypeQuery = await adminRequestDoc({\n query: MetafieldDefinitionsByOwnerType,\n session,\n variables: {ownerType: type, after},\n })\n definitions.push(...metafieldDefinitions.nodes)\n if (!metafieldDefinitions.pageInfo.hasNextPage) break\n const endCursor: string | null | undefined = metafieldDefinitions.pageInfo.endCursor\n if (!endCursor || endCursor === after) unexpectedGraphQLError('Failed to paginate metafield definitions')\n after = endCursor\n }\n\n return definitions.map((definition) => ({\n key: definition.key,\n namespace: definition.namespace,\n name: definition.name,\n description: definition.description,\n type: {\n name: definition.type.name,\n category: definition.type.category,\n },\n }))\n}\n\nexport async function passwordProtected(session: AdminSession): Promise<boolean> {\n recordEvent('theme-api:check-password-protection')\n const {onlineStore} = await adminRequestDoc({\n query: OnlineStorePasswordProtection,\n session,\n })\n if (!onlineStore) {\n unexpectedGraphQLError(\"Unable to get details about the storefront's password protection\")\n }\n\n const {passwordProtection} = onlineStore\n\n return passwordProtection.enabled\n}\n\nfunction unexpectedGraphQLError(message: string): never {\n throw recordError(new AbortError(message))\n}\n\n/**\n * Whether the error ends a Trust Battery challenge on a theme request. A caller that\n * retries theme requests must rethrow it, or the user is asked to verify again for\n * each attempt.\n *\n * @param error - The error to check.\n * @returns True when the error ends a Trust Battery challenge.\n */\nexport function isTrustChallengeError(error: unknown): boolean {\n return error instanceof TrustChallengeError\n}\n\nasync function requestThemeAdminDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n try {\n const response = await withTrustChallengeRetry(() => adminRequestDoc(options))\n return response\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n throw error\n }\n}\n\nfunction abortIfMissingThemeAccessScope(error: unknown): void {\n const requiredAccess = getThemeAccessRequirementForAccessDeniedError(error)\n if (!requiredAccess) return\n\n const nextSteps: TokenItem<InlineToken>[] = [\n [\n 'If you authenticated with an Admin API access token, update the app or integration that issued the token to include the required theme access scopes, then reauthorize it or generate a new token.',\n ],\n [\n 'For',\n {command: 'theme pull'},\n {char: ','},\n {command: 'theme list'},\n {char: ','},\n 'and',\n {command: 'theme info'},\n {char: ','},\n 'add the',\n {command: 'read_themes'},\n 'scope',\n {char: '.'},\n ],\n [\n 'For',\n {command: 'theme push'},\n {char: ','},\n {command: 'theme dev'},\n {char: ','},\n {command: 'theme publish'},\n {char: ','},\n {command: 'theme delete'},\n {char: ','},\n {command: 'theme rename'},\n {char: ','},\n 'and',\n {command: 'theme duplicate'},\n {char: ','},\n 'add both the',\n {command: 'read_themes'},\n 'and',\n {command: 'write_themes'},\n 'scopes',\n {char: '.'},\n ],\n [\n 'If you authenticated with your Shopify account, make sure your staff or collaborator account can access Online Store themes, then run',\n {command: 'shopify auth logout'},\n 'and try again',\n {char: '.'},\n ],\n ['See', {link: {label: 'Shopify access scopes', url: 'https://shopify.dev/api/usage/access-scopes'}}, {char: '.'}],\n ]\n\n throw recordError(\n new AbortError(`The authenticated account or access token is missing ${requiredAccess}.`, undefined, nextSteps),\n )\n}\n\nfunction getThemeAccessRequirementForAccessDeniedError(error: unknown): string | undefined {\n const accessDeniedError = extractGraphQLErrors(error).find(\n (graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED',\n )\n if (!accessDeniedError) return undefined\n\n const requiredAccess = accessDeniedError.extensions?.requiredAccess\n if (typeof requiredAccess !== 'string') return DEFAULT_THEME_ACCESS_REQUIREMENT\n\n return formatThemeAccessRequirement(requiredAccess)\n}\n\nfunction formatThemeAccessRequirement(requiredAccess: string): string {\n const requirement = requiredAccess\n .trim()\n .replace(/\\.$/, '')\n .replace(/^The user needs\\s+/i, '')\n\n return requirement || DEFAULT_THEME_ACCESS_REQUIREMENT\n}\n\nfunction themeGid(id: number): string {\n return `gid://shopify/OnlineStoreTheme/${id}`\n}\n\ntype OnlineStoreThemeFileBody =\n | {__typename: 'OnlineStoreThemeFileBodyBase64'; contentBase64: string}\n | {__typename: 'OnlineStoreThemeFileBodyText'; content: string}\n | {__typename: 'OnlineStoreThemeFileBodyUrl'; url: string}\n\nexport async function parseThemeFileContent(\n body: OnlineStoreThemeFileBody,\n): Promise<{value?: string; attachment?: string}> {\n switch (body.__typename) {\n case 'OnlineStoreThemeFileBodyText':\n return {value: body.content}\n case 'OnlineStoreThemeFileBodyBase64':\n return {attachment: body.contentBase64}\n case 'OnlineStoreThemeFileBodyUrl':\n try {\n // eslint-disable-next-line no-restricted-globals\n const response = await fetch(body.url)\n\n const arrayBuffer = await response.arrayBuffer()\n return {attachment: Buffer.from(arrayBuffer).toString('base64')}\n } catch (error) {\n // Raise error if we can't download the file\n throw recordError(new AbortError(`Error downloading content from URL: ${body.url}`))\n }\n }\n}\n"]}
|
|
@@ -11,5 +11,12 @@ export declare abstract class ThemeManager {
|
|
|
11
11
|
findOrCreate(name?: string, role?: Role): Promise<Theme>;
|
|
12
12
|
fetch(name?: string, role?: Role): Promise<Theme | undefined>;
|
|
13
13
|
generateThemeName(context: string): string;
|
|
14
|
-
create(themeRole?: Role, themeName?: string): Promise<
|
|
14
|
+
create(themeRole?: Role, themeName?: string): Promise<{
|
|
15
|
+
createdAtRuntime: boolean;
|
|
16
|
+
id: number;
|
|
17
|
+
name: string;
|
|
18
|
+
processing: boolean;
|
|
19
|
+
role: string;
|
|
20
|
+
src?: string;
|
|
21
|
+
}>;
|
|
15
22
|
}
|
|
@@ -44,7 +44,7 @@ export class ThemeManager {
|
|
|
44
44
|
throw new BugError(`Could not create theme with name "${name}" and role "${role}"`);
|
|
45
45
|
}
|
|
46
46
|
this.setTheme(theme.id.toString());
|
|
47
|
-
return theme;
|
|
47
|
+
return { ...theme, createdAtRuntime: true };
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
//# sourceMappingURL=theme-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-manager.js","sourceRoot":"","sources":["../../../../src/public/node/themes/theme-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,0BAA0B,EAAE,WAAW,EAAC,MAAM,UAAU,CAAA;AAE5E,OAAO,EAAC,sBAAsB,EAAO,MAAM,YAAY,CAAA;AACvD,OAAO,EAAC,iBAAiB,EAAC,MAAM,qDAAqD,CAAA;AAErF,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AAEpC,MAAM,OAAgB,YAAY;IAMV;IALZ,OAAO,CAAoB;IAKrC,YAAsB,YAA0B;QAA1B,iBAAY,GAAZ,YAAY,CAAc;IAAG,CAAC;IAEpD,KAAK,CAAC,YAAY,CAAC,IAAa,EAAE,IAAW;QAC3C,IAAI,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACxC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;QACpC,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACvC,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAa,EAAE,IAAW;QACpC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GACT,IAAI,IAAI,IAAI,KAAK,sBAAsB;YACrC,CAAC,CAAC,MAAM,0BAA0B,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC;YAC3D,CAAC,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAQ,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;QAEtE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,WAAW,EAAE,CAAA;QACpB,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,iBAAiB,CAAC,OAAe;QAC/B,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAgB,EAAE,SAAkB;QAC/C,MAAM,IAAI,GAAG,SAAS,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACzD,MAAM,IAAI,GAAG,SAAS,IAAI,sBAAsB,CAAA;QAChD,MAAM,KAAK,GAAG,MAAM,WAAW,CAC7B;YACE,IAAI;YACJ,IAAI;SACL,EACD,IAAI,CAAC,YAAY,CAClB,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,QAAQ,CAAC,qCAAqC,IAAI,eAAe,IAAI,GAAG,CAAC,CAAA;QACrF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;QAClC,OAAO,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"theme-manager.js","sourceRoot":"","sources":["../../../../src/public/node/themes/theme-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,0BAA0B,EAAE,WAAW,EAAC,MAAM,UAAU,CAAA;AAE5E,OAAO,EAAC,sBAAsB,EAAO,MAAM,YAAY,CAAA;AACvD,OAAO,EAAC,iBAAiB,EAAC,MAAM,qDAAqD,CAAA;AAErF,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AAEpC,MAAM,OAAgB,YAAY;IAMV;IALZ,OAAO,CAAoB;IAKrC,YAAsB,YAA0B;QAA1B,iBAAY,GAAZ,YAAY,CAAc;IAAG,CAAC;IAEpD,KAAK,CAAC,YAAY,CAAC,IAAa,EAAE,IAAW;QAC3C,IAAI,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACxC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;QACpC,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACvC,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAa,EAAE,IAAW;QACpC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GACT,IAAI,IAAI,IAAI,KAAK,sBAAsB;YACrC,CAAC,CAAC,MAAM,0BAA0B,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC;YAC3D,CAAC,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAQ,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;QAEtE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,WAAW,EAAE,CAAA;QACpB,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,iBAAiB,CAAC,OAAe;QAC/B,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAgB,EAAE,SAAkB;QAC/C,MAAM,IAAI,GAAG,SAAS,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACzD,MAAM,IAAI,GAAG,SAAS,IAAI,sBAAsB,CAAA;QAChD,MAAM,KAAK,GAAG,MAAM,WAAW,CAC7B;YACE,IAAI;YACJ,IAAI;SACL,EACD,IAAI,CAAC,YAAY,CAClB,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,QAAQ,CAAC,qCAAqC,IAAI,eAAe,IAAI,GAAG,CAAC,CAAA;QACrF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;QAClC,OAAO,EAAC,GAAG,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAC,CAAA;IAC3C,CAAC;CACF","sourcesContent":["import {fetchTheme, findDevelopmentThemeByName, themeCreate} from './api.js'\nimport {Theme} from './types.js'\nimport {DEVELOPMENT_THEME_ROLE, Role} from './utils.js'\nimport {generateThemeName} from '../../../private/node/themes/generate-theme-name.js'\nimport {AdminSession} from '../session.js'\nimport {BugError} from '../error.js'\n\nexport abstract class ThemeManager {\n protected themeId: string | undefined\n protected abstract setTheme(themeId: string): void\n protected abstract removeTheme(): void\n protected abstract context: string\n\n constructor(protected adminSession: AdminSession) {}\n\n async findOrCreate(name?: string, role?: Role): Promise<Theme> {\n let theme = await this.fetch(name, role)\n if (theme) {\n this.setTheme(theme.id.toString())\n } else {\n theme = await this.create(role, name)\n }\n return theme\n }\n\n async fetch(name?: string, role?: Role) {\n if (!this.themeId && !name) {\n return\n }\n\n const theme =\n name && role === DEVELOPMENT_THEME_ROLE\n ? await findDevelopmentThemeByName(name, this.adminSession)\n : await fetchTheme(parseInt(this.themeId!, 10), this.adminSession)\n\n if (!theme) {\n this.removeTheme()\n }\n return theme\n }\n\n generateThemeName(context: string) {\n return generateThemeName(context)\n }\n\n async create(themeRole?: Role, themeName?: string) {\n const name = themeName ?? generateThemeName(this.context)\n const role = themeRole ?? DEVELOPMENT_THEME_ROLE\n const theme = await themeCreate(\n {\n name,\n role,\n },\n this.adminSession,\n )\n if (!theme) {\n throw new BugError(`Could not create theme with name \"${name}\" and role \"${role}\"`)\n }\n this.setTheme(theme.id.toString())\n return {...theme, createdAtRuntime: true}\n }\n}\n"]}
|
|
@@ -49,13 +49,23 @@ function adaptedTreeKill(pid, killSignal, killRoot, callback) {
|
|
|
49
49
|
switch (process.platform) {
|
|
50
50
|
case 'win32': {
|
|
51
51
|
// Security: Use spawn instead of exec to avoid shell injection when killing processes on Windows
|
|
52
|
-
|
|
52
|
+
// Exclude the querying PowerShell process as well as the root when only children should stop.
|
|
53
|
+
const command = killRoot ? 'taskkill' : 'powershell.exe';
|
|
54
|
+
const args = killRoot
|
|
55
|
+
? ['/pid', rootPid, '/T', '/F']
|
|
56
|
+
: [
|
|
57
|
+
'-NoProfile',
|
|
58
|
+
'-NonInteractive',
|
|
59
|
+
'-Command',
|
|
60
|
+
`Get-CimInstance Win32_Process -Filter "ParentProcessId = ${rootPid} AND ProcessId <> $PID" -ErrorAction Stop | ForEach-Object { taskkill /pid $_.ProcessId /T /F | Out-Null }`,
|
|
61
|
+
];
|
|
62
|
+
const taskkill = spawn(command, args);
|
|
53
63
|
taskkill.on('close', (code) => {
|
|
54
64
|
if (code === 0) {
|
|
55
65
|
callback();
|
|
56
66
|
}
|
|
57
67
|
else {
|
|
58
|
-
callback(new Error(
|
|
68
|
+
callback(new Error(`${command} exited with code ${code}`));
|
|
59
69
|
}
|
|
60
70
|
});
|
|
61
71
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-kill.js","sourceRoot":"","sources":["../../../src/public/node/tree-kill.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable jsdoc/require-throws */\n/* eslint-disable no-restricted-imports */\n\nimport {outputDebug} from './output.js'\nimport {spawn} from 'child_process'\n\ntype ProcessTree = Record<string, string[]>\n\ntype AfterKillCallback = (error?: Error) => void\n\n/**\n * Kills the process that calls the method and all its children.\n *\n * @param pid - Pid of the process to kill.\n * @param killSignal - Type of kill signal to be used.\n * @param killRoot - Whether to kill the root process.\n * @param callback - Optional callback to run after killing the processes.\n */\nexport function treeKill(\n pid: number | string = process.pid,\n killSignal = 'SIGTERM',\n killRoot = true,\n callback?: AfterKillCallback,\n): void {\n const after =\n callback ??\n ((error?: Error) => {\n if (error) outputDebug(`Failed to kill process ${pid}: ${error}`)\n })\n adaptedTreeKill(pid, killSignal, killRoot, after)\n}\n\n/**\n * Adapted from https://github.com/pkrumins/node-tree-kill.\n *\n * Our implementation allows to skip killing the root process. This is useful for example when\n * gracefully exiting the 'dev' process, as the default tree-kill implementation will cause it\n * to exit with a non-zero code. Instead, we want to treat it as a graceful termination.\n * In addition, we also add debug logging for better visibility in what tree-kill is doing.\n *\n * @param pid - Pid of the process to kill.\n * @param killSignal - Type of kill signal to be used.\n * @param killRoot - Whether to kill the root process.\n * @param callback - Optional callback to run after killing the processes.\n */\nfunction adaptedTreeKill(\n pid: number | string,\n killSignal: string,\n killRoot: boolean,\n callback: (error?: Error) => void,\n): void {\n const rootPid = typeof pid === 'number' ? pid.toString() : pid\n\n // Security: Validate that the PID is a number to prevent command injection\n if (!/^\\d+$/.test(rootPid)) {\n callback(new Error('pid must be a number'))\n return\n }\n\n // A map from parent pid to an array of children pids\n const tree: ProcessTree = {}\n tree[rootPid] = []\n\n // A set of pids to visit. We use it to recursively find all the children pids\n const pidsToProcess = new Set<string>()\n pidsToProcess.add(rootPid)\n\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- default handles all Unix-like platforms\n switch (process.platform) {\n case 'win32': {\n // Security: Use spawn instead of exec to avoid shell injection when killing processes on Windows\n const taskkill = spawn('taskkill', ['/pid', rootPid, '/T', '/F'])\n taskkill.on('close', (code: number) => {\n if (code === 0) {\n callback()\n } else {\n callback(new Error(`taskkill exited with code ${code}`))\n }\n })\n break\n }\n case 'darwin':\n buildProcessTree(\n rootPid,\n tree,\n pidsToProcess,\n function (parentPid: string) {\n return spawn('pgrep', ['-lfP', parentPid])\n },\n function () {\n killAll(tree, killSignal, rootPid, killRoot, callback)\n },\n )\n break\n default:\n buildProcessTree(\n rootPid,\n tree,\n pidsToProcess,\n function (parentPid: string) {\n return spawn('ps', ['-o', 'pid command', '--no-headers', '--ppid', parentPid])\n },\n function () {\n killAll(tree, killSignal, rootPid, killRoot, callback)\n },\n )\n break\n }\n}\n\n/**\n * Kills all processes in the process tree.\n *\n * @param tree - Process tree.\n * @param killSignal - Type of kill signal to be used.\n * @param rootPid - Pid of the root process.\n * @param killRoot - Whether to kill the root process.\n * @param callback - Optional callback to run after killing the processes.\n */\nfunction killAll(\n tree: ProcessTree,\n killSignal: string,\n rootPid: string,\n killRoot: boolean,\n callback: AfterKillCallback,\n): void {\n const killed = new Set<string>()\n try {\n Object.keys(tree).forEach(function (pid) {\n tree[pid]!.forEach(function (pidpid) {\n if (!killed.has(pidpid)) {\n killPid(pidpid, killSignal)\n killed.add(pidpid)\n }\n })\n if (pid === rootPid && killRoot && !killed.has(pid)) {\n killPid(pid, killSignal)\n killed.add(pid)\n }\n })\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err: unknown) {\n // @ts-ignore\n callback(err)\n return\n }\n callback()\n}\n\n/**\n * Kills a process.\n *\n * @param pid - Pid of the process to kill.\n * @param killSignal - Type of kill signal to be used.\n */\nfunction killPid(pid: string, killSignal: string) {\n try {\n process.kill(parseInt(pid, 10), killSignal)\n } catch (err) {\n // @ts-ignore\n if (err.code !== 'ESRCH') throw err\n }\n}\n\n/**\n * Builds a process tree.\n *\n * @param parentPid - Pid of the parent process.\n * @param tree - Process tree.\n * @param pidsToProcess - Pids to process.\n * @param spawnChildProcessesList - Function to spawn child processes.\n * @param cb - Callback to run after building the process tree.\n */\nfunction buildProcessTree(\n parentPid: string,\n tree: ProcessTree,\n pidsToProcess: Set<string>,\n spawnChildProcessesList: (parentPid: string) => ReturnType<typeof spawn>,\n cb: () => void,\n) {\n const ps = spawnChildProcessesList(parentPid)\n let allData = ''\n ps.stdout?.on('data', function (data: Buffer) {\n const dataStr = data.toString('ascii')\n allData += dataStr\n })\n\n const onClose = (code: number) => {\n pidsToProcess.delete(parentPid)\n\n if (code !== 0) {\n // no more parent processes\n if (pidsToProcess.size === 0) {\n cb()\n return\n }\n return\n }\n\n allData\n .trim()\n .split('\\n')\n .forEach(function (line) {\n const match = line.match(/^(\\d+)\\s(.*)$/)\n if (match) {\n const pid = match[1]!\n const cmd = match[2]!\n tree[parentPid]!.push(pid)\n tree[pid] = []\n outputDebug(`Killing process ${pid}: ${cmd}`)\n pidsToProcess.add(pid)\n buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb)\n }\n })\n }\n\n ps.on('close', onClose)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tree-kill.js","sourceRoot":"","sources":["../../../src/public/node/tree-kill.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable jsdoc/require-throws */\n/* eslint-disable no-restricted-imports */\n\nimport {outputDebug} from './output.js'\nimport {spawn} from 'child_process'\n\ntype ProcessTree = Record<string, string[]>\n\ntype AfterKillCallback = (error?: Error) => void\n\n/**\n * Kills the process that calls the method and all its children.\n *\n * @param pid - Pid of the process to kill.\n * @param killSignal - Type of kill signal to be used.\n * @param killRoot - Whether to kill the root process.\n * @param callback - Optional callback to run after killing the processes.\n */\nexport function treeKill(\n pid: number | string = process.pid,\n killSignal = 'SIGTERM',\n killRoot = true,\n callback?: AfterKillCallback,\n): void {\n const after =\n callback ??\n ((error?: Error) => {\n if (error) outputDebug(`Failed to kill process ${pid}: ${error}`)\n })\n adaptedTreeKill(pid, killSignal, killRoot, after)\n}\n\n/**\n * Adapted from https://github.com/pkrumins/node-tree-kill.\n *\n * Our implementation allows to skip killing the root process. This is useful for example when\n * gracefully exiting the 'dev' process, as the default tree-kill implementation will cause it\n * to exit with a non-zero code. Instead, we want to treat it as a graceful termination.\n * In addition, we also add debug logging for better visibility in what tree-kill is doing.\n *\n * @param pid - Pid of the process to kill.\n * @param killSignal - Type of kill signal to be used.\n * @param killRoot - Whether to kill the root process.\n * @param callback - Optional callback to run after killing the processes.\n */\nfunction adaptedTreeKill(\n pid: number | string,\n killSignal: string,\n killRoot: boolean,\n callback: (error?: Error) => void,\n): void {\n const rootPid = typeof pid === 'number' ? pid.toString() : pid\n\n // Security: Validate that the PID is a number to prevent command injection\n if (!/^\\d+$/.test(rootPid)) {\n callback(new Error('pid must be a number'))\n return\n }\n\n // A map from parent pid to an array of children pids\n const tree: ProcessTree = {}\n tree[rootPid] = []\n\n // A set of pids to visit. We use it to recursively find all the children pids\n const pidsToProcess = new Set<string>()\n pidsToProcess.add(rootPid)\n\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- default handles all Unix-like platforms\n switch (process.platform) {\n case 'win32': {\n // Security: Use spawn instead of exec to avoid shell injection when killing processes on Windows\n // Exclude the querying PowerShell process as well as the root when only children should stop.\n const command = killRoot ? 'taskkill' : 'powershell.exe'\n const args = killRoot\n ? ['/pid', rootPid, '/T', '/F']\n : [\n '-NoProfile',\n '-NonInteractive',\n '-Command',\n `Get-CimInstance Win32_Process -Filter \"ParentProcessId = ${rootPid} AND ProcessId <> $PID\" -ErrorAction Stop | ForEach-Object { taskkill /pid $_.ProcessId /T /F | Out-Null }`,\n ]\n const taskkill = spawn(command, args)\n taskkill.on('close', (code: number) => {\n if (code === 0) {\n callback()\n } else {\n callback(new Error(`${command} exited with code ${code}`))\n }\n })\n break\n }\n case 'darwin':\n buildProcessTree(\n rootPid,\n tree,\n pidsToProcess,\n function (parentPid: string) {\n return spawn('pgrep', ['-lfP', parentPid])\n },\n function () {\n killAll(tree, killSignal, rootPid, killRoot, callback)\n },\n )\n break\n default:\n buildProcessTree(\n rootPid,\n tree,\n pidsToProcess,\n function (parentPid: string) {\n return spawn('ps', ['-o', 'pid command', '--no-headers', '--ppid', parentPid])\n },\n function () {\n killAll(tree, killSignal, rootPid, killRoot, callback)\n },\n )\n break\n }\n}\n\n/**\n * Kills all processes in the process tree.\n *\n * @param tree - Process tree.\n * @param killSignal - Type of kill signal to be used.\n * @param rootPid - Pid of the root process.\n * @param killRoot - Whether to kill the root process.\n * @param callback - Optional callback to run after killing the processes.\n */\nfunction killAll(\n tree: ProcessTree,\n killSignal: string,\n rootPid: string,\n killRoot: boolean,\n callback: AfterKillCallback,\n): void {\n const killed = new Set<string>()\n try {\n Object.keys(tree).forEach(function (pid) {\n tree[pid]!.forEach(function (pidpid) {\n if (!killed.has(pidpid)) {\n killPid(pidpid, killSignal)\n killed.add(pidpid)\n }\n })\n if (pid === rootPid && killRoot && !killed.has(pid)) {\n killPid(pid, killSignal)\n killed.add(pid)\n }\n })\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err: unknown) {\n // @ts-ignore\n callback(err)\n return\n }\n callback()\n}\n\n/**\n * Kills a process.\n *\n * @param pid - Pid of the process to kill.\n * @param killSignal - Type of kill signal to be used.\n */\nfunction killPid(pid: string, killSignal: string) {\n try {\n process.kill(parseInt(pid, 10), killSignal)\n } catch (err) {\n // @ts-ignore\n if (err.code !== 'ESRCH') throw err\n }\n}\n\n/**\n * Builds a process tree.\n *\n * @param parentPid - Pid of the parent process.\n * @param tree - Process tree.\n * @param pidsToProcess - Pids to process.\n * @param spawnChildProcessesList - Function to spawn child processes.\n * @param cb - Callback to run after building the process tree.\n */\nfunction buildProcessTree(\n parentPid: string,\n tree: ProcessTree,\n pidsToProcess: Set<string>,\n spawnChildProcessesList: (parentPid: string) => ReturnType<typeof spawn>,\n cb: () => void,\n) {\n const ps = spawnChildProcessesList(parentPid)\n let allData = ''\n ps.stdout?.on('data', function (data: Buffer) {\n const dataStr = data.toString('ascii')\n allData += dataStr\n })\n\n const onClose = (code: number) => {\n pidsToProcess.delete(parentPid)\n\n if (code !== 0) {\n // no more parent processes\n if (pidsToProcess.size === 0) {\n cb()\n return\n }\n return\n }\n\n allData\n .trim()\n .split('\\n')\n .forEach(function (line) {\n const match = line.match(/^(\\d+)\\s(.*)$/)\n if (match) {\n const pid = match[1]!\n const cmd = match[2]!\n tree[parentPid]!.push(pid)\n tree[pid] = []\n outputDebug(`Killing process ${pid}: ${cmd}`)\n pidsToProcess.add(pid)\n buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb)\n }\n })\n }\n\n ps.on('close', onClose)\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ConcurrentOutput, ConcurrentOutputContext, useConcurrentOutputContext, } from '../../../private/node/ui/components/ConcurrentOutput.js';
|
|
2
2
|
export { Alert } from '../../../private/node/ui/components/Alert.js';
|
|
3
3
|
export { Link } from '../../../private/node/ui/components/Link.js';
|
|
4
|
+
export { LoadingIndicator } from '../../../private/node/ui/components/LoadingIndicator.js';
|
|
4
5
|
export { TabularData } from '../../../private/node/ui/components/TabularData.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { ConcurrentOutput, useConcurrentOutputContext, } from '../../../private/node/ui/components/ConcurrentOutput.js';
|
|
2
2
|
export { Alert } from '../../../private/node/ui/components/Alert.js';
|
|
3
3
|
export { Link } from '../../../private/node/ui/components/Link.js';
|
|
4
|
+
export { LoadingIndicator } from '../../../private/node/ui/components/LoadingIndicator.js';
|
|
4
5
|
export { TabularData } from '../../../private/node/ui/components/TabularData.js';
|
|
5
6
|
//# sourceMappingURL=components.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","sourceRoot":"","sources":["../../../../src/public/node/ui/components.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,0BAA0B,GAC3B,MAAM,yDAAyD,CAAA;AAChE,OAAO,EAAC,KAAK,EAAC,MAAM,8CAA8C,CAAA;AAClE,OAAO,EAAC,IAAI,EAAC,MAAM,6CAA6C,CAAA;AAChE,OAAO,EAAC,WAAW,EAAC,MAAM,oDAAoD,CAAA","sourcesContent":["export {\n ConcurrentOutput,\n ConcurrentOutputContext,\n useConcurrentOutputContext,\n} from '../../../private/node/ui/components/ConcurrentOutput.js'\nexport {Alert} from '../../../private/node/ui/components/Alert.js'\nexport {Link} from '../../../private/node/ui/components/Link.js'\nexport {TabularData} from '../../../private/node/ui/components/TabularData.js'\n"]}
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../../../../src/public/node/ui/components.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,0BAA0B,GAC3B,MAAM,yDAAyD,CAAA;AAChE,OAAO,EAAC,KAAK,EAAC,MAAM,8CAA8C,CAAA;AAClE,OAAO,EAAC,IAAI,EAAC,MAAM,6CAA6C,CAAA;AAChE,OAAO,EAAC,gBAAgB,EAAC,MAAM,yDAAyD,CAAA;AACxF,OAAO,EAAC,WAAW,EAAC,MAAM,oDAAoD,CAAA","sourcesContent":["export {\n ConcurrentOutput,\n ConcurrentOutputContext,\n useConcurrentOutputContext,\n} from '../../../private/node/ui/components/ConcurrentOutput.js'\nexport {Alert} from '../../../private/node/ui/components/Alert.js'\nexport {Link} from '../../../private/node/ui/components/Link.js'\nexport {LoadingIndicator} from '../../../private/node/ui/components/LoadingIndicator.js'\nexport {TabularData} from '../../../private/node/ui/components/TabularData.js'\n"]}
|
package/dist/public/node/ui.d.ts
CHANGED
|
@@ -325,9 +325,9 @@ export interface RenderSingleTaskOptions<T> {
|
|
|
325
325
|
renderOptions?: RenderOptions;
|
|
326
326
|
}
|
|
327
327
|
/**
|
|
328
|
-
* Awaits a single task and displays a loading
|
|
328
|
+
* Awaits a single task and displays a loading indicator while it's in progress. The task's result is returned.
|
|
329
329
|
* @param options - Configuration object
|
|
330
|
-
* @param options.title - The initial title to display with the loading
|
|
330
|
+
* @param options.title - The initial title to display with the loading indicator
|
|
331
331
|
* @param options.task - The async task to execute. Receives an updateStatus callback to change the displayed title.
|
|
332
332
|
* @param options.retry - The number of additional attempts after a failure. Defaults to zero.
|
|
333
333
|
* @param options.renderOptions - Optional render configuration
|
|
@@ -375,10 +375,30 @@ export interface RenderDangerousConfirmationPromptOptions extends Omit<Dangerous
|
|
|
375
375
|
*
|
|
376
376
|
*/
|
|
377
377
|
export declare function renderDangerousConfirmationPrompt({ renderOptions, ...props }: RenderDangerousConfirmationPromptOptions, uiDebugOptions?: UIDebugOptions): Promise<boolean>;
|
|
378
|
-
|
|
378
|
+
interface KeypressOptions {
|
|
379
|
+
/**
|
|
380
|
+
* The keys that end the wait, for example `['\r']` for Enter. Other keys are ignored.
|
|
381
|
+
* Without this option, any key ends the wait.
|
|
382
|
+
*/
|
|
383
|
+
keys?: string[];
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Waits for a key to be pressed. Ctrl+C rejects with AbortSilentError, which terminates the process.
|
|
387
|
+
*
|
|
388
|
+
* Raw mode is set back to the state it had before the call. A command that keeps stdin raw for
|
|
389
|
+
* its own single-key shortcuts (for example `theme dev`) keeps them.
|
|
390
|
+
*
|
|
391
|
+
* Chunks are read as text: an active Ink renderer calls `stdin.setEncoding('utf8')`, and then
|
|
392
|
+
* stdin emits strings instead of Buffers.
|
|
393
|
+
*
|
|
394
|
+
* @param stdin - The stream to read from.
|
|
395
|
+
* @param uiDebugOptions - Debug options; `skipTTYCheck` allows a non-TTY stdin.
|
|
396
|
+
* @param options - The keys that end the wait.
|
|
397
|
+
* @returns A promise that resolves when an accepted key is pressed.
|
|
398
|
+
*/
|
|
379
399
|
export declare const keypress: (stdin?: NodeJS.ReadStream & {
|
|
380
400
|
fd: 0;
|
|
381
|
-
}, uiDebugOptions?: UIDebugOptions) => Promise<
|
|
401
|
+
}, uiDebugOptions?: UIDebugOptions, { keys }?: KeypressOptions) => Promise<void>;
|
|
382
402
|
interface IsTTYOptions {
|
|
383
403
|
stdin?: NodeJS.ReadStream;
|
|
384
404
|
uiDebugOptions?: UIDebugOptions;
|