@shopify/cli-hydrogen 5.0.2 → 5.1.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/commands/hydrogen/build.js +16 -2
- package/dist/commands/hydrogen/codegen-unstable.js +13 -24
- package/dist/commands/hydrogen/dev.js +45 -39
- package/dist/commands/hydrogen/env/list.js +25 -24
- package/dist/commands/hydrogen/env/list.test.js +46 -43
- package/dist/commands/hydrogen/env/pull.js +53 -25
- package/dist/commands/hydrogen/env/pull.test.js +123 -42
- package/dist/commands/hydrogen/generate/route.js +31 -132
- package/dist/commands/hydrogen/generate/route.test.js +34 -126
- package/dist/commands/hydrogen/init.js +46 -127
- package/dist/commands/hydrogen/init.test.js +352 -100
- package/dist/commands/hydrogen/link.js +70 -69
- package/dist/commands/hydrogen/link.test.js +72 -107
- package/dist/commands/hydrogen/list.js +22 -12
- package/dist/commands/hydrogen/list.test.js +51 -48
- package/dist/commands/hydrogen/login.js +31 -0
- package/dist/commands/hydrogen/logout.js +21 -0
- package/dist/commands/hydrogen/setup/css.js +79 -0
- package/dist/commands/hydrogen/setup/markets.js +53 -0
- package/dist/commands/hydrogen/setup.js +133 -0
- package/dist/commands/hydrogen/shortcut.js +2 -45
- package/dist/commands/hydrogen/shortcut.test.js +10 -37
- package/dist/generator-templates/assets/css-modules/package.json +6 -0
- package/dist/generator-templates/assets/postcss/package.json +10 -0
- package/dist/generator-templates/assets/postcss/postcss.config.js +8 -0
- package/dist/generator-templates/assets/tailwind/package.json +13 -0
- package/dist/generator-templates/assets/tailwind/postcss.config.js +10 -0
- package/dist/generator-templates/assets/tailwind/tailwind.config.js +8 -0
- package/dist/generator-templates/assets/tailwind/tailwind.css +3 -0
- package/dist/generator-templates/assets/vanilla-extract/package.json +9 -0
- package/dist/generator-templates/starter/.eslintignore +5 -0
- package/dist/generator-templates/starter/.eslintrc.js +18 -0
- package/dist/generator-templates/starter/.graphqlrc.yml +1 -0
- package/dist/generator-templates/starter/README.md +40 -0
- package/dist/generator-templates/starter/app/components/Aside.tsx +47 -0
- package/dist/generator-templates/starter/app/components/Cart.tsx +340 -0
- package/dist/generator-templates/starter/app/components/Footer.tsx +99 -0
- package/dist/generator-templates/starter/app/components/Header.tsx +178 -0
- package/dist/generator-templates/starter/app/components/Layout.tsx +95 -0
- package/dist/generator-templates/starter/app/components/Search.tsx +480 -0
- package/dist/generator-templates/starter/app/entry.client.tsx +12 -0
- package/dist/generator-templates/starter/app/entry.server.tsx +33 -0
- package/dist/generator-templates/starter/app/root.tsx +270 -0
- package/dist/generator-templates/starter/app/routes/$.tsx +7 -0
- package/dist/generator-templates/{routes → starter/app/routes}/[robots.txt].tsx +47 -69
- package/dist/generator-templates/starter/app/routes/[sitemap.xml].tsx +174 -0
- package/dist/generator-templates/starter/app/routes/_index.tsx +145 -0
- package/dist/generator-templates/starter/app/routes/account.$.tsx +9 -0
- package/dist/generator-templates/starter/app/routes/account.addresses.tsx +563 -0
- package/dist/generator-templates/starter/app/routes/account.orders.$id.tsx +309 -0
- package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +196 -0
- package/dist/generator-templates/starter/app/routes/account.profile.tsx +289 -0
- package/dist/generator-templates/starter/app/routes/account.tsx +203 -0
- package/dist/generator-templates/starter/app/routes/account_.activate.$id.$activationToken.tsx +157 -0
- package/dist/generator-templates/starter/app/routes/account_.login.tsx +143 -0
- package/dist/generator-templates/starter/app/routes/account_.logout.tsx +33 -0
- package/dist/generator-templates/starter/app/routes/account_.recover.tsx +124 -0
- package/dist/generator-templates/starter/app/routes/account_.register.tsx +207 -0
- package/dist/generator-templates/starter/app/routes/account_.reset.$id.$resetToken.tsx +136 -0
- package/dist/generator-templates/starter/app/routes/api.predictive-search.tsx +342 -0
- package/dist/generator-templates/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +88 -0
- package/dist/generator-templates/starter/app/routes/blogs.$blogHandle._index.tsx +162 -0
- package/dist/generator-templates/starter/app/routes/blogs._index.tsx +94 -0
- package/dist/generator-templates/starter/app/routes/cart.tsx +104 -0
- package/dist/generator-templates/starter/app/routes/collections.$handle.tsx +184 -0
- package/dist/generator-templates/starter/app/routes/collections._index.tsx +120 -0
- package/dist/generator-templates/starter/app/routes/pages.$handle.tsx +57 -0
- package/dist/generator-templates/starter/app/routes/policies.$handle.tsx +94 -0
- package/dist/generator-templates/starter/app/routes/policies._index.tsx +63 -0
- package/dist/generator-templates/starter/app/routes/products.$handle.tsx +418 -0
- package/dist/generator-templates/starter/app/routes/search.tsx +168 -0
- package/dist/generator-templates/starter/app/styles/app.css +473 -0
- package/dist/generator-templates/starter/app/styles/reset.css +129 -0
- package/dist/generator-templates/starter/app/utils.ts +46 -0
- package/dist/generator-templates/starter/package.json +43 -0
- package/dist/generator-templates/starter/public/favicon.svg +28 -0
- package/dist/generator-templates/starter/remix.config.js +26 -0
- package/dist/generator-templates/starter/remix.env.d.ts +39 -0
- package/dist/generator-templates/starter/server.ts +253 -0
- package/dist/generator-templates/starter/storefrontapi.generated.d.ts +1906 -0
- package/dist/generator-templates/starter/tsconfig.json +22 -0
- package/dist/lib/auth.js +123 -0
- package/dist/lib/auth.test.js +157 -0
- package/dist/lib/build.js +51 -0
- package/dist/lib/check-version.js +3 -3
- package/dist/lib/check-version.test.js +24 -0
- package/dist/lib/codegen.js +26 -17
- package/dist/lib/environment-variables.js +68 -0
- package/dist/lib/environment-variables.test.js +147 -0
- package/dist/lib/file.js +41 -0
- package/dist/lib/file.test.js +69 -0
- package/dist/lib/flags.js +39 -2
- package/dist/lib/format-code.js +26 -0
- package/dist/lib/gid.js +12 -0
- package/dist/lib/{graphql.test.js → gid.test.js} +1 -1
- package/dist/lib/graphql/admin/client.js +27 -0
- package/dist/lib/graphql/admin/client.test.js +51 -0
- package/dist/lib/graphql/admin/create-storefront.js +13 -15
- package/dist/lib/graphql/admin/create-storefront.test.js +64 -0
- package/dist/lib/graphql/admin/fetch-job.js +6 -15
- package/dist/lib/graphql/admin/link-storefront.js +7 -11
- package/dist/lib/graphql/admin/link-storefront.test.js +38 -0
- package/dist/lib/graphql/admin/list-environments.js +2 -2
- package/dist/lib/graphql/admin/list-environments.test.js +44 -0
- package/dist/lib/graphql/admin/list-storefronts.js +7 -11
- package/dist/lib/graphql/admin/list-storefronts.test.js +44 -0
- package/dist/lib/graphql/admin/pull-variables.js +3 -3
- package/dist/lib/graphql/admin/pull-variables.test.js +37 -0
- package/dist/lib/graphql/business-platform/user-account.js +83 -0
- package/dist/lib/graphql/business-platform/user-account.test.js +80 -0
- package/dist/lib/log.js +185 -9
- package/dist/lib/log.test.js +92 -0
- package/dist/lib/mini-oxygen.js +19 -9
- package/dist/lib/missing-routes.js +0 -2
- package/dist/lib/onboarding/common.js +456 -0
- package/dist/lib/onboarding/index.js +2 -0
- package/dist/lib/onboarding/local.js +229 -0
- package/dist/lib/onboarding/remote.js +89 -0
- package/dist/lib/remix-version-interop.js +5 -5
- package/dist/lib/remix-version-interop.test.js +11 -1
- package/dist/lib/render-errors.js +13 -11
- package/dist/lib/setups/css/assets.js +89 -0
- package/dist/lib/setups/css/css-modules.js +22 -0
- package/dist/lib/setups/css/index.js +44 -0
- package/dist/lib/setups/css/postcss.js +34 -0
- package/dist/lib/setups/css/replacers.js +137 -0
- package/dist/lib/setups/css/tailwind.js +54 -0
- package/dist/lib/setups/css/vanilla-extract.js +22 -0
- package/dist/lib/setups/i18n/domains.test.js +25 -0
- package/dist/lib/setups/i18n/index.js +46 -0
- package/dist/lib/setups/i18n/replacers.js +227 -0
- package/dist/lib/setups/i18n/subdomains.test.js +25 -0
- package/dist/lib/setups/i18n/subfolders.test.js +25 -0
- package/dist/lib/setups/i18n/templates/domains.js +14 -0
- package/dist/lib/setups/i18n/templates/domains.ts +25 -0
- package/dist/lib/setups/i18n/templates/subdomains.js +14 -0
- package/dist/lib/setups/i18n/templates/subdomains.ts +24 -0
- package/dist/lib/setups/i18n/templates/subfolders.js +14 -0
- package/dist/lib/setups/i18n/templates/subfolders.ts +28 -0
- package/dist/lib/setups/routes/generate.js +244 -0
- package/dist/lib/setups/routes/generate.test.js +313 -0
- package/dist/lib/shell.js +52 -5
- package/dist/lib/shell.test.js +42 -16
- package/dist/lib/shopify-config.js +23 -18
- package/dist/lib/shopify-config.test.js +63 -73
- package/dist/lib/template-downloader.js +9 -7
- package/dist/lib/transpile-ts.js +9 -29
- package/dist/virtual-routes/routes/index.jsx +40 -19
- package/oclif.manifest.json +710 -1
- package/package.json +16 -16
- package/dist/commands/hydrogen/build.d.ts +0 -23
- package/dist/commands/hydrogen/check.d.ts +0 -15
- package/dist/commands/hydrogen/codegen-unstable.d.ts +0 -15
- package/dist/commands/hydrogen/dev.d.ts +0 -21
- package/dist/commands/hydrogen/env/list.d.ts +0 -18
- package/dist/commands/hydrogen/env/pull.d.ts +0 -22
- package/dist/commands/hydrogen/g.d.ts +0 -10
- package/dist/commands/hydrogen/generate/route.d.ts +0 -32
- package/dist/commands/hydrogen/generate/route.test.d.ts +0 -1
- package/dist/commands/hydrogen/generate/routes.d.ts +0 -16
- package/dist/commands/hydrogen/init.d.ts +0 -24
- package/dist/commands/hydrogen/init.test.d.ts +0 -1
- package/dist/commands/hydrogen/link.d.ts +0 -23
- package/dist/commands/hydrogen/link.test.d.ts +0 -1
- package/dist/commands/hydrogen/list.d.ts +0 -21
- package/dist/commands/hydrogen/list.test.d.ts +0 -1
- package/dist/commands/hydrogen/preview.d.ts +0 -17
- package/dist/commands/hydrogen/shortcut.d.ts +0 -9
- package/dist/commands/hydrogen/shortcut.test.d.ts +0 -1
- package/dist/commands/hydrogen/unlink.d.ts +0 -16
- package/dist/commands/hydrogen/unlink.test.d.ts +0 -1
- package/dist/create-app.d.ts +0 -1
- package/dist/generator-templates/routes/[sitemap.xml].tsx +0 -235
- package/dist/generator-templates/routes/account/login.tsx +0 -103
- package/dist/generator-templates/routes/account/register.tsx +0 -103
- package/dist/generator-templates/routes/cart.tsx +0 -81
- package/dist/generator-templates/routes/collections/$collectionHandle.tsx +0 -104
- package/dist/generator-templates/routes/collections/index.tsx +0 -102
- package/dist/generator-templates/routes/graphiql.tsx +0 -10
- package/dist/generator-templates/routes/index.tsx +0 -40
- package/dist/generator-templates/routes/pages/$pageHandle.tsx +0 -112
- package/dist/generator-templates/routes/policies/$policyHandle.tsx +0 -140
- package/dist/generator-templates/routes/policies/index.tsx +0 -117
- package/dist/generator-templates/routes/products/$productHandle.tsx +0 -92
- package/dist/hooks/init.d.ts +0 -5
- package/dist/lib/admin-session.d.ts +0 -6
- package/dist/lib/admin-session.js +0 -16
- package/dist/lib/admin-session.test.d.ts +0 -1
- package/dist/lib/admin-session.test.js +0 -27
- package/dist/lib/admin-urls.d.ts +0 -8
- package/dist/lib/check-lockfile.d.ts +0 -3
- package/dist/lib/check-lockfile.test.d.ts +0 -1
- package/dist/lib/check-version.d.ts +0 -16
- package/dist/lib/check-version.test.d.ts +0 -1
- package/dist/lib/codegen.d.ts +0 -26
- package/dist/lib/combined-environment-variables.d.ts +0 -8
- package/dist/lib/combined-environment-variables.js +0 -57
- package/dist/lib/combined-environment-variables.test.d.ts +0 -1
- package/dist/lib/combined-environment-variables.test.js +0 -111
- package/dist/lib/config.d.ts +0 -20
- package/dist/lib/flags.d.ts +0 -27
- package/dist/lib/flags.test.d.ts +0 -1
- package/dist/lib/graphql/admin/create-storefront.d.ts +0 -17
- package/dist/lib/graphql/admin/fetch-job.d.ts +0 -23
- package/dist/lib/graphql/admin/link-storefront.d.ts +0 -14
- package/dist/lib/graphql/admin/list-environments.d.ts +0 -21
- package/dist/lib/graphql/admin/list-storefronts.d.ts +0 -25
- package/dist/lib/graphql/admin/pull-variables.d.ts +0 -21
- package/dist/lib/graphql.d.ts +0 -21
- package/dist/lib/graphql.js +0 -18
- package/dist/lib/graphql.test.d.ts +0 -1
- package/dist/lib/log.d.ts +0 -6
- package/dist/lib/mini-oxygen.d.ts +0 -22
- package/dist/lib/missing-routes.d.ts +0 -8
- package/dist/lib/missing-routes.test.d.ts +0 -1
- package/dist/lib/missing-storefronts.d.ts +0 -5
- package/dist/lib/missing-storefronts.js +0 -18
- package/dist/lib/process.d.ts +0 -6
- package/dist/lib/pull-environment-variables.d.ts +0 -20
- package/dist/lib/pull-environment-variables.js +0 -57
- package/dist/lib/pull-environment-variables.test.d.ts +0 -1
- package/dist/lib/pull-environment-variables.test.js +0 -174
- package/dist/lib/remix-version-interop.d.ts +0 -11
- package/dist/lib/remix-version-interop.test.d.ts +0 -1
- package/dist/lib/render-errors.d.ts +0 -16
- package/dist/lib/shell.d.ts +0 -11
- package/dist/lib/shell.test.d.ts +0 -1
- package/dist/lib/shop.d.ts +0 -7
- package/dist/lib/shop.js +0 -32
- package/dist/lib/shop.test.d.ts +0 -1
- package/dist/lib/shop.test.js +0 -78
- package/dist/lib/shopify-config.d.ts +0 -35
- package/dist/lib/shopify-config.test.d.ts +0 -1
- package/dist/lib/string.d.ts +0 -3
- package/dist/lib/string.test.d.ts +0 -1
- package/dist/lib/template-downloader.d.ts +0 -6
- package/dist/lib/transpile-ts.d.ts +0 -16
- package/dist/lib/user-errors.d.ts +0 -9
- package/dist/lib/user-errors.js +0 -11
- package/dist/lib/virtual-routes.d.ts +0 -7
- package/dist/lib/virtual-routes.test.d.ts +0 -1
- /package/dist/{commands/hydrogen/env/list.test.d.ts → lib/setups/css/common.js} +0 -0
- /package/dist/{commands/hydrogen/env/pull.test.d.ts → lib/setups/i18n/mock-i18n-types.js} +0 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { copy } from 'fs-extra/esm';
|
|
2
|
+
import { writeFile } from '@shopify/cli-kit/node/fs';
|
|
3
|
+
import { relativePath, joinPath } from '@shopify/cli-kit/node/path';
|
|
4
|
+
import { hyphenate } from '@shopify/cli-kit/common/string';
|
|
5
|
+
import colors from '@shopify/cli-kit/node/colors';
|
|
6
|
+
import { renderSelectPrompt, renderSuccess, renderConfirmationPrompt, renderTasks } from '@shopify/cli-kit/node/ui';
|
|
7
|
+
import { handleStorefrontLink, handleProjectLocation, createAbortHandler, generateProjectEntries, handleLanguage, createInitialCommit, handleCssStrategy, commitAll, handleDependencies, handleCliShortcut, handleI18n, handleRouteGeneration, renderProjectReady } from './common.js';
|
|
8
|
+
import { createStorefront } from '../graphql/admin/create-storefront.js';
|
|
9
|
+
import { waitForJob } from '../graphql/admin/fetch-job.js';
|
|
10
|
+
import { getStarterDir } from '../build.js';
|
|
11
|
+
import { replaceFileContent } from '../file.js';
|
|
12
|
+
import { setUserAccount, setStorefront } from '../shopify-config.js';
|
|
13
|
+
import { getCliCommand, ALIAS_NAME } from '../shell.js';
|
|
14
|
+
import { CSS_STRATEGY_NAME_MAP } from '../setups/css/index.js';
|
|
15
|
+
|
|
16
|
+
async function setupLocalStarterTemplate(options, controller) {
|
|
17
|
+
const templateAction = options.mockShop ? "mock" : await renderSelectPrompt({
|
|
18
|
+
message: "Connect to Shopify",
|
|
19
|
+
choices: [
|
|
20
|
+
{
|
|
21
|
+
label: "Use sample data from Mock.shop (no login required)",
|
|
22
|
+
value: "mock"
|
|
23
|
+
},
|
|
24
|
+
{ label: "Link your Shopify account", value: "link" }
|
|
25
|
+
],
|
|
26
|
+
defaultValue: "mock",
|
|
27
|
+
abortSignal: controller.signal
|
|
28
|
+
});
|
|
29
|
+
const storefrontInfo = templateAction === "link" ? await handleStorefrontLink(controller) : void 0;
|
|
30
|
+
const project = await handleProjectLocation({
|
|
31
|
+
...options,
|
|
32
|
+
storefrontInfo,
|
|
33
|
+
controller
|
|
34
|
+
});
|
|
35
|
+
if (!project)
|
|
36
|
+
return;
|
|
37
|
+
if (templateAction === "mock")
|
|
38
|
+
project.storefrontTitle = "Mock.shop";
|
|
39
|
+
const abort = createAbortHandler(controller, project);
|
|
40
|
+
const createStorefrontPromise = storefrontInfo && createStorefront(storefrontInfo.session, storefrontInfo.title).then(async ({ storefront, jobId }) => {
|
|
41
|
+
if (jobId)
|
|
42
|
+
await waitForJob(storefrontInfo.session, jobId);
|
|
43
|
+
return storefront;
|
|
44
|
+
}).catch(abort);
|
|
45
|
+
const templateDir = getStarterDir();
|
|
46
|
+
let backgroundWorkPromise = copy(
|
|
47
|
+
templateDir,
|
|
48
|
+
project.directory,
|
|
49
|
+
{
|
|
50
|
+
filter: (filepath) => !/^(app|dist|node_modules)\//i.test(
|
|
51
|
+
relativePath(templateDir, filepath)
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
).then(
|
|
55
|
+
() => generateProjectEntries({
|
|
56
|
+
rootDirectory: project.directory,
|
|
57
|
+
appDirectory: joinPath(project.directory, "app"),
|
|
58
|
+
typescript: true
|
|
59
|
+
})
|
|
60
|
+
).catch(abort);
|
|
61
|
+
const tasks = [
|
|
62
|
+
{
|
|
63
|
+
title: "Creating storefront",
|
|
64
|
+
task: async () => {
|
|
65
|
+
await createStorefrontPromise;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
title: "Setting up project",
|
|
70
|
+
task: async () => {
|
|
71
|
+
await backgroundWorkPromise;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
backgroundWorkPromise = backgroundWorkPromise.then(() => {
|
|
76
|
+
const promises = [
|
|
77
|
+
replaceFileContent(
|
|
78
|
+
joinPath(project.directory, "package.json"),
|
|
79
|
+
false,
|
|
80
|
+
(content) => content.replace(
|
|
81
|
+
/"name": "[^"]+"/,
|
|
82
|
+
`"name": "${hyphenate(storefrontInfo?.title ?? project.name)}"`
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
];
|
|
86
|
+
const envLeadingComment = "# The variables added in this file are only available locally in MiniOxygen\n";
|
|
87
|
+
if (storefrontInfo && createStorefrontPromise) {
|
|
88
|
+
promises.push(
|
|
89
|
+
setUserAccount(project.directory, storefrontInfo),
|
|
90
|
+
createStorefrontPromise.then(
|
|
91
|
+
(storefront) => setStorefront(project.directory, storefront)
|
|
92
|
+
),
|
|
93
|
+
writeFile(joinPath(project.directory, ".env"), envLeadingComment)
|
|
94
|
+
);
|
|
95
|
+
} else if (templateAction === "mock") {
|
|
96
|
+
promises.push(
|
|
97
|
+
writeFile(
|
|
98
|
+
joinPath(project.directory, ".env"),
|
|
99
|
+
envLeadingComment + "\n" + [
|
|
100
|
+
["SESSION_SECRET", "foobar"],
|
|
101
|
+
["PUBLIC_STORE_DOMAIN", "mock.shop"]
|
|
102
|
+
].map(([key, value]) => `${key}="${value}"`).join("\n") + "\n"
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return Promise.all(promises).catch(abort);
|
|
107
|
+
});
|
|
108
|
+
const { language, transpileProject } = await handleLanguage(
|
|
109
|
+
project.directory,
|
|
110
|
+
controller,
|
|
111
|
+
options.language
|
|
112
|
+
);
|
|
113
|
+
backgroundWorkPromise = backgroundWorkPromise.then(() => transpileProject().catch(abort)).then(
|
|
114
|
+
() => options.git ? createInitialCommit(project.directory) : void 0
|
|
115
|
+
);
|
|
116
|
+
const { setupCss, cssStrategy } = await handleCssStrategy(
|
|
117
|
+
project.directory,
|
|
118
|
+
controller,
|
|
119
|
+
options.styling
|
|
120
|
+
);
|
|
121
|
+
if (cssStrategy) {
|
|
122
|
+
backgroundWorkPromise = backgroundWorkPromise.then(() => setupCss().catch(abort)).then(
|
|
123
|
+
() => options.git ? commitAll(
|
|
124
|
+
project.directory,
|
|
125
|
+
"Setup " + CSS_STRATEGY_NAME_MAP[cssStrategy]
|
|
126
|
+
) : void 0
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
const { packageManager, shouldInstallDeps, installDeps } = await handleDependencies(
|
|
130
|
+
project.directory,
|
|
131
|
+
controller,
|
|
132
|
+
options.installDeps
|
|
133
|
+
);
|
|
134
|
+
const setupSummary = {
|
|
135
|
+
language,
|
|
136
|
+
packageManager,
|
|
137
|
+
cssStrategy,
|
|
138
|
+
depsInstalled: false,
|
|
139
|
+
hasCreatedShortcut: false
|
|
140
|
+
};
|
|
141
|
+
if (shouldInstallDeps) {
|
|
142
|
+
const installingDepsPromise = backgroundWorkPromise.then(async () => {
|
|
143
|
+
try {
|
|
144
|
+
await installDeps();
|
|
145
|
+
setupSummary.depsInstalled = true;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
setupSummary.depsError = error;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
tasks.push({
|
|
151
|
+
title: "Installing dependencies. This could take a few minutes",
|
|
152
|
+
task: async () => {
|
|
153
|
+
await installingDepsPromise;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const pkgManagerCommand = await getCliCommand("", packageManager);
|
|
158
|
+
const { createShortcut, showShortcutBanner } = await handleCliShortcut(
|
|
159
|
+
controller,
|
|
160
|
+
pkgManagerCommand,
|
|
161
|
+
options.shortcut
|
|
162
|
+
);
|
|
163
|
+
if (createShortcut) {
|
|
164
|
+
backgroundWorkPromise = backgroundWorkPromise.then(async () => {
|
|
165
|
+
setupSummary.hasCreatedShortcut = await createShortcut();
|
|
166
|
+
});
|
|
167
|
+
showShortcutBanner();
|
|
168
|
+
}
|
|
169
|
+
const cliCommand = createShortcut ? ALIAS_NAME : pkgManagerCommand;
|
|
170
|
+
renderSuccess({
|
|
171
|
+
headline: [
|
|
172
|
+
{ userInput: storefrontInfo?.title ?? project.name },
|
|
173
|
+
"is ready to build."
|
|
174
|
+
]
|
|
175
|
+
});
|
|
176
|
+
const continueWithSetup = (options.i18n ?? options.routes) !== void 0 || await renderConfirmationPrompt({
|
|
177
|
+
message: "Do you want to scaffold routes and core functionality?",
|
|
178
|
+
confirmationMessage: "Yes, set up now",
|
|
179
|
+
cancellationMessage: "No, set up later " + colors.dim(`(run \`${cliCommand} setup\`)`),
|
|
180
|
+
abortSignal: controller.signal
|
|
181
|
+
});
|
|
182
|
+
if (continueWithSetup) {
|
|
183
|
+
const { i18nStrategy, setupI18n } = await handleI18n(
|
|
184
|
+
controller,
|
|
185
|
+
cliCommand,
|
|
186
|
+
options.i18n
|
|
187
|
+
);
|
|
188
|
+
const { setupRoutes } = await handleRouteGeneration(
|
|
189
|
+
controller,
|
|
190
|
+
options.routes || true
|
|
191
|
+
);
|
|
192
|
+
setupSummary.i18n = i18nStrategy;
|
|
193
|
+
backgroundWorkPromise = backgroundWorkPromise.then(async () => {
|
|
194
|
+
await setupI18n({
|
|
195
|
+
rootDirectory: project.directory,
|
|
196
|
+
serverEntryPoint: language === "ts" ? "server.ts" : "server.js"
|
|
197
|
+
}).then(
|
|
198
|
+
() => options.git ? commitAll(
|
|
199
|
+
project.directory,
|
|
200
|
+
`Setup markets support using ${i18nStrategy}`
|
|
201
|
+
) : void 0
|
|
202
|
+
).catch((error) => {
|
|
203
|
+
setupSummary.i18nError = error;
|
|
204
|
+
});
|
|
205
|
+
await setupRoutes(project.directory, language, i18nStrategy).then((routes) => {
|
|
206
|
+
setupSummary.routes = routes;
|
|
207
|
+
if (options.git && routes) {
|
|
208
|
+
return commitAll(
|
|
209
|
+
project.directory,
|
|
210
|
+
`Generate routes for core functionality`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
}).catch((error) => {
|
|
214
|
+
setupSummary.routesError = error;
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
await renderTasks(tasks);
|
|
219
|
+
if (options.git) {
|
|
220
|
+
await commitAll(project.directory, "Lockfile");
|
|
221
|
+
}
|
|
222
|
+
await renderProjectReady(project, setupSummary);
|
|
223
|
+
return {
|
|
224
|
+
...project,
|
|
225
|
+
...setupSummary
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { setupLocalStarterTemplate };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
2
|
+
import { copyFile } from '@shopify/cli-kit/node/fs';
|
|
3
|
+
import { joinPath } from '@shopify/cli-kit/node/path';
|
|
4
|
+
import { renderTasks, renderInfo } from '@shopify/cli-kit/node/ui';
|
|
5
|
+
import { getLatestTemplates } from '../template-downloader.js';
|
|
6
|
+
import { handleProjectLocation, createAbortHandler, handleLanguage, createInitialCommit, handleDependencies, renderProjectReady } from './common.js';
|
|
7
|
+
|
|
8
|
+
async function setupRemoteTemplate(options, controller) {
|
|
9
|
+
const isOfficialTemplate = options.template === "demo-store" || options.template === "hello-world";
|
|
10
|
+
if (!isOfficialTemplate) {
|
|
11
|
+
throw new AbortError(
|
|
12
|
+
"Only `demo-store` and `hello-world` are supported in --template flag for now.",
|
|
13
|
+
"Skip the --template flag to run the setup flow."
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
const appTemplate = options.template;
|
|
17
|
+
const backgroundDownloadPromise = getLatestTemplates({
|
|
18
|
+
signal: controller.signal
|
|
19
|
+
}).catch((error) => {
|
|
20
|
+
throw abort(error);
|
|
21
|
+
});
|
|
22
|
+
const project = await handleProjectLocation({ ...options, controller });
|
|
23
|
+
if (!project)
|
|
24
|
+
return;
|
|
25
|
+
const abort = createAbortHandler(controller, project);
|
|
26
|
+
let backgroundWorkPromise = backgroundDownloadPromise.then(
|
|
27
|
+
({ templatesDir }) => copyFile(joinPath(templatesDir, appTemplate), project.directory).catch(
|
|
28
|
+
abort
|
|
29
|
+
)
|
|
30
|
+
);
|
|
31
|
+
const { language, transpileProject } = await handleLanguage(
|
|
32
|
+
project.directory,
|
|
33
|
+
controller,
|
|
34
|
+
options.language
|
|
35
|
+
);
|
|
36
|
+
backgroundWorkPromise = backgroundWorkPromise.then(() => transpileProject().catch(abort)).then(() => createInitialCommit(project.directory));
|
|
37
|
+
const { packageManager, shouldInstallDeps, installDeps } = await handleDependencies(
|
|
38
|
+
project.directory,
|
|
39
|
+
controller,
|
|
40
|
+
options.installDeps
|
|
41
|
+
);
|
|
42
|
+
const setupSummary = {
|
|
43
|
+
language,
|
|
44
|
+
packageManager,
|
|
45
|
+
depsInstalled: false,
|
|
46
|
+
hasCreatedShortcut: false
|
|
47
|
+
};
|
|
48
|
+
const tasks = [
|
|
49
|
+
{
|
|
50
|
+
title: "Downloading template",
|
|
51
|
+
task: async () => {
|
|
52
|
+
await backgroundDownloadPromise;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
title: "Setting up project",
|
|
57
|
+
task: async () => {
|
|
58
|
+
await backgroundWorkPromise;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
if (shouldInstallDeps) {
|
|
63
|
+
tasks.push({
|
|
64
|
+
title: "Installing dependencies. This could take a few minutes",
|
|
65
|
+
task: async () => {
|
|
66
|
+
try {
|
|
67
|
+
await installDeps();
|
|
68
|
+
setupSummary.depsInstalled = true;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
setupSummary.depsError = error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
await renderTasks(tasks);
|
|
76
|
+
await renderProjectReady(project, setupSummary);
|
|
77
|
+
if (isOfficialTemplate) {
|
|
78
|
+
renderInfo({
|
|
79
|
+
headline: `Your project will display inventory from the Hydrogen Demo Store.`,
|
|
80
|
+
body: `To connect this project to your Shopify store\u2019s inventory, update \`${project.name}/.env\` with your store ID and Storefront API key.`
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
...project,
|
|
85
|
+
...setupSummary
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { setupRemoteTemplate };
|
|
@@ -10,10 +10,10 @@ function isRemixV2() {
|
|
|
10
10
|
return false;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
async function getV2Flags(root) {
|
|
13
|
+
async function getV2Flags(root, remixConfigFuture) {
|
|
14
14
|
const isV2 = isRemixV2();
|
|
15
15
|
const futureFlags = {
|
|
16
|
-
...!isV2 && (await getRemixConfig(root, true)).future
|
|
16
|
+
...!isV2 && (remixConfigFuture ?? (await getRemixConfig(root, true)).future)
|
|
17
17
|
};
|
|
18
18
|
return {
|
|
19
19
|
isV2Meta: isV2 || !!futureFlags.v2_meta,
|
|
@@ -21,8 +21,8 @@ async function getV2Flags(root) {
|
|
|
21
21
|
isV2RouteConvention: isV2 ? !isV1RouteConventionInstalled() : !!futureFlags.v2_routeConvention
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
return route.replace(
|
|
24
|
+
function convertRouteToV1(route) {
|
|
25
|
+
return route.replace(/(^|\.)_index$/, "$1index").replace(/\.(?!\w+\])/g, "/");
|
|
26
26
|
}
|
|
27
27
|
function convertTemplateToRemixVersion(template, { isV2Meta, isV2ErrorBoundary }) {
|
|
28
28
|
template = isV2Meta ? convertToMetaV2(template) : convertToMetaV1(template);
|
|
@@ -51,4 +51,4 @@ function isV1RouteConventionInstalled() {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export {
|
|
54
|
+
export { convertRouteToV1, convertTemplateToRemixVersion, getV2Flags, isRemixV2 };
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { convertTemplateToRemixVersion } from './remix-version-interop.js';
|
|
2
|
+
import { convertRouteToV1, convertTemplateToRemixVersion } from './remix-version-interop.js';
|
|
3
3
|
|
|
4
4
|
describe("remix-version-interop", () => {
|
|
5
|
+
describe("v2_routeConvention", () => {
|
|
6
|
+
it("converts routes to v1", () => {
|
|
7
|
+
expect(convertRouteToV1("_index")).toEqual("index");
|
|
8
|
+
expect(convertRouteToV1("path.to.file")).toEqual("path/to/file");
|
|
9
|
+
expect(convertRouteToV1("path.to._index")).toEqual("path/to/index");
|
|
10
|
+
expect(convertRouteToV1("patht.to.[sitemap.xml]")).toEqual(
|
|
11
|
+
"patht/to/[sitemap.xml]"
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
5
15
|
describe("v2_meta", () => {
|
|
6
16
|
const META_TEMPLATE = `
|
|
7
17
|
import {type MetaFunction} from '@shopify/remix-oxygen';
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { renderFatalError } from '@shopify/cli-kit/node/ui';
|
|
2
2
|
import { outputContent, outputToken } from '@shopify/cli-kit/node/output';
|
|
3
3
|
import { hydrogenStorefrontsUrl } from './admin-urls.js';
|
|
4
|
-
import { parseGid } from './
|
|
4
|
+
import { parseGid } from './gid.js';
|
|
5
5
|
|
|
6
6
|
function renderMissingStorefront({
|
|
7
|
-
|
|
8
|
-
storefront
|
|
7
|
+
session,
|
|
8
|
+
storefront,
|
|
9
|
+
cliCommand
|
|
9
10
|
}) {
|
|
10
11
|
renderFatalError({
|
|
11
12
|
name: "NoStorefrontError",
|
|
@@ -15,22 +16,23 @@ function renderMissingStorefront({
|
|
|
15
16
|
)}`.value,
|
|
16
17
|
tryMessage: outputContent`Couldn’t find ${storefront.title} (ID: ${parseGid(
|
|
17
18
|
storefront.id
|
|
18
|
-
)}) on ${
|
|
19
|
-
|
|
19
|
+
)}) on ${session.storeFqdn}. Check that the storefront exists and run ${outputToken.genericShellCommand(
|
|
20
|
+
`${cliCommand} link`
|
|
20
21
|
)} to link this project to it.\n\n${outputToken.link(
|
|
21
22
|
"Hydrogen Storefronts Admin",
|
|
22
|
-
hydrogenStorefrontsUrl(
|
|
23
|
+
hydrogenStorefrontsUrl(session)
|
|
23
24
|
)}`.value
|
|
24
25
|
});
|
|
25
26
|
}
|
|
26
|
-
function renderMissingLink({
|
|
27
|
+
function renderMissingLink({ session, cliCommand }) {
|
|
27
28
|
renderFatalError({
|
|
28
29
|
name: "NoLinkedStorefrontError",
|
|
29
30
|
type: 0,
|
|
30
|
-
message: `No linked Hydrogen storefront on ${
|
|
31
|
-
tryMessage:
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
message: `No linked Hydrogen storefront on ${session.storeFqdn}`,
|
|
32
|
+
tryMessage: [
|
|
33
|
+
"To pull environment variables, link this project to a Hydrogen storefront. To select a storefront to link, run",
|
|
34
|
+
{ command: `${cliCommand} link` }
|
|
35
|
+
]
|
|
34
36
|
});
|
|
35
37
|
}
|
|
36
38
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFile, writeFile, fileExists } from '@shopify/cli-kit/node/fs';
|
|
2
|
+
import { joinPath } from '@shopify/cli-kit/node/path';
|
|
3
|
+
import { renderConfirmationPrompt } from '@shopify/cli-kit/node/ui';
|
|
4
|
+
import { readAndParsePackageJson, writePackageJSON } from '@shopify/cli-kit/node/node-package-manager';
|
|
5
|
+
import { GENERATOR_SETUP_ASSETS_SUB_DIRS, getAssetDir } from '../../build.js';
|
|
6
|
+
|
|
7
|
+
const SETUP_CSS_STRATEGIES = GENERATOR_SETUP_ASSETS_SUB_DIRS;
|
|
8
|
+
function copyAssets(feature, assets, rootDirectory, replacer = (content, filename) => content) {
|
|
9
|
+
const setupAssetsPath = getAssetDir(feature);
|
|
10
|
+
return Promise.all(
|
|
11
|
+
Object.entries(assets).map(async ([source, destination]) => {
|
|
12
|
+
const content = await readFile(joinPath(setupAssetsPath, source));
|
|
13
|
+
await writeFile(
|
|
14
|
+
joinPath(rootDirectory, destination),
|
|
15
|
+
replacer(content, source)
|
|
16
|
+
);
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
async function canWriteFiles(assetMap, directory, force) {
|
|
21
|
+
const fileExistPromises = Object.values(assetMap).map(
|
|
22
|
+
(file) => fileExists(joinPath(directory, file)).then(
|
|
23
|
+
(exists) => exists ? file : null
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
const existingFiles = (await Promise.all(fileExistPromises)).filter(
|
|
27
|
+
Boolean
|
|
28
|
+
);
|
|
29
|
+
if (existingFiles.length > 0) {
|
|
30
|
+
if (!force) {
|
|
31
|
+
const overwrite = await renderConfirmationPrompt({
|
|
32
|
+
message: `Some files already exist (${existingFiles.join(
|
|
33
|
+
", "
|
|
34
|
+
)}). Overwrite?`,
|
|
35
|
+
defaultValue: false
|
|
36
|
+
});
|
|
37
|
+
if (!overwrite) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const MANAGED_PACKAGE_JSON_KEYS = Object.freeze([
|
|
45
|
+
"dependencies",
|
|
46
|
+
"devDependencies",
|
|
47
|
+
"peerDependencies"
|
|
48
|
+
]);
|
|
49
|
+
async function mergePackageJson(feature, projectDir) {
|
|
50
|
+
const targetPkgJson = await readAndParsePackageJson(
|
|
51
|
+
joinPath(projectDir, "package.json")
|
|
52
|
+
);
|
|
53
|
+
const sourcePkgJson = await readAndParsePackageJson(
|
|
54
|
+
joinPath(getAssetDir(feature), "package.json")
|
|
55
|
+
);
|
|
56
|
+
delete sourcePkgJson.comment;
|
|
57
|
+
const unmanagedKeys = Object.keys(sourcePkgJson).filter(
|
|
58
|
+
(key) => !MANAGED_PACKAGE_JSON_KEYS.includes(key)
|
|
59
|
+
);
|
|
60
|
+
for (const key of unmanagedKeys) {
|
|
61
|
+
const sourceValue = sourcePkgJson[key];
|
|
62
|
+
const targetValue = targetPkgJson[key];
|
|
63
|
+
const newValue = Array.isArray(sourceValue) && Array.isArray(targetValue) ? [...targetValue, ...sourceValue] : typeof sourceValue === "object" && typeof targetValue === "object" ? { ...targetValue, ...sourceValue } : sourceValue;
|
|
64
|
+
targetPkgJson[key] = newValue;
|
|
65
|
+
}
|
|
66
|
+
const remixVersion = Object.entries(targetPkgJson.dependencies || {}).find(
|
|
67
|
+
([dep]) => dep.startsWith("@remix-run/")
|
|
68
|
+
)?.[1];
|
|
69
|
+
for (const key of MANAGED_PACKAGE_JSON_KEYS) {
|
|
70
|
+
if (sourcePkgJson[key]) {
|
|
71
|
+
targetPkgJson[key] = [
|
|
72
|
+
.../* @__PURE__ */ new Set([
|
|
73
|
+
...Object.keys(targetPkgJson[key] ?? {}),
|
|
74
|
+
...Object.keys(sourcePkgJson[key] ?? {})
|
|
75
|
+
])
|
|
76
|
+
].sort().reduce((acc, dep) => {
|
|
77
|
+
let version = sourcePkgJson[key]?.[dep] ?? targetPkgJson[key]?.[dep];
|
|
78
|
+
if (dep.startsWith("@remix-run/") && remixVersion) {
|
|
79
|
+
version = remixVersion;
|
|
80
|
+
}
|
|
81
|
+
acc[dep] = version;
|
|
82
|
+
return acc;
|
|
83
|
+
}, {});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
await writePackageJSON(projectDir, targetPkgJson);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { SETUP_CSS_STRATEGIES, canWriteFiles, copyAssets, mergePackageJson };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { mergePackageJson } from './assets.js';
|
|
2
|
+
import { getCodeFormatOptions } from '../../format-code.js';
|
|
3
|
+
import { injectCssBundlingLink } from './replacers.js';
|
|
4
|
+
|
|
5
|
+
async function setupCssModules({
|
|
6
|
+
rootDirectory,
|
|
7
|
+
appDirectory
|
|
8
|
+
}) {
|
|
9
|
+
const workPromise = Promise.all([
|
|
10
|
+
mergePackageJson("css-modules", rootDirectory),
|
|
11
|
+
getCodeFormatOptions(rootDirectory).then(
|
|
12
|
+
(formatConfig) => injectCssBundlingLink(appDirectory, formatConfig)
|
|
13
|
+
)
|
|
14
|
+
]);
|
|
15
|
+
return {
|
|
16
|
+
workPromise,
|
|
17
|
+
generatedAssets: [],
|
|
18
|
+
helpUrl: "https://github.com/css-modules/css-modules"
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { setupCssModules };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { renderSelectPrompt } from '@shopify/cli-kit/node/ui';
|
|
2
|
+
import { setupTailwind } from './tailwind.js';
|
|
3
|
+
import { setupPostCss } from './postcss.js';
|
|
4
|
+
import { setupCssModules } from './css-modules.js';
|
|
5
|
+
import { setupVanillaExtract } from './vanilla-extract.js';
|
|
6
|
+
export { SETUP_CSS_STRATEGIES } from './assets.js';
|
|
7
|
+
|
|
8
|
+
const CSS_STRATEGY_NAME_MAP = {
|
|
9
|
+
tailwind: "Tailwind",
|
|
10
|
+
"css-modules": "CSS Modules",
|
|
11
|
+
"vanilla-extract": "Vanilla Extract",
|
|
12
|
+
postcss: "CSS"
|
|
13
|
+
};
|
|
14
|
+
function setupCssStrategy(strategy, options, force) {
|
|
15
|
+
switch (strategy) {
|
|
16
|
+
case "tailwind":
|
|
17
|
+
return setupTailwind(options, force);
|
|
18
|
+
case "postcss":
|
|
19
|
+
return setupPostCss(options, force);
|
|
20
|
+
case "css-modules":
|
|
21
|
+
return setupCssModules(options);
|
|
22
|
+
case "vanilla-extract":
|
|
23
|
+
return setupVanillaExtract(options);
|
|
24
|
+
default:
|
|
25
|
+
throw new Error("Unknown strategy");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function renderCssPrompt(options) {
|
|
29
|
+
const cssStrategies = Object.entries({
|
|
30
|
+
...CSS_STRATEGY_NAME_MAP,
|
|
31
|
+
...options?.extraChoices
|
|
32
|
+
});
|
|
33
|
+
return renderSelectPrompt({
|
|
34
|
+
message: "Select a styling library",
|
|
35
|
+
...options,
|
|
36
|
+
choices: cssStrategies.map(([value, label]) => ({
|
|
37
|
+
value,
|
|
38
|
+
label
|
|
39
|
+
})),
|
|
40
|
+
defaultValue: "tailwind"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { CSS_STRATEGY_NAME_MAP, renderCssPrompt, setupCssStrategy };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { outputInfo } from '@shopify/cli-kit/node/output';
|
|
2
|
+
import { canWriteFiles, mergePackageJson, copyAssets } from './assets.js';
|
|
3
|
+
import { getCodeFormatOptions } from '../../format-code.js';
|
|
4
|
+
import { replaceRemixConfig } from './replacers.js';
|
|
5
|
+
|
|
6
|
+
async function setupPostCss({ rootDirectory, appDirectory, ...futureOptions }, force = false) {
|
|
7
|
+
const assetMap = {
|
|
8
|
+
"postcss.config.js": "postcss.config.js"
|
|
9
|
+
};
|
|
10
|
+
if (futureOptions.postcss) {
|
|
11
|
+
outputInfo(`PostCSS is already setup in ${rootDirectory}.`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (!await canWriteFiles(assetMap, appDirectory, force)) {
|
|
15
|
+
outputInfo(
|
|
16
|
+
`Skipping CSS setup as some files already exist. You may use \`--force\` or \`-f\` to override it.`
|
|
17
|
+
);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const workPromise = Promise.all([
|
|
21
|
+
mergePackageJson("postcss", rootDirectory),
|
|
22
|
+
copyAssets("postcss", assetMap, rootDirectory),
|
|
23
|
+
getCodeFormatOptions(rootDirectory).then(
|
|
24
|
+
(formatConfig) => replaceRemixConfig(rootDirectory, formatConfig, { postcss: true })
|
|
25
|
+
)
|
|
26
|
+
]);
|
|
27
|
+
return {
|
|
28
|
+
workPromise,
|
|
29
|
+
generatedAssets: Object.values(assetMap),
|
|
30
|
+
helpUrl: "https://postcss.org/"
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { setupPostCss };
|