@shopify/cli-kit 4.9.5 → 5.0.1
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 +5 -1
- package/dist/private/node/session/exchange.js +97 -7
- 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/private/node/ui/components/Table/Table.d.ts +8 -0
- package/dist/private/node/ui/components/Table/Table.js +18 -2
- package/dist/private/node/ui/components/Table/Table.js.map +1 -1
- 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 +38 -3
- package/dist/public/node/session.js +56 -9
- 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 +54 -21
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadingBar.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/LoadingBar.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {LoadingBar} from './LoadingBar.js'\nimport {Stdout} from '../../ui.js'\nimport {render} from '../../testing/ui.js'\nimport {shouldDisplayColors, unstyled} from '../../../../public/node/output.js'\nimport useLayout from '../hooks/use-layout.js'\nimport React from 'react'\n\nimport {beforeEach, describe, expect, test, vi} from 'vitest'\n\nvi.mock('../hooks/use-layout.js')\nvi.mock('../../../../public/node/output.js', async () => {\n const original: any = await vi.importActual('../../../../public/node/output.js')\n return {\n ...original,\n shouldDisplayColors: vi.fn(),\n }\n})\n\nbeforeEach(() => {\n vi.mocked(useLayout).mockReturnValue({\n twoThirds: 53,\n oneThird: 27,\n fullWidth: 80,\n })\n vi.mocked(shouldDisplayColors).mockReturnValue(true)\n})\n\n/**\n * Creates a Stdout test double simulating a TTY stream.\n * On real Node streams, isTTY is only present as an own property when the\n * stream IS a TTY.\n */\nfunction createTTYStdout(columns = 100) {\n const stdout = new Stdout({columns}) as Stdout & {isTTY: boolean}\n stdout.isTTY = true\n return stdout\n}\n\n/**\n * Renders LoadingBar with a TTY stdout so the animated progress bar renders.\n */\nfunction renderWithTTY(element: React.ReactElement) {\n const stdout = createTTYStdout()\n const instance = render(element, {stdout})\n return {lastFrame: stdout.lastFrame, unmount: instance.unmount}\n}\n\ndescribe('LoadingBar', () => {\n test('renders loading bar with default colored characters', async () => {\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Loading content\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n Loading content ...\"\n `)\n })\n\n test('renders loading bar with hill pattern when noColor prop is true', async () => {\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Processing files\" noColor />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅▄▄▃▃▂▂▁▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅\n Processing files ...\"\n `)\n })\n\n test('renders loading bar with hill pattern when shouldDisplayColors returns false', async () => {\n vi.mocked(shouldDisplayColors).mockReturnValue(false)\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Downloading packages\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅▄▄▃▃▂▂▁▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅\n Downloading packages ...\"\n `)\n })\n\n test('handles narrow terminal width correctly', async () => {\n vi.mocked(useLayout).mockReturnValue({twoThirds: 20, oneThird: 10, fullWidth: 30})\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Building app\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n Building app ...\"\n `)\n })\n\n test('handles narrow terminal width correctly in no-color mode', async () => {\n vi.mocked(useLayout).mockReturnValue({twoThirds: 15, oneThird: 8, fullWidth: 23})\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Installing\" noColor />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇\n Installing ...\"\n `)\n })\n\n test('handles very narrow terminal width in no-color mode', async () => {\n vi.mocked(useLayout).mockReturnValue({twoThirds: 5, oneThird: 3, fullWidth: 8})\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Wait\" noColor />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▁▁▁▂▂\n Wait ...\"\n `)\n })\n\n test('handles wide terminal width correctly', async () => {\n vi.mocked(useLayout).mockReturnValue({twoThirds: 100, oneThird: 50, fullWidth: 150})\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Synchronizing data\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n Synchronizing data ...\"\n `)\n })\n\n test('handles wide terminal width correctly in no-color mode with pattern repetition', async () => {\n vi.mocked(useLayout).mockReturnValue({twoThirds: 90, oneThird: 45, fullWidth: 135})\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Analyzing dependencies\" noColor />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅▄▄▃▃▂▂▁▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅▄▄▃▃▂▂▁▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅▄▄▃▃▂▂▁\n Analyzing dependencies ...\"\n `)\n })\n\n test('renders correctly with empty title', async () => {\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n ...\"\n `)\n })\n\n test('noColor prop overrides shouldDisplayColors when both would show colors', async () => {\n vi.mocked(shouldDisplayColors).mockReturnValue(true)\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Testing override\" noColor />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅▄▄▃▃▂▂▁▁▁▁▂▂▃▃▄▄▅▅▆▆▇▇██▇▇▆▆▅▅\n Testing override ...\"\n `)\n })\n\n test('renders consistently with same props', async () => {\n const props = {title: 'Consistent test', noColor: false}\n const {lastFrame: frame1} = renderWithTTY(<LoadingBar {...props} />)\n const {lastFrame: frame2} = renderWithTTY(<LoadingBar {...props} />)\n\n expect(frame1()).toBe(frame2())\n })\n\n test('hides progress bar when noProgressBar is true', async () => {\n vi.mocked(shouldDisplayColors).mockReturnValue(true)\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"task 1\" noProgressBar />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\"task 1 ...\"`)\n })\n\n test('shows only static title text when output stream is not a TTY', async () => {\n // Default test Stdout has no isTTY property, simulating a non-TTY stream\n const {lastFrame} = render(<LoadingBar title=\"Installing dependencies\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\"Installing dependencies ...\"`)\n })\n\n test('shows animated progress bar when output stream is a TTY', async () => {\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"Uploading theme\" />)\n\n const frame = unstyled(lastFrame()!)\n expect(frame).toContain('▀')\n expect(frame).toContain('Uploading theme ...')\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"LoadingBar.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/LoadingBar.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {LoadingBar} from './LoadingBar.js'\nimport {Stdout} from '../../ui.js'\nimport {render} from '../../testing/ui.js'\nimport {shouldDisplayColors, unstyled} from '../../../../public/node/output.js'\nimport React, {act} from 'react'\nimport chalk from 'chalk'\n\nimport {beforeEach, describe, expect, test, vi} from 'vitest'\n\nvi.mock('../../../../public/node/output.js', async () => {\n const original: any = await vi.importActual('../../../../public/node/output.js')\n return {\n ...original,\n shouldDisplayColors: vi.fn(),\n }\n})\n\nbeforeEach(() => {\n vi.mocked(shouldDisplayColors).mockReturnValue(true)\n})\n\nfunction createTTYStdout() {\n const stdout = new Stdout({columns: 100}) as Stdout & {isTTY: boolean}\n stdout.isTTY = true\n return stdout\n}\n\nfunction renderWithTTY(element: React.ReactElement) {\n const stdout = createTTYStdout()\n const instance = render(element, {stdout})\n return {lastFrame: stdout.lastFrame, unmount: instance.unmount}\n}\n\ndescribe('LoadingBar', () => {\n test('renders the Shopify loading indicator', async () => {\n const {lastFrame, unmount} = renderWithTTY(<LoadingBar title=\"Loading content\" />)\n const frame = lastFrame()!\n\n expect(unstyled(frame)).toBe('S> Loading content ...')\n expect(frame).toContain('\\u001B[1m')\n expect(frame).toContain('\\u001B[3m')\n expect(frame).toContain(chalk.hex('#96BF48')('>'))\n\n unmount()\n })\n\n test('blinks the chevron without shifting the title', async () => {\n vi.useFakeTimers()\n const {lastFrame, unmount} = renderWithTTY(<LoadingBar title=\"Uploading theme\" />)\n\n try {\n await act(async () => {\n await vi.advanceTimersByTimeAsync(350)\n })\n\n expect(unstyled(lastFrame()!)).toBe('S Uploading theme ...')\n } finally {\n unmount()\n vi.useRealTimers()\n }\n })\n\n test('renders the chevron without color when noColor is true', async () => {\n const {lastFrame, unmount} = renderWithTTY(<LoadingBar title=\"Processing files\" noColor />)\n const frame = lastFrame()!\n\n expect(unstyled(frame)).toBe('S> Processing files ...')\n expect(frame).not.toContain(chalk.hex('#96BF48')('>'))\n\n unmount()\n })\n\n test('renders the chevron without color when colors are disabled', async () => {\n vi.mocked(shouldDisplayColors).mockReturnValue(false)\n const {lastFrame, unmount} = renderWithTTY(<LoadingBar title=\"Downloading packages\" />)\n const frame = lastFrame()!\n\n expect(unstyled(frame)).toBe('S> Downloading packages ...')\n expect(frame).not.toContain(chalk.hex('#96BF48')('>'))\n\n unmount()\n })\n\n test('renders correctly with an empty title', async () => {\n const {lastFrame, unmount} = renderWithTTY(<LoadingBar title=\"\" />)\n\n expect(unstyled(lastFrame()!)).toBe('S> ...')\n\n unmount()\n })\n\n test('hides the loading indicator when noProgressBar is true', async () => {\n const {lastFrame} = renderWithTTY(<LoadingBar title=\"task 1\" noProgressBar />)\n\n expect(unstyled(lastFrame()!)).toBe('task 1 ...')\n })\n\n test('shows only static title text when output stream is not a TTY', async () => {\n const {lastFrame} = render(<LoadingBar title=\"Installing dependencies\" />)\n\n expect(unstyled(lastFrame()!)).toBe('Installing dependencies ...')\n })\n})\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { shouldDisplayColors } from '../../../../public/node/output.js';
|
|
2
|
+
import React, { useLayoutEffect, useState } from 'react';
|
|
3
|
+
import { Text } from 'ink';
|
|
4
|
+
const SHOPIFY_GREEN = '#96BF48';
|
|
5
|
+
const CHEVRON_BLINK_INTERVAL_MS = 350;
|
|
6
|
+
const LoadingIndicator = ({ title, noColor = !shouldDisplayColors() }) => {
|
|
7
|
+
const [isChevronVisible, setIsChevronVisible] = useState(true);
|
|
8
|
+
useLayoutEffect(() => {
|
|
9
|
+
const interval = setInterval(() => {
|
|
10
|
+
setIsChevronVisible((isVisible) => !isVisible);
|
|
11
|
+
}, CHEVRON_BLINK_INTERVAL_MS);
|
|
12
|
+
return () => {
|
|
13
|
+
clearInterval(interval);
|
|
14
|
+
};
|
|
15
|
+
}, []);
|
|
16
|
+
return (React.createElement(Text, null,
|
|
17
|
+
React.createElement(Text, { bold: true, italic: true }, "S"),
|
|
18
|
+
React.createElement(Text, { bold: true, color: noColor ? undefined : SHOPIFY_GREEN }, isChevronVisible ? '>' : ' '),
|
|
19
|
+
` ${title} ...`));
|
|
20
|
+
};
|
|
21
|
+
export { LoadingIndicator };
|
|
22
|
+
//# sourceMappingURL=LoadingIndicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoadingIndicator.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/LoadingIndicator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAC,MAAM,mCAAmC,CAAA;AACrE,OAAO,KAAK,EAAE,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAA;AACtD,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AAExB,MAAM,aAAa,GAAG,SAAS,CAAA;AAC/B,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAOrC,MAAM,gBAAgB,GAAG,CAAC,EAAC,KAAK,EAAE,OAAO,GAAG,CAAC,mBAAmB,EAAE,EAAwB,EAAE,EAAE;IAC5F,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAE9D,eAAe,CAAC,GAAG,EAAE;QACnB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,mBAAmB,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAA;QAChD,CAAC,EAAE,yBAAyB,CAAC,CAAA;QAE7B,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,QAAQ,CAAC,CAAA;QACzB,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,oBAAC,IAAI;QACH,oBAAC,IAAI,IAAC,IAAI,QAAC,MAAM,cAEV;QACP,oBAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,IAClD,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CACxB;QACN,IAAI,KAAK,MAAM,CACX,CACR,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,gBAAgB,EAAC,CAAA","sourcesContent":["import {shouldDisplayColors} from '../../../../public/node/output.js'\nimport React, {useLayoutEffect, useState} from 'react'\nimport {Text} from 'ink'\n\nconst SHOPIFY_GREEN = '#96BF48'\nconst CHEVRON_BLINK_INTERVAL_MS = 350\n\ninterface LoadingIndicatorProps {\n title: string\n noColor?: boolean\n}\n\nconst LoadingIndicator = ({title, noColor = !shouldDisplayColors()}: LoadingIndicatorProps) => {\n const [isChevronVisible, setIsChevronVisible] = useState(true)\n\n useLayoutEffect(() => {\n const interval = setInterval(() => {\n setIsChevronVisible((isVisible) => !isVisible)\n }, CHEVRON_BLINK_INTERVAL_MS)\n\n return () => {\n clearInterval(interval)\n }\n }, [])\n\n return (\n <Text>\n <Text bold italic>\n S\n </Text>\n <Text bold color={noColor ? undefined : SHOPIFY_GREEN}>\n {isChevronVisible ? '>' : ' '}\n </Text>\n {` ${title} ...`}\n </Text>\n )\n}\n\nexport {LoadingIndicator}\n"]}
|
|
@@ -11,5 +11,13 @@ export interface TableProps<T extends ScalarDict> {
|
|
|
11
11
|
rows: T[];
|
|
12
12
|
columns: TableColumn<T>;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* The width the table needs to show every cell on one line: the widest value or header of each column, plus the
|
|
16
|
+
* gap between columns.
|
|
17
|
+
*
|
|
18
|
+
* @param props - The table's rows and columns.
|
|
19
|
+
* @returns The width in characters.
|
|
20
|
+
*/
|
|
21
|
+
export declare function tableWidth<T extends ScalarDict>(props: TableProps<T>): number;
|
|
14
22
|
declare function Table<T extends ScalarDict>({ rows, columns: columnsConfiguration }: TableProps<T>): React.JSX.Element;
|
|
15
23
|
export { Table };
|
|
@@ -2,8 +2,9 @@ import { Row } from './Row.js';
|
|
|
2
2
|
import { unstyled } from '../../../../../public/node/output.js';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { Box } from 'ink';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const COLUMN_GAP = 2;
|
|
6
|
+
function tableColumns({ rows, columns: columnsConfiguration }) {
|
|
7
|
+
return Object.entries(columnsConfiguration).map(([key, { header, color }]) => {
|
|
7
8
|
const headerWidth = String(header ?? key).length;
|
|
8
9
|
const columnWidths = rows.map((row) => {
|
|
9
10
|
const value = row[key];
|
|
@@ -18,6 +19,21 @@ function Table({ rows, columns: columnsConfiguration }) {
|
|
|
18
19
|
color,
|
|
19
20
|
};
|
|
20
21
|
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The width the table needs to show every cell on one line: the widest value or header of each column, plus the
|
|
25
|
+
* gap between columns.
|
|
26
|
+
*
|
|
27
|
+
* @param props - The table's rows and columns.
|
|
28
|
+
* @returns The width in characters.
|
|
29
|
+
*/
|
|
30
|
+
export function tableWidth(props) {
|
|
31
|
+
const columns = tableColumns(props);
|
|
32
|
+
const gaps = Math.max(columns.length - 1, 0) * COLUMN_GAP;
|
|
33
|
+
return columns.reduce((width, column) => width + column.width, gaps);
|
|
34
|
+
}
|
|
35
|
+
function Table({ rows, columns: columnsConfiguration }) {
|
|
36
|
+
const columns = tableColumns({ rows, columns: columnsConfiguration });
|
|
21
37
|
const headings = Object.entries(columnsConfiguration).reduce((headings, [column, { header }]) => ({ ...headings, [column]: header ?? column }), {});
|
|
22
38
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
23
39
|
React.createElement(Row, { rowKey: "heading", fillerChar: " ", columns: columns, data: headings, ignoreColumnColor: true }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../../../../src/private/node/ui/components/Table/Table.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../../../../src/private/node/ui/components/Table/Table.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Row} from './Row.js'\nimport ScalarDict from './ScalarDict.js'\nimport {Column} from './Column.js'\nimport {unstyled} from '../../../../../public/node/output.js'\nimport React from 'react'\nimport {Box} from 'ink'\nimport {ForegroundColor} from 'chalk'\n\nexport type TableColumn<T> = {\n [column in keyof T]: {header?: string; color?: ForegroundColor | 'dim'}\n}\n\nexport interface TableProps<T extends ScalarDict> {\n rows: T[]\n columns: TableColumn<T>\n}\n\nconst COLUMN_GAP = 2\n\nfunction tableColumns<T extends ScalarDict>({rows, columns: columnsConfiguration}: TableProps<T>): Column<T>[] {\n return Object.entries(columnsConfiguration).map(([key, {header, color}]) => {\n const headerWidth = String(header ?? key).length\n const columnWidths = rows.map((row) => {\n const value = row[key]\n\n if (value === undefined || value === null) {\n return 0\n }\n\n return unstyled(String(value)).length\n })\n\n return {\n name: key,\n width: Math.max(...columnWidths, headerWidth),\n color,\n }\n })\n}\n\n/**\n * The width the table needs to show every cell on one line: the widest value or header of each column, plus the\n * gap between columns.\n *\n * @param props - The table's rows and columns.\n * @returns The width in characters.\n */\nexport function tableWidth<T extends ScalarDict>(props: TableProps<T>): number {\n const columns = tableColumns(props)\n const gaps = Math.max(columns.length - 1, 0) * COLUMN_GAP\n return columns.reduce((width, column) => width + column.width, gaps)\n}\n\nfunction Table<T extends ScalarDict>({rows, columns: columnsConfiguration}: TableProps<T>) {\n const columns = tableColumns({rows, columns: columnsConfiguration})\n const headings = Object.entries(columnsConfiguration).reduce(\n (headings, [column, {header}]) => ({...headings, [column]: header ?? column}),\n {},\n )\n\n return (\n <Box flexDirection=\"column\">\n <Row rowKey=\"heading\" fillerChar=\" \" columns={columns} data={headings} ignoreColumnColor />\n <Row rowKey=\"separator\" fillerChar=\"─\" columns={columns} data={{}} ignoreColumnColor />\n {rows.map((row, index) => {\n const key = `row-${index}`\n\n return (\n <Box flexDirection=\"column\" key={key}>\n <Row rowKey={`data-${key}`} fillerChar=\" \" columns={columns} data={row} />\n </Box>\n )\n })}\n </Box>\n )\n}\n\nexport {Table}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CLI_KIT_VERSION = "
|
|
1
|
+
export declare const CLI_KIT_VERSION = "5.0.1";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const CLI_KIT_VERSION = '
|
|
1
|
+
export const CLI_KIT_VERSION = '5.0.1';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/common/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/common/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '5.0.1'\n"]}
|
|
@@ -123,6 +123,19 @@ export async function fetchApiVersions(session, preferredBehaviour) {
|
|
|
123
123
|
const storeName = session.storeFqdn.replace('.myshopify.com', '');
|
|
124
124
|
throw new AbortError(outputContent `Looks like you don't have access to this dev store: (${outputToken.link(storeName, `https://${session.storeFqdn}`)})`, outputContent `If you're not the owner, create a dev store staff account for yourself`);
|
|
125
125
|
}
|
|
126
|
+
if (error instanceof ClientError && error.response.status === 401 && isThemeAccessSession(session)) {
|
|
127
|
+
throw new AbortError(`The Theme Access password was rejected for the store ${session.storeFqdn}.`, 'Theme Access passwords only work on the store they were generated for, and only with its permanent .myshopify.com domain.', [
|
|
128
|
+
'Check that the password was created in the Theme Access app on this store and has not been deleted.',
|
|
129
|
+
[
|
|
130
|
+
'Pass the permanent domain to',
|
|
131
|
+
{ command: '--store' },
|
|
132
|
+
{ char: '.' },
|
|
133
|
+
'It is the .myshopify.com domain listed in the Shopify admin under',
|
|
134
|
+
{ subdued: 'Settings > Domains' },
|
|
135
|
+
{ char: '.' },
|
|
136
|
+
],
|
|
137
|
+
]);
|
|
138
|
+
}
|
|
126
139
|
if (error instanceof ClientError && (error.response.status === 401 || error.response.status === 404)) {
|
|
127
140
|
throw new AbortError(`Error connecting to your store ${session.storeFqdn}: ${error.message} ${error.response.status} ${error.response.data}`);
|
|
128
141
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../src/public/node/api/admin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n graphqlRequest,\n graphqlRequestDoc,\n GraphQLResponseOptions,\n GraphQLVariables,\n UnauthorizedHandler,\n} from './graphql.js'\nimport {AdminSession} from '../session.js'\nimport {outputContent, outputToken} from '../output.js'\nimport {AbortError, BugError} from '../error.js'\nimport {\n restRequestBody,\n restRequestHeaders,\n restRequestUrl,\n isThemeAccessSession,\n} from '../../../private/node/api/rest.js'\nimport {isAbortedFetchError, isNetworkError} from '../../../private/node/api.js'\nimport {RequestModeInput, shopifyFetch} from '../http.js'\nimport {PublicApiVersions} from '../../../cli/api/graphql/admin/generated/public_api_versions.js'\nimport {themeKitAccessDomain} from '../../../private/node/constants.js'\nimport {serviceEnvironment} from '../../../private/node/context/service.js'\nimport {DevServerCore} from '../vendor/dev_server/index.js'\nimport {ClientError, Variables} from 'graphql-request'\n\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\nconst LatestApiVersionByFQDN = new Map<string, string>()\n\n/**\n * Executes a GraphQL query against the Admin API.\n *\n * @param query - GraphQL query to execute.\n * @param session - Shopify admin session including token and Store FQDN.\n * @param variables - GraphQL variables to pass to the query.\n * @param version - API version.\n * @returns The response of the query of generic type <T>.\n */\nexport async function adminRequest<T>(\n query: string,\n session: AdminSession,\n variables?: GraphQLVariables,\n version?: string,\n): Promise<T> {\n const api = 'Admin'\n const apiVersion = version ?? (await fetchLatestSupportedApiVersion(session))\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const url = adminUrl(storeDomain, apiVersion, session)\n return graphqlRequest({query, api, addedHeaders, url, token: session.token, variables})\n}\n\nexport interface AdminRequestOptions<TResult, TVariables extends Variables> {\n /** GraphQL query to execute. */\n query: TypedDocumentNode<TResult, TVariables>\n /** Shopify admin session including token and Store FQDN. */\n session: AdminSession\n /** GraphQL variables to pass to the query. */\n variables?: TVariables\n /** API version. */\n version?: string\n /** Control how API responses will be handled. */\n responseOptions?: GraphQLResponseOptions<TResult>\n /** Custom request behaviour for retries and timeouts. */\n preferredBehaviour?: RequestModeInput\n}\n\n/**\n * Executes a GraphQL query against the Admin API. Uses typed documents.\n *\n * @param options - Admin request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function adminRequestDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n const {query, session, variables, version, responseOptions, preferredBehaviour} = options\n\n let apiVersion = version ?? LatestApiVersionByFQDN.get(session.storeFqdn)\n apiVersion ??= await fetchLatestSupportedApiVersion(session, preferredBehaviour)\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const opts = {\n url: adminUrl(storeDomain, apiVersion, session),\n api: 'Admin',\n token: session.token,\n addedHeaders,\n }\n let unauthorizedHandler: UnauthorizedHandler | undefined\n if ('refresh' in session) {\n unauthorizedHandler = {type: 'token_refresh', handler: session.refresh as () => Promise<{token: string}>}\n }\n const result = graphqlRequestDoc<TResult, TVariables>({\n ...opts,\n query,\n variables,\n responseOptions,\n unauthorizedHandler,\n preferredBehaviour,\n })\n return result\n}\n\nfunction themeAccessHeaders(session: AdminSession): Record<string, string> {\n return isThemeAccessSession(session)\n ? {'X-Shopify-Shop': session.storeFqdn, 'X-Shopify-Access-Token': session.token}\n : {}\n}\n\n/**\n * GraphQL query to retrieve the latest supported API version.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - The latest supported API version.\n */\nasync function fetchLatestSupportedApiVersion(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string> {\n const apiVersions = await supportedApiVersions(session, preferredBehaviour)\n\n const latest = apiVersions.reverse()[0]!\n LatestApiVersionByFQDN.set(session.storeFqdn, latest)\n return latest\n}\n\n/**\n * GraphQL query to retrieve all supported API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported API versions.\n */\nexport async function supportedApiVersions(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string[]> {\n const apiVersions = await fetchApiVersions(session, preferredBehaviour)\n return apiVersions\n .filter((item) => item.supported)\n .map((item) => item.handle)\n .sort()\n}\n\n/**\n * GraphQL query to retrieve all API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported and unsupported API versions.\n */\nexport async function fetchApiVersions(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<ApiVersion[]> {\n try {\n const response = await adminRequestDoc({\n query: PublicApiVersions,\n session,\n variables: {},\n version: 'unstable',\n responseOptions: {handleErrors: false},\n preferredBehaviour,\n })\n return response.publicApiVersions\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 403) {\n const storeName = session.storeFqdn.replace('.myshopify.com', '')\n throw new AbortError(\n outputContent`Looks like you don't have access to this dev store: (${outputToken.link(\n storeName,\n `https://${session.storeFqdn}`,\n )})`,\n outputContent`If you're not the owner, create a dev store staff account for yourself`,\n )\n }\n if (error instanceof ClientError && (error.response.status === 401 || error.response.status === 404)) {\n throw new AbortError(\n `Error connecting to your store ${session.storeFqdn}: ${error.message} ${error.response.status} ${error.response.data}`,\n )\n }\n\n // HTTP 402 means the shop is frozen, paused, or closed. That is a store state the user can\n // fix, not a CLI bug, so it must not reach the BugError below.\n if (error instanceof ClientError && error.response.status === 402) {\n throw new AbortError(\n `The store ${session.storeFqdn} is currently unavailable.`,\n 'This usually means the store is frozen, paused, or closed. Check the store in the Shopify admin and try again once it is reactivated.',\n )\n }\n\n // HTTP 5xx is a Shopify-side failure. This query takes no user input, so the user's command\n // cannot have caused it. `isExpectedApiError` covers 502/503/504, but only for raw errors, so\n // it never sees one we have already wrapped in a BugError.\n if (error instanceof ClientError && error.response.status >= 500) {\n throw new AbortError(\n `The Admin API for ${session.storeFqdn} returned a server error (HTTP ${error.response.status}).`,\n 'This is a problem on the Shopify side, not with your command. Wait a moment and try again.',\n )\n }\n\n // A cancelled request is neither a store-state failure nor a CLI bug. Checked before\n // `isNetworkError` so the message says the request was aborted instead of blaming the\n // user's connection.\n if (isAbortedFetchError(error)) {\n throw new AbortError(\n `Request to ${session.storeFqdn} was aborted before it completed.`,\n 'The request was cancelled or timed out before the store responded. Try running the command again.',\n )\n }\n\n // Check for network-level errors (connection issues, timeouts, DNS failures, TLS/certificate errors, etc.)\n // All network errors should be treated as user-facing errors, not CLI bugs\n // Note: Some of these may have been retried already by lower-level retry logic\n if (isNetworkError(error)) {\n throw new AbortError(\n `Network error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n 'Check your internet connection and try again.',\n )\n }\n\n // Unknown errors are likely bugs in the CLI\n throw new BugError(\n `Unknown error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n}\n\n/**\n * Returns the Admin API URL for the given store and version.\n *\n * @param store - Store FQDN.\n * @param version - API version.\n * @param session - User session.\n * @returns - Admin API URL.\n */\nexport function adminUrl(store: string, version: string | undefined, session?: AdminSession): string {\n const realVersion = version ?? 'unstable'\n\n const url =\n session && isThemeAccessSession(session)\n ? `https://${themeKitAccessDomain}/cli/admin/api/${realVersion}/graphql.json`\n : `https://${store}/admin/api/${realVersion}/graphql.json`\n return url\n}\n\ninterface ApiVersion {\n handle: string\n supported: boolean\n}\n\n/**\n * Executes a REST request against the Admin API.\n *\n * @param method - Request's HTTP method.\n * @param path - Path of the REST resource.\n * @param session - Shopify Admin session including token and Store FQDN.\n * @param requestBody - Request body of including REST resource specific parameters.\n * @param searchParams - Search params, appended to the URL.\n * @param apiVersion - Admin API version.\n * @returns - The {@link RestResponse}.\n */\nexport async function restRequest<T>(\n method: string,\n path: string,\n session: AdminSession,\n requestBody?: T,\n searchParams: Record<string, string> = {},\n apiVersion = 'unstable',\n): Promise<RestResponse> {\n const url = restRequestUrl(session, apiVersion, path, searchParams)\n const body = restRequestBody<T>(requestBody)\n\n const headers = restRequestHeaders(session)\n const response = await shopifyFetch(url, {\n headers,\n method,\n body,\n })\n\n const json = await response.json().catch(() => ({}))\n\n return {\n json,\n status: response.status,\n headers: response.headers.raw(),\n }\n}\n\n/**\n * Respose of a REST request.\n */\nexport interface RestResponse {\n /**\n * REST JSON respose.\n */\n // Using `any` to avoid introducing extra DTO layers.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n json: any\n\n /**\n * HTTP response status.\n */\n status: number\n\n /**\n * HTTP response headers.\n */\n headers: Record<string, string[]>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../src/public/node/api/admin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n graphqlRequest,\n graphqlRequestDoc,\n GraphQLResponseOptions,\n GraphQLVariables,\n UnauthorizedHandler,\n} from './graphql.js'\nimport {AdminSession} from '../session.js'\nimport {outputContent, outputToken} from '../output.js'\nimport {AbortError, BugError} from '../error.js'\nimport {\n restRequestBody,\n restRequestHeaders,\n restRequestUrl,\n isThemeAccessSession,\n} from '../../../private/node/api/rest.js'\nimport {isAbortedFetchError, isNetworkError} from '../../../private/node/api.js'\nimport {RequestModeInput, shopifyFetch} from '../http.js'\nimport {PublicApiVersions} from '../../../cli/api/graphql/admin/generated/public_api_versions.js'\nimport {themeKitAccessDomain} from '../../../private/node/constants.js'\nimport {serviceEnvironment} from '../../../private/node/context/service.js'\nimport {DevServerCore} from '../vendor/dev_server/index.js'\nimport {ClientError, Variables} from 'graphql-request'\n\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\nconst LatestApiVersionByFQDN = new Map<string, string>()\n\n/**\n * Executes a GraphQL query against the Admin API.\n *\n * @param query - GraphQL query to execute.\n * @param session - Shopify admin session including token and Store FQDN.\n * @param variables - GraphQL variables to pass to the query.\n * @param version - API version.\n * @returns The response of the query of generic type <T>.\n */\nexport async function adminRequest<T>(\n query: string,\n session: AdminSession,\n variables?: GraphQLVariables,\n version?: string,\n): Promise<T> {\n const api = 'Admin'\n const apiVersion = version ?? (await fetchLatestSupportedApiVersion(session))\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const url = adminUrl(storeDomain, apiVersion, session)\n return graphqlRequest({query, api, addedHeaders, url, token: session.token, variables})\n}\n\nexport interface AdminRequestOptions<TResult, TVariables extends Variables> {\n /** GraphQL query to execute. */\n query: TypedDocumentNode<TResult, TVariables>\n /** Shopify admin session including token and Store FQDN. */\n session: AdminSession\n /** GraphQL variables to pass to the query. */\n variables?: TVariables\n /** API version. */\n version?: string\n /** Control how API responses will be handled. */\n responseOptions?: GraphQLResponseOptions<TResult>\n /** Custom request behaviour for retries and timeouts. */\n preferredBehaviour?: RequestModeInput\n}\n\n/**\n * Executes a GraphQL query against the Admin API. Uses typed documents.\n *\n * @param options - Admin request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function adminRequestDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n const {query, session, variables, version, responseOptions, preferredBehaviour} = options\n\n let apiVersion = version ?? LatestApiVersionByFQDN.get(session.storeFqdn)\n apiVersion ??= await fetchLatestSupportedApiVersion(session, preferredBehaviour)\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const opts = {\n url: adminUrl(storeDomain, apiVersion, session),\n api: 'Admin',\n token: session.token,\n addedHeaders,\n }\n let unauthorizedHandler: UnauthorizedHandler | undefined\n if ('refresh' in session) {\n unauthorizedHandler = {type: 'token_refresh', handler: session.refresh as () => Promise<{token: string}>}\n }\n const result = graphqlRequestDoc<TResult, TVariables>({\n ...opts,\n query,\n variables,\n responseOptions,\n unauthorizedHandler,\n preferredBehaviour,\n })\n return result\n}\n\nfunction themeAccessHeaders(session: AdminSession): Record<string, string> {\n return isThemeAccessSession(session)\n ? {'X-Shopify-Shop': session.storeFqdn, 'X-Shopify-Access-Token': session.token}\n : {}\n}\n\n/**\n * GraphQL query to retrieve the latest supported API version.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - The latest supported API version.\n */\nasync function fetchLatestSupportedApiVersion(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string> {\n const apiVersions = await supportedApiVersions(session, preferredBehaviour)\n\n const latest = apiVersions.reverse()[0]!\n LatestApiVersionByFQDN.set(session.storeFqdn, latest)\n return latest\n}\n\n/**\n * GraphQL query to retrieve all supported API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported API versions.\n */\nexport async function supportedApiVersions(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string[]> {\n const apiVersions = await fetchApiVersions(session, preferredBehaviour)\n return apiVersions\n .filter((item) => item.supported)\n .map((item) => item.handle)\n .sort()\n}\n\n/**\n * GraphQL query to retrieve all API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported and unsupported API versions.\n */\nexport async function fetchApiVersions(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<ApiVersion[]> {\n try {\n const response = await adminRequestDoc({\n query: PublicApiVersions,\n session,\n variables: {},\n version: 'unstable',\n responseOptions: {handleErrors: false},\n preferredBehaviour,\n })\n return response.publicApiVersions\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 403) {\n const storeName = session.storeFqdn.replace('.myshopify.com', '')\n throw new AbortError(\n outputContent`Looks like you don't have access to this dev store: (${outputToken.link(\n storeName,\n `https://${session.storeFqdn}`,\n )})`,\n outputContent`If you're not the owner, create a dev store staff account for yourself`,\n )\n }\n if (error instanceof ClientError && error.response.status === 401 && isThemeAccessSession(session)) {\n throw new AbortError(\n `The Theme Access password was rejected for the store ${session.storeFqdn}.`,\n 'Theme Access passwords only work on the store they were generated for, and only with its permanent .myshopify.com domain.',\n [\n 'Check that the password was created in the Theme Access app on this store and has not been deleted.',\n [\n 'Pass the permanent domain to',\n {command: '--store'},\n {char: '.'},\n 'It is the .myshopify.com domain listed in the Shopify admin under',\n {subdued: 'Settings > Domains'},\n {char: '.'},\n ],\n ],\n )\n }\n if (error instanceof ClientError && (error.response.status === 401 || error.response.status === 404)) {\n throw new AbortError(\n `Error connecting to your store ${session.storeFqdn}: ${error.message} ${error.response.status} ${error.response.data}`,\n )\n }\n\n // HTTP 402 means the shop is frozen, paused, or closed. That is a store state the user can\n // fix, not a CLI bug, so it must not reach the BugError below.\n if (error instanceof ClientError && error.response.status === 402) {\n throw new AbortError(\n `The store ${session.storeFqdn} is currently unavailable.`,\n 'This usually means the store is frozen, paused, or closed. Check the store in the Shopify admin and try again once it is reactivated.',\n )\n }\n\n // HTTP 5xx is a Shopify-side failure. This query takes no user input, so the user's command\n // cannot have caused it. `isExpectedApiError` covers 502/503/504, but only for raw errors, so\n // it never sees one we have already wrapped in a BugError.\n if (error instanceof ClientError && error.response.status >= 500) {\n throw new AbortError(\n `The Admin API for ${session.storeFqdn} returned a server error (HTTP ${error.response.status}).`,\n 'This is a problem on the Shopify side, not with your command. Wait a moment and try again.',\n )\n }\n\n // A cancelled request is neither a store-state failure nor a CLI bug. Checked before\n // `isNetworkError` so the message says the request was aborted instead of blaming the\n // user's connection.\n if (isAbortedFetchError(error)) {\n throw new AbortError(\n `Request to ${session.storeFqdn} was aborted before it completed.`,\n 'The request was cancelled or timed out before the store responded. Try running the command again.',\n )\n }\n\n // Check for network-level errors (connection issues, timeouts, DNS failures, TLS/certificate errors, etc.)\n // All network errors should be treated as user-facing errors, not CLI bugs\n // Note: Some of these may have been retried already by lower-level retry logic\n if (isNetworkError(error)) {\n throw new AbortError(\n `Network error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n 'Check your internet connection and try again.',\n )\n }\n\n // Unknown errors are likely bugs in the CLI\n throw new BugError(\n `Unknown error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n}\n\n/**\n * Returns the Admin API URL for the given store and version.\n *\n * @param store - Store FQDN.\n * @param version - API version.\n * @param session - User session.\n * @returns - Admin API URL.\n */\nexport function adminUrl(store: string, version: string | undefined, session?: AdminSession): string {\n const realVersion = version ?? 'unstable'\n\n const url =\n session && isThemeAccessSession(session)\n ? `https://${themeKitAccessDomain}/cli/admin/api/${realVersion}/graphql.json`\n : `https://${store}/admin/api/${realVersion}/graphql.json`\n return url\n}\n\ninterface ApiVersion {\n handle: string\n supported: boolean\n}\n\n/**\n * Executes a REST request against the Admin API.\n *\n * @param method - Request's HTTP method.\n * @param path - Path of the REST resource.\n * @param session - Shopify Admin session including token and Store FQDN.\n * @param requestBody - Request body of including REST resource specific parameters.\n * @param searchParams - Search params, appended to the URL.\n * @param apiVersion - Admin API version.\n * @returns - The {@link RestResponse}.\n */\nexport async function restRequest<T>(\n method: string,\n path: string,\n session: AdminSession,\n requestBody?: T,\n searchParams: Record<string, string> = {},\n apiVersion = 'unstable',\n): Promise<RestResponse> {\n const url = restRequestUrl(session, apiVersion, path, searchParams)\n const body = restRequestBody<T>(requestBody)\n\n const headers = restRequestHeaders(session)\n const response = await shopifyFetch(url, {\n headers,\n method,\n body,\n })\n\n const json = await response.json().catch(() => ({}))\n\n return {\n json,\n status: response.status,\n headers: response.headers.raw(),\n }\n}\n\n/**\n * Respose of a REST request.\n */\nexport interface RestResponse {\n /**\n * REST JSON respose.\n */\n // Using `any` to avoid introducing extra DTO layers.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n json: any\n\n /**\n * HTTP response status.\n */\n status: number\n\n /**\n * HTTP response headers.\n */\n headers: Record<string, string[]>\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { debugLogRequestInfo, errorHandler } from '../../../private/node/api/gra
|
|
|
3
3
|
import { addPublicMetadata, runWithTimer } from '../metadata.js';
|
|
4
4
|
import { retryAwareRequest } from '../../../private/node/api.js';
|
|
5
5
|
import { requestIdsCollection } from '../../../private/node/request-ids.js';
|
|
6
|
-
import { nonRandomUUID } from '../crypto.js';
|
|
6
|
+
import { nonRandomUUID, sha256 } from '../crypto.js';
|
|
7
7
|
import { cacheRetrieveOrRepopulate, timeIntervalToMilliseconds, } from '../../../private/node/conf-store.js';
|
|
8
8
|
import { abortSignalFromRequestBehaviour, requestMode } from '../http.js';
|
|
9
9
|
import { CLI_KIT_VERSION } from '../../common/version.js';
|
|
@@ -95,7 +95,16 @@ async function performGraphQLRequest(options) {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
: undefined;
|
|
98
|
-
const
|
|
98
|
+
const handleErrors = responseOptions?.handleErrors !== false;
|
|
99
|
+
const request = () => retryAwareRequest({ request: rawGraphQLRequest, url, ...behaviour }, handleErrors ? errorHandler(api) : undefined);
|
|
100
|
+
// `retryAwareRequest` hands a 401 back raw so the token can be refreshed and the request repeated. Once that is
|
|
101
|
+
// settled, the error goes through the same handler as every other failed response: a raw graphql-request error
|
|
102
|
+
// carries the whole request, query text included, and would otherwise reach the user as a CLI bug.
|
|
103
|
+
const unauthorizedError = (error) => {
|
|
104
|
+
if (!handleErrors || !(error instanceof ClientError) || error.response.status !== 401)
|
|
105
|
+
return error;
|
|
106
|
+
return errorHandler(api)(error, requestIdFromClientError(error));
|
|
107
|
+
};
|
|
99
108
|
const executeWithTimer = () => runWithTimer('cmd_all_timing_network_ms')(async () => {
|
|
100
109
|
let response;
|
|
101
110
|
try {
|
|
@@ -104,14 +113,19 @@ async function performGraphQLRequest(options) {
|
|
|
104
113
|
catch (error) {
|
|
105
114
|
if (error instanceof ClientError && error.response.status === 401 && tokenRefreshUnauthorizedHandlerFunction) {
|
|
106
115
|
if (await tokenRefreshUnauthorizedHandlerFunction()) {
|
|
107
|
-
|
|
116
|
+
try {
|
|
117
|
+
response = await request();
|
|
118
|
+
}
|
|
119
|
+
catch (retryError) {
|
|
120
|
+
throw unauthorizedError(retryError);
|
|
121
|
+
}
|
|
108
122
|
}
|
|
109
123
|
else {
|
|
110
|
-
throw error;
|
|
124
|
+
throw unauthorizedError(error);
|
|
111
125
|
}
|
|
112
126
|
}
|
|
113
127
|
else {
|
|
114
|
-
throw error;
|
|
128
|
+
throw unauthorizedError(error);
|
|
115
129
|
}
|
|
116
130
|
}
|
|
117
131
|
if (responseOptions?.onResponse) {
|
|
@@ -124,16 +138,33 @@ async function performGraphQLRequest(options) {
|
|
|
124
138
|
return executeWithTimer();
|
|
125
139
|
}
|
|
126
140
|
const { cacheTTL, cacheExtraKey, cacheStore } = cacheOptions;
|
|
127
|
-
// The cache key is a combination of the hashed query and variables,
|
|
141
|
+
// The cache key is a combination of the hashed query and variables, the hashed endpoint and token, and an optional
|
|
142
|
+
// extra key provided by the user. The endpoint and token keep one principal's cached response from being returned
|
|
143
|
+
// to another principal or another API; they are hashed so the raw token is never written to the cache.
|
|
128
144
|
const queryHash = nonRandomUUID(queryAsString);
|
|
129
145
|
const variablesHash = nonRandomUUID(JSON.stringify(variables ?? {}));
|
|
130
|
-
const
|
|
146
|
+
const principalHash = graphQLCachePrincipalHash(url, token);
|
|
147
|
+
const cacheKey = `q-${queryHash}-${variablesHash}-${CLI_KIT_VERSION}-${principalHash}-${cacheExtraKey ?? ''}`;
|
|
131
148
|
const result = await cacheRetrieveOrRepopulate(cacheKey, async () => {
|
|
132
149
|
const result = await executeWithTimer();
|
|
133
150
|
return JSON.stringify(result);
|
|
134
151
|
}, timeIntervalToMilliseconds(cacheTTL), cacheStore);
|
|
135
152
|
return JSON.parse(result);
|
|
136
153
|
}
|
|
154
|
+
function requestIdFromClientError(error) {
|
|
155
|
+
try {
|
|
156
|
+
// graphql-request types the response without headers, but it carries the fetch Response's headers.
|
|
157
|
+
const headers = error.response.headers;
|
|
158
|
+
return headers?.get?.('x-request-id') ?? undefined;
|
|
159
|
+
// eslint-disable-next-line no-catch-all/no-catch-all
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function graphQLCachePrincipalHash(url, token) {
|
|
166
|
+
return sha256(JSON.stringify([url, token ?? ''])).toString('hex');
|
|
167
|
+
}
|
|
137
168
|
async function logLastRequestIdFromResponse(response) {
|
|
138
169
|
try {
|
|
139
170
|
const requestId = response.headers.get('x-request-id');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/public/node/api/graphql.ts"],"names":[],"mappings":"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","sourcesContent":["import {buildHeaders, httpsAgent} from '../../../private/node/api/headers.js'\nimport {debugLogRequestInfo, errorHandler} from '../../../private/node/api/graphql.js'\nimport {addPublicMetadata, runWithTimer} from '../metadata.js'\nimport {retryAwareRequest} from '../../../private/node/api.js'\nimport {requestIdsCollection} from '../../../private/node/request-ids.js'\nimport {nonRandomUUID} from '../crypto.js'\nimport {\n cacheRetrieveOrRepopulate,\n ConfSchema,\n GraphQLRequestKey,\n TimeInterval,\n timeIntervalToMilliseconds,\n} from '../../../private/node/conf-store.js'\nimport {LocalStorage} from '../local-storage.js'\nimport {abortSignalFromRequestBehaviour, RequestBehaviour, requestMode, RequestModeInput} from '../http.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {sleep} from '../system.js'\nimport {outputContent, outputDebug} from '../output.js'\nimport {\n GraphQLClient,\n rawRequest,\n RequestDocument,\n resolveRequestDocument,\n Variables,\n ClientError,\n} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\n// to replace TVariable type when there graphql query has no variables\nexport type Exact<T extends Record<string, unknown>> = {[K in keyof T]: T[K]}\n\n// Using a more permissive type to allow generated GraphQL variable interfaces\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type GraphQLVariables = Record<string, any>\n\nexport type GraphQLResponse<T> = Awaited<ReturnType<typeof rawRequest<T>>>\n\nexport interface CacheOptions {\n cacheTTL: TimeInterval\n cacheExtraKey?: string\n cacheStore?: LocalStorage<ConfSchema>\n}\n\ninterface RefreshedTokenOnAuthorizedResponse {\n token?: string\n}\n\nexport type RefreshTokenOnAuthorizedResponse = Promise<RefreshedTokenOnAuthorizedResponse>\n\nexport interface UnauthorizedHandler {\n type: 'token_refresh'\n handler: () => RefreshTokenOnAuthorizedResponse\n}\n\ninterface GraphQLRequestBaseOptions<TResult> {\n api: string\n url: string\n token?: string\n addedHeaders?: Record<string, string>\n responseOptions?: GraphQLResponseOptions<TResult>\n cacheOptions?: CacheOptions\n preferredBehaviour?: RequestModeInput\n}\n\ntype PerformGraphQLRequestOptions<TResult> = GraphQLRequestBaseOptions<TResult> & {\n queryAsString: string\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\n autoRateLimitRestore?: boolean\n}\n\nexport type GraphQLRequestOptions<T> = GraphQLRequestBaseOptions<T> & {\n query: RequestDocument\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\n}\n\nexport type GraphQLRequestDocOptions<TResult, TVariables> = GraphQLRequestBaseOptions<TResult> & {\n query: TypedDocumentNode<TResult, TVariables> | TypedDocumentNode<TResult, Exact<Record<string, never>>>\n variables?: TVariables\n unauthorizedHandler?: UnauthorizedHandler\n autoRateLimitRestore?: boolean\n}\n\ninterface RunRawGraphQLRequestOptions<TResult> {\n client: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setAbortSignal: (signal: any) => void\n rawRequest: (query: string, variables?: Variables) => Promise<GraphQLResponse<TResult>>\n }\n behaviour: RequestBehaviour\n queryAsString: string\n variables?: Variables\n autoRateLimitRestore: boolean\n}\n\nexport interface GraphQLResponseOptions<T> {\n handleErrors?: boolean\n onResponse?: (response: GraphQLResponse<T>) => void\n}\n\nconst MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS = 0.3\n\nasync function createGraphQLClient({\n url,\n addedHeaders,\n token,\n}: {\n url: string\n token: string | undefined\n addedHeaders?: Record<string, string>\n}) {\n const headers = {\n ...addedHeaders,\n ...buildHeaders(token),\n }\n const clientOptions = {agent: await httpsAgent(), headers}\n\n return {\n client: new GraphQLClient(url, clientOptions),\n headers,\n }\n}\n\nasync function waitForRateLimitRestore(fullResponse: GraphQLResponse<unknown>) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cost = (fullResponse.extensions as any)?.cost\n const actualQueryCost = cost?.actualQueryCost\n const restoreRate = cost?.throttleStatus?.restoreRate\n if (actualQueryCost && typeof actualQueryCost === 'number' && restoreRate && typeof restoreRate === 'number') {\n const secondsToRestoreRate = actualQueryCost / restoreRate\n outputDebug(outputContent`Sleeping for ${secondsToRestoreRate.toString()} seconds to restore the rate limit.`)\n await sleep(Math.min(secondsToRestoreRate, MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS))\n }\n}\n\nasync function runSingleRawGraphQLRequest<TResult>(\n options: RunRawGraphQLRequestOptions<TResult>,\n): Promise<GraphQLResponse<TResult>> {\n const {client, behaviour, queryAsString, variables, autoRateLimitRestore} = options\n let fullResponse: GraphQLResponse<TResult>\n // there is a errorPolicy option which returns rather than throwing on errors, but we _do_ ultimately want to\n // throw.\n try {\n client.setAbortSignal(abortSignalFromRequestBehaviour(behaviour))\n fullResponse = await client.rawRequest(queryAsString, variables)\n await logLastRequestIdFromResponse(fullResponse)\n\n if (autoRateLimitRestore) {\n await waitForRateLimitRestore(fullResponse)\n }\n\n return fullResponse\n } catch (error) {\n if (error instanceof ClientError) {\n // error.response does have a headers property like a normal response, but it's not typed as such.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await logLastRequestIdFromResponse(error.response as any)\n }\n throw error\n }\n}\n\nasync function performGraphQLRequest<TResult>(options: PerformGraphQLRequestOptions<TResult>) {\n const {\n token,\n addedHeaders,\n queryAsString,\n variables,\n api,\n url,\n responseOptions,\n unauthorizedHandler,\n cacheOptions,\n autoRateLimitRestore,\n } = options\n const behaviour = requestMode(options.preferredBehaviour ?? 'default')\n\n let {headers, client} = await createGraphQLClient({url, addedHeaders, token})\n debugLogRequestInfo(api, queryAsString, url, variables, headers)\n\n const rawGraphQLRequest = async () => {\n return runSingleRawGraphQLRequest({\n client: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setAbortSignal: (signal: any) => {\n client.requestConfig.signal = signal\n },\n rawRequest: (query: string, variables?: Variables) => client.rawRequest<TResult>(query, variables),\n },\n behaviour,\n queryAsString,\n variables,\n autoRateLimitRestore: autoRateLimitRestore ?? false,\n })\n }\n\n const tokenRefreshHandler = unauthorizedHandler?.handler\n\n const tokenRefreshUnauthorizedHandlerFunction = tokenRefreshHandler\n ? async () => {\n const refreshTokenResult = await tokenRefreshHandler()\n if (refreshTokenResult.token) {\n const {client: newClient, headers: newHeaders} = await createGraphQLClient({\n url,\n addedHeaders,\n token: refreshTokenResult.token,\n })\n client = newClient\n headers = newHeaders\n return true\n } else {\n return false\n }\n }\n : undefined\n\n const request = () =>\n retryAwareRequest(\n {request: rawGraphQLRequest, url, ...behaviour},\n responseOptions?.handleErrors === false ? undefined : errorHandler(api),\n )\n\n const executeWithTimer = () =>\n runWithTimer('cmd_all_timing_network_ms')(async () => {\n let response\n try {\n response = await request()\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 401 && tokenRefreshUnauthorizedHandlerFunction) {\n if (await tokenRefreshUnauthorizedHandlerFunction()) {\n response = await request()\n } else {\n throw error\n }\n } else {\n throw error\n }\n }\n\n if (responseOptions?.onResponse) {\n responseOptions.onResponse(response)\n }\n return response.data\n })\n\n // If there is no cache config for this query, just execute it and return the result.\n if (cacheOptions === undefined) {\n return executeWithTimer()\n }\n\n const {cacheTTL, cacheExtraKey, cacheStore} = cacheOptions\n\n // The cache key is a combination of the hashed query and variables, with an optional extra key provided by the user.\n const queryHash = nonRandomUUID(queryAsString)\n const variablesHash = nonRandomUUID(JSON.stringify(variables ?? {}))\n const cacheKey: GraphQLRequestKey = `q-${queryHash}-${variablesHash}-${CLI_KIT_VERSION}-${cacheExtraKey ?? ''}`\n\n const result = await cacheRetrieveOrRepopulate(\n cacheKey,\n async () => {\n const result = await executeWithTimer()\n return JSON.stringify(result)\n },\n timeIntervalToMilliseconds(cacheTTL),\n cacheStore,\n )\n\n return JSON.parse(result) as TResult\n}\n\nasync function logLastRequestIdFromResponse(response: GraphQLResponse<unknown>) {\n try {\n const requestId = response.headers.get('x-request-id')\n requestIdsCollection.addRequestId(requestId)\n await addPublicMetadata(() => ({\n cmd_all_last_graphql_request_id: requestId ?? undefined,\n }))\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n // no problem if unable to get request ID.\n }\n}\n\n/**\n * Executes a GraphQL query to an endpoint.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <T>.\n */\nexport async function graphqlRequest<T>(options: GraphQLRequestOptions<T>): Promise<T> {\n return performGraphQLRequest<T>({\n ...options,\n queryAsString: options.query as string,\n })\n}\n\n/**\n * Executes a GraphQL query to an endpoint. Uses typed documents.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function graphqlRequestDoc<TResult, TVariables extends Variables>(\n options: GraphQLRequestDocOptions<TResult, TVariables>,\n): Promise<TResult> {\n return performGraphQLRequest<TResult>({\n ...options,\n queryAsString: resolveRequestDocument(options.query).query,\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/public/node/api/graphql.ts"],"names":[],"mappings":"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","sourcesContent":["import {buildHeaders, httpsAgent} from '../../../private/node/api/headers.js'\nimport {debugLogRequestInfo, errorHandler} from '../../../private/node/api/graphql.js'\nimport {addPublicMetadata, runWithTimer} from '../metadata.js'\nimport {retryAwareRequest} from '../../../private/node/api.js'\nimport {requestIdsCollection} from '../../../private/node/request-ids.js'\nimport {nonRandomUUID, sha256} from '../crypto.js'\nimport {\n cacheRetrieveOrRepopulate,\n ConfSchema,\n GraphQLRequestKey,\n TimeInterval,\n timeIntervalToMilliseconds,\n} from '../../../private/node/conf-store.js'\nimport {LocalStorage} from '../local-storage.js'\nimport {abortSignalFromRequestBehaviour, RequestBehaviour, requestMode, RequestModeInput} from '../http.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {sleep} from '../system.js'\nimport {outputContent, outputDebug} from '../output.js'\nimport {\n GraphQLClient,\n rawRequest,\n RequestDocument,\n resolveRequestDocument,\n Variables,\n ClientError,\n} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\n// to replace TVariable type when there graphql query has no variables\nexport type Exact<T extends Record<string, unknown>> = {[K in keyof T]: T[K]}\n\n// Using a more permissive type to allow generated GraphQL variable interfaces\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type GraphQLVariables = Record<string, any>\n\nexport type GraphQLResponse<T> = Awaited<ReturnType<typeof rawRequest<T>>>\n\nexport interface CacheOptions {\n cacheTTL: TimeInterval\n cacheExtraKey?: string\n cacheStore?: LocalStorage<ConfSchema>\n}\n\ninterface RefreshedTokenOnAuthorizedResponse {\n token?: string\n}\n\nexport type RefreshTokenOnAuthorizedResponse = Promise<RefreshedTokenOnAuthorizedResponse>\n\nexport interface UnauthorizedHandler {\n type: 'token_refresh'\n handler: () => RefreshTokenOnAuthorizedResponse\n}\n\ninterface GraphQLRequestBaseOptions<TResult> {\n api: string\n url: string\n token?: string\n addedHeaders?: Record<string, string>\n responseOptions?: GraphQLResponseOptions<TResult>\n cacheOptions?: CacheOptions\n preferredBehaviour?: RequestModeInput\n}\n\ntype PerformGraphQLRequestOptions<TResult> = GraphQLRequestBaseOptions<TResult> & {\n queryAsString: string\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\n autoRateLimitRestore?: boolean\n}\n\nexport type GraphQLRequestOptions<T> = GraphQLRequestBaseOptions<T> & {\n query: RequestDocument\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\n}\n\nexport type GraphQLRequestDocOptions<TResult, TVariables> = GraphQLRequestBaseOptions<TResult> & {\n query: TypedDocumentNode<TResult, TVariables> | TypedDocumentNode<TResult, Exact<Record<string, never>>>\n variables?: TVariables\n unauthorizedHandler?: UnauthorizedHandler\n autoRateLimitRestore?: boolean\n}\n\ninterface RunRawGraphQLRequestOptions<TResult> {\n client: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setAbortSignal: (signal: any) => void\n rawRequest: (query: string, variables?: Variables) => Promise<GraphQLResponse<TResult>>\n }\n behaviour: RequestBehaviour\n queryAsString: string\n variables?: Variables\n autoRateLimitRestore: boolean\n}\n\nexport interface GraphQLResponseOptions<T> {\n handleErrors?: boolean\n onResponse?: (response: GraphQLResponse<T>) => void\n}\n\nconst MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS = 0.3\n\nasync function createGraphQLClient({\n url,\n addedHeaders,\n token,\n}: {\n url: string\n token: string | undefined\n addedHeaders?: Record<string, string>\n}) {\n const headers = {\n ...addedHeaders,\n ...buildHeaders(token),\n }\n const clientOptions = {agent: await httpsAgent(), headers}\n\n return {\n client: new GraphQLClient(url, clientOptions),\n headers,\n }\n}\n\nasync function waitForRateLimitRestore(fullResponse: GraphQLResponse<unknown>) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cost = (fullResponse.extensions as any)?.cost\n const actualQueryCost = cost?.actualQueryCost\n const restoreRate = cost?.throttleStatus?.restoreRate\n if (actualQueryCost && typeof actualQueryCost === 'number' && restoreRate && typeof restoreRate === 'number') {\n const secondsToRestoreRate = actualQueryCost / restoreRate\n outputDebug(outputContent`Sleeping for ${secondsToRestoreRate.toString()} seconds to restore the rate limit.`)\n await sleep(Math.min(secondsToRestoreRate, MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS))\n }\n}\n\nasync function runSingleRawGraphQLRequest<TResult>(\n options: RunRawGraphQLRequestOptions<TResult>,\n): Promise<GraphQLResponse<TResult>> {\n const {client, behaviour, queryAsString, variables, autoRateLimitRestore} = options\n let fullResponse: GraphQLResponse<TResult>\n // there is a errorPolicy option which returns rather than throwing on errors, but we _do_ ultimately want to\n // throw.\n try {\n client.setAbortSignal(abortSignalFromRequestBehaviour(behaviour))\n fullResponse = await client.rawRequest(queryAsString, variables)\n await logLastRequestIdFromResponse(fullResponse)\n\n if (autoRateLimitRestore) {\n await waitForRateLimitRestore(fullResponse)\n }\n\n return fullResponse\n } catch (error) {\n if (error instanceof ClientError) {\n // error.response does have a headers property like a normal response, but it's not typed as such.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await logLastRequestIdFromResponse(error.response as any)\n }\n throw error\n }\n}\n\nasync function performGraphQLRequest<TResult>(options: PerformGraphQLRequestOptions<TResult>) {\n const {\n token,\n addedHeaders,\n queryAsString,\n variables,\n api,\n url,\n responseOptions,\n unauthorizedHandler,\n cacheOptions,\n autoRateLimitRestore,\n } = options\n const behaviour = requestMode(options.preferredBehaviour ?? 'default')\n\n let {headers, client} = await createGraphQLClient({url, addedHeaders, token})\n debugLogRequestInfo(api, queryAsString, url, variables, headers)\n\n const rawGraphQLRequest = async () => {\n return runSingleRawGraphQLRequest({\n client: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setAbortSignal: (signal: any) => {\n client.requestConfig.signal = signal\n },\n rawRequest: (query: string, variables?: Variables) => client.rawRequest<TResult>(query, variables),\n },\n behaviour,\n queryAsString,\n variables,\n autoRateLimitRestore: autoRateLimitRestore ?? false,\n })\n }\n\n const tokenRefreshHandler = unauthorizedHandler?.handler\n\n const tokenRefreshUnauthorizedHandlerFunction = tokenRefreshHandler\n ? async () => {\n const refreshTokenResult = await tokenRefreshHandler()\n if (refreshTokenResult.token) {\n const {client: newClient, headers: newHeaders} = await createGraphQLClient({\n url,\n addedHeaders,\n token: refreshTokenResult.token,\n })\n client = newClient\n headers = newHeaders\n return true\n } else {\n return false\n }\n }\n : undefined\n\n const handleErrors = responseOptions?.handleErrors !== false\n\n const request = () =>\n retryAwareRequest({request: rawGraphQLRequest, url, ...behaviour}, handleErrors ? errorHandler(api) : undefined)\n\n // `retryAwareRequest` hands a 401 back raw so the token can be refreshed and the request repeated. Once that is\n // settled, the error goes through the same handler as every other failed response: a raw graphql-request error\n // carries the whole request, query text included, and would otherwise reach the user as a CLI bug.\n const unauthorizedError = (error: unknown): unknown => {\n if (!handleErrors || !(error instanceof ClientError) || error.response.status !== 401) return error\n return errorHandler(api)(error, requestIdFromClientError(error))\n }\n\n const executeWithTimer = () =>\n runWithTimer('cmd_all_timing_network_ms')(async () => {\n let response\n try {\n response = await request()\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 401 && tokenRefreshUnauthorizedHandlerFunction) {\n if (await tokenRefreshUnauthorizedHandlerFunction()) {\n try {\n response = await request()\n } catch (retryError) {\n throw unauthorizedError(retryError)\n }\n } else {\n throw unauthorizedError(error)\n }\n } else {\n throw unauthorizedError(error)\n }\n }\n\n if (responseOptions?.onResponse) {\n responseOptions.onResponse(response)\n }\n return response.data\n })\n\n // If there is no cache config for this query, just execute it and return the result.\n if (cacheOptions === undefined) {\n return executeWithTimer()\n }\n\n const {cacheTTL, cacheExtraKey, cacheStore} = cacheOptions\n\n // The cache key is a combination of the hashed query and variables, the hashed endpoint and token, and an optional\n // extra key provided by the user. The endpoint and token keep one principal's cached response from being returned\n // to another principal or another API; they are hashed so the raw token is never written to the cache.\n const queryHash = nonRandomUUID(queryAsString)\n const variablesHash = nonRandomUUID(JSON.stringify(variables ?? {}))\n const principalHash = graphQLCachePrincipalHash(url, token)\n const cacheKey: GraphQLRequestKey = `q-${queryHash}-${variablesHash}-${CLI_KIT_VERSION}-${principalHash}-${\n cacheExtraKey ?? ''\n }`\n\n const result = await cacheRetrieveOrRepopulate(\n cacheKey,\n async () => {\n const result = await executeWithTimer()\n return JSON.stringify(result)\n },\n timeIntervalToMilliseconds(cacheTTL),\n cacheStore,\n )\n\n return JSON.parse(result) as TResult\n}\n\nfunction requestIdFromClientError(error: ClientError): string | undefined {\n try {\n // graphql-request types the response without headers, but it carries the fetch Response's headers.\n const headers = (error.response as {headers?: {get?: (name: string) => string | null}}).headers\n return headers?.get?.('x-request-id') ?? undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return undefined\n }\n}\n\nfunction graphQLCachePrincipalHash(url: string, token: string | undefined): string {\n return sha256(JSON.stringify([url, token ?? ''])).toString('hex')\n}\n\nasync function logLastRequestIdFromResponse(response: GraphQLResponse<unknown>) {\n try {\n const requestId = response.headers.get('x-request-id')\n requestIdsCollection.addRequestId(requestId)\n await addPublicMetadata(() => ({\n cmd_all_last_graphql_request_id: requestId ?? undefined,\n }))\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n // no problem if unable to get request ID.\n }\n}\n\n/**\n * Executes a GraphQL query to an endpoint.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <T>.\n */\nexport async function graphqlRequest<T>(options: GraphQLRequestOptions<T>): Promise<T> {\n return performGraphQLRequest<T>({\n ...options,\n queryAsString: options.query as string,\n })\n}\n\n/**\n * Executes a GraphQL query to an endpoint. Uses typed documents.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function graphqlRequestDoc<TResult, TVariables extends Variables>(\n options: GraphQLRequestDocOptions<TResult, TVariables>,\n): Promise<TResult> {\n return performGraphQLRequest<TResult>({\n ...options,\n queryAsString: resolveRequestDocument(options.query).query,\n })\n}\n"]}
|
|
@@ -26,11 +26,19 @@ export async function zip(options) {
|
|
|
26
26
|
return new Promise((resolve, reject) => {
|
|
27
27
|
const archive = archiver('zip');
|
|
28
28
|
const output = createWriteStream(outputZipPath);
|
|
29
|
+
let outputError;
|
|
30
|
+
output.on('error', (error) => {
|
|
31
|
+
outputError = error;
|
|
32
|
+
archive.abort();
|
|
33
|
+
});
|
|
29
34
|
output.on('close', () => {
|
|
30
|
-
|
|
35
|
+
if (outputError)
|
|
36
|
+
reject(outputError);
|
|
37
|
+
else
|
|
38
|
+
resolve();
|
|
31
39
|
});
|
|
32
40
|
archive.on('error', (error) => {
|
|
33
|
-
|
|
41
|
+
output.destroy(error);
|
|
34
42
|
});
|
|
35
43
|
archive.pipe(output);
|
|
36
44
|
const directoriesToAdd = new Set();
|
|
@@ -51,12 +59,11 @@ export async function zip(options) {
|
|
|
51
59
|
// Wait for all files to be read and added before finalizing
|
|
52
60
|
Promise.all(addFilesPromises)
|
|
53
61
|
.then(() => {
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
if (!output.destroyed)
|
|
63
|
+
return archive.finalize();
|
|
56
64
|
})
|
|
57
65
|
.catch((error) => {
|
|
58
|
-
|
|
59
|
-
reject(error);
|
|
66
|
+
output.destroy(error instanceof Error ? error : new Error(String(error)));
|
|
60
67
|
});
|
|
61
68
|
});
|
|
62
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiver.js","sourceRoot":"","sources":["../../../src/public/node/archiver.ts"],"names":[],"mappings":"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","sourcesContent":["import {outputDebug, outputContent, outputToken} from './output.js'\nimport {glob, removeFile} from './fs.js'\nimport {relativePath, joinPath, dirname} from './path.js'\nimport archiver from 'archiver'\nimport {createWriteStream, readFileSync, writeFileSync} from 'fs'\nimport {readFile} from 'fs/promises'\nimport {tmpdir} from 'os'\nimport {randomUUID} from 'crypto'\nimport {brotliCompressSync, constants as zlibConstants} from 'zlib'\n\ninterface ZipOptions {\n /**\n * The absolute path to the directory to be zipped.\n */\n inputDirectory: string\n\n /**\n * The absolute path to the output zip file.\n */\n outputZipPath: string\n\n /**\n * Pattern(s) to match when adding files to zip, uses glob expressions.\n */\n matchFilePattern?: string | string[]\n}\n\n/**\n * It zips a directory and by default normalizes the paths to be forward-slash.\n * Even with forward-slash paths, zip files should still be able to be opened on\n * Windows.\n *\n * @param options - ZipOptions.\n */\nexport async function zip(options: ZipOptions): Promise<void> {\n const {inputDirectory, outputZipPath, matchFilePattern = '**/*'} = options\n outputDebug(outputContent`Zipping ${outputToken.path(inputDirectory)} into ${outputToken.path(outputZipPath)}`)\n const pathsToZip = await glob(matchFilePattern, {\n cwd: inputDirectory,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n })\n\n return new Promise((resolve, reject) => {\n const archive = archiver('zip')\n\n const output = createWriteStream(outputZipPath)\n output.on('close', () => {\n resolve()\n })\n archive.on('error', (error) => {\n reject(error)\n })\n archive.pipe(output)\n\n const directoriesToAdd = new Set<string>()\n for (const filePath of pathsToZip) {\n const fileRelativePath = relativePath(inputDirectory, filePath)\n collectParentDirectories(fileRelativePath, directoriesToAdd)\n }\n\n const sortedDirs = Array.from(directoriesToAdd).sort((left, right) => left.localeCompare(right))\n for (const dir of sortedDirs) {\n const dirName = dir.endsWith('/') ? dir : `${dir}/`\n archive.append(Buffer.alloc(0), {name: dirName})\n }\n\n // Read all files immediately before adding to archive to prevent ENOENT errors\n // Using archive.file() causes lazy loading which fails if files are deleted before finalize()\n const addFilesPromises = pathsToZip.map(async (filePath) => {\n await archiveFile(inputDirectory, filePath, archive)\n })\n\n // Wait for all files to be read and added before finalizing\n Promise.all(addFilesPromises)\n .then(() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n archive.finalize()\n })\n .catch((error) => {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject(error)\n })\n })\n}\n\nfunction collectParentDirectories(fileRelativePath: string, accumulator: Set<string>): void {\n let currentDir = dirname(fileRelativePath)\n while (currentDir && currentDir !== '.' && currentDir !== '/') {\n accumulator.add(currentDir)\n const parent = dirname(currentDir)\n if (parent === currentDir) break\n currentDir = parent\n }\n}\n\nasync function archiveFile(inputDirectory: string, filePath: string, archive: archiver.Archiver): Promise<void> {\n const fileRelativePath = relativePath(inputDirectory, filePath)\n if (!filePath || !fileRelativePath) return\n\n // Read file content immediately to avoid race conditions\n const fileContent = await readFile(filePath)\n // Use append with Buffer instead of file() to avoid lazy file reading\n archive.append(fileContent, {name: fileRelativePath})\n}\n\nexport interface BrotliOptions {\n /**\n * The directory to compress.\n */\n inputDirectory: string\n\n /**\n * The path where the compressed file will be saved.\n */\n outputPath: string\n\n /**\n * An optional glob pattern to match files.\n */\n matchFilePattern?: string | string[]\n\n /**\n * Brotli compression level (0-11, default: 11).\n */\n level?: number\n}\n\n/**\n * Options for decompressing a Brotli compressed tar archive.\n */\nexport interface DecompressionOptions {\n /**\n * Path to the compressed file.\n */\n inputFile: string\n\n /**\n * Directory where files should be extracted.\n */\n outputDirectory: string\n}\n\n/**\n * It compresses a directory with Brotli.\n * First creates a tar archive to preserve directory structure,\n * then compresses it with Brotli.\n *\n * @param options - BrotliOptions.\n */\nexport async function brotliCompress(options: BrotliOptions): Promise<void> {\n const tempTarPath = joinPath(tmpdir(), `${randomUUID()}.tar`)\n\n try {\n // Create tar archive using archiver\n await new Promise<void>((resolve, reject) => {\n const archive = archiver('tar')\n const output = createWriteStream(tempTarPath)\n\n output.on('close', () => resolve())\n archive.on('error', (error) => reject(error))\n archive.pipe(output)\n\n glob(options.matchFilePattern ?? '**/*', {\n cwd: options.inputDirectory,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n })\n .then(async (pathsToZip) => {\n // Read all files immediately to prevent ENOENT errors during race conditions\n const addFilesPromises = pathsToZip.map(async (filePath) => {\n await archiveFile(options.inputDirectory, filePath, archive)\n })\n\n await Promise.all(addFilesPromises)\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n archive.finalize()\n })\n .catch((error) => {\n reject(error instanceof Error ? error : new Error(String(error)))\n })\n })\n\n const tarContent = readFileSync(tempTarPath)\n const compressed = brotliCompressSync(tarContent, {\n params: {\n [zlibConstants.BROTLI_PARAM_QUALITY]: 7,\n [zlibConstants.BROTLI_PARAM_MODE]: zlibConstants.BROTLI_MODE_GENERIC,\n },\n })\n\n writeFileSync(options.outputPath, compressed)\n } finally {\n try {\n await removeFile(tempTarPath)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n outputDebug(outputContent`Failed to clean up temporary file: ${outputToken.path(tempTarPath)}`)\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"archiver.js","sourceRoot":"","sources":["../../../src/public/node/archiver.ts"],"names":[],"mappings":"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","sourcesContent":["import {outputDebug, outputContent, outputToken} from './output.js'\nimport {glob, removeFile} from './fs.js'\nimport {relativePath, joinPath, dirname} from './path.js'\nimport archiver from 'archiver'\nimport {createWriteStream, readFileSync, writeFileSync} from 'fs'\nimport {readFile} from 'fs/promises'\nimport {tmpdir} from 'os'\nimport {randomUUID} from 'crypto'\nimport {brotliCompressSync, constants as zlibConstants} from 'zlib'\n\ninterface ZipOptions {\n /**\n * The absolute path to the directory to be zipped.\n */\n inputDirectory: string\n\n /**\n * The absolute path to the output zip file.\n */\n outputZipPath: string\n\n /**\n * Pattern(s) to match when adding files to zip, uses glob expressions.\n */\n matchFilePattern?: string | string[]\n}\n\n/**\n * It zips a directory and by default normalizes the paths to be forward-slash.\n * Even with forward-slash paths, zip files should still be able to be opened on\n * Windows.\n *\n * @param options - ZipOptions.\n */\nexport async function zip(options: ZipOptions): Promise<void> {\n const {inputDirectory, outputZipPath, matchFilePattern = '**/*'} = options\n outputDebug(outputContent`Zipping ${outputToken.path(inputDirectory)} into ${outputToken.path(outputZipPath)}`)\n const pathsToZip = await glob(matchFilePattern, {\n cwd: inputDirectory,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n })\n\n return new Promise((resolve, reject) => {\n const archive = archiver('zip')\n\n const output = createWriteStream(outputZipPath)\n let outputError: Error | undefined\n output.on('error', (error) => {\n outputError = error\n archive.abort()\n })\n output.on('close', () => {\n if (outputError) reject(outputError)\n else resolve()\n })\n archive.on('error', (error) => {\n output.destroy(error)\n })\n archive.pipe(output)\n\n const directoriesToAdd = new Set<string>()\n for (const filePath of pathsToZip) {\n const fileRelativePath = relativePath(inputDirectory, filePath)\n collectParentDirectories(fileRelativePath, directoriesToAdd)\n }\n\n const sortedDirs = Array.from(directoriesToAdd).sort((left, right) => left.localeCompare(right))\n for (const dir of sortedDirs) {\n const dirName = dir.endsWith('/') ? dir : `${dir}/`\n archive.append(Buffer.alloc(0), {name: dirName})\n }\n\n // Read all files immediately before adding to archive to prevent ENOENT errors\n // Using archive.file() causes lazy loading which fails if files are deleted before finalize()\n const addFilesPromises = pathsToZip.map(async (filePath) => {\n await archiveFile(inputDirectory, filePath, archive)\n })\n\n // Wait for all files to be read and added before finalizing\n Promise.all(addFilesPromises)\n .then(() => {\n if (!output.destroyed) return archive.finalize()\n })\n .catch((error) => {\n output.destroy(error instanceof Error ? error : new Error(String(error)))\n })\n })\n}\n\nfunction collectParentDirectories(fileRelativePath: string, accumulator: Set<string>): void {\n let currentDir = dirname(fileRelativePath)\n while (currentDir && currentDir !== '.' && currentDir !== '/') {\n accumulator.add(currentDir)\n const parent = dirname(currentDir)\n if (parent === currentDir) break\n currentDir = parent\n }\n}\n\nasync function archiveFile(inputDirectory: string, filePath: string, archive: archiver.Archiver): Promise<void> {\n const fileRelativePath = relativePath(inputDirectory, filePath)\n if (!filePath || !fileRelativePath) return\n\n // Read file content immediately to avoid race conditions\n const fileContent = await readFile(filePath)\n // Use append with Buffer instead of file() to avoid lazy file reading\n archive.append(fileContent, {name: fileRelativePath})\n}\n\nexport interface BrotliOptions {\n /**\n * The directory to compress.\n */\n inputDirectory: string\n\n /**\n * The path where the compressed file will be saved.\n */\n outputPath: string\n\n /**\n * An optional glob pattern to match files.\n */\n matchFilePattern?: string | string[]\n\n /**\n * Brotli compression level (0-11, default: 11).\n */\n level?: number\n}\n\n/**\n * Options for decompressing a Brotli compressed tar archive.\n */\nexport interface DecompressionOptions {\n /**\n * Path to the compressed file.\n */\n inputFile: string\n\n /**\n * Directory where files should be extracted.\n */\n outputDirectory: string\n}\n\n/**\n * It compresses a directory with Brotli.\n * First creates a tar archive to preserve directory structure,\n * then compresses it with Brotli.\n *\n * @param options - BrotliOptions.\n */\nexport async function brotliCompress(options: BrotliOptions): Promise<void> {\n const tempTarPath = joinPath(tmpdir(), `${randomUUID()}.tar`)\n\n try {\n // Create tar archive using archiver\n await new Promise<void>((resolve, reject) => {\n const archive = archiver('tar')\n const output = createWriteStream(tempTarPath)\n\n output.on('close', () => resolve())\n archive.on('error', (error) => reject(error))\n archive.pipe(output)\n\n glob(options.matchFilePattern ?? '**/*', {\n cwd: options.inputDirectory,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n })\n .then(async (pathsToZip) => {\n // Read all files immediately to prevent ENOENT errors during race conditions\n const addFilesPromises = pathsToZip.map(async (filePath) => {\n await archiveFile(options.inputDirectory, filePath, archive)\n })\n\n await Promise.all(addFilesPromises)\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n archive.finalize()\n })\n .catch((error) => {\n reject(error instanceof Error ? error : new Error(String(error)))\n })\n })\n\n const tarContent = readFileSync(tempTarPath)\n const compressed = brotliCompressSync(tarContent, {\n params: {\n [zlibConstants.BROTLI_PARAM_QUALITY]: 7,\n [zlibConstants.BROTLI_PARAM_MODE]: zlibConstants.BROTLI_MODE_GENERIC,\n },\n })\n\n writeFileSync(options.outputPath, compressed)\n } finally {\n try {\n await removeFile(tempTarPath)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n outputDebug(outputContent`Failed to clean up temporary file: ${outputToken.path(tempTarPath)}`)\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type JsonOutputSchema } from './json-output-schema.js';
|
|
2
|
+
import { JsonMap } from '../../private/common/json.js';
|
|
2
3
|
import { Command } from '@oclif/core';
|
|
3
4
|
import { OutputFlags, Input, ParserOutput, FlagInput, OutputArgs } from '@oclif/core/parser';
|
|
4
5
|
export type ArgOutput = OutputArgs<any>;
|
|
@@ -20,12 +21,14 @@ declare abstract class BaseCommand extends Command {
|
|
|
20
21
|
static descriptionWithoutMarkdown(): string | undefined;
|
|
21
22
|
static analyticsNameOverride(): string | undefined;
|
|
22
23
|
static analyticsStopCommand(): string | undefined;
|
|
24
|
+
private jsonOutputFromFlags;
|
|
23
25
|
catch(error: Error & {
|
|
24
26
|
skipOclifErrorHandling: boolean;
|
|
25
27
|
}): Promise<void>;
|
|
26
28
|
protected _run<T>(): Promise<T>;
|
|
27
29
|
protected init(): Promise<unknown>;
|
|
28
30
|
protected showNpmFlagWarning(): void;
|
|
31
|
+
protected showDeprecatedAutomationTokenVariableWarning(): Promise<void>;
|
|
29
32
|
protected exitWithTimestampWhenEnvVariablePresent(): void;
|
|
30
33
|
protected parse<TFlags extends FlagOutput & {
|
|
31
34
|
path?: string;
|
|
@@ -34,7 +37,10 @@ declare abstract class BaseCommand extends Command {
|
|
|
34
37
|
}, TGlobalFlags extends FlagOutput, TArgs extends ArgOutput>(options?: Input<TFlags, TGlobalFlags, TArgs>, argv?: string[]): Promise<ParserOutput<TFlags, TGlobalFlags, TArgs> & {
|
|
35
38
|
argv: string[];
|
|
36
39
|
}>;
|
|
40
|
+
protected runWithParsedOutput<T>(flags: FlagOutput, execute: () => T): T;
|
|
37
41
|
protected environmentsFilename(): string | undefined;
|
|
42
|
+
protected parseEnvironmentFlags<TFlags extends FlagOutput, TGlobalFlags extends FlagOutput, TArgs extends ArgOutput>(environment: JsonMap, options: Input<TFlags, TGlobalFlags, TArgs>, explicitFlags: FlagOutput): Promise<FlagOutput>;
|
|
43
|
+
protected validateNonTTYFlags(flags: FlagOutput): void;
|
|
38
44
|
protected failMissingNonTTYFlags(flags: FlagOutput, requiredFlags: string[]): void;
|
|
39
45
|
private failMissingNonTTYFlagRequirements;
|
|
40
46
|
private applicableNonTTYFlagRequirements;
|