@shopify/cli-hydrogen 3.34.0 → 3.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/models/hydrogen.js +6 -5
- package/dist/cli/models/hydrogen.js.map +1 -1
- package/dist/cli/services/build/check-lockfile.js +5 -3
- package/dist/cli/services/build/check-lockfile.js.map +1 -1
- package/dist/cli/services/deploy/config.js +16 -12
- package/dist/cli/services/deploy/config.js.map +1 -1
- package/dist/cli/services/deploy/upload.js +4 -3
- package/dist/cli/services/deploy/upload.js.map +1 -1
- package/dist/cli/services/eslint.js +6 -5
- package/dist/cli/services/eslint.js.map +1 -1
- package/dist/cli/services/preview.js +5 -4
- package/dist/cli/services/preview.js.map +1 -1
- package/dist/cli/services/tailwind.js +12 -11
- package/dist/cli/services/tailwind.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { loadConfig } from '../utilities/load-config.js';
|
|
2
|
-
import { path, error as kitError
|
|
2
|
+
import { path, error as kitError } from '@shopify/cli-kit';
|
|
3
3
|
import { getDependencies, getPackageName, pnpmLockfile, yarnLockfile, } from '@shopify/cli-kit/node/node-package-manager';
|
|
4
|
+
import { fileExists } from '@shopify/cli-kit/node/fs';
|
|
4
5
|
class AppErrors {
|
|
5
6
|
constructor() {
|
|
6
7
|
this.errors = {};
|
|
@@ -24,18 +25,18 @@ class HydrogenAppLoader {
|
|
|
24
25
|
this.directory = directory;
|
|
25
26
|
}
|
|
26
27
|
async loaded() {
|
|
27
|
-
if (!(await
|
|
28
|
+
if (!(await fileExists(this.directory))) {
|
|
28
29
|
throw new kitError.Abort(`Couldn't find directory ${this.directory}`);
|
|
29
30
|
}
|
|
30
31
|
const { configuration } = await this.loadConfig();
|
|
31
32
|
const yarnLockPath = path.join(this.directory, yarnLockfile);
|
|
32
|
-
const yarnLockExists = await
|
|
33
|
+
const yarnLockExists = await fileExists(yarnLockPath);
|
|
33
34
|
const pnpmLockPath = path.join(this.directory, pnpmLockfile);
|
|
34
|
-
const pnpmLockExists = await
|
|
35
|
+
const pnpmLockExists = await fileExists(pnpmLockPath);
|
|
35
36
|
const packageJSONPath = path.join(this.directory, 'package.json');
|
|
36
37
|
const name = await getPackageName(packageJSONPath);
|
|
37
38
|
const nodeDependencies = await getDependencies(packageJSONPath);
|
|
38
|
-
const tsConfigExists = await
|
|
39
|
+
const tsConfigExists = await fileExists(path.join(this.directory, 'tsconfig.json'));
|
|
39
40
|
const language = tsConfigExists && nodeDependencies.typescript ? 'TypeScript' : 'JavaScript';
|
|
40
41
|
let packageManager;
|
|
41
42
|
if (yarnLockExists) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydrogen.js","sourceRoot":"","sources":["../../../src/cli/models/hydrogen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAC,IAAI,EAAE,KAAK,IAAI,QAAQ,
|
|
1
|
+
{"version":3,"file":"hydrogen.js","sourceRoot":"","sources":["../../../src/cli/models/hydrogen.ts"],"names":[],"mappings":"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","sourcesContent":["import {loadConfig} from '../utilities/load-config.js'\nimport {path, error as kitError} from '@shopify/cli-kit'\nimport {\n getDependencies,\n getPackageName,\n PackageManager,\n pnpmLockfile,\n yarnLockfile,\n} from '@shopify/cli-kit/node/node-package-manager'\n\nimport {fileExists} from '@shopify/cli-kit/node/fs'\n/* eslint-disable @typescript-eslint/ban-ts-comment */\n// @ts-ignore\nimport type {HydrogenConfig} from '@shopify/hydrogen/config'\n/* eslint-enable @typescript-eslint/ban-ts-comment */\n\nexport interface HydrogenApp {\n name: string\n directory: string\n packageManager: PackageManager\n configuration: HydrogenConfig\n nodeDependencies: {[key: string]: string}\n language: 'JavaScript' | 'TypeScript'\n errors?: AppErrors\n}\n\ninterface AppLoaderConstructorArgs {\n directory: string\n}\n\nclass AppErrors {\n private errors: {\n [key: string]: string\n } = {}\n\n addError(path: string, message: string): void {\n this.errors[path] = message\n }\n\n getError(path: string) {\n return this.errors[path]\n }\n\n isEmpty() {\n return Object.keys(this.errors).length === 0\n }\n\n toJSON(): string[] {\n return Object.values(this.errors)\n }\n}\n\nclass HydrogenAppLoader {\n private directory: string\n private errors: AppErrors = new AppErrors()\n\n constructor({directory}: AppLoaderConstructorArgs) {\n this.directory = directory\n }\n\n async loaded() {\n if (!(await fileExists(this.directory))) {\n throw new kitError.Abort(`Couldn't find directory ${this.directory}`)\n }\n\n const {configuration} = await this.loadConfig()\n\n const yarnLockPath = path.join(this.directory, yarnLockfile)\n const yarnLockExists = await fileExists(yarnLockPath)\n const pnpmLockPath = path.join(this.directory, pnpmLockfile)\n const pnpmLockExists = await fileExists(pnpmLockPath)\n const packageJSONPath = path.join(this.directory, 'package.json')\n const name = await getPackageName(packageJSONPath)\n const nodeDependencies = await getDependencies(packageJSONPath)\n const tsConfigExists = await fileExists(path.join(this.directory, 'tsconfig.json'))\n const language = tsConfigExists && nodeDependencies.typescript ? 'TypeScript' : 'JavaScript'\n\n let packageManager: PackageManager\n if (yarnLockExists) {\n packageManager = 'yarn'\n } else if (pnpmLockExists) {\n packageManager = 'pnpm'\n } else {\n packageManager = 'npm'\n }\n\n const app: HydrogenApp = {\n name: name ?? path.basename(this.directory),\n directory: this.directory,\n configuration,\n packageManager,\n nodeDependencies,\n language,\n }\n\n if (!this.errors.isEmpty()) app.errors = this.errors\n\n return app\n }\n\n async loadConfig() {\n const abortError = new kitError.Abort(`Couldn't find hydrogen configuration file`)\n\n try {\n const config = await loadConfig({root: this.directory})\n\n if (!config) {\n throw abortError\n }\n\n return config\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n abortError.stack = error.stack\n throw abortError\n }\n }\n}\n\nexport async function load(directory: string): Promise<HydrogenApp> {\n const loader = new HydrogenAppLoader({directory})\n\n return loader.loaded()\n}\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { path } from '@shopify/cli-kit';
|
|
2
2
|
import { renderWarning } from '@shopify/cli-kit/node/ui';
|
|
3
3
|
import { lockfiles } from '@shopify/cli-kit/node/node-package-manager';
|
|
4
|
+
import { fileExists } from '@shopify/cli-kit/node/fs';
|
|
5
|
+
import { gitFactory } from '@shopify/cli-kit/node/git';
|
|
4
6
|
function missingLockfileWarning() {
|
|
5
7
|
renderWarning({
|
|
6
8
|
headline: 'No lockfile found',
|
|
@@ -53,7 +55,7 @@ function lockfileIgnoredWarning(lockfile) {
|
|
|
53
55
|
export async function checkLockfileStatus(directory) {
|
|
54
56
|
const availableLockfiles = await lockfiles.reduce(async (acc, lockFileName) => {
|
|
55
57
|
const lockfilePath = path.resolve(directory, lockFileName);
|
|
56
|
-
if (await
|
|
58
|
+
if (await fileExists(lockfilePath)) {
|
|
57
59
|
return (await acc).concat(lockFileName);
|
|
58
60
|
}
|
|
59
61
|
else {
|
|
@@ -68,7 +70,7 @@ export async function checkLockfileStatus(directory) {
|
|
|
68
70
|
multipleLockfilesWarning(availableLockfiles);
|
|
69
71
|
return 'multiple';
|
|
70
72
|
}
|
|
71
|
-
const repo =
|
|
73
|
+
const repo = gitFactory(directory);
|
|
72
74
|
const lockfile = availableLockfiles[0];
|
|
73
75
|
const ignoredLockfile = await repo.checkIgnore([lockfile]);
|
|
74
76
|
if (ignoredLockfile.length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-lockfile.js","sourceRoot":"","sources":["../../../../src/cli/services/build/check-lockfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"check-lockfile.js","sourceRoot":"","sources":["../../../../src/cli/services/build/check-lockfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAC,SAAS,EAAC,MAAM,4CAA4C,CAAA;AACpE,OAAO,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAA;AAGpD,SAAS,sBAAsB;IAC7B,aAAa,CAAC;QACZ,QAAQ,EAAE,mBAAmB;QAC7B,IAAI,EACF,wEAAwE;YACxE,0EAA0E;YAC1E,gDAAgD;QAClD,SAAS,EAAE;YACT;gBACE,0BAA0B;gBAC1B;oBACE,OAAO,EAAE,uBAAuB;iBACjC;aACF;YACD,wCAAwC;SACzC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,SAAqB;IACrD,MAAM,eAAe,GAAG;QACtB,WAAW,EAAE,MAAM;QACnB,mBAAmB,EAAE,KAAK;QAC1B,gBAAgB,EAAE,MAAM;KACzB,CAAA;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC9C,OAAO,GAAG,QAAQ,gBAAgB,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAA;IAChE,CAAC,CAAC,CAAA;IAEF,aAAa,CAAC;QACZ,QAAQ,EAAE,0BAA0B;QACpC,IAAI,EAAE;YACJ,uEAAuE;gBACrE,kEAAkE;gBAClE,4BAA4B;YAC9B,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,YAAY,EAAC,EAAC;SAC9B;QACD,SAAS,EAAE,CAAC,+BAA+B,EAAE,sCAAsC,CAAC;KACrF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,QAAgB;IAC9C,aAAa,CAAC;QACZ,QAAQ,EAAE,yBAAyB;QACnC,IAAI,EACF,0EAA0E;YAC1E,0EAA0E;YAC1E,YAAY;QACd,SAAS,EAAE;YACT,+DAA+D,QAAQ,EAAE;YACzE,sCAAsC;SACvC;KACF,CAAC,CAAA;AACJ,CAAC;AAID,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IACzD,MAAM,kBAAkB,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE;QAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;QAC1D,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE;YAClC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;SACxC;aAAM;YACL,OAAO,GAAG,CAAA;SACX;IACH,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAgB,CAAC,CAAC,CAAA;IAErC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE;QAC9B,sBAAsB,EAAE,CAAA;QACxB,OAAO,SAAS,CAAA;KACjB;IAED,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;QACjC,wBAAwB,CAAC,kBAAkB,CAAC,CAAA;QAC5C,OAAO,UAAU,CAAA;KAClB;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAE,CAAA;IACvC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IAE1D,IAAI,eAAe,CAAC,MAAM,EAAE;QAC1B,sBAAsB,CAAC,QAAQ,CAAC,CAAA;QAChC,OAAO,SAAS,CAAA;KACjB;IAED,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import {path} from '@shopify/cli-kit'\nimport {renderWarning} from '@shopify/cli-kit/node/ui'\nimport {lockfiles} from '@shopify/cli-kit/node/node-package-manager'\nimport {fileExists} from '@shopify/cli-kit/node/fs'\nimport {gitFactory} from '@shopify/cli-kit/node/git'\nimport type {Lockfile} from '@shopify/cli-kit/node/node-package-manager'\n\nfunction missingLockfileWarning() {\n renderWarning({\n headline: 'No lockfile found',\n body:\n `If you don’t commit a lockfile, then your app might install the wrong ` +\n `package versions when deploying. To avoid versioning issues, generate a ` +\n `new lockfile and commit it to your repository.`,\n nextSteps: [\n [\n 'Generate a lockfile. Run',\n {\n command: 'npm|yarn|pnpm install',\n },\n ],\n 'Commit the new file to your repository',\n ],\n })\n}\n\nfunction multipleLockfilesWarning(lockfiles: Lockfile[]) {\n const packageManagers = {\n 'yarn.lock': 'yarn',\n 'package-lock.json': 'npm',\n 'pnpm-lock.yaml': 'pnpm',\n }\n\n const lockfileList = lockfiles.map((lockfile) => {\n return `${lockfile} (created by ${packageManagers[lockfile]})`\n })\n\n renderWarning({\n headline: 'Multiple lockfiles found',\n body: [\n `Your project contains more than one lockfile. This can cause version ` +\n `conflicts when installing and deploying your app. The following ` +\n `lockfiles were detected:\\n`,\n {list: {items: lockfileList}},\n ],\n nextSteps: ['Delete any unneeded lockfiles', 'Commit the change to your repository'],\n })\n}\n\nfunction lockfileIgnoredWarning(lockfile: string) {\n renderWarning({\n headline: 'Lockfile ignored by Git',\n body:\n `Your project’s lockfile isn’t being tracked by Git. If you don’t commit ` +\n `a lockfile, then your app might install the wrong package versions when ` +\n `deploying.`,\n nextSteps: [\n `In your project’s .gitignore file, delete any references to ${lockfile}`,\n 'Commit the change to your repository',\n ],\n })\n}\n\ntype LockFileStatus = 'missing' | 'multiple' | 'ignored' | 'ok'\n\nexport async function checkLockfileStatus(directory: string): Promise<LockFileStatus> {\n const availableLockfiles = await lockfiles.reduce(async (acc, lockFileName) => {\n const lockfilePath = path.resolve(directory, lockFileName)\n if (await fileExists(lockfilePath)) {\n return (await acc).concat(lockFileName)\n } else {\n return acc\n }\n }, Promise.resolve([] as Lockfile[]))\n\n if (!availableLockfiles.length) {\n missingLockfileWarning()\n return 'missing'\n }\n\n if (availableLockfiles.length > 1) {\n multipleLockfilesWarning(availableLockfiles)\n return 'multiple'\n }\n\n const repo = gitFactory(directory)\n const lockfile = availableLockfiles[0]!\n const ignoredLockfile = await repo.checkIgnore([lockfile])\n\n if (ignoredLockfile.length) {\n lockfileIgnoredWarning(lockfile)\n return 'ignored'\n }\n\n return 'ok'\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { gitInit } from '../../prompts/git-init.js';
|
|
2
|
-
import {
|
|
2
|
+
import { error, path } from '@shopify/cli-kit';
|
|
3
|
+
import { addAllToGitFromDirectory, createGitCommit, createGitIgnore, ensureGitIsPresentOrAbort, ensureInsideGitDirectory, getHeadSymbolicRef, getLatestGitCommit, initializeGitRepository, OutsideGitDirectoryError, } from '@shopify/cli-kit/node/git';
|
|
3
4
|
const MINIMAL_GIT_IGNORE = {
|
|
4
5
|
system: ['.DS_Store'],
|
|
5
6
|
logs: ['logs', '*.log', 'npm-debug.log*', 'yarn-debug.log*', 'yarn-error.log*'],
|
|
@@ -10,14 +11,17 @@ const MINIMAL_GIT_IGNORE = {
|
|
|
10
11
|
production: ['/dist'],
|
|
11
12
|
};
|
|
12
13
|
export const validateProject = async (config) => {
|
|
13
|
-
await
|
|
14
|
+
await ensureGitIsPresentOrAbort();
|
|
14
15
|
try {
|
|
15
|
-
await
|
|
16
|
+
await ensureInsideGitDirectory(config.path);
|
|
16
17
|
}
|
|
17
18
|
catch (err) {
|
|
18
|
-
if (err
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
if (err instanceof OutsideGitDirectoryError) {
|
|
20
|
+
await initializeGit(config);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw err;
|
|
24
|
+
}
|
|
21
25
|
}
|
|
22
26
|
};
|
|
23
27
|
export const initializeGit = async (config) => {
|
|
@@ -26,15 +30,15 @@ export const initializeGit = async (config) => {
|
|
|
26
30
|
if (!shouldGitInit)
|
|
27
31
|
throw new error.AbortSilent();
|
|
28
32
|
}
|
|
29
|
-
await
|
|
30
|
-
|
|
31
|
-
await
|
|
32
|
-
await
|
|
33
|
+
await initializeGitRepository(config.path);
|
|
34
|
+
createGitIgnore(config.path, MINIMAL_GIT_IGNORE);
|
|
35
|
+
await addAllToGitFromDirectory(config.path);
|
|
36
|
+
await createGitCommit('Initial commit generated by Hydrogen', { directory: config.path });
|
|
33
37
|
};
|
|
34
38
|
export const fillDeployConfig = async (config) => {
|
|
35
39
|
const [latestCommit, commitRef] = await Promise.all([
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
getLatestGitCommit(config.path),
|
|
41
|
+
getHeadSymbolicRef(config.path),
|
|
38
42
|
]);
|
|
39
43
|
return {
|
|
40
44
|
...config,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/cli/services/deploy/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,2BAA2B,CAAA;AACjD,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/cli/services/deploy/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,2BAA2B,CAAA;AACjD,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAElB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,2BAA2B,CAAA;AAElC,MAAM,kBAAkB,GAAsB;IAC5C,MAAM,EAAE,CAAC,WAAW,CAAC;IACrB,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;IAC/E,OAAO,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC;IAChC,YAAY,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,CAAC;IAC9E,UAAU,EAAE,CAAC,eAAe,CAAC;IAC7B,WAAW,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC;IAChD,UAAU,EAAE,CAAC,OAAO,CAAC;CACtB,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,MAAoB,EAAE,EAAE;IAC5D,MAAM,yBAAyB,EAAE,CAAA;IACjC,IAAI;QACF,MAAM,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;KAC5C;IAAC,OAAO,GAAY,EAAE;QACrB,IAAI,GAAG,YAAY,wBAAwB,EAAE;YAC3C,MAAM,aAAa,CAAC,MAAM,CAAC,CAAA;SAC5B;aAAM;YACL,MAAM,GAAG,CAAA;SACV;KACF;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,MAAoB,EAAE,EAAE;IAC1D,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;QACrB,MAAM,aAAa,GAAG,MAAM,OAAO,EAAE,CAAA;QACrC,IAAI,CAAC,aAAa;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,CAAA;KAClD;IAED,MAAM,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1C,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAA;IAChD,MAAM,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3C,MAAM,eAAe,CAAC,sCAAsC,EAAE,EAAC,SAAS,EAAE,MAAM,CAAC,IAAI,EAAC,CAAC,CAAA;AACzF,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,MAAoB,EAA4B,EAAE;IACvF,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/B,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC;KAChC,CAAC,CAAA;IAEF,OAAO;QACL,GAAG,MAAM;QACT,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;QACvE,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,YAAY,CAAC,OAAO;QAC3D,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,YAAY,CAAC,WAAW;QAC7D,SAAS,EAAE,YAAY,CAAC,IAAI;QAC5B,SAAS,EAAE,YAAY,CAAC,IAAI;QAC5B,SAAS;KACV,CAAA;AACH,CAAC,CAAA","sourcesContent":["import {DeployConfig, ReqDeployConfig} from './types.js'\nimport {gitInit} from '../../prompts/git-init.js'\nimport {error, path} from '@shopify/cli-kit'\nimport {\n addAllToGitFromDirectory,\n createGitCommit,\n createGitIgnore,\n ensureGitIsPresentOrAbort,\n ensureInsideGitDirectory,\n getHeadSymbolicRef,\n getLatestGitCommit,\n GitIgnoreTemplate,\n initializeGitRepository,\n OutsideGitDirectoryError,\n} from '@shopify/cli-kit/node/git'\n\nconst MINIMAL_GIT_IGNORE: GitIgnoreTemplate = {\n system: ['.DS_Store'],\n logs: ['logs', '*.log', 'npm-debug.log*', 'yarn-debug.log*', 'yarn-error.log*'],\n testing: ['/coverage', '*.lcov'],\n dependencies: ['/node_modules', '.npm', '.yarn-integrity', '/.pnp', '.pnp.js'],\n typescript: ['*.tsbuildinfo'],\n environment: ['.env', '.env.test', '.env.local'],\n production: ['/dist'],\n}\n\nexport const validateProject = async (config: DeployConfig) => {\n await ensureGitIsPresentOrAbort()\n try {\n await ensureInsideGitDirectory(config.path)\n } catch (err: unknown) {\n if (err instanceof OutsideGitDirectoryError) {\n await initializeGit(config)\n } else {\n throw err\n }\n }\n}\n\nexport const initializeGit = async (config: DeployConfig) => {\n if (!config.assumeYes) {\n const shouldGitInit = await gitInit()\n if (!shouldGitInit) throw new error.AbortSilent()\n }\n\n await initializeGitRepository(config.path)\n createGitIgnore(config.path, MINIMAL_GIT_IGNORE)\n await addAllToGitFromDirectory(config.path)\n await createGitCommit('Initial commit generated by Hydrogen', {directory: config.path})\n}\n\nexport const fillDeployConfig = async (config: DeployConfig): Promise<ReqDeployConfig> => {\n const [latestCommit, commitRef] = await Promise.all([\n getLatestGitCommit(config.path),\n getHeadSymbolicRef(config.path),\n ])\n\n return {\n ...config,\n pathToBuild: config.pathToBuild ? path.resolve(config.pathToBuild) : '',\n commitMessage: config.commitMessage ?? latestCommit.message,\n commitAuthor: config.commitAuthor ?? latestCommit.author_name,\n commitSha: latestCommit.hash,\n timestamp: latestCommit.date,\n commitRef,\n }\n}\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CreateDeploymentQuery, } from './graphql/create_deployment.js';
|
|
2
2
|
import { UnrecoverableError, WebPageNotAvailable, TooManyRequestsError } from './error.js';
|
|
3
3
|
import { UploadDeploymentQuery } from './graphql/upload_deployment.js';
|
|
4
|
-
import { http
|
|
4
|
+
import { http } from '@shopify/cli-kit';
|
|
5
5
|
import { zip } from '@shopify/cli-kit/node/archiver';
|
|
6
6
|
import { ClientError } from 'graphql-request';
|
|
7
7
|
import { uploadOxygenDeploymentFile, oxygenRequest } from '@shopify/cli-kit/node/api/oxygen';
|
|
8
|
+
import { inTemporaryDirectory, createFileReadStream } from '@shopify/cli-kit/node/fs';
|
|
8
9
|
export const createDeployment = async (config) => {
|
|
9
10
|
const variables = {
|
|
10
11
|
input: {
|
|
@@ -36,14 +37,14 @@ export const createDeployment = async (config) => {
|
|
|
36
37
|
};
|
|
37
38
|
export const uploadDeployment = async (config, deploymentID) => {
|
|
38
39
|
let deploymentData;
|
|
39
|
-
await
|
|
40
|
+
await inTemporaryDirectory(async (tmpDir) => {
|
|
40
41
|
const distPath = config.pathToBuild ? config.pathToBuild : `${config.path}/dist`;
|
|
41
42
|
const distZipPath = `${tmpDir}/dist.zip`;
|
|
42
43
|
await zip(distPath, distZipPath);
|
|
43
44
|
const formData = http.formData();
|
|
44
45
|
formData.append('operations', buildOperationsString(deploymentID));
|
|
45
46
|
formData.append('map', JSON.stringify({ '0': ['variables.file'] }));
|
|
46
|
-
formData.append('0',
|
|
47
|
+
formData.append('0', createFileReadStream(distZipPath), { filename: distZipPath });
|
|
47
48
|
const response = await uploadOxygenDeploymentFile(config.oxygenAddress, config.deploymentToken, formData);
|
|
48
49
|
if (!response.ok) {
|
|
49
50
|
if (response.status === 429) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../../src/cli/services/deploy/upload.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,qBAAqB,GACtB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,YAAY,CAAA;AACxF,OAAO,EAAC,qBAAqB,EAAC,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../../src/cli/services/deploy/upload.ts"],"names":[],"mappings":"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","sourcesContent":["import {ReqDeployConfig, UploadDeploymentResponse} from './types.js'\nimport {\n CreateDeploymentResponse,\n CreateDeploymentQuerySchema,\n CreateDeploymentQuery,\n} from './graphql/create_deployment.js'\nimport {UnrecoverableError, WebPageNotAvailable, TooManyRequestsError} from './error.js'\nimport {UploadDeploymentQuery} from './graphql/upload_deployment.js'\nimport {http} from '@shopify/cli-kit'\nimport {zip} from '@shopify/cli-kit/node/archiver'\nimport {ClientError} from 'graphql-request'\nimport {uploadOxygenDeploymentFile, oxygenRequest} from '@shopify/cli-kit/node/api/oxygen'\nimport {inTemporaryDirectory, createFileReadStream} from '@shopify/cli-kit/node/fs'\n\nexport const createDeployment = async (config: ReqDeployConfig): Promise<CreateDeploymentResponse> => {\n const variables = {\n input: {\n branch: config.commitRef,\n commitHash: config.commitSha,\n commitAuthor: config.commitAuthor,\n commitMessage: config.commitMessage,\n commitTimestamp: config.timestamp,\n },\n }\n\n try {\n const response: CreateDeploymentQuerySchema = await oxygenRequest(\n config.oxygenAddress,\n CreateDeploymentQuery,\n config.deploymentToken,\n variables,\n )\n\n if (response.createDeployment?.error) {\n if (response.createDeployment.error.unrecoverable) {\n throw UnrecoverableError(response.createDeployment.error.debugInfo)\n }\n\n throw new Error(`Failed to create deployment. ${response.createDeployment.error.debugInfo}`)\n }\n\n return response.createDeployment\n } catch (error) {\n if (error instanceof ClientError) {\n if (error.response.status === 429) {\n throw TooManyRequestsError()\n }\n }\n\n throw error\n }\n}\n\nexport const uploadDeployment = async (config: ReqDeployConfig, deploymentID: string): Promise<string> => {\n let deploymentData: UploadDeploymentResponse | undefined\n\n await inTemporaryDirectory(async (tmpDir) => {\n const distPath = config.pathToBuild ? config.pathToBuild : `${config.path}/dist`\n const distZipPath = `${tmpDir}/dist.zip`\n await zip(distPath, distZipPath)\n\n const formData = http.formData()\n formData.append('operations', buildOperationsString(deploymentID))\n formData.append('map', JSON.stringify({'0': ['variables.file']}))\n formData.append('0', createFileReadStream(distZipPath), {filename: distZipPath})\n\n const response = await uploadOxygenDeploymentFile(config.oxygenAddress, config.deploymentToken, formData)\n if (!response.ok) {\n if (response.status === 429) {\n throw TooManyRequestsError()\n }\n if (response.status !== 200 && response.status !== 202) {\n throw new Error(`Failed to upload deployment. ${await response.json()}`)\n }\n }\n\n deploymentData = (await response.json()) as UploadDeploymentResponse\n })\n\n if (!deploymentData) {\n throw new Error('Failed to upload deployment.')\n }\n const deploymentError = deploymentData.data?.uploadDeployment?.error\n if (deploymentError) {\n if (deploymentError.unrecoverable) {\n throw UnrecoverableError(deploymentError.debugInfo)\n }\n\n throw new Error(`Failed to upload deployment: ${deploymentError.debugInfo}`)\n }\n\n return deploymentData.data.uploadDeployment.deployment.previewURL\n}\n\nexport const healthCheck = async (pingUrl: string) => {\n const url = `${pingUrl}/__health`\n const result = await http.fetch(url, {method: 'GET'})\n if (result.status !== 200) throw WebPageNotAvailable()\n}\n\nconst buildOperationsString = (deploymentID: string): string => {\n return JSON.stringify({\n query: UploadDeploymentQuery,\n variables: {deploymentID, file: null},\n })\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { genericConfigurationFileNames } from '../constants.js';
|
|
2
|
-
import { ui, npm,
|
|
2
|
+
import { ui, npm, path, error } from '@shopify/cli-kit';
|
|
3
3
|
import { addNPMDependenciesWithoutVersionIfNeeded } from '@shopify/cli-kit/node/node-package-manager';
|
|
4
4
|
import { addRecommendedExtensions, isVSCode } from '@shopify/cli-kit/node/vscode';
|
|
5
5
|
import { isUnitTest } from '@shopify/cli-kit/node/environment/local';
|
|
6
|
+
import { writeFile, fileExists, removeFile, fileContentPrettyFormat } from '@shopify/cli-kit/node/fs';
|
|
6
7
|
import stream from 'stream';
|
|
7
8
|
export async function addESLint({ app, force, install }) {
|
|
8
9
|
const list = ui.newListr([
|
|
@@ -35,9 +36,9 @@ export async function addESLint({ app, force, install }) {
|
|
|
35
36
|
title: 'Adding ESLint configuration',
|
|
36
37
|
task: async (_, task) => {
|
|
37
38
|
const eslintConfigPath = path.join(app.directory, genericConfigurationFileNames.eslint);
|
|
38
|
-
if (await
|
|
39
|
+
if (await fileExists(eslintConfigPath)) {
|
|
39
40
|
if (force) {
|
|
40
|
-
await
|
|
41
|
+
await removeFile(eslintConfigPath);
|
|
41
42
|
}
|
|
42
43
|
else {
|
|
43
44
|
throw new error.Abort('ESLint config already exists.', 'Use --force to override existing config.');
|
|
@@ -47,8 +48,8 @@ export async function addESLint({ app, force, install }) {
|
|
|
47
48
|
if (app.language === 'TypeScript') {
|
|
48
49
|
extended.push(`'plugin:hydrogen/typescript'`);
|
|
49
50
|
}
|
|
50
|
-
const eslintConfig = await
|
|
51
|
-
await
|
|
51
|
+
const eslintConfig = await fileContentPrettyFormat(['module.exports = {', 'extends: [', `${extended.join(',')}`, ' ],', ' };'].join('\n'), { path: genericConfigurationFileNames.eslint });
|
|
52
|
+
await writeFile(eslintConfigPath, eslintConfig);
|
|
52
53
|
task.title = 'ESLint configuration added';
|
|
53
54
|
},
|
|
54
55
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../../src/cli/services/eslint.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,6BAA6B,EAAC,MAAM,iBAAiB,CAAA;AAC7D,OAAO,EAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,
|
|
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, npm, path, error} from '@shopify/cli-kit'\nimport {addNPMDependenciesWithoutVersionIfNeeded} from '@shopify/cli-kit/node/node-package-manager'\nimport {addRecommendedExtensions, isVSCode} from '@shopify/cli-kit/node/vscode'\nimport {isUnitTest} from '@shopify/cli-kit/node/environment/local'\nimport {writeFile, fileExists, removeFile, fileContentPrettyFormat} from '@shopify/cli-kit/node/fs'\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 fileExists(eslintConfigPath)) {\n if (force) {\n await removeFile(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 fileContentPrettyFormat(\n ['module.exports = {', 'extends: [', `${extended.join(',')}`, ' ],', ' };'].join('\\n'),\n {path: genericConfigurationFileNames.eslint},\n )\n\n await writeFile(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 isVSCode(app.directory)),\n task: async (_, task) => {\n await addRecommendedExtensions(app.directory, ['dbaeumer.vscode-eslint'])\n task.title = 'Editor plugin recommendations added'\n },\n },\n ],\n {rendererSilent: isUnitTest()},\n )\n await list.run()\n}\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { path, error,
|
|
1
|
+
import { path, error, output } from '@shopify/cli-kit';
|
|
2
2
|
import { readAndParseDotEnv } from '@shopify/cli-kit/node/dot-env';
|
|
3
|
+
import { fileExists, removeFileSync, writeFile } from '@shopify/cli-kit/node/fs';
|
|
3
4
|
import { exec } from '@shopify/cli-kit/node/system';
|
|
4
5
|
import { fileURLToPath } from 'url';
|
|
5
6
|
export async function previewInNode({ directory, port }) {
|
|
6
7
|
const buildOutputPath = await path.resolve(directory, 'dist/node');
|
|
7
|
-
if (!(await
|
|
8
|
+
if (!(await fileExists(buildOutputPath))) {
|
|
8
9
|
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.`);
|
|
9
10
|
await exec('yarn', ['shopify', 'hydrogen', 'build', '--target=node'], {
|
|
10
11
|
cwd: directory,
|
|
@@ -31,10 +32,10 @@ export async function previewInWorker({ directory, port, envPath }) {
|
|
|
31
32
|
autoReload: true,
|
|
32
33
|
...(envPath && (await parseEnvPath(envPath))),
|
|
33
34
|
};
|
|
34
|
-
await
|
|
35
|
+
await writeFile(path.resolve(directory, 'mini-oxygen.config.json'), JSON.stringify(config, null, 2));
|
|
35
36
|
function cleanUp(options) {
|
|
36
37
|
if (options.exit) {
|
|
37
|
-
|
|
38
|
+
removeFileSync(path.resolve(directory, 'mini-oxygen.config.json'));
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
async function parseEnvPath(envPath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/cli/services/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/cli/services/preview.ts"],"names":[],"mappings":"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","sourcesContent":["import {path, error, output} from '@shopify/cli-kit'\nimport {readAndParseDotEnv, DotEnvFile} from '@shopify/cli-kit/node/dot-env'\nimport {fileExists, removeFileSync, writeFile} from '@shopify/cli-kit/node/fs'\nimport {exec} from '@shopify/cli-kit/node/system'\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 fileExists(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 exec('yarn', ['shopify', 'hydrogen', 'build', '--target=node'], {\n cwd: directory,\n stdout: process.stdout,\n stderr: process.stderr,\n })\n }\n\n await 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 writeFile(path.resolve(directory, 'mini-oxygen.config.json'), JSON.stringify(config, null, 2))\n\n function cleanUp(options: {exit: boolean}) {\n if (options.exit) {\n removeFileSync(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 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"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ui, path,
|
|
1
|
+
import { ui, path, error } from '@shopify/cli-kit';
|
|
2
2
|
import { addNPMDependenciesWithoutVersionIfNeeded } from '@shopify/cli-kit/node/node-package-manager';
|
|
3
3
|
import { addRecommendedExtensions } from '@shopify/cli-kit/node/vscode';
|
|
4
4
|
import { exec } from '@shopify/cli-kit/node/system';
|
|
5
|
+
import { writeFile, fileExists, removeFile, fileContentPrettyFormat, readFile } from '@shopify/cli-kit/node/fs';
|
|
5
6
|
import stream from 'stream';
|
|
6
7
|
const tailwindImports = [
|
|
7
8
|
"@import 'tailwindcss/base';",
|
|
@@ -40,16 +41,16 @@ export async function addTailwind({ app, force, install, directory }) {
|
|
|
40
41
|
title: 'Adding PostCSS configuration',
|
|
41
42
|
task: async (_, task) => {
|
|
42
43
|
const postCSSConfiguration = path.join(directory, 'postcss.config.js');
|
|
43
|
-
if (await
|
|
44
|
+
if (await fileExists(postCSSConfiguration)) {
|
|
44
45
|
if (force) {
|
|
45
|
-
await
|
|
46
|
+
await removeFile(postCSSConfiguration);
|
|
46
47
|
}
|
|
47
48
|
else {
|
|
48
49
|
throw new error.Abort('PostCSS config already exists.\nUse --force to override existing config.');
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
const postCSSConfig = await
|
|
52
|
-
await
|
|
52
|
+
const postCSSConfig = await fileContentPrettyFormat(['module.exports = {', 'plugins: {', 'tailwindcss: {},', 'autoprefixer: {},', '},', ' };'].join('\n'), { path: 'postcss.config.js' });
|
|
53
|
+
await writeFile(postCSSConfiguration, postCSSConfig);
|
|
53
54
|
task.title = 'PostCSS configuration added';
|
|
54
55
|
},
|
|
55
56
|
},
|
|
@@ -57,9 +58,9 @@ export async function addTailwind({ app, force, install, directory }) {
|
|
|
57
58
|
title: 'Initializing Tailwind CSS...',
|
|
58
59
|
task: async (_, task) => {
|
|
59
60
|
const tailwindConfigurationPath = path.join(directory, 'tailwind.config.js');
|
|
60
|
-
if (await
|
|
61
|
+
if (await fileExists(tailwindConfigurationPath)) {
|
|
61
62
|
if (force) {
|
|
62
|
-
await
|
|
63
|
+
await removeFile(tailwindConfigurationPath);
|
|
63
64
|
}
|
|
64
65
|
else {
|
|
65
66
|
throw new error.Abort('Tailwind config already exists.\nUse --force to override existing config.');
|
|
@@ -76,13 +77,13 @@ export async function addTailwind({ app, force, install, directory }) {
|
|
|
76
77
|
title: 'Importing Tailwind CSS in index.css',
|
|
77
78
|
task: async (_ctx, task) => {
|
|
78
79
|
const indexCSSPath = path.join(directory, 'src', 'index.css');
|
|
79
|
-
const indexCSS = await
|
|
80
|
+
const indexCSS = await readFile(indexCSSPath);
|
|
80
81
|
if (tailwindImportsExist(indexCSS)) {
|
|
81
82
|
task.skip('Imports already exist in index.css');
|
|
82
83
|
}
|
|
83
84
|
else {
|
|
84
85
|
const newIndexCSS = tailwindImports.join('\n') + indexCSS;
|
|
85
|
-
await
|
|
86
|
+
await writeFile(indexCSSPath, newIndexCSS);
|
|
86
87
|
}
|
|
87
88
|
task.title = 'Tailwind imports added';
|
|
88
89
|
},
|
|
@@ -98,8 +99,8 @@ export async function addTailwind({ app, force, install, directory }) {
|
|
|
98
99
|
await list.run();
|
|
99
100
|
}
|
|
100
101
|
async function replace(find, replace, filepath) {
|
|
101
|
-
const original = await
|
|
102
|
+
const original = await readFile(filepath);
|
|
102
103
|
const modified = original.replace(find, replace);
|
|
103
|
-
await
|
|
104
|
+
await writeFile(filepath, modified);
|
|
104
105
|
}
|
|
105
106
|
//# sourceMappingURL=tailwind.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailwind.js","sourceRoot":"","sources":["../../../src/cli/services/tailwind.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,EAAE,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"tailwind.js","sourceRoot":"","sources":["../../../src/cli/services/tailwind.ts"],"names":[],"mappings":"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","sourcesContent":["import {HydrogenApp} from '../models/hydrogen.js'\nimport {ui, path, error} from '@shopify/cli-kit'\nimport {addNPMDependenciesWithoutVersionIfNeeded} from '@shopify/cli-kit/node/node-package-manager'\nimport {addRecommendedExtensions} from '@shopify/cli-kit/node/vscode'\nimport {exec} from '@shopify/cli-kit/node/system'\nimport {writeFile, fileExists, removeFile, fileContentPrettyFormat, readFile} from '@shopify/cli-kit/node/fs'\nimport stream from 'stream'\n\ninterface AddTailwindOptions {\n app: HydrogenApp\n force: boolean\n directory: string\n install: boolean\n}\n\nconst tailwindImports = [\n \"@import 'tailwindcss/base';\",\n \"@import 'tailwindcss/components';\",\n \"@import 'tailwindcss/utilities';\",\n]\n\nconst tailwindImportsExist = (indexCSS: string) =>\n tailwindImports.map((el) => new RegExp(el)).every((tailwindDirective) => tailwindDirective.test(indexCSS))\n\nexport async function addTailwind({app, force, install, directory}: AddTailwindOptions) {\n const list = ui.newListr([\n {\n title: 'Installing additional dependencies',\n skip: () => !install,\n task: async (_, task) => {\n const requiredDependencies = ['postcss', 'postcss-loader', 'tailwindcss', 'autoprefixer']\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 PostCSS configuration',\n task: async (_, task) => {\n const postCSSConfiguration = path.join(directory, 'postcss.config.js')\n\n if (await fileExists(postCSSConfiguration)) {\n if (force) {\n await removeFile(postCSSConfiguration)\n } else {\n throw new error.Abort('PostCSS config already exists.\\nUse --force to override existing config.')\n }\n }\n\n const postCSSConfig = await fileContentPrettyFormat(\n ['module.exports = {', 'plugins: {', 'tailwindcss: {},', 'autoprefixer: {},', '},', ' };'].join('\\n'),\n {path: 'postcss.config.js'},\n )\n\n await writeFile(postCSSConfiguration, postCSSConfig)\n\n task.title = 'PostCSS configuration added'\n },\n },\n\n {\n title: 'Initializing Tailwind CSS...',\n task: async (_, task) => {\n const tailwindConfigurationPath = path.join(directory, 'tailwind.config.js')\n\n if (await fileExists(tailwindConfigurationPath)) {\n if (force) {\n await removeFile(tailwindConfigurationPath)\n } else {\n throw new error.Abort('Tailwind config already exists.\\nUse --force to override existing config.')\n }\n }\n\n await exec(app.packageManager, ['tailwindcss', 'init', tailwindConfigurationPath], {\n cwd: directory,\n })\n\n await replace(\n 'content: []',\n \"content: ['./index.html', './src/**/*.{js,jsx,ts,tsx}']\",\n tailwindConfigurationPath,\n )\n\n task.title = 'Tailwind configuration added'\n },\n },\n {\n title: 'Importing Tailwind CSS in index.css',\n task: async (_ctx, task) => {\n const indexCSSPath = path.join(directory, 'src', 'index.css')\n const indexCSS = await readFile(indexCSSPath)\n\n if (tailwindImportsExist(indexCSS)) {\n task.skip('Imports already exist in index.css')\n } else {\n const newIndexCSS = tailwindImports.join('\\n') + indexCSS\n\n await writeFile(indexCSSPath, newIndexCSS)\n }\n\n task.title = 'Tailwind imports added'\n },\n },\n {\n title: 'Adding editor plugin recommendations',\n task: async (_, task) => {\n await addRecommendedExtensions(directory, ['csstools.postcss', 'bradlc.vscode-tailwindcss'])\n task.title = 'Editor plugin recommendations added'\n },\n },\n ])\n await list.run()\n}\n\nasync function replace(find: string | RegExp, replace: string, filepath: string) {\n const original = await readFile(filepath)\n const modified = original.replace(find, replace)\n await writeFile(filepath, modified)\n}\n"]}
|