@cedarjs/cli 8.0.0-canary.3373 → 8.0.0-canary.3378
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/generate/scaffold/scaffold.js +1 -1
- package/dist/commands/generate/scaffold/scaffoldHandler.js +13 -3
- package/dist/commands/generate/scaffold/templates/assets/scaffold.tailwind.css.template +12 -7
- package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +61 -81
- package/package.json +13 -13
- package/dist/commands/setup/ui/templates/postcss.config.cjs.template +0 -9
|
@@ -13,7 +13,7 @@ const builder = (yargs) => {
|
|
|
13
13
|
description: "Generate test files",
|
|
14
14
|
type: "boolean"
|
|
15
15
|
}).option("tailwind", {
|
|
16
|
-
description: "Generate TailwindCSS version of scaffold.css (automatically set to `true` if
|
|
16
|
+
description: "Generate TailwindCSS version of scaffold.css (automatically set to `true` if the web side depends on `tailwindcss`)",
|
|
17
17
|
type: "boolean"
|
|
18
18
|
}).option("rollback", {
|
|
19
19
|
description: "Revert all generator actions if an error occurs",
|
|
@@ -97,11 +97,21 @@ const getTemplateStrings = (name, scaffoldPath, nestScaffoldByModel = true) => {
|
|
|
97
97
|
...getImportComponentNames(name, scaffoldPath, nestScaffoldByModel)
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
|
+
const webDependsOnTailwindCSS = () => {
|
|
101
|
+
const webPackageJsonPath = path.join(getPaths().web.base, "package.json");
|
|
102
|
+
if (!fs.existsSync(webPackageJsonPath)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const { dependencies, devDependencies } = JSON.parse(
|
|
106
|
+
fs.readFileSync(webPackageJsonPath, "utf-8")
|
|
107
|
+
);
|
|
108
|
+
return Boolean(
|
|
109
|
+
dependencies?.["tailwindcss"] || devDependencies?.["tailwindcss"]
|
|
110
|
+
);
|
|
111
|
+
};
|
|
100
112
|
const shouldUseTailwindCSS = (flag) => {
|
|
101
113
|
if (flag === void 0) {
|
|
102
|
-
return
|
|
103
|
-
path.join(getPaths().web.config, "tailwind.config.cjs")
|
|
104
|
-
);
|
|
114
|
+
return webDependsOnTailwindCSS();
|
|
105
115
|
} else {
|
|
106
116
|
return flag;
|
|
107
117
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Makes your app's Tailwind theme and utilities available to `@apply`
|
|
3
|
+
* without emitting any of the styles in index.css a second time
|
|
4
|
+
*/
|
|
5
|
+
@reference './index.css';
|
|
6
|
+
|
|
1
7
|
.rw-scaffold {
|
|
2
8
|
@apply bg-white text-gray-600;
|
|
3
9
|
}
|
|
@@ -27,8 +33,7 @@
|
|
|
27
33
|
@apply mx-4 pb-4;
|
|
28
34
|
}
|
|
29
35
|
.rw-segment {
|
|
30
|
-
@apply rounded-lg overflow-hidden w-full border border-gray-200;
|
|
31
|
-
scrollbar-color: theme('colors.zinc.400') transparent;
|
|
36
|
+
@apply rounded-lg overflow-hidden w-full border border-gray-200 scrollbar-thumb-zinc-400 scrollbar-track-transparent;
|
|
32
37
|
}
|
|
33
38
|
.rw-segment::-webkit-scrollbar {
|
|
34
39
|
height: initial;
|
|
@@ -80,7 +85,7 @@
|
|
|
80
85
|
}
|
|
81
86
|
.rw-cell-error,
|
|
82
87
|
.rw-form-error-wrapper {
|
|
83
|
-
@apply p-4 bg-red-50 text-red-600 border border-red-100 rounded my-4;
|
|
88
|
+
@apply p-4 bg-red-50 text-red-600 border border-red-100 rounded-sm my-4;
|
|
84
89
|
}
|
|
85
90
|
.rw-form-error-title {
|
|
86
91
|
@apply m-0 font-semibold;
|
|
@@ -89,13 +94,13 @@
|
|
|
89
94
|
@apply mt-2 list-disc list-inside;
|
|
90
95
|
}
|
|
91
96
|
.rw-button {
|
|
92
|
-
@apply flex justify-center py-1 px-4 border-0 rounded bg-gray-200 text-gray-500 text-xs font-semibold uppercase tracking-wide leading-loose no-underline cursor-pointer transition duration-100;
|
|
97
|
+
@apply flex justify-center py-1 px-4 border-0 rounded-sm bg-gray-200 text-gray-500 text-xs font-semibold uppercase tracking-wide leading-loose no-underline cursor-pointer transition duration-100;
|
|
93
98
|
}
|
|
94
99
|
.rw-button:hover {
|
|
95
100
|
@apply bg-gray-500 text-white;
|
|
96
101
|
}
|
|
97
102
|
.rw-button.rw-button-small {
|
|
98
|
-
@apply text-xs rounded-
|
|
103
|
+
@apply text-xs rounded-xs py-1 px-2;
|
|
99
104
|
}
|
|
100
105
|
.rw-button.rw-button-green {
|
|
101
106
|
@apply bg-green-500 text-white;
|
|
@@ -134,7 +139,7 @@
|
|
|
134
139
|
@apply text-red-600;
|
|
135
140
|
}
|
|
136
141
|
.rw-input {
|
|
137
|
-
@apply block mt-2 w-full p-2 bg-white border border-gray-200 rounded outline-
|
|
142
|
+
@apply block mt-2 w-full p-2 bg-white border border-gray-200 rounded-sm outline-hidden;
|
|
138
143
|
}
|
|
139
144
|
.rw-check-radio-items {
|
|
140
145
|
@apply flex justify-items-center;
|
|
@@ -153,7 +158,7 @@
|
|
|
153
158
|
@apply border-red-600 text-red-600;
|
|
154
159
|
}
|
|
155
160
|
.rw-input-error:focus {
|
|
156
|
-
@apply border-red-600 outline-
|
|
161
|
+
@apply border-red-600 outline-hidden;
|
|
157
162
|
box-shadow: 0 0 5px #c53030;
|
|
158
163
|
}
|
|
159
164
|
.rw-field-error {
|
|
@@ -6,7 +6,6 @@ import { Listr } from "listr2";
|
|
|
6
6
|
import { terminalLink } from "termi-link";
|
|
7
7
|
import { colors as c } from "@cedarjs/cli-helpers/colors";
|
|
8
8
|
import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
|
|
9
|
-
import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
|
|
10
9
|
import {
|
|
11
10
|
addRootPackages,
|
|
12
11
|
addWorkspacePackages
|
|
@@ -14,36 +13,24 @@ import {
|
|
|
14
13
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
|
|
15
14
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
16
15
|
import { getPaths, usingVSCode } from "../../../../lib/index.js";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
];
|
|
22
|
-
const tailwindDirectivesExist = (indexCSS) => tailwindDirectives.every(
|
|
23
|
-
(tailwindDirective) => indexCSS.includes(tailwindDirective)
|
|
24
|
-
);
|
|
25
|
-
const tailwindImportsAndNotes = [
|
|
16
|
+
import { insertPluginsBeforeCedar } from "../../deploy/helpers/index.js";
|
|
17
|
+
const tailwindImport = "@import 'tailwindcss';";
|
|
18
|
+
const tailwindImportRegExp = /@import\s+['"]tailwindcss['"]/;
|
|
19
|
+
const tailwindImportAndNotes = [
|
|
26
20
|
"/**",
|
|
27
21
|
" * START --- SETUP TAILWINDCSS EDIT",
|
|
28
22
|
" *",
|
|
29
|
-
` * \`${formatCedarCommand(["setup", "ui", "tailwindcss"])}\` placed
|
|
23
|
+
` * \`${formatCedarCommand(["setup", "ui", "tailwindcss"])}\` placed this import here`,
|
|
30
24
|
" * to inject Tailwind's styles into your CSS.",
|
|
31
25
|
" * For more information, see: https://tailwindcss.com/docs/installation",
|
|
32
26
|
" */",
|
|
33
|
-
|
|
27
|
+
tailwindImport,
|
|
34
28
|
"/**",
|
|
35
29
|
" * END --- SETUP TAILWINDCSS EDIT",
|
|
36
30
|
" */\n"
|
|
37
31
|
];
|
|
38
|
-
const recommendedVSCodeExtensions = [
|
|
39
|
-
"csstools.postcss",
|
|
40
|
-
"bradlc.vscode-tailwindcss"
|
|
41
|
-
];
|
|
32
|
+
const recommendedVSCodeExtensions = ["bradlc.vscode-tailwindcss"];
|
|
42
33
|
const recommendationTexts = {
|
|
43
|
-
"csstools.postcss": terminalLink(
|
|
44
|
-
"PostCSS Language Support",
|
|
45
|
-
"https://marketplace.visualstudio.com/items?itemName=csstools.postcss"
|
|
46
|
-
),
|
|
47
34
|
"bradlc.vscode-tailwindcss": terminalLink(
|
|
48
35
|
"Tailwind CSS IntelliSense",
|
|
49
36
|
"https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss"
|
|
@@ -87,9 +74,8 @@ const handler = async ({
|
|
|
87
74
|
const rwPaths = getPaths();
|
|
88
75
|
const projectPackages = ["prettier-plugin-tailwindcss@^0.8.0"];
|
|
89
76
|
const webWorkspacePackages = [
|
|
90
|
-
"
|
|
91
|
-
"tailwindcss@^3.
|
|
92
|
-
"autoprefixer"
|
|
77
|
+
"tailwindcss@^4.3.3",
|
|
78
|
+
"@tailwindcss/vite@^4.3.3"
|
|
93
79
|
];
|
|
94
80
|
const tasks = new Listr(
|
|
95
81
|
[
|
|
@@ -140,62 +126,45 @@ const handler = async ({
|
|
|
140
126
|
}
|
|
141
127
|
},
|
|
142
128
|
{
|
|
143
|
-
title: "
|
|
144
|
-
task: () => {
|
|
145
|
-
const
|
|
146
|
-
if (!
|
|
129
|
+
title: "Adding the Tailwind CSS plugin to the Vite config...",
|
|
130
|
+
task: (_ctx, task) => {
|
|
131
|
+
const viteConfigPath = rwPaths.web.viteConfig;
|
|
132
|
+
if (!viteConfigPath || !fs.existsSync(viteConfigPath)) {
|
|
133
|
+
throw new Error("Could not find web/vite.config.{ts,js}");
|
|
134
|
+
}
|
|
135
|
+
const viteConfig = fs.readFileSync(viteConfigPath, "utf-8");
|
|
136
|
+
if (viteConfig.includes("@tailwindcss/vite")) {
|
|
137
|
+
task.skip("The Tailwind CSS Vite plugin is already configured");
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const viteConfigWithPlugin = insertPluginsBeforeCedar({
|
|
141
|
+
content: viteConfig,
|
|
142
|
+
pluginCodes: ["tailwindcss()"]
|
|
143
|
+
});
|
|
144
|
+
if (!viteConfigWithPlugin) {
|
|
147
145
|
throw new Error(
|
|
148
|
-
|
|
146
|
+
`Could not find \`cedar()\` in the plugins array in ${viteConfigPath}.
|
|
147
|
+
Add \`import tailwindcss from '@tailwindcss/vite'\` to the top of the file and \`tailwindcss()\` to the plugins array yourself, and then run this command again.`
|
|
149
148
|
);
|
|
150
|
-
} else {
|
|
151
|
-
const postCSSConfig = fs.readFileSync(
|
|
152
|
-
path.join(
|
|
153
|
-
import.meta.dirname,
|
|
154
|
-
"../templates/postcss.config.cjs.template"
|
|
155
|
-
),
|
|
156
|
-
"utf-8"
|
|
157
|
-
);
|
|
158
|
-
fs.mkdirSync(path.dirname(postCSSConfigPath), { recursive: true });
|
|
159
|
-
return fs.writeFileSync(postCSSConfigPath, postCSSConfig);
|
|
160
149
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
rwPaths.web.config,
|
|
168
|
-
"tailwind.config.cjs"
|
|
150
|
+
const tailwindPluginImport = "import tailwindcss from '@tailwindcss/vite'\n";
|
|
151
|
+
const importAnchor = /^import .* from ['"]vite['"]/m.exec(viteConfigWithPlugin) ?? /^import /m.exec(viteConfigWithPlugin);
|
|
152
|
+
const insertAt = importAnchor?.index ?? 0;
|
|
153
|
+
fs.writeFileSync(
|
|
154
|
+
viteConfigPath,
|
|
155
|
+
viteConfigWithPlugin.slice(0, insertAt) + tailwindPluginImport + viteConfigWithPlugin.slice(insertAt)
|
|
169
156
|
);
|
|
170
|
-
if (fs.existsSync(tailwindConfigPath)) {
|
|
171
|
-
if (force) {
|
|
172
|
-
fs.unlinkSync(tailwindConfigPath);
|
|
173
|
-
} else {
|
|
174
|
-
throw new Error(
|
|
175
|
-
"Tailwind CSS config already exists.\nUse --force to override existing config."
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
await runBin("tailwindcss", ["init", tailwindConfigPath], {
|
|
180
|
-
cwd: rwPaths.web.base
|
|
181
|
-
});
|
|
182
|
-
const tailwindConfig = fs.readFileSync(tailwindConfigPath, "utf-8");
|
|
183
|
-
const newTailwindConfig = 'const { join } = require("node:path");\n\n' + tailwindConfig.replace(
|
|
184
|
-
"content: []",
|
|
185
|
-
"content: [join(__dirname, '../src/**/*.{js,jsx,ts,tsx}')]"
|
|
186
|
-
).replace("export default {", "module.exports = {");
|
|
187
|
-
fs.writeFileSync(tailwindConfigPath, newTailwindConfig);
|
|
188
157
|
}
|
|
189
158
|
},
|
|
190
159
|
{
|
|
191
|
-
title: "Adding
|
|
160
|
+
title: "Adding Tailwind CSS import to index.css...",
|
|
192
161
|
task: (_ctx, task) => {
|
|
193
162
|
const INDEX_CSS_PATH = path.join(rwPaths.web.src, "index.css");
|
|
194
163
|
const indexCSS = fs.readFileSync(INDEX_CSS_PATH, "utf-8");
|
|
195
|
-
if (
|
|
196
|
-
task.skip("
|
|
164
|
+
if (tailwindImportRegExp.test(indexCSS)) {
|
|
165
|
+
task.skip("Tailwind CSS import already exists in index.css");
|
|
197
166
|
} else {
|
|
198
|
-
const newIndexCSS =
|
|
167
|
+
const newIndexCSS = tailwindImportAndNotes.join("\n") + indexCSS;
|
|
199
168
|
fs.writeFileSync(INDEX_CSS_PATH, newIndexCSS);
|
|
200
169
|
}
|
|
201
170
|
}
|
|
@@ -276,7 +245,9 @@ const handler = async ({
|
|
|
276
245
|
"activeClassName",
|
|
277
246
|
"errorClassName"
|
|
278
247
|
];
|
|
248
|
+
const fileAssociations = { "*.css": "tailwindcss" };
|
|
279
249
|
let newSettingsJson = {
|
|
250
|
+
["files.associations"]: fileAssociations,
|
|
280
251
|
["tailwindCSS.classAttributes"]: classAttributes
|
|
281
252
|
};
|
|
282
253
|
if (fs.existsSync(VS_CODE_SETTINGS_PATH)) {
|
|
@@ -294,8 +265,13 @@ const handler = async ({
|
|
|
294
265
|
const mergedClassAttributes = Array.from(
|
|
295
266
|
/* @__PURE__ */ new Set([...classAttributes, ...originalTwClassAttributesJson])
|
|
296
267
|
);
|
|
268
|
+
const existingAssociations = originalSettingsJson["files.associations"];
|
|
297
269
|
newSettingsJson = {
|
|
298
270
|
...originalSettingsJson,
|
|
271
|
+
["files.associations"]: {
|
|
272
|
+
...existingAssociations && typeof existingAssociations === "object" && !Array.isArray(existingAssociations) ? existingAssociations : {},
|
|
273
|
+
...fileAssociations
|
|
274
|
+
},
|
|
299
275
|
["tailwindCSS.classAttributes"]: mergedClassAttributes
|
|
300
276
|
};
|
|
301
277
|
}
|
|
@@ -306,34 +282,38 @@ const handler = async ({
|
|
|
306
282
|
}
|
|
307
283
|
},
|
|
308
284
|
{
|
|
309
|
-
title: "Adding tailwind
|
|
285
|
+
title: "Adding tailwind stylesheet entry in prettier...",
|
|
310
286
|
task: async (_ctx) => {
|
|
311
287
|
const prettierConfigPath = path.join(
|
|
312
288
|
rwPaths.base,
|
|
313
289
|
"prettier.config.cjs"
|
|
314
290
|
);
|
|
315
291
|
const prettierConfig = fs.readFileSync(prettierConfigPath, "utf-8");
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
path.posix.join(rwPaths.web.config, "tailwind.config.cjs")
|
|
319
|
-
).replaceAll("\\", "/");
|
|
292
|
+
const tailwindStylesheetPath = path.relative(rwPaths.base, path.join(rwPaths.web.src, "index.css")).replaceAll("\\", "/");
|
|
293
|
+
const tailwindStylesheetEntry = `tailwindStylesheet: './${tailwindStylesheetPath}',`;
|
|
320
294
|
let newPrettierConfig = prettierConfig;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
295
|
+
const stringEntryRegExp = /tailwindStylesheet:\s*(['"`])[^'"`\n]*\1,?/;
|
|
296
|
+
if (newPrettierConfig.includes("tailwindStylesheet")) {
|
|
297
|
+
if (!force) {
|
|
298
|
+
throw new Error(
|
|
299
|
+
"tailwindStylesheet setting already exists in prettier configuration.\nUse --force to override existing config."
|
|
326
300
|
);
|
|
327
|
-
}
|
|
301
|
+
}
|
|
302
|
+
if (!stringEntryRegExp.test(newPrettierConfig)) {
|
|
328
303
|
throw new Error(
|
|
329
|
-
|
|
304
|
+
`Could not update the tailwindStylesheet setting in ${prettierConfigPath}.
|
|
305
|
+
Set it to './${tailwindStylesheetPath}' yourself.`
|
|
330
306
|
);
|
|
331
307
|
}
|
|
308
|
+
newPrettierConfig = newPrettierConfig.replace(
|
|
309
|
+
stringEntryRegExp,
|
|
310
|
+
tailwindStylesheetEntry
|
|
311
|
+
);
|
|
332
312
|
} else {
|
|
333
313
|
newPrettierConfig = newPrettierConfig.replace(
|
|
334
314
|
/,(\n\s*)(\}\n?)$/,
|
|
335
315
|
`,
|
|
336
|
-
|
|
316
|
+
${tailwindStylesheetEntry}$1$2`
|
|
337
317
|
);
|
|
338
318
|
}
|
|
339
319
|
fs.writeFileSync(prettierConfigPath, newPrettierConfig);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/cli",
|
|
3
|
-
"version": "8.0.0-canary.
|
|
3
|
+
"version": "8.0.0-canary.3378",
|
|
4
4
|
"description": "The CedarJS Command Line",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,17 +36,17 @@
|
|
|
36
36
|
"@babel/preset-typescript": "7.29.7",
|
|
37
37
|
"@babel/traverse": "7.29.10",
|
|
38
38
|
"@babel/types": "7.29.8",
|
|
39
|
-
"@cedarjs/api-server": "8.0.0-canary.
|
|
40
|
-
"@cedarjs/babel-config": "8.0.0-canary.
|
|
41
|
-
"@cedarjs/cli-helpers": "8.0.0-canary.
|
|
42
|
-
"@cedarjs/internal": "8.0.0-canary.
|
|
43
|
-
"@cedarjs/prerender": "8.0.0-canary.
|
|
44
|
-
"@cedarjs/project-config": "8.0.0-canary.
|
|
45
|
-
"@cedarjs/structure": "8.0.0-canary.
|
|
46
|
-
"@cedarjs/telemetry": "8.0.0-canary.
|
|
47
|
-
"@cedarjs/utils": "8.0.0-canary.
|
|
48
|
-
"@cedarjs/vite": "8.0.0-canary.
|
|
49
|
-
"@cedarjs/web-server": "8.0.0-canary.
|
|
39
|
+
"@cedarjs/api-server": "8.0.0-canary.3378",
|
|
40
|
+
"@cedarjs/babel-config": "8.0.0-canary.3378",
|
|
41
|
+
"@cedarjs/cli-helpers": "8.0.0-canary.3378",
|
|
42
|
+
"@cedarjs/internal": "8.0.0-canary.3378",
|
|
43
|
+
"@cedarjs/prerender": "8.0.0-canary.3378",
|
|
44
|
+
"@cedarjs/project-config": "8.0.0-canary.3378",
|
|
45
|
+
"@cedarjs/structure": "8.0.0-canary.3378",
|
|
46
|
+
"@cedarjs/telemetry": "8.0.0-canary.3378",
|
|
47
|
+
"@cedarjs/utils": "8.0.0-canary.3378",
|
|
48
|
+
"@cedarjs/vite": "8.0.0-canary.3378",
|
|
49
|
+
"@cedarjs/web-server": "8.0.0-canary.3378",
|
|
50
50
|
"@listr2/prompt-adapter-enquirer": "4.3.3",
|
|
51
51
|
"@opentelemetry/api": "1.9.1",
|
|
52
52
|
"@opentelemetry/core": "2.12.0",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"yargs": "17.7.3"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@cedarjs/framework-tools": "8.0.0-canary.
|
|
97
|
+
"@cedarjs/framework-tools": "8.0.0-canary.3378",
|
|
98
98
|
"@prisma/dmmf": "7.10.0",
|
|
99
99
|
"@types/archiver": "^7.0.0",
|
|
100
100
|
"memfs": "4.80.0",
|