juo 0.0.1-alpha.5 → 0.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/README.md +6 -5
- package/dist/{analytics-B2gwRg5Q.js → analytics-CgHTVQWO.js} +7 -7
- package/dist/commands/create.d.ts +4 -3
- package/dist/commands/create.js +158 -264
- package/dist/commands/generate.d.ts +6 -5
- package/dist/commands/generate.js +2 -1
- package/dist/commands/publish/index.d.ts +7 -7
- package/dist/commands/publish/index.js +4 -3
- package/dist/generate-vpUPJZRH.js +118 -0
- package/dist/hooks/postrun.js +39 -11
- package/dist/hooks/prerun.js +1 -1
- package/dist/juoTemplateGenerator-MZ8llr7w.js +130 -0
- package/dist/lib/index.d.ts +69 -0
- package/dist/lib/index.js +4 -0
- package/dist/packageGenerator-Dno-ecHh.js +117 -0
- package/oclif.manifest.json +12 -7
- package/package.json +6 -2
- package/templates/block/preact/index.ts.liquid +4 -5
- package/templates/block/preact/{{block.clsName}}.tsx.liquid +1 -2
- package/templates/block/react/index.ts.liquid +3 -6
- package/templates/block/react/{{block.clsName}}.tsx.liquid +2 -3
- package/templates/tailwind/vite.config.ts.liquid +11 -1
- package/dist/generate-D7J6nPBd.js +0 -252
- package/templates/block/react/state.ts.liquid +0 -105
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
CLI for publishing Juo blocks to registry
|
|
4
4
|
|
|
5
5
|
[](https://oclif.io)
|
|
6
|
-
[](https://npmjs.org/package/juo)
|
|
7
|
+
[](https://npmjs.org/package/juo)
|
|
8
8
|
|
|
9
9
|
<!-- toc -->
|
|
10
10
|
* [juo](#juo)
|
|
@@ -20,7 +20,7 @@ $ npm install -g juo
|
|
|
20
20
|
$ juo COMMAND
|
|
21
21
|
running command...
|
|
22
22
|
$ juo (--version)
|
|
23
|
-
juo/0.
|
|
23
|
+
juo/0.1.0 linux-x64 node-v22.21.0
|
|
24
24
|
$ juo --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ juo COMMAND
|
|
@@ -42,11 +42,12 @@ Generate a new Juo project
|
|
|
42
42
|
|
|
43
43
|
```
|
|
44
44
|
USAGE
|
|
45
|
-
$ juo create [-q] [-v]
|
|
45
|
+
$ juo create [-q] [--storybook] [-v]
|
|
46
46
|
|
|
47
47
|
FLAGS
|
|
48
48
|
-q, --quickstart
|
|
49
49
|
-v, --verbose
|
|
50
|
+
--[no-]storybook
|
|
50
51
|
|
|
51
52
|
DESCRIPTION
|
|
52
53
|
Generate a new Juo project
|
|
@@ -58,7 +59,7 @@ Generate blocks for your project
|
|
|
58
59
|
|
|
59
60
|
```
|
|
60
61
|
USAGE
|
|
61
|
-
$ juo generate [-n <value>] [--type block] [-
|
|
62
|
+
$ juo generate [-n <value>] [-t] [--type block] [-v]
|
|
62
63
|
|
|
63
64
|
FLAGS
|
|
64
65
|
-n, --name=<value> The name of the component
|
|
@@ -12,7 +12,7 @@ const CUSTOMERIO_API_KEY = "1d54688e66cddda9ea72";
|
|
|
12
12
|
const log = debug("juo:analytics");
|
|
13
13
|
let userId = null;
|
|
14
14
|
function getUserId() {
|
|
15
|
-
if (!userId) userId = `cli_${Date.now()}_${Math.random().toString(36).
|
|
15
|
+
if (!userId) userId = `cli_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
16
16
|
return userId;
|
|
17
17
|
}
|
|
18
18
|
async function sendToMixpanel(event) {
|
|
@@ -22,15 +22,15 @@ async function sendToMixpanel(event) {
|
|
|
22
22
|
event: event.event,
|
|
23
23
|
properties: {
|
|
24
24
|
...event.properties,
|
|
25
|
-
token: MIXPANEL_TOKEN,
|
|
26
25
|
distinct_id: getUserId(),
|
|
27
|
-
time: Math.floor(Date.now() / 1e3)
|
|
26
|
+
time: Math.floor(Date.now() / 1e3),
|
|
27
|
+
token: MIXPANEL_TOKEN
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
const encodedData = Buffer.from(JSON.stringify(data)).toString("base64");
|
|
31
31
|
await fetch(`${MIXPANEL_API_URL}/track?data=${encodedData}`, {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
headers: { "Content-Type": "application/json" },
|
|
33
|
+
method: "GET"
|
|
34
34
|
}).catch((error) => {
|
|
35
35
|
log("Failed to send analytics event to Mixpanel: %O", error);
|
|
36
36
|
});
|
|
@@ -60,8 +60,8 @@ function trackCommandCompleted(commandName, success = true) {
|
|
|
60
60
|
}
|
|
61
61
|
function trackBetaSignup(email, commandContext) {
|
|
62
62
|
trackEvent("cli.beta.signup", {
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
command: commandContext,
|
|
64
|
+
email
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Command } from "@oclif/core";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _oclif_core_interfaces7 from "@oclif/core/interfaces";
|
|
3
3
|
|
|
4
4
|
//#region src/commands/create.d.ts
|
|
5
5
|
declare class Create extends Command {
|
|
6
6
|
static description: string;
|
|
7
7
|
static flags: {
|
|
8
|
-
quickstart:
|
|
9
|
-
|
|
8
|
+
quickstart: _oclif_core_interfaces7.BooleanFlag<boolean>;
|
|
9
|
+
storybook: _oclif_core_interfaces7.BooleanFlag<boolean>;
|
|
10
|
+
verbose: _oclif_core_interfaces7.BooleanFlag<boolean>;
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
12
13
|
private getProjectConfig;
|
package/dist/commands/create.js
CHANGED
|
@@ -1,125 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as BaseTemplateGenerator } from "../juoTemplateGenerator-MZ8llr7w.js";
|
|
2
|
+
import { t as PackageGenerator } from "../packageGenerator-Dno-ecHh.js";
|
|
3
|
+
import { t as Generate } from "../generate-vpUPJZRH.js";
|
|
2
4
|
import { Command, Flags } from "@oclif/core";
|
|
3
|
-
import { isCancel, outro, select, spinner, text } from "@clack/prompts";
|
|
4
5
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
6
|
import path from "node:path";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { defineTSConfig, writeTSConfig } from "pkg-types";
|
|
9
|
+
import { confirm, isCancel, outro, select, spinner, text } from "@clack/prompts";
|
|
8
10
|
import { readdir, rm, stat, unlink } from "node:fs/promises";
|
|
9
11
|
|
|
10
|
-
//#region src/utils/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"@juo/orion-core": "^0.4.0-rc.1",
|
|
15
|
-
"@mantine/core": "7.5.3",
|
|
16
|
-
"@mantine/hooks": "7.5.3",
|
|
17
|
-
react: "^18.2.0",
|
|
18
|
-
"react-dom": "^18.2.0"
|
|
19
|
-
},
|
|
20
|
-
devDependencies: {
|
|
21
|
-
"@storybook/react-vite": "^10.0.7",
|
|
22
|
-
"@types/react": "^18.2.55",
|
|
23
|
-
"@types/react-dom": "^18.2.19",
|
|
24
|
-
"@vitejs/plugin-react": "^5.1.1",
|
|
25
|
-
"vite-plugin-svgr": "^4.5.0"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
preact: {
|
|
29
|
-
dependencies: { preact: "^10.26.8" },
|
|
30
|
-
devDependencies: {
|
|
31
|
-
"@storybook/react-vite": "^10.0.7",
|
|
32
|
-
"json-schema-to-ts": "^3.1.1",
|
|
33
|
-
"@preact/preset-vite": "^2.10.2",
|
|
34
|
-
"vite-plugin-svgr": "^4.5.0"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var PackageGenerator = class {
|
|
39
|
-
static async generate(destDir, options) {
|
|
40
|
-
if (!existsSync(destDir)) mkdirSync(destDir, { recursive: true });
|
|
41
|
-
const packageJsonPath = path.join(destDir, "package.json");
|
|
42
|
-
const packageJson = this.buildPackageJson(options);
|
|
43
|
-
try {
|
|
44
|
-
await writePackageJSON(packageJsonPath, packageJson);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
throw new Error(`Failed to write package.json to ${packageJsonPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
static sort(packageJson) {
|
|
50
|
-
return sortPackage(packageJson);
|
|
51
|
-
}
|
|
52
|
-
static readPackageManagerVersion(packageManager) {
|
|
53
|
-
try {
|
|
54
|
-
return execSync(`${packageManager} --version`, {
|
|
55
|
-
encoding: "utf-8",
|
|
56
|
-
stdio: [
|
|
57
|
-
"pipe",
|
|
58
|
-
"pipe",
|
|
59
|
-
"ignore"
|
|
60
|
-
]
|
|
61
|
-
}).trim();
|
|
62
|
-
} catch (error) {
|
|
63
|
-
console.warn(`Failed to read ${packageManager} version, using fallback`);
|
|
64
|
-
return "latest";
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
static buildPackageJson(options) {
|
|
68
|
-
const pmVersion = this.readPackageManagerVersion(options.packageManager);
|
|
69
|
-
const baseConfig = definePackageJSON({
|
|
70
|
-
name: options.name,
|
|
71
|
-
private: true,
|
|
72
|
-
version: "0.0.0",
|
|
73
|
-
type: "module",
|
|
74
|
-
scripts: {
|
|
75
|
-
dev: "vite build -w & vite preview --port 5174",
|
|
76
|
-
build: "tsc && vite build",
|
|
77
|
-
preview: "vite preview",
|
|
78
|
-
storybook: "storybook dev -p 6006",
|
|
79
|
-
"build-storybook": "storybook build"
|
|
80
|
-
},
|
|
81
|
-
engines: {
|
|
82
|
-
node: ">=20.0.0",
|
|
83
|
-
pnpm: ">=7.0.0"
|
|
84
|
-
},
|
|
85
|
-
packageManager: `${options.packageManager}@${pmVersion}`,
|
|
86
|
-
devDependencies: {
|
|
87
|
-
"@testing-library/dom": "^10.4.0",
|
|
88
|
-
"@types/node": "^22.15.29",
|
|
89
|
-
"json-schema-to-ts": "^3.1.1",
|
|
90
|
-
postcss: "^8.5.3",
|
|
91
|
-
"postcss-prefix-selector": "^2.1.1",
|
|
92
|
-
prettier: "^3.5.3",
|
|
93
|
-
...options.tailwind ? {
|
|
94
|
-
tailwindcss: "^4.1.17",
|
|
95
|
-
"@tailwindcss/vite": "^4.1.17"
|
|
96
|
-
} : {},
|
|
97
|
-
storybook: "^10.0.7",
|
|
98
|
-
typebox: "^1.0.51",
|
|
99
|
-
typescript: "~5.7.2",
|
|
100
|
-
vite: "^6.3.1"
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
if (options.framework === "react") {
|
|
104
|
-
baseConfig.devDependencies = {
|
|
105
|
-
...baseConfig.devDependencies,
|
|
106
|
-
...FRAMEWORK_CONFIGS.react.devDependencies
|
|
107
|
-
};
|
|
108
|
-
baseConfig.dependencies = {
|
|
109
|
-
...baseConfig.dependencies,
|
|
110
|
-
...FRAMEWORK_CONFIGS.react.dependencies
|
|
111
|
-
};
|
|
112
|
-
} else if (options.framework === "preact") {
|
|
113
|
-
baseConfig.dependencies = {
|
|
114
|
-
...baseConfig.dependencies,
|
|
115
|
-
...FRAMEWORK_CONFIGS.preact.dependencies
|
|
116
|
-
};
|
|
117
|
-
baseConfig.devDependencies = {
|
|
118
|
-
...baseConfig.devDependencies,
|
|
119
|
-
...FRAMEWORK_CONFIGS.preact.devDependencies
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
return this.sort(baseConfig);
|
|
12
|
+
//#region src/utils/configFilesGenerator.ts
|
|
13
|
+
var ConfigFilesGenerator = class extends BaseTemplateGenerator {
|
|
14
|
+
async generate(destDir, options) {
|
|
15
|
+
this.renderTemplate("configFiles", destDir, { framework: options.framework });
|
|
123
16
|
}
|
|
124
17
|
};
|
|
125
18
|
|
|
@@ -127,10 +20,33 @@ var PackageGenerator = class {
|
|
|
127
20
|
//#region src/utils/storybookGenerator.ts
|
|
128
21
|
const COMMAND_CONFIG = {
|
|
129
22
|
npm: "npx",
|
|
130
|
-
|
|
131
|
-
|
|
23
|
+
pnpm: "pnpm dlx",
|
|
24
|
+
yarn: "yarn dlx"
|
|
132
25
|
};
|
|
133
26
|
var StorybookGenerator = class extends BaseTemplateGenerator {
|
|
27
|
+
async appendStylesToPreview(destDir) {
|
|
28
|
+
const storybookDir = path.join(destDir, ".storybook");
|
|
29
|
+
const previewJsPath = path.join(storybookDir, "preview.js");
|
|
30
|
+
const previewTsPath = path.join(storybookDir, "preview.ts");
|
|
31
|
+
const importStatement = "import \"../src/styles.css\";\n";
|
|
32
|
+
try {
|
|
33
|
+
const previewJsExists = existsSync(previewJsPath);
|
|
34
|
+
const previewTsExists = existsSync(previewTsPath);
|
|
35
|
+
let targetPath;
|
|
36
|
+
if (previewTsExists) targetPath = previewTsPath;
|
|
37
|
+
else if (previewJsExists) targetPath = previewJsPath;
|
|
38
|
+
else {
|
|
39
|
+
targetPath = previewTsPath;
|
|
40
|
+
mkdirSync(storybookDir, { recursive: true });
|
|
41
|
+
writeFileSync(targetPath, importStatement);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const existingContent = readFileSync(targetPath, "utf8");
|
|
45
|
+
if (!existingContent.includes("import \"../src/styles.css\"")) writeFileSync(targetPath, importStatement + existingContent);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw new Error(`Error appending styles to preview: ${error}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
134
50
|
async generate(destDir, options) {
|
|
135
51
|
const args = [
|
|
136
52
|
"storybook@latest",
|
|
@@ -153,12 +69,12 @@ var StorybookGenerator = class extends BaseTemplateGenerator {
|
|
|
153
69
|
return new Promise((resolve, reject) => {
|
|
154
70
|
const child = spawn(command, args, {
|
|
155
71
|
cwd: destDir,
|
|
72
|
+
shell: true,
|
|
156
73
|
stdio: options.verbose ? "inherit" : [
|
|
157
74
|
"ignore",
|
|
158
75
|
"ignore",
|
|
159
76
|
"ignore"
|
|
160
|
-
]
|
|
161
|
-
shell: true
|
|
77
|
+
]
|
|
162
78
|
});
|
|
163
79
|
child.on("close", async (code) => {
|
|
164
80
|
if (code === 0) try {
|
|
@@ -174,28 +90,27 @@ var StorybookGenerator = class extends BaseTemplateGenerator {
|
|
|
174
90
|
});
|
|
175
91
|
});
|
|
176
92
|
}
|
|
93
|
+
async appendPreviewHead(destDir) {
|
|
94
|
+
const storybookDir = path.join(destDir, ".storybook");
|
|
95
|
+
this.renderTemplate(".storybook", storybookDir, {});
|
|
96
|
+
}
|
|
177
97
|
async cleanUp(destDir) {
|
|
178
98
|
try {
|
|
179
99
|
const items = await readdir(destDir);
|
|
180
|
-
const itemsToSkip = ["assets", "Configure.mdx"];
|
|
100
|
+
const itemsToSkip = new Set(["assets", "Configure.mdx"]);
|
|
181
101
|
for (const item of items) {
|
|
182
102
|
const itemPath = path.join(destDir, item);
|
|
183
103
|
const stats = await stat(itemPath);
|
|
184
|
-
if (itemsToSkip.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
});
|
|
189
|
-
else await unlink(itemPath);
|
|
104
|
+
if (itemsToSkip.has(item)) continue;
|
|
105
|
+
await (stats.isDirectory() ? rm(itemPath, {
|
|
106
|
+
force: true,
|
|
107
|
+
recursive: true
|
|
108
|
+
}) : unlink(itemPath));
|
|
190
109
|
}
|
|
191
110
|
} catch (error) {
|
|
192
111
|
throw new Error(`Error cleaning up storybook: ${error}`);
|
|
193
112
|
}
|
|
194
113
|
}
|
|
195
|
-
async appendPreviewHead(destDir) {
|
|
196
|
-
const storybookDir = path.join(destDir, ".storybook");
|
|
197
|
-
this.renderTemplate(".storybook", storybookDir, {});
|
|
198
|
-
}
|
|
199
114
|
async postGenerate(destDir) {
|
|
200
115
|
const storiesDir = path.join(destDir, "stories");
|
|
201
116
|
try {
|
|
@@ -206,86 +121,6 @@ var StorybookGenerator = class extends BaseTemplateGenerator {
|
|
|
206
121
|
throw new Error(`Error post-generating storybook: ${error}`);
|
|
207
122
|
}
|
|
208
123
|
}
|
|
209
|
-
async appendStylesToPreview(destDir) {
|
|
210
|
-
const storybookDir = path.join(destDir, ".storybook");
|
|
211
|
-
const previewJsPath = path.join(storybookDir, "preview.js");
|
|
212
|
-
const previewTsPath = path.join(storybookDir, "preview.ts");
|
|
213
|
-
const importStatement = "import \"../src/styles.css\";\n";
|
|
214
|
-
try {
|
|
215
|
-
const previewJsExists = existsSync(previewJsPath);
|
|
216
|
-
const previewTsExists = existsSync(previewTsPath);
|
|
217
|
-
let targetPath;
|
|
218
|
-
if (previewTsExists) targetPath = previewTsPath;
|
|
219
|
-
else if (previewJsExists) targetPath = previewJsPath;
|
|
220
|
-
else {
|
|
221
|
-
targetPath = previewTsPath;
|
|
222
|
-
mkdirSync(storybookDir, { recursive: true });
|
|
223
|
-
writeFileSync(targetPath, importStatement);
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
const existingContent = readFileSync(targetPath, "utf-8");
|
|
227
|
-
if (!existingContent.includes("import \"../src/styles.css\"")) writeFileSync(targetPath, importStatement + existingContent);
|
|
228
|
-
} catch (error) {
|
|
229
|
-
throw new Error(`Error appending styles to preview: ${error}`);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
//#endregion
|
|
235
|
-
//#region src/utils/tsconfigGenerator.ts
|
|
236
|
-
const baseTSConfig = {
|
|
237
|
-
compilerOptions: {
|
|
238
|
-
target: "ES2022",
|
|
239
|
-
module: "ESNext",
|
|
240
|
-
moduleResolution: "bundler",
|
|
241
|
-
jsx: "react-jsx",
|
|
242
|
-
strict: true,
|
|
243
|
-
esModuleInterop: true,
|
|
244
|
-
allowSyntheticDefaultImports: true,
|
|
245
|
-
skipLibCheck: true,
|
|
246
|
-
resolveJsonModule: true,
|
|
247
|
-
allowImportingTsExtensions: true,
|
|
248
|
-
isolatedModules: true,
|
|
249
|
-
noEmit: true,
|
|
250
|
-
forceConsistentCasingInFileNames: true,
|
|
251
|
-
types: ["vitest/globals", "node"]
|
|
252
|
-
},
|
|
253
|
-
include: [
|
|
254
|
-
"src/**/*",
|
|
255
|
-
"vitest.config.ts",
|
|
256
|
-
"vitest.shims.d.ts",
|
|
257
|
-
"vite-env.d.ts"
|
|
258
|
-
],
|
|
259
|
-
exclude: ["node_modules", "dist"]
|
|
260
|
-
};
|
|
261
|
-
const preactTSConfig = {
|
|
262
|
-
...baseTSConfig,
|
|
263
|
-
compilerOptions: {
|
|
264
|
-
...baseTSConfig.compilerOptions,
|
|
265
|
-
paths: {
|
|
266
|
-
react: ["./node_modules/preact/compat/"],
|
|
267
|
-
"react-dom": ["./node_modules/preact/compat/"]
|
|
268
|
-
},
|
|
269
|
-
jsxImportSource: "preact"
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
const configs = {
|
|
273
|
-
react: {
|
|
274
|
-
...baseTSConfig,
|
|
275
|
-
compilerOptions: { ...baseTSConfig.compilerOptions }
|
|
276
|
-
},
|
|
277
|
-
preact: preactTSConfig
|
|
278
|
-
};
|
|
279
|
-
var TsconfigGenerator = class {
|
|
280
|
-
static async generate(destDir, options) {
|
|
281
|
-
try {
|
|
282
|
-
const tsconfigPath = path.join(destDir, "tsconfig.json");
|
|
283
|
-
if (!existsSync(tsconfigPath)) mkdirSync(path.dirname(tsconfigPath), { recursive: true });
|
|
284
|
-
await writeTSConfig(tsconfigPath, defineTSConfig(configs[options.framework] ?? baseTSConfig));
|
|
285
|
-
} catch (error) {
|
|
286
|
-
throw new Error(`Error generating TypeScript configuration: ${error}`);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
124
|
};
|
|
290
125
|
|
|
291
126
|
//#endregion
|
|
@@ -293,7 +128,7 @@ var TsconfigGenerator = class {
|
|
|
293
128
|
var TailwindGenerator = class extends BaseTemplateGenerator {
|
|
294
129
|
async generate(destDir, options) {
|
|
295
130
|
this.renderTemplate("tailwind", destDir, { framework: options.framework });
|
|
296
|
-
await this.appendStorybookPreview(destDir);
|
|
131
|
+
if (options.storybook) await this.appendStorybookPreview(destDir);
|
|
297
132
|
}
|
|
298
133
|
async appendStorybookPreview(destDir) {
|
|
299
134
|
const storybookDir = path.join(destDir, ".storybook");
|
|
@@ -316,7 +151,7 @@ var TailwindGenerator = class extends BaseTemplateGenerator {
|
|
|
316
151
|
}
|
|
317
152
|
}
|
|
318
153
|
try {
|
|
319
|
-
const existingContent = readFileSync(targetPath, "
|
|
154
|
+
const existingContent = readFileSync(targetPath, "utf8");
|
|
320
155
|
if (!existingContent.includes("import \"../src/tailwind.css\"")) writeFileSync(targetPath, importStatement + existingContent);
|
|
321
156
|
} catch (error) {
|
|
322
157
|
throw new Error(`Error appending Storybook preview: ${error}`);
|
|
@@ -325,12 +160,53 @@ var TailwindGenerator = class extends BaseTemplateGenerator {
|
|
|
325
160
|
};
|
|
326
161
|
|
|
327
162
|
//#endregion
|
|
328
|
-
//#region src/utils/
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
163
|
+
//#region src/utils/tsconfigGenerator.ts
|
|
164
|
+
const baseTSConfig = {
|
|
165
|
+
compilerOptions: {
|
|
166
|
+
allowImportingTsExtensions: true,
|
|
167
|
+
allowSyntheticDefaultImports: true,
|
|
168
|
+
esModuleInterop: true,
|
|
169
|
+
forceConsistentCasingInFileNames: true,
|
|
170
|
+
isolatedModules: true,
|
|
171
|
+
jsx: "react-jsx",
|
|
172
|
+
module: "ESNext",
|
|
173
|
+
moduleResolution: "bundler",
|
|
174
|
+
noEmit: true,
|
|
175
|
+
resolveJsonModule: true,
|
|
176
|
+
skipLibCheck: true,
|
|
177
|
+
strict: true,
|
|
178
|
+
target: "ES2022",
|
|
179
|
+
types: ["node"]
|
|
180
|
+
},
|
|
181
|
+
exclude: ["node_modules", "dist"],
|
|
182
|
+
include: ["src/**/*", "vite-env.d.ts"]
|
|
183
|
+
};
|
|
184
|
+
const configs = {
|
|
185
|
+
preact: {
|
|
186
|
+
...baseTSConfig,
|
|
187
|
+
compilerOptions: {
|
|
188
|
+
...baseTSConfig.compilerOptions,
|
|
189
|
+
jsxImportSource: "preact",
|
|
190
|
+
paths: {
|
|
191
|
+
react: ["./node_modules/preact/compat/"],
|
|
192
|
+
"react-dom": ["./node_modules/preact/compat/"]
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
react: {
|
|
197
|
+
...baseTSConfig,
|
|
198
|
+
compilerOptions: { ...baseTSConfig.compilerOptions }
|
|
332
199
|
}
|
|
333
200
|
};
|
|
201
|
+
const TsconfigGenerator = { async generate(destDir, options) {
|
|
202
|
+
try {
|
|
203
|
+
const tsconfigPath = path.join(destDir, "tsconfig.json");
|
|
204
|
+
if (!existsSync(tsconfigPath)) mkdirSync(path.dirname(tsconfigPath), { recursive: true });
|
|
205
|
+
await writeTSConfig(tsconfigPath, defineTSConfig(configs[options.framework] ?? baseTSConfig));
|
|
206
|
+
} catch (error) {
|
|
207
|
+
throw new Error(`Error generating TypeScript configuration: ${error}`);
|
|
208
|
+
}
|
|
209
|
+
} };
|
|
334
210
|
|
|
335
211
|
//#endregion
|
|
336
212
|
//#region src/commands/create.ts
|
|
@@ -338,34 +214,39 @@ var Create = class Create extends Command {
|
|
|
338
214
|
static description = "Generate a new Juo project";
|
|
339
215
|
static flags = {
|
|
340
216
|
quickstart: Flags.boolean({ char: "q" }),
|
|
217
|
+
storybook: Flags.boolean({ allowNo: true }),
|
|
341
218
|
verbose: Flags.boolean({ char: "v" })
|
|
342
219
|
};
|
|
343
220
|
async run() {
|
|
344
221
|
const { flags } = await this.parse(Create);
|
|
345
|
-
const {
|
|
346
|
-
const storybookGenerator = new StorybookGenerator();
|
|
222
|
+
const { framework, packageManager, packageName, storybook, tailwind } = await this.getProjectConfig(flags.quickstart, flags.storybook);
|
|
347
223
|
const projectDir = path.resolve("./", packageName);
|
|
348
224
|
const packageJsonSpinner = spinner();
|
|
349
225
|
packageJsonSpinner.start();
|
|
350
226
|
packageJsonSpinner.message("Generating package.json file");
|
|
351
227
|
await PackageGenerator.generate(projectDir, {
|
|
228
|
+
framework,
|
|
352
229
|
name: packageName,
|
|
353
230
|
packageManager,
|
|
354
|
-
|
|
231
|
+
storybook,
|
|
355
232
|
tailwind
|
|
356
233
|
});
|
|
357
234
|
packageJsonSpinner.stop("Generated package.json");
|
|
358
235
|
await new ConfigFilesGenerator().generate(projectDir, { framework });
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
236
|
+
if (storybook) {
|
|
237
|
+
const storybookGenerator = new StorybookGenerator();
|
|
238
|
+
const storybookSpinner = spinner();
|
|
239
|
+
storybookSpinner.start();
|
|
240
|
+
storybookSpinner.message("Generating Storybook configuration");
|
|
241
|
+
await storybookGenerator.generate(projectDir, {
|
|
242
|
+
framework,
|
|
243
|
+
logger: (msg) => storybookSpinner.message(msg),
|
|
244
|
+
packageManager,
|
|
245
|
+
verbose: flags.verbose
|
|
246
|
+
});
|
|
247
|
+
storybookSpinner.stop("Generated Storybook configuration");
|
|
248
|
+
if (!tailwind) await storybookGenerator.appendStylesToPreview(projectDir);
|
|
249
|
+
}
|
|
369
250
|
const tsconfigSpinner = spinner();
|
|
370
251
|
tsconfigSpinner.start();
|
|
371
252
|
tsconfigSpinner.message("Generating TypeScript configuration");
|
|
@@ -375,9 +256,12 @@ var Create = class Create extends Command {
|
|
|
375
256
|
const tailwindSpinner = spinner();
|
|
376
257
|
tailwindSpinner.start();
|
|
377
258
|
tailwindSpinner.message("Generating Tailwind CSS configuration");
|
|
378
|
-
await new TailwindGenerator().generate(projectDir, {
|
|
259
|
+
await new TailwindGenerator().generate(projectDir, {
|
|
260
|
+
framework,
|
|
261
|
+
storybook
|
|
262
|
+
});
|
|
379
263
|
tailwindSpinner.stop("Generated Tailwind CSS configuration");
|
|
380
|
-
}
|
|
264
|
+
}
|
|
381
265
|
const originalCwd = process.cwd();
|
|
382
266
|
try {
|
|
383
267
|
process.chdir(projectDir);
|
|
@@ -390,72 +274,82 @@ var Create = class Create extends Command {
|
|
|
390
274
|
process.chdir(originalCwd);
|
|
391
275
|
}
|
|
392
276
|
outro(`Run \`cd ${packageName}\` to start developing your project.`);
|
|
393
|
-
process.exit(0);
|
|
394
277
|
}
|
|
395
|
-
async getProjectConfig(quickstart) {
|
|
278
|
+
async getProjectConfig(quickstart, storybookFlag) {
|
|
396
279
|
if (quickstart) return {
|
|
397
|
-
packageName: "juo-theme",
|
|
398
|
-
packageManager: "npm",
|
|
399
280
|
framework: "react",
|
|
281
|
+
packageManager: "npm",
|
|
282
|
+
packageName: "juo-theme",
|
|
283
|
+
storybook: storybookFlag ?? false,
|
|
400
284
|
tailwind: true
|
|
401
285
|
};
|
|
402
286
|
const packageName = await text({
|
|
287
|
+
initialValue: "juo-theme",
|
|
403
288
|
message: "What is the name of the package?",
|
|
404
289
|
placeholder: "juo-theme",
|
|
405
|
-
initialValue: "juo-theme",
|
|
406
290
|
validate(value) {
|
|
407
291
|
if (value.length === 0) return `Value is required!`;
|
|
408
292
|
if (!/^[a-z0-9-]+$/.test(value)) return `Invalid package name`;
|
|
409
293
|
}
|
|
410
294
|
});
|
|
411
|
-
if (isCancel(packageName))
|
|
295
|
+
if (isCancel(packageName)) this.exit(0);
|
|
412
296
|
const packageManager = await select({
|
|
297
|
+
initialValue: "npm",
|
|
413
298
|
message: "What package manager to use?",
|
|
414
299
|
options: [
|
|
415
300
|
{
|
|
416
|
-
|
|
417
|
-
|
|
301
|
+
label: "npm",
|
|
302
|
+
value: "npm"
|
|
418
303
|
},
|
|
419
304
|
{
|
|
420
|
-
|
|
421
|
-
|
|
305
|
+
label: "pnpm",
|
|
306
|
+
value: "pnpm"
|
|
422
307
|
},
|
|
423
308
|
{
|
|
424
|
-
|
|
425
|
-
|
|
309
|
+
label: "yarn",
|
|
310
|
+
value: "yarn"
|
|
426
311
|
}
|
|
427
|
-
]
|
|
428
|
-
initialValue: "npm"
|
|
312
|
+
]
|
|
429
313
|
});
|
|
430
|
-
if (isCancel(packageManager))
|
|
314
|
+
if (isCancel(packageManager)) this.exit(0);
|
|
431
315
|
const framework = await select({
|
|
316
|
+
initialValue: "react",
|
|
432
317
|
message: "What framework to use?",
|
|
433
318
|
options: [{
|
|
434
|
-
|
|
435
|
-
|
|
319
|
+
label: "React",
|
|
320
|
+
value: "react"
|
|
436
321
|
}, {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}]
|
|
440
|
-
initialValue: "react"
|
|
322
|
+
label: "Preact",
|
|
323
|
+
value: "preact"
|
|
324
|
+
}]
|
|
441
325
|
});
|
|
442
|
-
if (isCancel(framework))
|
|
326
|
+
if (isCancel(framework)) this.exit(0);
|
|
443
327
|
const tailwind = await select({
|
|
328
|
+
initialValue: true,
|
|
444
329
|
message: "Do you want to use Tailwind CSS?",
|
|
445
330
|
options: [{
|
|
446
|
-
|
|
447
|
-
|
|
331
|
+
label: "Yes",
|
|
332
|
+
value: true
|
|
448
333
|
}, {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}]
|
|
452
|
-
initialValue: true
|
|
334
|
+
label: "No",
|
|
335
|
+
value: false
|
|
336
|
+
}]
|
|
453
337
|
});
|
|
454
|
-
if (isCancel(tailwind))
|
|
338
|
+
if (isCancel(tailwind)) this.exit(0);
|
|
339
|
+
let storybook;
|
|
340
|
+
if (storybookFlag === void 0) {
|
|
341
|
+
const storybookAnswer = await confirm({
|
|
342
|
+
initialValue: false,
|
|
343
|
+
message: "Do you want Storybook?"
|
|
344
|
+
});
|
|
345
|
+
if (isCancel(storybookAnswer)) this.exit(0);
|
|
346
|
+
storybook = storybookAnswer;
|
|
347
|
+
} else storybook = storybookFlag;
|
|
455
348
|
return {
|
|
456
|
-
packageName,
|
|
457
|
-
packageManager,
|
|
458
349
|
framework,
|
|
350
|
+
packageManager,
|
|
351
|
+
packageName,
|
|
352
|
+
storybook,
|
|
459
353
|
tailwind
|
|
460
354
|
};
|
|
461
355
|
}
|
|
@@ -3,18 +3,19 @@ import * as _oclif_core_interfaces0 from "@oclif/core/interfaces";
|
|
|
3
3
|
|
|
4
4
|
//#region src/commands/generate.d.ts
|
|
5
5
|
declare class Generate extends Command {
|
|
6
|
-
static id: string;
|
|
7
6
|
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
8
|
static flags: {
|
|
9
9
|
name: _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
10
|
-
type: _oclif_core_interfaces0.OptionFlag<string, _oclif_core_interfaces0.CustomOptions>;
|
|
11
10
|
tailwind: _oclif_core_interfaces0.BooleanFlag<boolean>;
|
|
11
|
+
type: _oclif_core_interfaces0.OptionFlag<string, _oclif_core_interfaces0.CustomOptions>;
|
|
12
12
|
verbose: _oclif_core_interfaces0.BooleanFlag<boolean>;
|
|
13
13
|
};
|
|
14
|
-
static
|
|
15
|
-
private resolvePackageJsonPath;
|
|
16
|
-
private resolveCSSFramework;
|
|
14
|
+
static id: string;
|
|
17
15
|
run(): Promise<void>;
|
|
16
|
+
private detectStorybook;
|
|
17
|
+
private resolveCSSFramework;
|
|
18
|
+
private resolvePackageJsonPath;
|
|
18
19
|
}
|
|
19
20
|
//#endregion
|
|
20
21
|
export { Generate as default };
|