juo 0.0.1-alpha.4 → 0.0.2-pre.1
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-CyANz2YH.js} +12 -12
- package/dist/commands/create.d.ts +4 -3
- package/dist/commands/create.js +155 -260
- package/dist/commands/generate.d.ts +10 -9
- 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-Be3Ctuvv.js +118 -0
- package/dist/hooks/postrun.js +10 -10
- package/dist/hooks/prerun.js +1 -1
- package/dist/juoTemplateGenerator-C0le5FdK.js +130 -0
- package/dist/lib/index.d.ts +69 -0
- package/dist/lib/index.js +4 -0
- package/dist/packageGenerator-8E_-V5CL.js +117 -0
- package/oclif.manifest.json +12 -7
- package/package.json +10 -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.0.
|
|
23
|
+
juo/0.0.2-pre.1 darwin-arm64 node-v22.13.1
|
|
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
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
2
|
|
|
3
3
|
//#region src/utils/config.ts
|
|
4
|
-
const MIXPANEL_TOKEN = "
|
|
5
|
-
const MIXPANEL_API_URL = "https://api
|
|
6
|
-
const CUSTOMERIO_BETA_FORM_URL = "
|
|
7
|
-
const CUSTOMERIO_SITE_ID = "
|
|
8
|
-
const CUSTOMERIO_API_KEY = "
|
|
4
|
+
const MIXPANEL_TOKEN = "";
|
|
5
|
+
const MIXPANEL_API_URL = "https://api.mixpanel.com";
|
|
6
|
+
const CUSTOMERIO_BETA_FORM_URL = "";
|
|
7
|
+
const CUSTOMERIO_SITE_ID = "";
|
|
8
|
+
const CUSTOMERIO_API_KEY = "";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/utils/analytics.ts
|
|
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_interfaces5 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_interfaces5.BooleanFlag<boolean>;
|
|
9
|
+
storybook: _oclif_core_interfaces5.BooleanFlag<boolean>;
|
|
10
|
+
verbose: _oclif_core_interfaces5.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-C0le5FdK.js";
|
|
2
|
+
import { t as PackageGenerator } from "../packageGenerator-8E_-V5CL.js";
|
|
3
|
+
import { t as Generate } from "../generate-Be3Ctuvv.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: "pnpx",
|
|
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);
|
|
@@ -392,17 +276,18 @@ var Create = class Create extends Command {
|
|
|
392
276
|
outro(`Run \`cd ${packageName}\` to start developing your project.`);
|
|
393
277
|
process.exit(0);
|
|
394
278
|
}
|
|
395
|
-
async getProjectConfig(quickstart) {
|
|
279
|
+
async getProjectConfig(quickstart, storybookFlag) {
|
|
396
280
|
if (quickstart) return {
|
|
397
|
-
packageName: "juo-theme",
|
|
398
|
-
packageManager: "npm",
|
|
399
281
|
framework: "react",
|
|
282
|
+
packageManager: "npm",
|
|
283
|
+
packageName: "juo-theme",
|
|
284
|
+
storybook: storybookFlag ?? false,
|
|
400
285
|
tailwind: true
|
|
401
286
|
};
|
|
402
287
|
const packageName = await text({
|
|
288
|
+
initialValue: "juo-theme",
|
|
403
289
|
message: "What is the name of the package?",
|
|
404
290
|
placeholder: "juo-theme",
|
|
405
|
-
initialValue: "juo-theme",
|
|
406
291
|
validate(value) {
|
|
407
292
|
if (value.length === 0) return `Value is required!`;
|
|
408
293
|
if (!/^[a-z0-9-]+$/.test(value)) return `Invalid package name`;
|
|
@@ -410,52 +295,62 @@ var Create = class Create extends Command {
|
|
|
410
295
|
});
|
|
411
296
|
if (isCancel(packageName)) process.exit(0);
|
|
412
297
|
const packageManager = await select({
|
|
298
|
+
initialValue: "npm",
|
|
413
299
|
message: "What package manager to use?",
|
|
414
300
|
options: [
|
|
415
301
|
{
|
|
416
|
-
|
|
417
|
-
|
|
302
|
+
label: "npm",
|
|
303
|
+
value: "npm"
|
|
418
304
|
},
|
|
419
305
|
{
|
|
420
|
-
|
|
421
|
-
|
|
306
|
+
label: "pnpm",
|
|
307
|
+
value: "pnpm"
|
|
422
308
|
},
|
|
423
309
|
{
|
|
424
|
-
|
|
425
|
-
|
|
310
|
+
label: "yarn",
|
|
311
|
+
value: "yarn"
|
|
426
312
|
}
|
|
427
|
-
]
|
|
428
|
-
initialValue: "npm"
|
|
313
|
+
]
|
|
429
314
|
});
|
|
430
315
|
if (isCancel(packageManager)) process.exit(0);
|
|
431
316
|
const framework = await select({
|
|
317
|
+
initialValue: "react",
|
|
432
318
|
message: "What framework to use?",
|
|
433
319
|
options: [{
|
|
434
|
-
|
|
435
|
-
|
|
320
|
+
label: "React",
|
|
321
|
+
value: "react"
|
|
436
322
|
}, {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}]
|
|
440
|
-
initialValue: "react"
|
|
323
|
+
label: "Preact",
|
|
324
|
+
value: "preact"
|
|
325
|
+
}]
|
|
441
326
|
});
|
|
442
|
-
if (isCancel(framework)) process.exit(
|
|
327
|
+
if (isCancel(framework)) process.exit();
|
|
443
328
|
const tailwind = await select({
|
|
329
|
+
initialValue: true,
|
|
444
330
|
message: "Do you want to use Tailwind CSS?",
|
|
445
331
|
options: [{
|
|
446
|
-
|
|
447
|
-
|
|
332
|
+
label: "Yes",
|
|
333
|
+
value: true
|
|
448
334
|
}, {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}]
|
|
452
|
-
initialValue: true
|
|
335
|
+
label: "No",
|
|
336
|
+
value: false
|
|
337
|
+
}]
|
|
453
338
|
});
|
|
454
339
|
if (isCancel(tailwind)) process.exit(0);
|
|
340
|
+
let storybook;
|
|
341
|
+
if (storybookFlag === void 0) {
|
|
342
|
+
const storybookAnswer = await confirm({
|
|
343
|
+
initialValue: false,
|
|
344
|
+
message: "Do you want Storybook?"
|
|
345
|
+
});
|
|
346
|
+
if (isCancel(storybookAnswer)) process.exit(0);
|
|
347
|
+
storybook = storybookAnswer;
|
|
348
|
+
} else storybook = storybookFlag;
|
|
455
349
|
return {
|
|
456
|
-
packageName,
|
|
457
|
-
packageManager,
|
|
458
350
|
framework,
|
|
351
|
+
packageManager,
|
|
352
|
+
packageName,
|
|
353
|
+
storybook,
|
|
459
354
|
tailwind
|
|
460
355
|
};
|
|
461
356
|
}
|