@pauldvlp/vp-react-ts-shadcn 0.5.0 → 0.5.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/dist/index.js +43 -67
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -63,6 +63,19 @@ function addIconDeps(pkg, iconLibrary) {
|
|
|
63
63
|
const iconDeps = ICON_LIBS[iconLibrary] ?? ICON_LIBS.hugeicons;
|
|
64
64
|
pkg.dependencies = { ...pkg.dependencies, ...iconDeps };
|
|
65
65
|
}
|
|
66
|
+
function validateScope(value) {
|
|
67
|
+
return /^@?[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(value.trim()) ? void 0 : "must be a package scope/name, e.g. @acme";
|
|
68
|
+
}
|
|
69
|
+
function validateName(value) {
|
|
70
|
+
return /^@?[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(value.trim()) ? void 0 : "must be a package name, e.g. my-app or @acme/app";
|
|
71
|
+
}
|
|
72
|
+
function validatePreset(value) {
|
|
73
|
+
return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(value.trim()) ? void 0 : "must be a style name or ui.shadcn.com code";
|
|
74
|
+
}
|
|
75
|
+
function validateComponents(value) {
|
|
76
|
+
const parts = value.split(",").map((c) => c.trim()).filter(Boolean);
|
|
77
|
+
return parts.every((c) => /^[a-z0-9][a-z0-9-]*$/.test(c)) ? void 0 : "comma-separated component names, e.g. button,card,dialog";
|
|
78
|
+
}
|
|
66
79
|
function withRequiredComponents(csv, required = ["button", "badge"]) {
|
|
67
80
|
const requested = csv.split(",").map((c) => c.trim()).filter(Boolean);
|
|
68
81
|
return Array.from(/* @__PURE__ */ new Set([...required, ...requested]));
|
|
@@ -106,30 +119,36 @@ function appComponentsJson(theme) {
|
|
|
106
119
|
}
|
|
107
120
|
};
|
|
108
121
|
}
|
|
109
|
-
function
|
|
122
|
+
function shadcnInitArgs(opts) {
|
|
110
123
|
return [
|
|
111
|
-
|
|
112
|
-
|
|
124
|
+
"--base",
|
|
125
|
+
opts.base,
|
|
126
|
+
"--preset",
|
|
127
|
+
opts.preset,
|
|
113
128
|
opts.cssVariables ? "--css-variables" : "--no-css-variables",
|
|
114
129
|
opts.rtl ? "--rtl" : "--no-rtl",
|
|
115
130
|
opts.pointer ? "--pointer" : "--no-pointer",
|
|
116
131
|
"--no-reinstall",
|
|
117
132
|
"-y",
|
|
118
133
|
"-f"
|
|
119
|
-
]
|
|
134
|
+
];
|
|
120
135
|
}
|
|
121
136
|
function defineTemplate(config) {
|
|
122
137
|
return config;
|
|
123
138
|
}
|
|
124
|
-
function writeTree(node, dir) {
|
|
139
|
+
function writeTree(node, dir, root = path.resolve(dir)) {
|
|
125
140
|
for (const [name, value] of Object.entries(node)) {
|
|
126
|
-
const p = path.
|
|
141
|
+
const p = path.resolve(dir, name);
|
|
142
|
+
const rel = path.relative(root, p);
|
|
143
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel)) {
|
|
144
|
+
throw new Error(`Refusing to write outside the target directory: ${name}`);
|
|
145
|
+
}
|
|
127
146
|
if (typeof value === "string") {
|
|
128
147
|
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
129
148
|
fs.writeFileSync(p, value);
|
|
130
149
|
} else {
|
|
131
150
|
fs.mkdirSync(p, { recursive: true });
|
|
132
|
-
writeTree(value, p);
|
|
151
|
+
writeTree(value, p, root);
|
|
133
152
|
}
|
|
134
153
|
}
|
|
135
154
|
}
|
|
@@ -269,8 +288,9 @@ async function runTemplateCLI(template) {
|
|
|
269
288
|
writeTree(creation.files, directory);
|
|
270
289
|
if (creation.scripts?.length) {
|
|
271
290
|
for (const step of [...creation.scripts].sort((a, b) => a.phase - b.phase)) {
|
|
272
|
-
for (const
|
|
273
|
-
|
|
291
|
+
for (const [program, ...commandArgs] of step.commands) {
|
|
292
|
+
if (!program) continue;
|
|
293
|
+
execFileSync(program, commandArgs, { cwd: directory, stdio: "inherit" });
|
|
274
294
|
}
|
|
275
295
|
}
|
|
276
296
|
}
|
|
@@ -283,75 +303,31 @@ async function runTemplateCLI(template) {
|
|
|
283
303
|
}
|
|
284
304
|
|
|
285
305
|
// src/template.ts
|
|
306
|
+
import { readFileSync } from "node:fs";
|
|
286
307
|
import path2 from "node:path";
|
|
287
308
|
import { fileURLToPath } from "node:url";
|
|
288
|
-
|
|
289
|
-
// package.json
|
|
290
|
-
var package_default = {
|
|
291
|
-
name: "@pauldvlp/vp-react-ts-shadcn",
|
|
292
|
-
version: "0.5.0",
|
|
293
|
-
description: "Vite+ monorepo template: one frontend app (website) + a shared shadcn UI package, themeable via shadcn presets.",
|
|
294
|
-
author: "pauldvlp (https://github.com/pauldvlp/vp-templates)",
|
|
295
|
-
license: "MIT",
|
|
296
|
-
homepage: "https://github.com/pauldvlp/vp-templates",
|
|
297
|
-
repository: {
|
|
298
|
-
type: "git",
|
|
299
|
-
url: "git+https://github.com/pauldvlp/vp-templates.git",
|
|
300
|
-
directory: "packages/vp-react-ts-shadcn"
|
|
301
|
-
},
|
|
302
|
-
bugs: "https://github.com/pauldvlp/vp-templates/issues",
|
|
303
|
-
keywords: [
|
|
304
|
-
"vite-plus-generator",
|
|
305
|
-
"vite-plus",
|
|
306
|
-
"shadcn",
|
|
307
|
-
"react",
|
|
308
|
-
"template"
|
|
309
|
-
],
|
|
310
|
-
bin: "./dist/index.js",
|
|
311
|
-
type: "module",
|
|
312
|
-
files: [
|
|
313
|
-
"dist",
|
|
314
|
-
"template"
|
|
315
|
-
],
|
|
316
|
-
scripts: {
|
|
317
|
-
build: "esbuild bin/index.ts --bundle --outfile=dist/index.js --format=esm --platform=node --target=node22 --packages=external",
|
|
318
|
-
dev: "node bin/index.ts",
|
|
319
|
-
prepack: "pnpm run build"
|
|
320
|
-
},
|
|
321
|
-
dependencies: {
|
|
322
|
-
"@clack/prompts": "^1.6.0"
|
|
323
|
-
},
|
|
324
|
-
devDependencies: {
|
|
325
|
-
"@pauldvlp/template-kit": "workspace:*",
|
|
326
|
-
"@types/node": "^24",
|
|
327
|
-
esbuild: "^0.25.0",
|
|
328
|
-
typescript: "^5"
|
|
329
|
-
},
|
|
330
|
-
engines: {
|
|
331
|
-
node: ">=22.18.0"
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
// src/template.ts
|
|
336
309
|
var TEMPLATE_DIR = path2.join(path2.dirname(fileURLToPath(import.meta.url)), "..", "template");
|
|
310
|
+
var { name: pkgName, description: pkgDescription } = JSON.parse(
|
|
311
|
+
readFileSync(new URL("../package.json", import.meta.url), "utf8")
|
|
312
|
+
);
|
|
337
313
|
var template_default = defineTemplate({
|
|
338
314
|
about: {
|
|
339
|
-
name:
|
|
340
|
-
description:
|
|
315
|
+
name: pkgName,
|
|
316
|
+
description: pkgDescription
|
|
341
317
|
},
|
|
342
318
|
options: [
|
|
343
319
|
// Default the name to the target directory the user chose, so they don't retype it.
|
|
344
|
-
{ key: "name", type: "string", message: "Root project / package name", default: ({ directory }) => dirName(directory) },
|
|
320
|
+
{ key: "name", type: "string", message: "Root project / package name", default: ({ directory }) => dirName(directory), validate: validateName },
|
|
345
321
|
// Lazily default the package scope to `@<name>` (prefixing `@` unless the name already has one),
|
|
346
322
|
// so it tracks the project name instead of a fixed value. Falls back to `@app` when no name is set.
|
|
347
|
-
{ key: "scope", type: "string", message: "npm scope for workspace packages, e.g. @acme (defaults to @<name>)", default: ({ options }) => options.name ? toScope(options.name) : "@app" },
|
|
323
|
+
{ key: "scope", type: "string", message: "npm scope for workspace packages, e.g. @acme (defaults to @<name>)", default: ({ options }) => options.name ? toScope(options.name) : "@app", validate: validateScope },
|
|
348
324
|
{ key: "base", type: "select", message: "shadcn component library base (radix-ui or @base-ui)", choices: ["radix", "base"], default: "radix" },
|
|
349
|
-
{ key: "preset", type: "string", message: "shadcn preset: a style name (nova, vega, maia, lyra, mira, luma, sera, rhea) or a code from ui.shadcn.com", default: DEFAULT_PRESET },
|
|
325
|
+
{ key: "preset", type: "string", message: "shadcn preset: a style name (nova, vega, maia, lyra, mira, luma, sera, rhea) or a code from ui.shadcn.com", default: DEFAULT_PRESET, validate: validatePreset },
|
|
350
326
|
{ key: "iconLibrary", type: "select", message: "Icon library", choices: ["lucide", "hugeicons", "radix", "tabler"], default: "hugeicons" },
|
|
351
327
|
{ key: "cssVariables", type: "boolean", message: "Use CSS variables for theming", default: true },
|
|
352
328
|
{ key: "rtl", type: "boolean", message: "Enable RTL support", default: false },
|
|
353
329
|
{ key: "pointer", type: "boolean", message: "Use pointer cursor on interactive elements", default: false },
|
|
354
|
-
{ key: "components", type: "string", message: "Comma-separated shadcn components to pre-install, e.g. button,card,dialog", default: "button,badge" },
|
|
330
|
+
{ key: "components", type: "string", message: "Comma-separated shadcn components to pre-install, e.g. button,card,dialog", default: "button,badge", validate: validateComponents },
|
|
355
331
|
{ key: "install", type: "boolean", message: "Install deps and apply the shadcn theme after scaffolding", default: true }
|
|
356
332
|
],
|
|
357
333
|
async produce({ options }) {
|
|
@@ -373,11 +349,11 @@ var template_default = defineTemplate({
|
|
|
373
349
|
}
|
|
374
350
|
const adds = withRequiredComponents(options.components);
|
|
375
351
|
const ui = `${scope}/ui`;
|
|
376
|
-
const
|
|
352
|
+
const initArgs = shadcnInitArgs(options);
|
|
377
353
|
const scripts = options.install ? [
|
|
378
|
-
{ commands: ["pnpm install --silent"], phase: 0 },
|
|
379
|
-
{ commands: [
|
|
380
|
-
{ commands: [
|
|
354
|
+
{ commands: [["pnpm", "install", "--silent"]], phase: 0 },
|
|
355
|
+
{ commands: [["pnpm", "--filter", ui, "exec", "shadcn", "init", ...initArgs]], phase: 1 },
|
|
356
|
+
{ commands: [["pnpm", "--filter", ui, "exec", "shadcn", "add", ...adds, "-y"]], phase: 2 }
|
|
381
357
|
] : [];
|
|
382
358
|
return {
|
|
383
359
|
files,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pauldvlp/vp-react-ts-shadcn",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Vite+ monorepo template: one frontend app (website) + a shared shadcn UI package, themeable via shadcn presets.",
|
|
5
5
|
"author": "pauldvlp (https://github.com/pauldvlp/vp-templates)",
|
|
6
6
|
"license": "MIT",
|