@shopify/cli-hydrogen 0.0.0-nightly-20230110194301
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/LICENSE +8 -0
- package/README.md +63 -0
- package/dist/cli/commands/hydrogen/add/eslint.d.ts +11 -0
- package/dist/cli/commands/hydrogen/add/eslint.js +26 -0
- package/dist/cli/commands/hydrogen/add/eslint.js.map +1 -0
- package/dist/cli/commands/hydrogen/add/tailwind.d.ts +11 -0
- package/dist/cli/commands/hydrogen/add/tailwind.js +26 -0
- package/dist/cli/commands/hydrogen/add/tailwind.js.map +1 -0
- package/dist/cli/commands/hydrogen/build.d.ts +14 -0
- package/dist/cli/commands/hydrogen/build.js +49 -0
- package/dist/cli/commands/hydrogen/build.js.map +1 -0
- package/dist/cli/commands/hydrogen/deploy.d.ts +19 -0
- package/dist/cli/commands/hydrogen/deploy.js +58 -0
- package/dist/cli/commands/hydrogen/deploy.js.map +1 -0
- package/dist/cli/commands/hydrogen/dev.d.ts +13 -0
- package/dist/cli/commands/hydrogen/dev.js +31 -0
- package/dist/cli/commands/hydrogen/dev.js.map +1 -0
- package/dist/cli/commands/hydrogen/info.d.ts +12 -0
- package/dist/cli/commands/hydrogen/info.js +28 -0
- package/dist/cli/commands/hydrogen/info.js.map +1 -0
- package/dist/cli/commands/hydrogen/preview.d.ts +13 -0
- package/dist/cli/commands/hydrogen/preview.js +46 -0
- package/dist/cli/commands/hydrogen/preview.js.map +1 -0
- package/dist/cli/constants.d.ts +15 -0
- package/dist/cli/constants.js +16 -0
- package/dist/cli/constants.js.map +1 -0
- package/dist/cli/flags.d.ts +4 -0
- package/dist/cli/flags.js +16 -0
- package/dist/cli/flags.js.map +1 -0
- package/dist/cli/models/hydrogen.d.ts +22 -0
- package/dist/cli/models/hydrogen.js +82 -0
- package/dist/cli/models/hydrogen.js.map +1 -0
- package/dist/cli/prompts/git-init.d.ts +1 -0
- package/dist/cli/prompts/git-init.js +16 -0
- package/dist/cli/prompts/git-init.js.map +1 -0
- package/dist/cli/services/build/check-lockfile.d.ts +3 -0
- package/dist/cli/services/build/check-lockfile.js +80 -0
- package/dist/cli/services/build/check-lockfile.js.map +1 -0
- package/dist/cli/services/build.d.ts +14 -0
- package/dist/cli/services/build.js +44 -0
- package/dist/cli/services/build.js.map +1 -0
- package/dist/cli/services/deploy/config.d.ts +4 -0
- package/dist/cli/services/deploy/config.js +49 -0
- package/dist/cli/services/deploy/config.js.map +1 -0
- package/dist/cli/services/deploy/error.d.ts +4 -0
- package/dist/cli/services/deploy/error.js +11 -0
- package/dist/cli/services/deploy/error.js.map +1 -0
- package/dist/cli/services/deploy/graphql/create_deployment.d.ts +10 -0
- package/dist/cli/services/deploy/graphql/create_deployment.js +15 -0
- package/dist/cli/services/deploy/graphql/create_deployment.js.map +1 -0
- package/dist/cli/services/deploy/graphql/upload_deployment.d.ts +1 -0
- package/dist/cli/services/deploy/graphql/upload_deployment.js +16 -0
- package/dist/cli/services/deploy/graphql/upload_deployment.js.map +1 -0
- package/dist/cli/services/deploy/types.d.ts +37 -0
- package/dist/cli/services/deploy/types.js +2 -0
- package/dist/cli/services/deploy/types.js.map +1 -0
- package/dist/cli/services/deploy/upload.d.ts +5 -0
- package/dist/cli/services/deploy/upload.js +81 -0
- package/dist/cli/services/deploy/upload.js.map +1 -0
- package/dist/cli/services/deploy.d.ts +2 -0
- package/dist/cli/services/deploy.js +103 -0
- package/dist/cli/services/deploy.js.map +1 -0
- package/dist/cli/services/dev/check-version.d.ts +1 -0
- package/dist/cli/services/dev/check-version.js +30 -0
- package/dist/cli/services/dev/check-version.js.map +1 -0
- package/dist/cli/services/dev.d.ts +10 -0
- package/dist/cli/services/dev.js +37 -0
- package/dist/cli/services/dev.js.map +1 -0
- package/dist/cli/services/eslint.d.ts +8 -0
- package/dist/cli/services/eslint.js +74 -0
- package/dist/cli/services/eslint.js.map +1 -0
- package/dist/cli/services/info.d.ts +7 -0
- package/dist/cli/services/info.js +132 -0
- package/dist/cli/services/info.js.map +1 -0
- package/dist/cli/services/preview.d.ts +12 -0
- package/dist/cli/services/preview.js +63 -0
- package/dist/cli/services/preview.js.map +1 -0
- package/dist/cli/services/tailwind.d.ts +9 -0
- package/dist/cli/services/tailwind.js +103 -0
- package/dist/cli/services/tailwind.js.map +1 -0
- package/dist/cli/utilities/load-config.d.ts +5 -0
- package/dist/cli/utilities/load-config.js +6 -0
- package/dist/cli/utilities/load-config.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/oclif.manifest.json +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createDeployment, healthCheck, uploadDeployment } from './deploy/upload.js';
|
|
2
|
+
import { buildTaskList } from './build.js';
|
|
3
|
+
import { validateProject, fillDeployConfig } from './deploy/config.js';
|
|
4
|
+
import { environment, system, ui } from '@shopify/cli-kit';
|
|
5
|
+
const isUnitTest = environment.local.isUnitTest();
|
|
6
|
+
const backoffPolicy = [5, 10, 15, 30, 60];
|
|
7
|
+
export async function deployToOxygen(_config) {
|
|
8
|
+
await validateProject(_config);
|
|
9
|
+
/* eslint-disable require-atomic-updates */
|
|
10
|
+
const tasks = [
|
|
11
|
+
{
|
|
12
|
+
title: '📝 Getting deployment config',
|
|
13
|
+
task: async (ctx, task) => {
|
|
14
|
+
ctx.config = await fillDeployConfig(_config);
|
|
15
|
+
task.title = '📝 Deployment config parsed';
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: '💡 Initializing deployment',
|
|
20
|
+
task: async (ctx, task) => {
|
|
21
|
+
await shouldRetryOxygenCall(task, 'Could not create deployment on Oxygen.');
|
|
22
|
+
const { deploymentID, assetBaseURL } = await createDeployment(ctx.config);
|
|
23
|
+
ctx.assetBaseURL = assetBaseURL;
|
|
24
|
+
ctx.deploymentID = deploymentID;
|
|
25
|
+
task.title = '✨ Deployment initialized';
|
|
26
|
+
},
|
|
27
|
+
retry: backoffPolicy.length,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
title: '🛠 Building project',
|
|
31
|
+
task: async (ctx, task) => {
|
|
32
|
+
const subTasks = buildTaskList({
|
|
33
|
+
directory: ctx.config.path,
|
|
34
|
+
targets: {
|
|
35
|
+
client: true,
|
|
36
|
+
worker: '@shopify/hydrogen/platforms/worker',
|
|
37
|
+
node: false,
|
|
38
|
+
},
|
|
39
|
+
assetBaseURL: ctx.assetBaseURL,
|
|
40
|
+
});
|
|
41
|
+
return task.newListr(subTasks);
|
|
42
|
+
},
|
|
43
|
+
skip: (ctx) => ctx.config.pathToBuild,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: '🚀 Uploading deployment files',
|
|
47
|
+
task: async (ctx, task) => {
|
|
48
|
+
await shouldRetryOxygenCall(task, 'Uploading files to Oxygen failed.');
|
|
49
|
+
ctx.previewURL = await uploadDeployment(ctx.config, ctx.deploymentID);
|
|
50
|
+
task.output = `Preview URL: ${ctx.previewURL}`;
|
|
51
|
+
task.title = '🚀 Files uploaded';
|
|
52
|
+
},
|
|
53
|
+
options: {
|
|
54
|
+
bottomBar: Infinity,
|
|
55
|
+
persistentOutput: true,
|
|
56
|
+
},
|
|
57
|
+
retry: backoffPolicy.length,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
title: '📡 Checking deployment health',
|
|
61
|
+
task: async (ctx, task) => {
|
|
62
|
+
const retryCount = task.isRetrying()?.count;
|
|
63
|
+
if (retryCount === backoffPolicy.length) {
|
|
64
|
+
task.title =
|
|
65
|
+
"The deployment uploaded but hasn't become reachable within 2 minutes. Check the preview URL to see if deployment succeeded. If it didn't, then try again later.";
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (retryCount && !isUnitTest)
|
|
69
|
+
await system.sleep(backoffPolicy[retryCount - 1]);
|
|
70
|
+
await healthCheck(ctx.previewURL);
|
|
71
|
+
task.title = '✅ Deployed successfully';
|
|
72
|
+
},
|
|
73
|
+
retry: backoffPolicy.length,
|
|
74
|
+
skip: (ctx) => !ctx.config.healthCheck,
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
/* eslint-enable require-atomic-updates */
|
|
78
|
+
const list = ui.newListr(tasks, {
|
|
79
|
+
concurrent: false,
|
|
80
|
+
rendererOptions: { collapse: false },
|
|
81
|
+
rendererSilent: isUnitTest,
|
|
82
|
+
});
|
|
83
|
+
return list.run();
|
|
84
|
+
}
|
|
85
|
+
async function shouldRetryOxygenCall(
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
task, errorMessage) {
|
|
88
|
+
const retryCount = task.isRetrying()?.count;
|
|
89
|
+
if (retryCount === backoffPolicy.length) {
|
|
90
|
+
throw new Error(`${errorMessage} ${task.errors[task.errors.length - 1]?.message}`);
|
|
91
|
+
}
|
|
92
|
+
if (retryCount) {
|
|
93
|
+
if (task.errors.length > 0) {
|
|
94
|
+
const unrecoverableError = task.errors.find((error) => error.message.includes('Unrecoverable'));
|
|
95
|
+
if (unrecoverableError) {
|
|
96
|
+
throw new Error(unrecoverableError.message);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (retryCount && !isUnitTest)
|
|
101
|
+
await system.sleep(backoffPolicy[retryCount - 1]);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/cli/services/deploy.ts"],"names":[],"mappings":"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","sourcesContent":["import {DeployConfig, ReqDeployConfig} from './deploy/types.js'\nimport {createDeployment, healthCheck, uploadDeployment} from './deploy/upload.js'\nimport {buildTaskList} from './build.js'\nimport {validateProject, fillDeployConfig} from './deploy/config.js'\nimport {environment, system, ui} from '@shopify/cli-kit'\n\ninterface TaskContext {\n config: ReqDeployConfig\n deploymentID: string\n assetBaseURL: string\n previewURL: string\n}\n\nconst isUnitTest = environment.local.isUnitTest()\nconst backoffPolicy = [5, 10, 15, 30, 60]\n\nexport async function deployToOxygen(_config: DeployConfig) {\n await validateProject(_config)\n\n /* eslint-disable require-atomic-updates */\n const tasks: ui.ListrTask<TaskContext>[] = [\n {\n title: '📝 Getting deployment config',\n task: async (ctx, task) => {\n ctx.config = await fillDeployConfig(_config)\n task.title = '📝 Deployment config parsed'\n },\n },\n {\n title: '💡 Initializing deployment',\n task: async (ctx, task) => {\n await shouldRetryOxygenCall(task, 'Could not create deployment on Oxygen.')\n\n const {deploymentID, assetBaseURL} = await createDeployment(ctx.config)\n ctx.assetBaseURL = assetBaseURL\n ctx.deploymentID = deploymentID\n task.title = '✨ Deployment initialized'\n },\n retry: backoffPolicy.length,\n },\n {\n title: '🛠 Building project',\n task: async (ctx, task) => {\n const subTasks = buildTaskList({\n directory: ctx.config.path,\n targets: {\n client: true,\n worker: '@shopify/hydrogen/platforms/worker',\n node: false,\n },\n assetBaseURL: ctx.assetBaseURL,\n })\n\n return task.newListr(subTasks)\n },\n skip: (ctx) => ctx.config.pathToBuild,\n },\n {\n title: '🚀 Uploading deployment files',\n task: async (ctx, task) => {\n await shouldRetryOxygenCall(task, 'Uploading files to Oxygen failed.')\n\n ctx.previewURL = await uploadDeployment(ctx.config, ctx.deploymentID)\n task.output = `Preview URL: ${ctx.previewURL}`\n task.title = '🚀 Files uploaded'\n },\n options: {\n bottomBar: Infinity,\n persistentOutput: true,\n },\n retry: backoffPolicy.length,\n },\n {\n title: '📡 Checking deployment health',\n task: async (ctx, task) => {\n const retryCount = task.isRetrying()?.count\n\n if (retryCount === backoffPolicy.length) {\n task.title =\n \"The deployment uploaded but hasn't become reachable within 2 minutes. Check the preview URL to see if deployment succeeded. If it didn't, then try again later.\"\n return\n }\n if (retryCount && !isUnitTest) await system.sleep(backoffPolicy[retryCount - 1]!)\n\n await healthCheck(ctx.previewURL)\n task.title = '✅ Deployed successfully'\n },\n retry: backoffPolicy.length,\n skip: (ctx) => !ctx.config.healthCheck,\n },\n ]\n /* eslint-enable require-atomic-updates */\n\n const list = ui.newListr(tasks, {\n concurrent: false,\n rendererOptions: {collapse: false},\n rendererSilent: isUnitTest,\n })\n\n return list.run()\n}\n\nasync function shouldRetryOxygenCall(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n task: ui.ListrTaskWrapper<TaskContext, any>,\n errorMessage: string,\n) {\n const retryCount = task.isRetrying()?.count\n if (retryCount === backoffPolicy.length) {\n throw new Error(`${errorMessage} ${task.errors[task.errors.length - 1]?.message}`)\n }\n if (retryCount) {\n if (task.errors.length > 0) {\n const unrecoverableError = task.errors.find((error) => error.message.includes('Unrecoverable'))\n if (unrecoverableError) {\n throw new Error(unrecoverableError.message)\n }\n }\n }\n if (retryCount && !isUnitTest) await system.sleep(backoffPolicy[retryCount - 1]!)\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function checkHydrogenVersion(directory: string): Promise<string | undefined>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { system } from '@shopify/cli-kit';
|
|
2
|
+
import { checkForNewVersion } from '@shopify/cli-kit/node/node-package-manager';
|
|
3
|
+
import { renderInfo } from '@shopify/cli-kit/node/ui';
|
|
4
|
+
const PACKAGE_NAME = '@shopify/hydrogen';
|
|
5
|
+
export async function checkHydrogenVersion(directory) {
|
|
6
|
+
const currentVersion = await system.captureOutput('node', ['-p', `require('./node_modules/${PACKAGE_NAME}/package.json').version`], {
|
|
7
|
+
cwd: directory,
|
|
8
|
+
});
|
|
9
|
+
if (!currentVersion) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const newVersionAvailable = await checkForNewVersion(PACKAGE_NAME, currentVersion);
|
|
13
|
+
if (newVersionAvailable) {
|
|
14
|
+
renderInfo({
|
|
15
|
+
headline: 'Upgrade available',
|
|
16
|
+
body: `Version ${newVersionAvailable} of ${PACKAGE_NAME} is now available.\n\n` +
|
|
17
|
+
`You are currently running v${currentVersion}.`,
|
|
18
|
+
reference: [
|
|
19
|
+
{
|
|
20
|
+
link: {
|
|
21
|
+
label: 'Hydrogen releases',
|
|
22
|
+
url: 'https://github.com/Shopify/hydrogen/releases',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
return newVersionAvailable;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=check-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-version.js","sourceRoot":"","sources":["../../../../src/cli/services/dev/check-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAC,kBAAkB,EAAC,MAAM,4CAA4C,CAAA;AAC7E,OAAO,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAA;AAEnD,MAAM,YAAY,GAAG,mBAAmB,CAAA;AAExC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,SAAiB;IAC1D,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,aAAa,CAC/C,MAAM,EACN,CAAC,IAAI,EAAE,2BAA2B,YAAY,yBAAyB,CAAC,EACxE;QACE,GAAG,EAAE,SAAS;KACf,CACF,CAAA;IAED,IAAI,CAAC,cAAc,EAAE;QACnB,OAAM;KACP;IAED,MAAM,mBAAmB,GAAG,MAAM,kBAAkB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;IAElF,IAAI,mBAAmB,EAAE;QACvB,UAAU,CAAC;YACT,QAAQ,EAAE,mBAAmB;YAC7B,IAAI,EACF,WAAW,mBAAmB,OAAO,YAAY,wBAAwB;gBACzE,8BAA8B,cAAc,GAAG;YACjD,SAAS,EAAE;gBACT;oBACE,IAAI,EAAE;wBACJ,KAAK,EAAE,mBAAmB;wBAC1B,GAAG,EAAE,8CAA8C;qBACpD;iBACF;aACF;SACF,CAAC,CAAA;QAEF,OAAO,mBAAmB,CAAA;KAC3B;AACH,CAAC","sourcesContent":["import {system} from '@shopify/cli-kit'\nimport {checkForNewVersion} from '@shopify/cli-kit/node/node-package-manager'\nimport {renderInfo} from '@shopify/cli-kit/node/ui'\n\nconst PACKAGE_NAME = '@shopify/hydrogen'\n\nexport async function checkHydrogenVersion(directory: string): Promise<string | undefined> {\n const currentVersion = await system.captureOutput(\n 'node',\n ['-p', `require('./node_modules/${PACKAGE_NAME}/package.json').version`],\n {\n cwd: directory,\n },\n )\n\n if (!currentVersion) {\n return\n }\n\n const newVersionAvailable = await checkForNewVersion(PACKAGE_NAME, currentVersion)\n\n if (newVersionAvailable) {\n renderInfo({\n headline: 'Upgrade available',\n body:\n `Version ${newVersionAvailable} of ${PACKAGE_NAME} is now available.\\n\\n` +\n `You are currently running v${currentVersion}.`,\n reference: [\n {\n link: {\n label: 'Hydrogen releases',\n url: 'https://github.com/Shopify/hydrogen/releases',\n },\n },\n ],\n })\n\n return newVersionAvailable\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Config } from '@oclif/core';
|
|
2
|
+
interface DevOptions {
|
|
3
|
+
commandConfig: Config;
|
|
4
|
+
directory: string;
|
|
5
|
+
force: boolean;
|
|
6
|
+
host: boolean;
|
|
7
|
+
open: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare function dev({ commandConfig, directory, force, host, open }: DevOptions): Promise<void>;
|
|
10
|
+
export default dev;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { checkHydrogenVersion } from './dev/check-version.js';
|
|
2
|
+
import { createServer } from 'vite';
|
|
3
|
+
import { error as kitError } from '@shopify/cli-kit';
|
|
4
|
+
import { reportAnalyticsEvent } from '@shopify/cli-kit/node/analytics';
|
|
5
|
+
async function dev({ commandConfig, directory, force, host, open }) {
|
|
6
|
+
try {
|
|
7
|
+
await checkHydrogenVersion(directory);
|
|
8
|
+
const server = await createServer({
|
|
9
|
+
root: directory,
|
|
10
|
+
server: {
|
|
11
|
+
open,
|
|
12
|
+
force,
|
|
13
|
+
host,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
await server.listen();
|
|
17
|
+
server.printUrls();
|
|
18
|
+
server.config.logger.info('');
|
|
19
|
+
await reportAnalyticsEvent({ config: commandConfig });
|
|
20
|
+
await closeEvent(server);
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
const abortError = new kitError.Abort(error.message);
|
|
25
|
+
abortError.stack = error.stack;
|
|
26
|
+
throw abortError;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function closeEvent(server) {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
server.ws.on('close', () => {
|
|
32
|
+
return resolve();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export default dev;
|
|
37
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/cli/services/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAC,YAAY,EAAgB,MAAM,MAAM,CAAA;AAChD,OAAO,EAAC,KAAK,IAAI,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAA;AAWpE,KAAK,UAAU,GAAG,CAAC,EAAC,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAa;IAC1E,IAAI;QACF,MAAM,oBAAoB,CAAC,SAAS,CAAC,CAAA;QAErC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;YAChC,IAAI,EAAE,SAAS;YACf,MAAM,EAAE;gBACN,IAAI;gBACJ,KAAK;gBACL,IAAI;aACL;SACF,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,MAAM,EAAE,CAAA;QACrB,MAAM,CAAC,SAAS,EAAE,CAAA;QAClB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC7B,MAAM,oBAAoB,CAAC,EAAC,MAAM,EAAE,aAAa,EAAC,CAAC,CAAA;QACnD,MAAM,UAAU,CAAC,MAAM,CAAC,CAAA;QACxB,8DAA8D;KAC/D;IAAC,OAAO,KAAU,EAAE;QACnB,MAAM,UAAU,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACpD,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;QAC9B,MAAM,UAAU,CAAA;KACjB;AACH,CAAC;AAED,SAAS,UAAU,CAAC,MAAqB;IACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACzB,OAAO,OAAO,EAAE,CAAA;QAClB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,eAAe,GAAG,CAAA","sourcesContent":["import {checkHydrogenVersion} from './dev/check-version.js'\nimport {createServer, ViteDevServer} from 'vite'\nimport {error as kitError} from '@shopify/cli-kit'\nimport {reportAnalyticsEvent} from '@shopify/cli-kit/node/analytics'\nimport {Config} from '@oclif/core'\n\ninterface DevOptions {\n commandConfig: Config\n directory: string\n force: boolean\n host: boolean\n open: boolean\n}\n\nasync function dev({commandConfig, directory, force, host, open}: DevOptions) {\n try {\n await checkHydrogenVersion(directory)\n\n const server = await createServer({\n root: directory,\n server: {\n open,\n force,\n host,\n },\n })\n await server.listen()\n server.printUrls()\n server.config.logger.info('')\n await reportAnalyticsEvent({config: commandConfig})\n await closeEvent(server)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n const abortError = new kitError.Abort(error.message)\n abortError.stack = error.stack\n throw abortError\n }\n}\n\nfunction closeEvent(server: ViteDevServer): Promise<void> {\n return new Promise((resolve) => {\n server.ws.on('close', () => {\n return resolve()\n })\n })\n}\n\nexport default dev\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { genericConfigurationFileNames } from '../constants.js';
|
|
2
|
+
import { ui, vscode, npm, file, path, error, environment } from '@shopify/cli-kit';
|
|
3
|
+
import { addNPMDependenciesWithoutVersionIfNeeded } from '@shopify/cli-kit/node/node-package-manager';
|
|
4
|
+
import stream from 'stream';
|
|
5
|
+
export async function addESLint({ app, force, install }) {
|
|
6
|
+
const list = ui.newListr([
|
|
7
|
+
{
|
|
8
|
+
title: 'Installing additional dependencies',
|
|
9
|
+
skip: () => !install,
|
|
10
|
+
task: async (_, task) => {
|
|
11
|
+
const requiredDependencies = ['eslint', 'eslint-plugin-hydrogen', 'prettier', '@shopify/prettier-config'];
|
|
12
|
+
await addNPMDependenciesWithoutVersionIfNeeded(requiredDependencies, {
|
|
13
|
+
packageManager: app.packageManager,
|
|
14
|
+
type: 'prod',
|
|
15
|
+
directory: app.directory,
|
|
16
|
+
stderr: new stream.Writable({
|
|
17
|
+
write(chunk, encoding, next) {
|
|
18
|
+
task.output = chunk.toString();
|
|
19
|
+
next();
|
|
20
|
+
},
|
|
21
|
+
}),
|
|
22
|
+
stdout: new stream.Writable({
|
|
23
|
+
write(chunk, encoding, next) {
|
|
24
|
+
task.output = chunk.toString();
|
|
25
|
+
next();
|
|
26
|
+
},
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
task.title = 'Dependencies installed';
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: 'Adding ESLint configuration',
|
|
34
|
+
task: async (_, task) => {
|
|
35
|
+
const eslintConfigPath = path.join(app.directory, genericConfigurationFileNames.eslint);
|
|
36
|
+
if (await file.exists(eslintConfigPath)) {
|
|
37
|
+
if (force) {
|
|
38
|
+
await file.remove(eslintConfigPath);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
throw new error.Abort('ESLint config already exists.', 'Use --force to override existing config.');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const extended = [`'plugin:hydrogen/recommended'`];
|
|
45
|
+
if (app.language === 'TypeScript') {
|
|
46
|
+
extended.push(`'plugin:hydrogen/typescript'`);
|
|
47
|
+
}
|
|
48
|
+
const eslintConfig = await file.format(['module.exports = {', 'extends: [', `${extended.join(',')}`, ' ],', ' };'].join('\n'), { path: genericConfigurationFileNames.eslint });
|
|
49
|
+
await file.write(eslintConfigPath, eslintConfig);
|
|
50
|
+
task.title = 'ESLint configuration added';
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
title: 'Updating package.json',
|
|
55
|
+
task: async (_, task) => {
|
|
56
|
+
const packageJSON = await npm.readPackageJSON(app.directory);
|
|
57
|
+
packageJSON.scripts.lint = `eslint --ext .js,.ts,.jsx,.tsx src/`;
|
|
58
|
+
packageJSON.prettier = '@shopify/prettier-config';
|
|
59
|
+
await npm.writePackageJSON(app.directory, packageJSON);
|
|
60
|
+
task.title = 'Package.json updated';
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
title: 'Adding editor plugin recommendations',
|
|
65
|
+
skip: async () => !(await vscode.isVSCode(app.directory)),
|
|
66
|
+
task: async (_, task) => {
|
|
67
|
+
await vscode.addRecommendedExtensions(app.directory, ['dbaeumer.vscode-eslint']);
|
|
68
|
+
task.title = 'Editor plugin recommendations added';
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
], { rendererSilent: environment.local.isUnitTest() });
|
|
72
|
+
await list.run();
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=eslint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../../src/cli/services/eslint.ts"],"names":[],"mappings":"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","sourcesContent":["import {HydrogenApp} from '../models/hydrogen.js'\nimport {genericConfigurationFileNames} from '../constants.js'\nimport {ui, vscode, npm, file, path, error, environment} from '@shopify/cli-kit'\nimport {addNPMDependenciesWithoutVersionIfNeeded} from '@shopify/cli-kit/node/node-package-manager'\nimport stream from 'stream'\n\ninterface AddESlintOptions {\n app: HydrogenApp\n force: boolean\n install: boolean\n}\n\nexport async function addESLint({app, force, install}: AddESlintOptions) {\n const list = ui.newListr(\n [\n {\n title: 'Installing additional dependencies',\n skip: () => !install,\n task: async (_, task) => {\n const requiredDependencies = ['eslint', 'eslint-plugin-hydrogen', 'prettier', '@shopify/prettier-config']\n await addNPMDependenciesWithoutVersionIfNeeded(requiredDependencies, {\n packageManager: app.packageManager,\n type: 'prod',\n directory: app.directory,\n stderr: new stream.Writable({\n write(chunk, encoding, next) {\n task.output = chunk.toString()\n next()\n },\n }),\n stdout: new stream.Writable({\n write(chunk, encoding, next) {\n task.output = chunk.toString()\n next()\n },\n }),\n })\n task.title = 'Dependencies installed'\n },\n },\n\n {\n title: 'Adding ESLint configuration',\n task: async (_, task) => {\n const eslintConfigPath = path.join(app.directory, genericConfigurationFileNames.eslint)\n\n if (await file.exists(eslintConfigPath)) {\n if (force) {\n await file.remove(eslintConfigPath)\n } else {\n throw new error.Abort('ESLint config already exists.', 'Use --force to override existing config.')\n }\n }\n\n const extended = [`'plugin:hydrogen/recommended'`]\n\n if (app.language === 'TypeScript') {\n extended.push(`'plugin:hydrogen/typescript'`)\n }\n\n const eslintConfig = await file.format(\n ['module.exports = {', 'extends: [', `${extended.join(',')}`, ' ],', ' };'].join('\\n'),\n {path: genericConfigurationFileNames.eslint},\n )\n\n await file.write(eslintConfigPath, eslintConfig)\n\n task.title = 'ESLint configuration added'\n },\n },\n {\n title: 'Updating package.json',\n task: async (_, task) => {\n const packageJSON = await npm.readPackageJSON(app.directory)\n\n packageJSON.scripts.lint = `eslint --ext .js,.ts,.jsx,.tsx src/`\n\n packageJSON.prettier = '@shopify/prettier-config'\n\n await npm.writePackageJSON(app.directory, packageJSON)\n\n task.title = 'Package.json updated'\n },\n },\n {\n title: 'Adding editor plugin recommendations',\n skip: async () => !(await vscode.isVSCode(app.directory)),\n task: async (_, task) => {\n await vscode.addRecommendedExtensions(app.directory, ['dbaeumer.vscode-eslint'])\n task.title = 'Editor plugin recommendations added'\n },\n },\n ],\n {rendererSilent: environment.local.isUnitTest()},\n )\n await list.run()\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HydrogenApp } from '../models/hydrogen.js';
|
|
2
|
+
import { output } from '@shopify/cli-kit';
|
|
3
|
+
interface InfoOptions {
|
|
4
|
+
showPrivateData: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function info(app: HydrogenApp, { showPrivateData }: InfoOptions): output.Message;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { output, string } from '@shopify/cli-kit';
|
|
2
|
+
import { platformAndArch } from '@shopify/cli-kit/node/os';
|
|
3
|
+
export function info(app, { showPrivateData }) {
|
|
4
|
+
const appInfo = new HydrogenAppInfo(app);
|
|
5
|
+
return appInfo.output({ showPrivateData });
|
|
6
|
+
}
|
|
7
|
+
const NOT_FOUND_TEXT = output.content `${output.token.italic('Not found')}`.value;
|
|
8
|
+
const NOT_CONFIGURED_TEXT = output.content `${output.token.italic('Not yet configured')}`.value;
|
|
9
|
+
class AppInfo {
|
|
10
|
+
constructor(app) {
|
|
11
|
+
this.app = app;
|
|
12
|
+
}
|
|
13
|
+
output({ showPrivateData }) {
|
|
14
|
+
const sections = [
|
|
15
|
+
this.projectSettingsSection(),
|
|
16
|
+
this.storefrontSettingsSection({ showPrivateData }),
|
|
17
|
+
this.eslintSection(),
|
|
18
|
+
this.systemInfoSection(),
|
|
19
|
+
];
|
|
20
|
+
return sections.map((sectionContents) => this.section(...sectionContents)).join('\n\n');
|
|
21
|
+
}
|
|
22
|
+
projectSettingsSection() {
|
|
23
|
+
const title = 'Your Project';
|
|
24
|
+
const lines = [
|
|
25
|
+
['Name', this.app.name],
|
|
26
|
+
['Project location', this.app.directory],
|
|
27
|
+
['Language', this.app.language],
|
|
28
|
+
];
|
|
29
|
+
const projectInfo = this.linesToColumns(lines);
|
|
30
|
+
return [title, projectInfo];
|
|
31
|
+
}
|
|
32
|
+
storefrontSettingsSection({ showPrivateData }) {
|
|
33
|
+
const errors = [];
|
|
34
|
+
const title = 'Storefront';
|
|
35
|
+
if (this.app.configuration.shopify && typeof this.app.configuration.shopify === 'function') {
|
|
36
|
+
return [title, 'Storefront settings defined as a function are not supported in this command.'];
|
|
37
|
+
}
|
|
38
|
+
const privateFields = showPrivateData ? ['storefrontToken'] : [];
|
|
39
|
+
const fields = [
|
|
40
|
+
'storeDomain',
|
|
41
|
+
'storefrontApiVersion',
|
|
42
|
+
...privateFields,
|
|
43
|
+
];
|
|
44
|
+
const storefrontInfo = this.configurationCheck(fields, this.app.configuration.shopify);
|
|
45
|
+
let errorContent = `\n${errors.map(this.formattedError).join('\n')}`;
|
|
46
|
+
if (errorContent.trim() === '')
|
|
47
|
+
errorContent = '';
|
|
48
|
+
return [title, `${this.linesToColumns(storefrontInfo)}${errorContent}`];
|
|
49
|
+
}
|
|
50
|
+
eslintSection() {
|
|
51
|
+
const errors = [];
|
|
52
|
+
const title = 'ESLint';
|
|
53
|
+
const dependencyResults = this.dependencyCheck(['eslint', 'eslint-plugin-hydrogen']);
|
|
54
|
+
if (this.app.nodeDependencies.eslint && !this.app.nodeDependencies['eslint-plugin-hydrogen']) {
|
|
55
|
+
errors.push('Run `yarn shopify add eslint` to install and configure eslint for hydrogen');
|
|
56
|
+
}
|
|
57
|
+
let errorContent = `\n${errors.map(this.formattedError).join('\n')}`;
|
|
58
|
+
if (errorContent.trim() === '')
|
|
59
|
+
errorContent = '';
|
|
60
|
+
return [title, `${this.linesToColumns(dependencyResults)}${errorContent}`];
|
|
61
|
+
}
|
|
62
|
+
configurationCheck(key, configObject = this.app.configuration) {
|
|
63
|
+
const keys = Array.isArray(key) ? key : [key];
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
const result = keys.reduce((acc, key) => {
|
|
67
|
+
const found = configObject[key];
|
|
68
|
+
if (typeof found === 'string') {
|
|
69
|
+
const result = [string.capitalize(key.toString()), found];
|
|
70
|
+
return [...acc, result];
|
|
71
|
+
}
|
|
72
|
+
const result = [key, NOT_CONFIGURED_TEXT];
|
|
73
|
+
return [...acc, result];
|
|
74
|
+
}, []);
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
dependencyCheck(dependency) {
|
|
78
|
+
const dependencies = Array.isArray(dependency) ? dependency : [dependency];
|
|
79
|
+
const result = dependencies.reduce((acc, dependency) => {
|
|
80
|
+
const found = this.app.nodeDependencies[dependency];
|
|
81
|
+
if (found) {
|
|
82
|
+
const result = [dependency, found];
|
|
83
|
+
return [...acc, result];
|
|
84
|
+
}
|
|
85
|
+
const result = [dependency, NOT_FOUND_TEXT];
|
|
86
|
+
return [...acc, result];
|
|
87
|
+
}, []);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
formattedError(str) {
|
|
91
|
+
const [errorFirstLine, ...errorRemainingLines] = str.split('\n');
|
|
92
|
+
const errorLines = [`! ${errorFirstLine}`, ...errorRemainingLines.map((line) => ` ${line}`)];
|
|
93
|
+
return output.content `${output.token.errorText(errorLines.join('\n'))}`.value;
|
|
94
|
+
}
|
|
95
|
+
systemInfoSection() {
|
|
96
|
+
const title = 'Tooling and System';
|
|
97
|
+
const { platform, arch } = platformAndArch();
|
|
98
|
+
const lines = [
|
|
99
|
+
...this.dependencyCheck(['@shopify/hydrogen', '@shopify/cli-hydrogen', '@shopify/cli']),
|
|
100
|
+
['Package manager', this.app.packageManager],
|
|
101
|
+
['OS', `${platform}-${arch}`],
|
|
102
|
+
['Shell', process.env.SHELL || 'unknown'],
|
|
103
|
+
['Node.js version', process.version],
|
|
104
|
+
];
|
|
105
|
+
return [title, this.linesToColumns(lines)];
|
|
106
|
+
}
|
|
107
|
+
linesToColumns(lines) {
|
|
108
|
+
const widths = [];
|
|
109
|
+
for (let i = 0; lines[0] && i < lines[0].length; i++) {
|
|
110
|
+
const columnRows = lines.map((line) => line[i]);
|
|
111
|
+
widths.push(Math.max(...columnRows.map((row) => output.unstyled(row).length)));
|
|
112
|
+
}
|
|
113
|
+
const paddedLines = lines
|
|
114
|
+
.map((line) => {
|
|
115
|
+
return line
|
|
116
|
+
.map((col, index) => {
|
|
117
|
+
return `${col}${' '.repeat(widths[index] - output.unstyled(col).length)}`;
|
|
118
|
+
})
|
|
119
|
+
.join(' ')
|
|
120
|
+
.trimEnd();
|
|
121
|
+
})
|
|
122
|
+
.join('\n');
|
|
123
|
+
return paddedLines;
|
|
124
|
+
}
|
|
125
|
+
section(title, body) {
|
|
126
|
+
const formattedTitle = `${title.toUpperCase()}${' '.repeat(35 - title.length)}`;
|
|
127
|
+
return output.content `${output.token.heading(formattedTitle)}\n${body}`.value;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
class HydrogenAppInfo extends AppInfo {
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../../src/cli/services/info.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AAMxD,MAAM,UAAU,IAAI,CAAC,GAAgB,EAAE,EAAC,eAAe,EAAc;IACnE,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAA;IAExC,OAAO,OAAO,CAAC,MAAM,CAAC,EAAC,eAAe,EAAC,CAAC,CAAA;AAC1C,CAAC;AAED,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAA,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAA;AAChF,MAAM,mBAAmB,GAAG,MAAM,CAAC,OAAO,CAAA,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC,KAAK,CAAA;AAE9F,MAAM,OAAO;IAEX,YAAY,GAAgB;QAC1B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;IAChB,CAAC;IAED,MAAM,CAAC,EAAC,eAAe,EAAc;QACnC,MAAM,QAAQ,GAAuB;YACnC,IAAI,CAAC,sBAAsB,EAAE;YAC7B,IAAI,CAAC,yBAAyB,CAAC,EAAC,eAAe,EAAC,CAAC;YACjD,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,iBAAiB,EAAE;SACzB,CAAA;QACD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,eAAiC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3G,CAAC;IAED,sBAAsB;QACpB,MAAM,KAAK,GAAG,cAAc,CAAA;QAE5B,MAAM,KAAK,GAAG;YACZ,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YACvB,CAAC,kBAAkB,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YACxC,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;SAChC,CAAA;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QAC9C,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IAC7B,CAAC;IAED,yBAAyB,CAAC,EAAC,eAAe,EAAc;QACtD,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,YAAY,CAAA;QAE1B,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,KAAK,UAAU,EAAE;YAC1F,OAAO,CAAC,KAAK,EAAE,8EAA8E,CAAC,CAAA;SAC/F;QAED,MAAM,aAAa,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAEhE,MAAM,MAAM,GAAG;YACb,aAAa;YACb,sBAAsB;YACtB,GAAG,aAAa;SAC+B,CAAA;QAEjD,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QAEtF,IAAI,YAAY,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;QAEpE,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,YAAY,GAAG,EAAE,CAAA;QAEjD,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,YAAY,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,aAAa;QACX,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,QAAQ,CAAA;QACtB,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC,CAAA;QAEpF,IAAI,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,EAAE;YAC5F,MAAM,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAA;SAC1F;QAED,IAAI,YAAY,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;QAEpE,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,YAAY,GAAG,EAAE,CAAA;QAEjD,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,GAAG,YAAY,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,kBAAkB,CAChB,GAAkD,EAClD,eAA2D,IAAI,CAAC,GAAG,CAAC,aAAa;QAEjF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAE7C,6DAA6D;QAC7D,aAAa;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtC,MAAM,KAAK,GAAG,YAAY,CAAC,GAA6D,CAAC,CAAA;YAEzF,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;gBAC7B,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;gBACzD,OAAO,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,CAAA;aACxB;YAED,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAA;YACzC,OAAO,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,CAAA;QACzB,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,OAAO,MAAM,CAAA;IACf,CAAC;IAED,eAAe,CAAC,UAA6B;QAC3C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QAE1E,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAa,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE;YACjE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAA;YACnD,IAAI,KAAK,EAAE;gBACT,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;gBAClC,OAAO,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,CAAA;aACxB;YAED,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;YAC3C,OAAO,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,CAAA;QACzB,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,OAAO,MAAM,CAAA;IACf,CAAC;IAED,cAAc,CAAC,GAAW;QACxB,MAAM,CAAC,cAAc,EAAE,GAAG,mBAAmB,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAChE,MAAM,UAAU,GAAG,CAAC,KAAK,cAAc,EAAE,EAAE,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAA;QAC7F,OAAO,MAAM,CAAC,OAAO,CAAA,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAA;IAC/E,CAAC;IAED,iBAAiB;QACf,MAAM,KAAK,GAAG,oBAAoB,CAAA;QAClC,MAAM,EAAC,QAAQ,EAAE,IAAI,EAAC,GAAG,eAAe,EAAE,CAAA;QAC1C,MAAM,KAAK,GAAe;YACxB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,cAAc,CAAC,CAAC;YACvF,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;YAC5C,CAAC,IAAI,EAAE,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC7B,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,SAAS,CAAC;YACzC,CAAC,iBAAiB,EAAE,OAAO,CAAC,OAAO,CAAC;SACrC,CAAA;QAED,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5C,CAAC;IAED,cAAc,CAAC,KAAiB;QAC9B,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACpD,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAA;YAChD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;SAC/E;QACD,MAAM,WAAW,GAAG,KAAK;aACtB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,OAAO,IAAI;iBACR,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBAClB,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAA;YAC5E,CAAC,CAAC;iBACD,IAAI,CAAC,KAAK,CAAC;iBACX,OAAO,EAAE,CAAA;QACd,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAA;QACb,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,IAAY;QACjC,MAAM,cAAc,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;QAC/E,OAAO,MAAM,CAAC,OAAO,CAAA,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAA;IAC/E,CAAC;CACF;AAED,MAAM,eAAgB,SAAQ,OAAO;CAAG","sourcesContent":["import {HydrogenApp} from '../models/hydrogen.js'\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport {HydrogenConfig} from '@shopify/hydrogen/config'\nimport {output, string} from '@shopify/cli-kit'\nimport {platformAndArch} from '@shopify/cli-kit/node/os'\n\ninterface InfoOptions {\n showPrivateData: boolean\n}\n\nexport function info(app: HydrogenApp, {showPrivateData}: InfoOptions): output.Message {\n const appInfo = new HydrogenAppInfo(app)\n\n return appInfo.output({showPrivateData})\n}\n\nconst NOT_FOUND_TEXT = output.content`${output.token.italic('Not found')}`.value\nconst NOT_CONFIGURED_TEXT = output.content`${output.token.italic('Not yet configured')}`.value\n\nclass AppInfo {\n private app: HydrogenApp\n constructor(app: HydrogenApp) {\n this.app = app\n }\n\n output({showPrivateData}: InfoOptions): string {\n const sections: [string, string][] = [\n this.projectSettingsSection(),\n this.storefrontSettingsSection({showPrivateData}),\n this.eslintSection(),\n this.systemInfoSection(),\n ]\n return sections.map((sectionContents: [string, string]) => this.section(...sectionContents)).join('\\n\\n')\n }\n\n projectSettingsSection(): [string, string] {\n const title = 'Your Project'\n\n const lines = [\n ['Name', this.app.name],\n ['Project location', this.app.directory],\n ['Language', this.app.language],\n ]\n\n const projectInfo = this.linesToColumns(lines)\n return [title, projectInfo]\n }\n\n storefrontSettingsSection({showPrivateData}: InfoOptions): [string, string] {\n const errors: string[] = []\n const title = 'Storefront'\n\n if (this.app.configuration.shopify && typeof this.app.configuration.shopify === 'function') {\n return [title, 'Storefront settings defined as a function are not supported in this command.']\n }\n\n const privateFields = showPrivateData ? ['storefrontToken'] : []\n\n const fields = [\n 'storeDomain',\n 'storefrontApiVersion',\n ...privateFields,\n ] as unknown as keyof HydrogenConfig['shopify'][]\n\n const storefrontInfo = this.configurationCheck(fields, this.app.configuration.shopify)\n\n let errorContent = `\\n${errors.map(this.formattedError).join('\\n')}`\n\n if (errorContent.trim() === '') errorContent = ''\n\n return [title, `${this.linesToColumns(storefrontInfo)}${errorContent}`]\n }\n\n eslintSection(): [string, string] {\n const errors: string[] = []\n const title = 'ESLint'\n const dependencyResults = this.dependencyCheck(['eslint', 'eslint-plugin-hydrogen'])\n\n if (this.app.nodeDependencies.eslint && !this.app.nodeDependencies['eslint-plugin-hydrogen']) {\n errors.push('Run `yarn shopify add eslint` to install and configure eslint for hydrogen')\n }\n\n let errorContent = `\\n${errors.map(this.formattedError).join('\\n')}`\n\n if (errorContent.trim() === '') errorContent = ''\n\n return [title, `${this.linesToColumns(dependencyResults)}${errorContent}`]\n }\n\n configurationCheck(\n key: keyof HydrogenConfig | keyof HydrogenConfig[],\n configObject: HydrogenConfig | HydrogenConfig['shopify'] = this.app.configuration,\n ): string[][] {\n const keys = Array.isArray(key) ? key : [key]\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const result = keys.reduce((acc, key) => {\n const found = configObject[key as keyof HydrogenConfig & keyof HydrogenConfig['shopify']]\n\n if (typeof found === 'string') {\n const result = [string.capitalize(key.toString()), found]\n return [...acc, result]\n }\n\n const result = [key, NOT_CONFIGURED_TEXT]\n return [...acc, result]\n }, [])\n\n return result\n }\n\n dependencyCheck(dependency: string | string[]): string[][] {\n const dependencies = Array.isArray(dependency) ? dependency : [dependency]\n\n const result = dependencies.reduce<string[][]>((acc, dependency) => {\n const found = this.app.nodeDependencies[dependency]\n if (found) {\n const result = [dependency, found]\n return [...acc, result]\n }\n\n const result = [dependency, NOT_FOUND_TEXT]\n return [...acc, result]\n }, [])\n\n return result\n }\n\n formattedError(str: string): string {\n const [errorFirstLine, ...errorRemainingLines] = str.split('\\n')\n const errorLines = [`! ${errorFirstLine}`, ...errorRemainingLines.map((line) => ` ${line}`)]\n return output.content`${output.token.errorText(errorLines.join('\\n'))}`.value\n }\n\n systemInfoSection(): [string, string] {\n const title = 'Tooling and System'\n const {platform, arch} = platformAndArch()\n const lines: string[][] = [\n ...this.dependencyCheck(['@shopify/hydrogen', '@shopify/cli-hydrogen', '@shopify/cli']),\n ['Package manager', this.app.packageManager],\n ['OS', `${platform}-${arch}`],\n ['Shell', process.env.SHELL || 'unknown'],\n ['Node.js version', process.version],\n ]\n\n return [title, this.linesToColumns(lines)]\n }\n\n linesToColumns(lines: string[][]): string {\n const widths: number[] = []\n for (let i = 0; lines[0] && i < lines[0].length; i++) {\n const columnRows = lines.map((line) => line[i]!)\n widths.push(Math.max(...columnRows.map((row) => output.unstyled(row).length)))\n }\n const paddedLines = lines\n .map((line) => {\n return line\n .map((col, index) => {\n return `${col}${' '.repeat(widths[index]! - output.unstyled(col).length)}`\n })\n .join(' ')\n .trimEnd()\n })\n .join('\\n')\n return paddedLines\n }\n\n section(title: string, body: string): string {\n const formattedTitle = `${title.toUpperCase()}${' '.repeat(35 - title.length)}`\n return output.content`${output.token.heading(formattedTitle)}\\n${body}`.value\n }\n}\n\nclass HydrogenAppInfo extends AppInfo {}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { error } from '@shopify/cli-kit';
|
|
2
|
+
interface PreviewOptions {
|
|
3
|
+
directory: string;
|
|
4
|
+
port: number;
|
|
5
|
+
}
|
|
6
|
+
interface PreviewOptionsWorker extends PreviewOptions {
|
|
7
|
+
envPath: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
export declare function previewInNode({ directory, port }: PreviewOptions): Promise<void>;
|
|
10
|
+
export declare function previewInWorker({ directory, port, envPath }: PreviewOptionsWorker): Promise<void>;
|
|
11
|
+
export declare const OxygenPreviewExecutableNotFound: error.Bug;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { path, error, system, file, output } from '@shopify/cli-kit';
|
|
2
|
+
import { readAndParseDotEnv } from '@shopify/cli-kit/node/dot-env';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
export async function previewInNode({ directory, port }) {
|
|
5
|
+
const buildOutputPath = await path.resolve(directory, 'dist/node');
|
|
6
|
+
if (!(await file.exists(buildOutputPath))) {
|
|
7
|
+
output.info(output.content `Couldn’t find a Node.js server build for this project. Running ${output.token.packagejsonScript('yarn', 'shopify hydrogen build', '--target=node')} to create one.`);
|
|
8
|
+
await system.exec('yarn', ['shopify', 'hydrogen', 'build', '--target=node'], {
|
|
9
|
+
cwd: directory,
|
|
10
|
+
stdout: process.stdout,
|
|
11
|
+
stderr: process.stderr,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
await system.exec('node', ['--enable-source-maps', buildOutputPath], {
|
|
15
|
+
env: { PORT: `${port}` },
|
|
16
|
+
cwd: directory,
|
|
17
|
+
stdout: process.stdout,
|
|
18
|
+
stderr: process.stderr,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export async function previewInWorker({ directory, port, envPath }) {
|
|
22
|
+
const config = {
|
|
23
|
+
port,
|
|
24
|
+
workerFile: 'dist/worker/index.js',
|
|
25
|
+
assetsDir: 'dist/client',
|
|
26
|
+
buildCommand: 'yarn build',
|
|
27
|
+
modules: true,
|
|
28
|
+
watch: true,
|
|
29
|
+
buildWatchPaths: ['./src'],
|
|
30
|
+
autoReload: true,
|
|
31
|
+
...(envPath && (await parseEnvPath(envPath))),
|
|
32
|
+
};
|
|
33
|
+
await file.write(path.resolve(directory, 'mini-oxygen.config.json'), JSON.stringify(config, null, 2));
|
|
34
|
+
function cleanUp(options) {
|
|
35
|
+
if (options.exit) {
|
|
36
|
+
file.removeSync(path.resolve(directory, 'mini-oxygen.config.json'));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function parseEnvPath(envPath) {
|
|
40
|
+
const { variables } = await readAndParseDotEnv(envPath);
|
|
41
|
+
return {
|
|
42
|
+
env: variables,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
process.on('SIGINT', cleanUp.bind(null, { exit: true }));
|
|
46
|
+
const executable = await oxygenPreviewExecutable();
|
|
47
|
+
await system.exec(executable, [], {
|
|
48
|
+
env: { NODE_OPTIONS: '--experimental-vm-modules' },
|
|
49
|
+
cwd: directory,
|
|
50
|
+
stdout: process.stdout,
|
|
51
|
+
stderr: process.stderr,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export const OxygenPreviewExecutableNotFound = new error.Bug('Could not locate the executable file to run Oxygen locally.');
|
|
55
|
+
async function oxygenPreviewExecutable() {
|
|
56
|
+
const cwd = path.dirname(fileURLToPath(import.meta.url));
|
|
57
|
+
const executablePath = await path.findUp('node_modules/.bin/oxygen-preview', { type: 'file', cwd, allowSymlinks: true });
|
|
58
|
+
if (!executablePath) {
|
|
59
|
+
throw OxygenPreviewExecutableNotFound;
|
|
60
|
+
}
|
|
61
|
+
return executablePath;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/cli/services/preview.ts"],"names":[],"mappings":"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","sourcesContent":["import {path, error, system, file, output} from '@shopify/cli-kit'\nimport {readAndParseDotEnv, DotEnvFile} from '@shopify/cli-kit/node/dot-env'\nimport {fileURLToPath} from 'url'\n\ninterface PreviewOptions {\n directory: string\n port: number\n}\n\ninterface PreviewOptionsWorker extends PreviewOptions {\n envPath: string | undefined\n}\n\ninterface EnvConfig {\n env: DotEnvFile['variables']\n}\n\nexport async function previewInNode({directory, port}: PreviewOptions) {\n const buildOutputPath = await path.resolve(directory, 'dist/node')\n\n if (!(await file.exists(buildOutputPath))) {\n output.info(\n output.content`Couldn’t find a Node.js server build for this project. Running ${output.token.packagejsonScript(\n 'yarn',\n 'shopify hydrogen build',\n '--target=node',\n )} to create one.`,\n )\n\n await system.exec('yarn', ['shopify', 'hydrogen', 'build', '--target=node'], {\n cwd: directory,\n stdout: process.stdout,\n stderr: process.stderr,\n })\n }\n\n await system.exec('node', ['--enable-source-maps', buildOutputPath], {\n env: {PORT: `${port}`},\n cwd: directory,\n stdout: process.stdout,\n stderr: process.stderr,\n })\n}\n\nexport async function previewInWorker({directory, port, envPath}: PreviewOptionsWorker) {\n const config = {\n port,\n workerFile: 'dist/worker/index.js',\n assetsDir: 'dist/client',\n buildCommand: 'yarn build',\n modules: true,\n watch: true,\n buildWatchPaths: ['./src'],\n autoReload: true,\n ...(envPath && (await parseEnvPath(envPath))),\n }\n\n await file.write(path.resolve(directory, 'mini-oxygen.config.json'), JSON.stringify(config, null, 2))\n\n function cleanUp(options: {exit: boolean}) {\n if (options.exit) {\n file.removeSync(path.resolve(directory, 'mini-oxygen.config.json'))\n }\n }\n\n async function parseEnvPath(envPath: string): Promise<EnvConfig> {\n const {variables} = await readAndParseDotEnv(envPath)\n return {\n env: variables,\n }\n }\n\n process.on('SIGINT', cleanUp.bind(null, {exit: true}))\n\n const executable = await oxygenPreviewExecutable()\n\n await system.exec(executable, [], {\n env: {NODE_OPTIONS: '--experimental-vm-modules'},\n cwd: directory,\n stdout: process.stdout,\n stderr: process.stderr,\n })\n}\n\nexport const OxygenPreviewExecutableNotFound = new error.Bug(\n 'Could not locate the executable file to run Oxygen locally.',\n)\n\nasync function oxygenPreviewExecutable(): Promise<string> {\n const cwd = path.dirname(fileURLToPath(import.meta.url))\n const executablePath = await path.findUp('node_modules/.bin/oxygen-preview', {type: 'file', cwd, allowSymlinks: true})\n if (!executablePath) {\n throw OxygenPreviewExecutableNotFound\n }\n return executablePath\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HydrogenApp } from '../models/hydrogen.js';
|
|
2
|
+
interface AddTailwindOptions {
|
|
3
|
+
app: HydrogenApp;
|
|
4
|
+
force: boolean;
|
|
5
|
+
directory: string;
|
|
6
|
+
install: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function addTailwind({ app, force, install, directory }: AddTailwindOptions): Promise<void>;
|
|
9
|
+
export {};
|