shopify 3.93.1 → 3.94.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.
Files changed (94) hide show
  1. package/dist/assets/dev-console/extensions/dev-console/assets/index-Bm_GpKQW.js +51 -0
  2. package/dist/assets/dev-console/index.html +1 -1
  3. package/dist/chunk-52KHWFYF.js +1 -0
  4. package/dist/chunk-7F3HZJH4.js +3 -0
  5. package/dist/{chunk-TCRHJ3ZH.js → chunk-7JFIBCHH.js} +66 -66
  6. package/dist/{chunk-PB3UDYWH.js → chunk-AQOYGO3U.js} +16 -16
  7. package/dist/{chunk-T57REQVZ.js → chunk-DBDY2YEY.js} +1 -1
  8. package/dist/chunk-DEW5QFGH.js +415 -0
  9. package/dist/chunk-FU2Y2M3M.js +5 -0
  10. package/dist/chunk-JBSYWYIP.js +2 -0
  11. package/dist/chunk-QYR5VPQA.js +4 -0
  12. package/dist/{chunk-SVYSLNQH.js → chunk-R6N4NGU6.js} +178 -182
  13. package/dist/{chunk-P3ASN7B5.js → chunk-SVA22NZQ.js} +209 -211
  14. package/dist/cli/commands/config/autoupgrade/constants.d.ts +5 -0
  15. package/dist/cli/commands/config/autoupgrade/constants.js +6 -0
  16. package/dist/cli/commands/config/autoupgrade/off.d.ts +7 -0
  17. package/dist/cli/commands/config/autoupgrade/off.js +22 -0
  18. package/dist/cli/commands/config/autoupgrade/on.d.ts +7 -0
  19. package/dist/cli/commands/config/autoupgrade/on.js +22 -0
  20. package/dist/cli/commands/config/autoupgrade/status.d.ts +7 -0
  21. package/dist/cli/commands/config/autoupgrade/status.js +30 -0
  22. package/dist/cli/commands/docs/generate.d.ts +1 -1
  23. package/dist/cli/commands/docs/generate.js +6 -3
  24. package/dist/cli/commands/upgrade.js +3 -1
  25. package/dist/cli/services/kitchen-sink/static.js +1 -1
  26. package/dist/configs/all.yml +3 -0
  27. package/dist/configs/recommended.yml +3 -0
  28. package/dist/data/filters.json +30 -0
  29. package/dist/data/objects.json +17 -1
  30. package/dist/data/setting.json +25 -0
  31. package/dist/data/shopify_system_translations.json +29 -6
  32. package/dist/error-handler-JHFQZGYG.js +1 -0
  33. package/dist/hooks/postrun.js +1 -1
  34. package/dist/hooks/prerun.js +1 -1
  35. package/dist/{http-proxy-node16-KBILO6A6.js → http-proxy-node16-TTURN6MD.js} +1 -1
  36. package/dist/index.js +1117 -1121
  37. package/dist/lib-3WHF5XD3.js +1 -0
  38. package/dist/{local-JCUIPKND.js → local-4PW2CHVR.js} +1 -1
  39. package/dist/{morph-6DCXNO2H.js → morph-DQREIZD2.js} +1 -1
  40. package/dist/node-package-manager-NTQEYCSE.js +1 -0
  41. package/dist/path-HUAU3YBW.js +1 -0
  42. package/dist/tsconfig.tsbuildinfo +1 -1
  43. package/dist/{ui-XTVYPIVY.js → ui-7Z2HOOEO.js} +1 -1
  44. package/dist/{workerd-3GJRSBJN.js → workerd-VL54JTEU.js} +1 -1
  45. package/oclif.manifest.json +63 -3
  46. package/package.json +7 -6
  47. package/dist/assets/dev-console/extensions/dev-console/assets/index-BnXVL6nA.js +0 -78
  48. package/dist/chunk-NOSKVZWJ.js +0 -2
  49. package/dist/chunk-QJEBL3WX.js +0 -4
  50. package/dist/chunk-VLDSGLBP.js +0 -1
  51. package/dist/chunk-WOERFYNW.js +0 -415
  52. package/dist/chunk-XV44IQDO.js +0 -5
  53. package/dist/cli/commands/store/auth.d.ts +0 -15
  54. package/dist/cli/commands/store/auth.js +0 -46
  55. package/dist/cli/commands/store/execute.d.ts +0 -21
  56. package/dist/cli/commands/store/execute.js +0 -89
  57. package/dist/cli/services/store/auth/callback.d.ts +0 -8
  58. package/dist/cli/services/store/auth/callback.js +0 -140
  59. package/dist/cli/services/store/auth/config.d.ts +0 -6
  60. package/dist/cli/services/store/auth/config.js +0 -15
  61. package/dist/cli/services/store/auth/existing-scopes.d.ts +0 -5
  62. package/dist/cli/services/store/auth/existing-scopes.js +0 -40
  63. package/dist/cli/services/store/auth/index.d.ts +0 -18
  64. package/dist/cli/services/store/auth/index.js +0 -88
  65. package/dist/cli/services/store/auth/pkce.d.ts +0 -36
  66. package/dist/cli/services/store/auth/pkce.js +0 -49
  67. package/dist/cli/services/store/auth/recovery.d.ts +0 -4
  68. package/dist/cli/services/store/auth/recovery.js +0 -17
  69. package/dist/cli/services/store/auth/result.d.ts +0 -24
  70. package/dist/cli/services/store/auth/result.js +0 -39
  71. package/dist/cli/services/store/auth/scopes.d.ts +0 -4
  72. package/dist/cli/services/store/auth/scopes.js +0 -53
  73. package/dist/cli/services/store/auth/session-lifecycle.d.ts +0 -3
  74. package/dist/cli/services/store/auth/session-lifecycle.js +0 -69
  75. package/dist/cli/services/store/auth/session-store.d.ts +0 -32
  76. package/dist/cli/services/store/auth/session-store.js +0 -127
  77. package/dist/cli/services/store/auth/token-client.d.ts +0 -40
  78. package/dist/cli/services/store/auth/token-client.js +0 -95
  79. package/dist/cli/services/store/execute/admin-context.d.ts +0 -11
  80. package/dist/cli/services/store/execute/admin-context.js +0 -41
  81. package/dist/cli/services/store/execute/admin-transport.d.ts +0 -6
  82. package/dist/cli/services/store/execute/admin-transport.js +0 -42
  83. package/dist/cli/services/store/execute/index.d.ts +0 -13
  84. package/dist/cli/services/store/execute/index.js +0 -22
  85. package/dist/cli/services/store/execute/request.d.ts +0 -21
  86. package/dist/cli/services/store/execute/request.js +0 -88
  87. package/dist/cli/services/store/execute/result.d.ts +0 -3
  88. package/dist/cli/services/store/execute/result.js +0 -29
  89. package/dist/cli/services/store/execute/targets.d.ts +0 -18
  90. package/dist/cli/services/store/execute/targets.js +0 -21
  91. package/dist/error-handler-54XVSWV5.js +0 -1
  92. package/dist/lib-EN3PX6IK.js +0 -1
  93. package/dist/node-package-manager-P7JQBCHZ.js +0 -1
  94. package/dist/path-IT7KPARG.js +0 -1
@@ -1,24 +0,0 @@
1
- export interface StoreAuthResult {
2
- store: string;
3
- userId: string;
4
- scopes: string[];
5
- acquiredAt: string;
6
- expiresAt?: string;
7
- refreshTokenExpiresAt?: string;
8
- hasRefreshToken: boolean;
9
- associatedUser?: {
10
- id: number;
11
- email?: string;
12
- firstName?: string;
13
- lastName?: string;
14
- accountOwner?: boolean;
15
- };
16
- }
17
- type StoreAuthOutputFormat = 'text' | 'json';
18
- export interface StoreAuthPresenter {
19
- openingBrowser: () => void;
20
- manualAuthUrl: (authorizationUrl: string) => void;
21
- success: (result: StoreAuthResult) => void;
22
- }
23
- export declare function createStoreAuthPresenter(format?: StoreAuthOutputFormat): StoreAuthPresenter;
24
- export {};
@@ -1,39 +0,0 @@
1
- import { outputCompleted, outputInfo, outputResult, outputToken, outputContent } from '@shopify/cli-kit/node/output';
2
- function serializeStoreAuthResult(result) {
3
- return JSON.stringify(result, null, 2);
4
- }
5
- function buildStoreAuthSuccessText(result) {
6
- const displayName = result.associatedUser?.email ? ` as ${result.associatedUser.email}` : '';
7
- return {
8
- completed: ['Logged in.', `Authenticated${displayName} against ${result.store}.`],
9
- info: ['', 'To verify that authentication worked, run:', `shopify store execute --store ${result.store} --query 'query { shop { name id } }'`],
10
- };
11
- }
12
- function displayStoreAuthOpeningBrowser() {
13
- outputInfo('Shopify CLI will open the app authorization page in your browser.');
14
- outputInfo('');
15
- }
16
- function displayStoreAuthManualAuthUrl(authorizationUrl) {
17
- outputInfo('Browser did not open automatically. Open this URL manually:');
18
- outputInfo(outputContent `${outputToken.link(authorizationUrl)}`);
19
- outputInfo('');
20
- }
21
- function displayStoreAuthResult(result, format = 'text') {
22
- if (format === 'json') {
23
- outputResult(serializeStoreAuthResult(result));
24
- return;
25
- }
26
- const text = buildStoreAuthSuccessText(result);
27
- text.completed.forEach((line) => outputCompleted(line));
28
- text.info.forEach((line) => outputInfo(line));
29
- }
30
- export function createStoreAuthPresenter(format = 'text') {
31
- return {
32
- openingBrowser: displayStoreAuthOpeningBrowser,
33
- manualAuthUrl: displayStoreAuthManualAuthUrl,
34
- success(result) {
35
- displayStoreAuthResult(result, format);
36
- },
37
- };
38
- }
39
- //# sourceMappingURL=result.js.map
@@ -1,4 +0,0 @@
1
- import type { StoreTokenResponse } from './token-client.js';
2
- export declare function parseStoreAuthScopes(input: string): string[];
3
- export declare function mergeRequestedAndStoredScopes(requestedScopes: string[], storedScopes: string[]): string[];
4
- export declare function resolveGrantedScopes(tokenResponse: StoreTokenResponse, requestedScopes: string[]): string[];
@@ -1,53 +0,0 @@
1
- import { AbortError } from '@shopify/cli-kit/node/error';
2
- import { outputContent, outputDebug } from '@shopify/cli-kit/node/output';
3
- export function parseStoreAuthScopes(input) {
4
- const scopes = input
5
- .split(',')
6
- .map((scope) => scope.trim())
7
- .filter(Boolean);
8
- if (scopes.length === 0) {
9
- throw new AbortError('At least one scope is required.', 'Pass --scopes as a comma-separated list.');
10
- }
11
- return [...new Set(scopes)];
12
- }
13
- function expandImpliedStoreScopes(scopes) {
14
- const expandedScopes = new Set(scopes);
15
- for (const scope of scopes) {
16
- const matches = scope.match(/^(unauthenticated_)?write_(.*)$/);
17
- if (matches) {
18
- expandedScopes.add(`${matches[1] ?? ''}read_${matches[2]}`);
19
- }
20
- }
21
- return expandedScopes;
22
- }
23
- export function mergeRequestedAndStoredScopes(requestedScopes, storedScopes) {
24
- const mergedScopes = [...storedScopes];
25
- const expandedScopes = expandImpliedStoreScopes(storedScopes);
26
- for (const scope of requestedScopes) {
27
- if (expandedScopes.has(scope))
28
- continue;
29
- mergedScopes.push(scope);
30
- for (const expandedScope of expandImpliedStoreScopes([scope])) {
31
- expandedScopes.add(expandedScope);
32
- }
33
- }
34
- return mergedScopes;
35
- }
36
- export function resolveGrantedScopes(tokenResponse, requestedScopes) {
37
- if (!tokenResponse.scope) {
38
- outputDebug(outputContent `Token response did not include scope; falling back to requested scopes`);
39
- return requestedScopes;
40
- }
41
- const grantedScopes = parseStoreAuthScopes(tokenResponse.scope);
42
- const expandedGrantedScopes = expandImpliedStoreScopes(grantedScopes);
43
- const missingScopes = requestedScopes.filter((scope) => !expandedGrantedScopes.has(scope));
44
- if (missingScopes.length > 0) {
45
- throw new AbortError('Shopify granted fewer scopes than were requested.', `Missing scopes: ${missingScopes.join(', ')}.`, [
46
- 'Update the app or store installation scopes.',
47
- 'See https://shopify.dev/app/scopes',
48
- 'Re-run shopify store auth.',
49
- ]);
50
- }
51
- return grantedScopes;
52
- }
53
- //# sourceMappingURL=scopes.js.map
@@ -1,3 +0,0 @@
1
- import type { StoredStoreAppSession } from './session-store.js';
2
- export declare function isSessionExpired(session: StoredStoreAppSession): boolean;
3
- export declare function loadStoredStoreSession(store: string): Promise<StoredStoreAppSession>;
@@ -1,69 +0,0 @@
1
- import { AbortError } from '@shopify/cli-kit/node/error';
2
- import { outputContent, outputDebug, outputToken } from '@shopify/cli-kit/node/output';
3
- import { maskToken } from './config.js';
4
- import { createStoredStoreAuthError, reauthenticateStoreAuthError } from './recovery.js';
5
- import { clearStoredStoreAppSession, getCurrentStoredStoreAppSession, setStoredStoreAppSession, } from './session-store.js';
6
- import { refreshStoreAccessToken } from './token-client.js';
7
- const EXPIRY_MARGIN_MS = 4 * 60 * 1000;
8
- export function isSessionExpired(session) {
9
- if (!session.expiresAt)
10
- return false;
11
- const expiresAtMs = new Date(session.expiresAt).getTime();
12
- if (Number.isNaN(expiresAtMs))
13
- return true;
14
- return expiresAtMs - EXPIRY_MARGIN_MS < Date.now();
15
- }
16
- function buildRefreshedStoredSession(session, refresh) {
17
- const now = Date.now();
18
- const expiresAt = refresh.expiresIn ? new Date(now + refresh.expiresIn * 1000).toISOString() : session.expiresAt;
19
- return {
20
- ...session,
21
- accessToken: refresh.accessToken,
22
- refreshToken: refresh.refreshToken ?? session.refreshToken,
23
- expiresAt,
24
- refreshTokenExpiresAt: refresh.refreshTokenExpiresIn
25
- ? new Date(now + refresh.refreshTokenExpiresIn * 1000).toISOString()
26
- : session.refreshTokenExpiresAt,
27
- acquiredAt: new Date(now).toISOString(),
28
- };
29
- }
30
- export async function loadStoredStoreSession(store) {
31
- let session = getCurrentStoredStoreAppSession(store);
32
- if (!session) {
33
- throw createStoredStoreAuthError(store);
34
- }
35
- outputDebug(outputContent `Loaded stored session for ${outputToken.raw(store)}: token=${outputToken.raw(maskToken(session.accessToken))}, expires=${outputToken.raw(session.expiresAt ?? 'unknown')}`);
36
- if (!isSessionExpired(session)) {
37
- return session;
38
- }
39
- if (!session.refreshToken) {
40
- throw reauthenticateStoreAuthError(`No refresh token stored for ${session.store}.`, session.store, session.scopes.join(','));
41
- }
42
- outputDebug(outputContent `Refreshing expired token for ${outputToken.raw(session.store)} (expired at ${outputToken.raw(session.expiresAt ?? 'unknown')}, refresh_token=${outputToken.raw(maskToken(session.refreshToken))})`);
43
- const previousAccessToken = session.accessToken;
44
- let refreshed;
45
- try {
46
- refreshed = await refreshStoreAccessToken({
47
- store: session.store,
48
- refreshToken: session.refreshToken,
49
- });
50
- }
51
- catch (error) {
52
- clearStoredStoreAppSession(session.store, session.userId);
53
- if (error instanceof AbortError && error.message.startsWith(`Token refresh failed for ${session.store} (HTTP `)) {
54
- throw reauthenticateStoreAuthError(error.message, session.store, session.scopes.join(','));
55
- }
56
- if (error instanceof AbortError && error.message === `Token refresh returned an invalid response for ${session.store}.`) {
57
- throw reauthenticateStoreAuthError(error.message, session.store, session.scopes.join(','));
58
- }
59
- if (error instanceof AbortError && error.message === 'Received an invalid refresh response from Shopify.') {
60
- throw error;
61
- }
62
- throw error;
63
- }
64
- session = buildRefreshedStoredSession(session, refreshed);
65
- outputDebug(outputContent `Token refresh succeeded for ${outputToken.raw(session.store)}: ${outputToken.raw(maskToken(previousAccessToken))} → ${outputToken.raw(maskToken(session.accessToken))}, new expiry ${outputToken.raw(session.expiresAt ?? 'unknown')}`);
66
- setStoredStoreAppSession(session);
67
- return session;
68
- }
69
- //# sourceMappingURL=session-lifecycle.js.map
@@ -1,32 +0,0 @@
1
- import { LocalStorage } from '@shopify/cli-kit/node/local-storage';
2
- export interface StoredStoreAppSession {
3
- store: string;
4
- clientId: string;
5
- userId: string;
6
- accessToken: string;
7
- refreshToken?: string;
8
- scopes: string[];
9
- acquiredAt: string;
10
- expiresAt?: string;
11
- refreshTokenExpiresAt?: string;
12
- associatedUser?: {
13
- id: number;
14
- email?: string;
15
- firstName?: string;
16
- lastName?: string;
17
- accountOwner?: boolean;
18
- };
19
- }
20
- interface StoredStoreAppSessionBucket {
21
- currentUserId: string;
22
- sessionsByUserId: {
23
- [userId: string]: StoredStoreAppSession;
24
- };
25
- }
26
- interface StoreSessionSchema {
27
- [key: string]: StoredStoreAppSessionBucket;
28
- }
29
- export declare function getCurrentStoredStoreAppSession(store: string, storage?: LocalStorage<StoreSessionSchema>): StoredStoreAppSession | undefined;
30
- export declare function setStoredStoreAppSession(session: StoredStoreAppSession, storage?: LocalStorage<StoreSessionSchema>): void;
31
- export declare function clearStoredStoreAppSession(store: string, userIdOrStorage?: string | LocalStorage<StoreSessionSchema>, maybeStorage?: LocalStorage<StoreSessionSchema>): void;
32
- export {};
@@ -1,127 +0,0 @@
1
- import { LocalStorage } from '@shopify/cli-kit/node/local-storage';
2
- import { storeAuthSessionKey } from './config.js';
3
- let _storeSessionStorage;
4
- function storeSessionStorage() {
5
- _storeSessionStorage ?? (_storeSessionStorage = new LocalStorage({ projectName: 'shopify-cli-store' }));
6
- return _storeSessionStorage;
7
- }
8
- function isString(value) {
9
- return typeof value === 'string';
10
- }
11
- function sanitizeAssociatedUser(value) {
12
- if (!value || typeof value !== 'object')
13
- return undefined;
14
- const associatedUser = value;
15
- if (typeof associatedUser.id !== 'number')
16
- return undefined;
17
- return {
18
- id: associatedUser.id,
19
- ...(isString(associatedUser.email) ? { email: associatedUser.email } : {}),
20
- ...(isString(associatedUser.firstName) ? { firstName: associatedUser.firstName } : {}),
21
- ...(isString(associatedUser.lastName) ? { lastName: associatedUser.lastName } : {}),
22
- ...(typeof associatedUser.accountOwner === 'boolean' ? { accountOwner: associatedUser.accountOwner } : {}),
23
- };
24
- }
25
- function sanitizeStoredStoreAppSession(value) {
26
- if (!value || typeof value !== 'object')
27
- return undefined;
28
- const session = value;
29
- if (!isString(session.store) ||
30
- !isString(session.clientId) ||
31
- !isString(session.userId) ||
32
- !isString(session.accessToken) ||
33
- !Array.isArray(session.scopes) ||
34
- !session.scopes.every(isString) ||
35
- !isString(session.acquiredAt)) {
36
- return undefined;
37
- }
38
- return {
39
- store: session.store,
40
- clientId: session.clientId,
41
- userId: session.userId,
42
- accessToken: session.accessToken,
43
- scopes: session.scopes,
44
- acquiredAt: session.acquiredAt,
45
- ...(isString(session.refreshToken) ? { refreshToken: session.refreshToken } : {}),
46
- ...(isString(session.expiresAt) ? { expiresAt: session.expiresAt } : {}),
47
- ...(isString(session.refreshTokenExpiresAt) ? { refreshTokenExpiresAt: session.refreshTokenExpiresAt } : {}),
48
- ...(sanitizeAssociatedUser(session.associatedUser) ? { associatedUser: sanitizeAssociatedUser(session.associatedUser) } : {}),
49
- };
50
- }
51
- function readStoredStoreAppSessionBucket(store, storage) {
52
- const key = storeAuthSessionKey(store);
53
- const storedBucket = storage.get(key);
54
- if (!storedBucket || typeof storedBucket !== 'object')
55
- return undefined;
56
- const { sessionsByUserId, currentUserId } = storedBucket;
57
- if (!sessionsByUserId || typeof sessionsByUserId !== 'object' || Array.isArray(sessionsByUserId) || typeof currentUserId !== 'string') {
58
- storage.delete(key);
59
- return undefined;
60
- }
61
- const sanitizedSessionsByUserId = Object.fromEntries(Object.entries(sessionsByUserId).flatMap(([userId, session]) => {
62
- const sanitizedSession = sanitizeStoredStoreAppSession(session);
63
- return sanitizedSession ? [[userId, sanitizedSession]] : [];
64
- }));
65
- if (Object.keys(sanitizedSessionsByUserId).length !== Object.keys(sessionsByUserId).length) {
66
- if (sanitizedSessionsByUserId[currentUserId]) {
67
- storage.set(key, {
68
- currentUserId,
69
- sessionsByUserId: sanitizedSessionsByUserId,
70
- });
71
- }
72
- else {
73
- storage.delete(key);
74
- return undefined;
75
- }
76
- }
77
- return {
78
- currentUserId,
79
- sessionsByUserId: sanitizedSessionsByUserId,
80
- };
81
- }
82
- export function getCurrentStoredStoreAppSession(store, storage = storeSessionStorage()) {
83
- const bucket = readStoredStoreAppSessionBucket(store, storage);
84
- if (!bucket)
85
- return undefined;
86
- const session = bucket.sessionsByUserId[bucket.currentUserId];
87
- if (!session) {
88
- storage.delete(storeAuthSessionKey(store));
89
- return undefined;
90
- }
91
- return session;
92
- }
93
- export function setStoredStoreAppSession(session, storage = storeSessionStorage()) {
94
- const key = storeAuthSessionKey(session.store);
95
- const existingBucket = readStoredStoreAppSessionBucket(session.store, storage);
96
- const nextBucket = {
97
- currentUserId: session.userId,
98
- sessionsByUserId: {
99
- ...(existingBucket?.sessionsByUserId ?? {}),
100
- [session.userId]: session,
101
- },
102
- };
103
- storage.set(key, nextBucket);
104
- }
105
- export function clearStoredStoreAppSession(store, userIdOrStorage, maybeStorage) {
106
- const userId = typeof userIdOrStorage === 'string' ? userIdOrStorage : undefined;
107
- const storage = (typeof userIdOrStorage === 'string' ? maybeStorage : userIdOrStorage) ?? storeSessionStorage();
108
- const key = storeAuthSessionKey(store);
109
- if (!userId) {
110
- storage.delete(key);
111
- return;
112
- }
113
- const existingBucket = readStoredStoreAppSessionBucket(store, storage);
114
- if (!existingBucket)
115
- return;
116
- const { [userId]: _removedSession, ...remainingSessions } = existingBucket.sessionsByUserId;
117
- const remainingUserIds = Object.keys(remainingSessions);
118
- if (remainingUserIds.length === 0) {
119
- storage.delete(key);
120
- return;
121
- }
122
- storage.set(key, {
123
- currentUserId: existingBucket.currentUserId === userId ? remainingUserIds[0] : existingBucket.currentUserId,
124
- sessionsByUserId: remainingSessions,
125
- });
126
- }
127
- //# sourceMappingURL=session-store.js.map
@@ -1,40 +0,0 @@
1
- export interface StoreTokenResponse {
2
- access_token: string;
3
- token_type?: string;
4
- scope?: string;
5
- expires_in?: number;
6
- refresh_token?: string;
7
- refresh_token_expires_in?: number;
8
- associated_user_scope?: string;
9
- associated_user?: {
10
- id: number;
11
- first_name?: string;
12
- last_name?: string;
13
- email?: string;
14
- account_owner?: boolean;
15
- locale?: string;
16
- collaborator?: boolean;
17
- email_verified?: boolean;
18
- };
19
- }
20
- interface StoreTokenRefreshPayload {
21
- accessToken: string;
22
- refreshToken?: string;
23
- expiresIn?: number;
24
- refreshTokenExpiresIn?: number;
25
- }
26
- export declare function exchangeStoreAuthCodeForToken(options: {
27
- store: string;
28
- code: string;
29
- codeVerifier: string;
30
- redirectUri: string;
31
- }): Promise<StoreTokenResponse>;
32
- export declare function refreshStoreAccessToken(options: {
33
- store: string;
34
- refreshToken: string;
35
- }): Promise<StoreTokenRefreshPayload>;
36
- export declare function fetchCurrentStoreAuthScopes(options: {
37
- store: string;
38
- accessToken: string;
39
- }): Promise<string[]>;
40
- export {};
@@ -1,95 +0,0 @@
1
- import { adminUrl } from '@shopify/cli-kit/node/api/admin';
2
- import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
3
- import { AbortError } from '@shopify/cli-kit/node/error';
4
- import { fetch } from '@shopify/cli-kit/node/http';
5
- import { outputContent, outputDebug, outputToken } from '@shopify/cli-kit/node/output';
6
- import { maskToken, STORE_AUTH_APP_CLIENT_ID } from './config.js';
7
- function truncateHttpErrorBody(body, length = 300) {
8
- return body.slice(0, length);
9
- }
10
- export async function exchangeStoreAuthCodeForToken(options) {
11
- const endpoint = `https://${options.store}/admin/oauth/access_token`;
12
- outputDebug(outputContent `Exchanging authorization code for token at ${outputToken.raw(endpoint)}`);
13
- const response = await fetch(endpoint, {
14
- method: 'POST',
15
- headers: { 'Content-Type': 'application/json' },
16
- body: JSON.stringify({
17
- client_id: STORE_AUTH_APP_CLIENT_ID,
18
- code: options.code,
19
- code_verifier: options.codeVerifier,
20
- redirect_uri: options.redirectUri,
21
- }),
22
- });
23
- const body = await response.text();
24
- if (!response.ok) {
25
- outputDebug(outputContent `Token exchange failed with HTTP ${outputToken.raw(String(response.status))}: ${outputToken.raw(truncateHttpErrorBody(body || response.statusText))}`);
26
- throw new AbortError(`Failed to exchange OAuth code for an access token (HTTP ${response.status}).`, body || response.statusText);
27
- }
28
- let parsed;
29
- try {
30
- parsed = JSON.parse(body);
31
- }
32
- catch {
33
- throw new AbortError('Received an invalid token response from Shopify.');
34
- }
35
- outputDebug(outputContent `Token exchange succeeded: access_token=${outputToken.raw(maskToken(parsed.access_token))}, refresh_token=${outputToken.raw(parsed.refresh_token ? maskToken(parsed.refresh_token) : 'none')}, expires_in=${outputToken.raw(String(parsed.expires_in ?? 'unknown'))}s, user=${outputToken.raw(String(parsed.associated_user?.id ?? 'unknown'))} (${outputToken.raw(parsed.associated_user?.email ?? 'no email')})`);
36
- return parsed;
37
- }
38
- export async function refreshStoreAccessToken(options) {
39
- const endpoint = `https://${options.store}/admin/oauth/access_token`;
40
- outputDebug(outputContent `Refreshing access token for ${outputToken.raw(options.store)} using refresh_token=${outputToken.raw(maskToken(options.refreshToken))}`);
41
- const response = await fetch(endpoint, {
42
- method: 'POST',
43
- headers: { 'Content-Type': 'application/json' },
44
- body: JSON.stringify({
45
- client_id: STORE_AUTH_APP_CLIENT_ID,
46
- grant_type: 'refresh_token',
47
- refresh_token: options.refreshToken,
48
- }),
49
- });
50
- const body = await response.text();
51
- if (!response.ok) {
52
- outputDebug(outputContent `Token refresh failed with HTTP ${outputToken.raw(String(response.status))}: ${outputToken.raw(truncateHttpErrorBody(body || response.statusText))}`);
53
- throw new AbortError(`Token refresh failed for ${options.store} (HTTP ${response.status}).`);
54
- }
55
- let parsed;
56
- try {
57
- parsed = JSON.parse(body);
58
- }
59
- catch {
60
- throw new AbortError('Received an invalid refresh response from Shopify.');
61
- }
62
- if (!parsed.access_token) {
63
- throw new AbortError(`Token refresh returned an invalid response for ${options.store}.`);
64
- }
65
- return {
66
- accessToken: parsed.access_token,
67
- refreshToken: parsed.refresh_token,
68
- expiresIn: parsed.expires_in,
69
- refreshTokenExpiresIn: parsed.refresh_token_expires_in,
70
- };
71
- }
72
- const CurrentAppInstallationAccessScopesQuery = `#graphql
73
- query CurrentAppInstallationAccessScopes {
74
- currentAppInstallation {
75
- accessScopes {
76
- handle
77
- }
78
- }
79
- }
80
- `;
81
- export async function fetchCurrentStoreAuthScopes(options) {
82
- outputDebug(outputContent `Fetching current app installation scopes for ${outputToken.raw(options.store)} using token ${outputToken.raw(maskToken(options.accessToken))}`);
83
- const data = await graphqlRequest({
84
- query: CurrentAppInstallationAccessScopesQuery,
85
- api: 'Admin',
86
- url: adminUrl(options.store, 'unstable'),
87
- token: options.accessToken,
88
- responseOptions: { handleErrors: false },
89
- });
90
- if (!Array.isArray(data.currentAppInstallation?.accessScopes)) {
91
- throw new Error('Shopify did not return currentAppInstallation.accessScopes.');
92
- }
93
- return data.currentAppInstallation.accessScopes.flatMap((scope) => typeof scope.handle === 'string' ? [scope.handle] : []);
94
- }
95
- //# sourceMappingURL=token-client.js.map
@@ -1,11 +0,0 @@
1
- import type { AdminSession } from '@shopify/cli-kit/node/session';
2
- import type { StoredStoreAppSession } from '../auth/session-store.js';
3
- export interface AdminStoreGraphQLContext {
4
- adminSession: AdminSession;
5
- version: string;
6
- session: StoredStoreAppSession;
7
- }
8
- export declare function prepareAdminStoreGraphQLContext(input: {
9
- store: string;
10
- userSpecifiedVersion?: string;
11
- }): Promise<AdminStoreGraphQLContext>;
@@ -1,41 +0,0 @@
1
- import { fetchApiVersions } from '@shopify/cli-kit/node/api/admin';
2
- import { AbortError } from '@shopify/cli-kit/node/error';
3
- import { reauthenticateStoreAuthError } from '../auth/recovery.js';
4
- import { clearStoredStoreAppSession } from '../auth/session-store.js';
5
- import { loadStoredStoreSession } from '../auth/session-lifecycle.js';
6
- async function resolveApiVersion(options) {
7
- const { session, adminSession, userSpecifiedVersion } = options;
8
- if (userSpecifiedVersion === 'unstable')
9
- return userSpecifiedVersion;
10
- let availableVersions;
11
- try {
12
- availableVersions = await fetchApiVersions(adminSession);
13
- }
14
- catch (error) {
15
- if (error instanceof AbortError &&
16
- error.message.includes(`Error connecting to your store ${adminSession.storeFqdn}:`) &&
17
- /\b(?:401|404)\b/.test(error.message)) {
18
- clearStoredStoreAppSession(session.store, session.userId);
19
- throw reauthenticateStoreAuthError(`Stored app authentication for ${session.store} is no longer valid.`, session.store, session.scopes.join(','));
20
- }
21
- throw error;
22
- }
23
- if (!userSpecifiedVersion) {
24
- const supportedVersions = availableVersions.filter((version) => version.supported).map((version) => version.handle);
25
- return supportedVersions.sort().reverse()[0];
26
- }
27
- const versionList = availableVersions.map((version) => version.handle);
28
- if (versionList.includes(userSpecifiedVersion))
29
- return userSpecifiedVersion;
30
- throw new AbortError(`Invalid API version: ${userSpecifiedVersion}`, `Allowed versions: ${versionList.join(', ')}`);
31
- }
32
- export async function prepareAdminStoreGraphQLContext(input) {
33
- const session = await loadStoredStoreSession(input.store);
34
- const adminSession = {
35
- token: session.accessToken,
36
- storeFqdn: session.store,
37
- };
38
- const version = await resolveApiVersion({ session, adminSession, userSpecifiedVersion: input.userSpecifiedVersion });
39
- return { adminSession, version, session };
40
- }
41
- //# sourceMappingURL=admin-context.js.map
@@ -1,6 +0,0 @@
1
- import type { PreparedStoreExecuteRequest } from './request.js';
2
- import type { AdminStoreGraphQLContext } from './admin-context.js';
3
- export declare function runAdminStoreGraphQLOperation(input: {
4
- context: AdminStoreGraphQLContext;
5
- request: PreparedStoreExecuteRequest;
6
- }): Promise<unknown>;
@@ -1,42 +0,0 @@
1
- import { adminUrl } from '@shopify/cli-kit/node/api/admin';
2
- import { graphqlRequest } from '@shopify/cli-kit/node/api/graphql';
3
- import { AbortError } from '@shopify/cli-kit/node/error';
4
- import { outputContent } from '@shopify/cli-kit/node/output';
5
- import { renderSingleTask } from '@shopify/cli-kit/node/ui';
6
- import { reauthenticateStoreAuthError } from '../auth/recovery.js';
7
- import { clearStoredStoreAppSession } from '../auth/session-store.js';
8
- function isGraphQLClientError(error) {
9
- if (!error || typeof error !== 'object' || !('response' in error))
10
- return false;
11
- const response = error.response;
12
- return !!response && typeof response === 'object';
13
- }
14
- export async function runAdminStoreGraphQLOperation(input) {
15
- try {
16
- return await renderSingleTask({
17
- title: outputContent `Executing GraphQL operation`,
18
- task: async () => {
19
- return graphqlRequest({
20
- query: input.request.query,
21
- api: 'Admin',
22
- url: adminUrl(input.context.adminSession.storeFqdn, input.context.version, input.context.adminSession),
23
- token: input.context.adminSession.token,
24
- variables: input.request.parsedVariables,
25
- responseOptions: { handleErrors: false },
26
- });
27
- },
28
- renderOptions: { stdout: process.stderr },
29
- });
30
- }
31
- catch (error) {
32
- if (isGraphQLClientError(error) && error.response.status === 401) {
33
- clearStoredStoreAppSession(input.context.session.store, input.context.session.userId);
34
- throw reauthenticateStoreAuthError(`Stored app authentication for ${input.context.session.store} is no longer valid.`, input.context.session.store, input.context.session.scopes.join(','));
35
- }
36
- if (isGraphQLClientError(error) && error.response.errors) {
37
- throw new AbortError('GraphQL operation failed.', JSON.stringify({ errors: error.response.errors }, null, 2));
38
- }
39
- throw error;
40
- }
41
- }
42
- //# sourceMappingURL=admin-transport.js.map
@@ -1,13 +0,0 @@
1
- import { type StoreGraphQLApi } from './targets.js';
2
- interface ExecuteStoreOperationInput {
3
- store: string;
4
- api?: StoreGraphQLApi;
5
- query?: string;
6
- queryFile?: string;
7
- variables?: string;
8
- variableFile?: string;
9
- version?: string;
10
- allowMutations?: boolean;
11
- }
12
- export declare function executeStoreOperation(input: ExecuteStoreOperationInput): Promise<unknown>;
13
- export {};
@@ -1,22 +0,0 @@
1
- import { renderSingleTask } from '@shopify/cli-kit/node/ui';
2
- import { outputContent } from '@shopify/cli-kit/node/output';
3
- import { prepareStoreExecuteRequest } from './request.js';
4
- import { getStoreGraphQLTarget } from './targets.js';
5
- export async function executeStoreOperation(input) {
6
- const target = getStoreGraphQLTarget(input.api ?? 'admin');
7
- const request = await prepareStoreExecuteRequest({
8
- query: input.query,
9
- queryFile: input.queryFile,
10
- variables: input.variables,
11
- variableFile: input.variableFile,
12
- version: input.version,
13
- allowMutations: input.allowMutations,
14
- });
15
- const context = await renderSingleTask({
16
- title: outputContent `Loading stored store auth`,
17
- task: async () => target.prepareContext({ store: input.store, requestedVersion: request.requestedVersion }),
18
- renderOptions: { stdout: process.stderr },
19
- });
20
- return await target.execute({ context, request });
21
- }
22
- //# sourceMappingURL=index.js.map
@@ -1,21 +0,0 @@
1
- import { OperationDefinitionNode } from 'graphql';
2
- interface ParsedGraphQLOperation {
3
- operationDefinition: OperationDefinitionNode;
4
- }
5
- export interface PreparedStoreExecuteRequest {
6
- query: string;
7
- parsedOperation: ParsedGraphQLOperation;
8
- parsedVariables?: {
9
- [key: string]: unknown;
10
- };
11
- requestedVersion?: string;
12
- }
13
- export declare function prepareStoreExecuteRequest(input: {
14
- query?: string;
15
- queryFile?: string;
16
- variables?: string;
17
- variableFile?: string;
18
- version?: string;
19
- allowMutations?: boolean;
20
- }): Promise<PreparedStoreExecuteRequest>;
21
- export {};