@webjsdev/cli 0.8.5 → 0.8.6

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.
Files changed (2) hide show
  1. package/lib/create.js +68 -20
  2. package/package.json +1 -1
package/lib/create.js CHANGED
@@ -72,11 +72,10 @@ const UI_REGISTRY_ROOT = resolve(
72
72
  * utils/ folder: `../../lib/utils/cn.ts`.
73
73
  *
74
74
  * @param {string} name component name without `.ts` (e.g. 'button')
75
- * @returns {Promise<string|null>} source or null if not found
75
+ * @returns {Promise<string>} source with import rewritten
76
76
  */
77
77
  async function readUiComponent(name) {
78
78
  const src = join(UI_REGISTRY_ROOT, 'components', `${name}.ts`);
79
- if (!existsSync(src)) return null;
80
79
  const raw = await readFile(src, 'utf8');
81
80
  return raw
82
81
  .replaceAll("'../lib/utils.ts'", "'../../lib/utils/cn.ts'")
@@ -85,7 +84,10 @@ async function readUiComponent(name) {
85
84
 
86
85
  /**
87
86
  * Copy a list of @webjsdev/ui registry components into the scaffolded app
88
- * under `components/ui/`. Silently skips any name that isn't in the registry.
87
+ * under `components/ui/`. Throws if any name is missing from the registry,
88
+ * since the scaffold's generated pages import these by name and a missing
89
+ * file would produce ERR_MODULE_NOT_FOUND at first request. Caller must
90
+ * have already invoked assertUiRegistryAvailable().
89
91
  *
90
92
  * @param {string} appDir destination app root
91
93
  * @param {string[]} names list of component file basenames (without `.ts`)
@@ -94,9 +96,16 @@ async function copyUiComponents(appDir, names) {
94
96
  const uiDir = join(appDir, 'components', 'ui');
95
97
  await mkdir(uiDir, { recursive: true });
96
98
  for (const n of names) {
97
- const content = await readUiComponent(n);
98
- if (content == null) continue;
99
- await writeFile(join(uiDir, `${n}.ts`), content);
99
+ const src = join(UI_REGISTRY_ROOT, 'components', `${n}.ts`);
100
+ if (!existsSync(src)) {
101
+ throw new Error(
102
+ `@webjsdev/ui registry is missing component '${n}.ts' at ${src}. ` +
103
+ `The scaffold's example pages import this component by name. ` +
104
+ `Either the registry was published incompletely or the scaffold's ` +
105
+ `component list is out of sync with the registry.`,
106
+ );
107
+ }
108
+ await writeFile(join(uiDir, `${n}.ts`), await readUiComponent(n));
100
109
  }
101
110
  }
102
111
 
@@ -110,13 +119,15 @@ async function copyUiComponents(appDir, names) {
110
119
  * @param {string} appDir
111
120
  */
112
121
  async function writeUiBootstrap(appDir) {
122
+ // Caller (scaffoldApp) has already invoked assertUiRegistryAvailable(),
123
+ // so the source files below are guaranteed to exist.
124
+
113
125
  // 1) lib/utils/cn.ts: the cn() helper
114
- const utilsSrc = join(UI_REGISTRY_ROOT, 'lib', 'utils.ts');
115
- if (existsSync(utilsSrc)) {
116
- const content = await readFile(utilsSrc, 'utf8');
117
- await mkdir(join(appDir, 'lib', 'utils'), { recursive: true });
118
- await writeFile(join(appDir, 'lib', 'utils', 'cn.ts'), content);
119
- }
126
+ const utilsContent = await readFile(
127
+ join(UI_REGISTRY_ROOT, 'lib', 'utils.ts'), 'utf8',
128
+ );
129
+ await mkdir(join(appDir, 'lib', 'utils'), { recursive: true });
130
+ await writeFile(join(appDir, 'lib', 'utils', 'cn.ts'), utilsContent);
120
131
 
121
132
  // 2) components.json: the same shape `webjsui init` writes for webjs
122
133
  // projects (see packages/ui/src/utils/detect-project.js). The utils alias
@@ -144,12 +155,11 @@ async function writeUiBootstrap(appDir) {
144
155
 
145
156
  // 3) app/globals.css: copy the neutral theme verbatim. components.json
146
157
  // references this path, and future `webjs ui add` calls append to it.
147
- const themeSrc = join(UI_REGISTRY_ROOT, 'themes', 'index.css');
148
- if (existsSync(themeSrc)) {
149
- const css = await readFile(themeSrc, 'utf8');
150
- await mkdir(join(appDir, 'app'), { recursive: true });
151
- await writeFile(join(appDir, 'app', 'globals.css'), css);
152
- }
158
+ const css = await readFile(
159
+ join(UI_REGISTRY_ROOT, 'themes', 'index.css'), 'utf8',
160
+ );
161
+ await mkdir(join(appDir, 'app'), { recursive: true });
162
+ await writeFile(join(appDir, 'app', 'globals.css'), css);
153
163
  }
154
164
 
155
165
  /**
@@ -159,14 +169,45 @@ async function writeUiBootstrap(appDir) {
159
169
  * tokens (`--color-primary`, `--color-card`, …) the registry components
160
170
  * consume are available at runtime without a build step.
161
171
  *
162
- * @returns {Promise<string>} theme CSS source, or '' if registry missing
172
+ * @returns {Promise<string>} theme CSS source
163
173
  */
164
174
  async function readThemeCss() {
165
175
  const src = join(UI_REGISTRY_ROOT, 'themes', 'index.css');
166
- if (!existsSync(src)) return '';
167
176
  return await readFile(src, 'utf8');
168
177
  }
169
178
 
179
+ /**
180
+ * Fail loudly when the @webjsdev/ui registry is not on disk. The scaffold
181
+ * reads component sources, the cn() helper, and the shadcn theme from
182
+ * UI_REGISTRY_ROOT and weaves them into a generated app/page.ts that
183
+ * imports `components/ui/button.ts`. If the registry is missing, the
184
+ * generated app boots to ERR_MODULE_NOT_FOUND on first request, which is
185
+ * a confusing failure for end-users to debug.
186
+ *
187
+ * The check guards against an @webjsdev/ui published tarball that forgets
188
+ * to ship `packages/registry/` in its `files` array (the bug fixed in
189
+ * the same commit), and against a corrupted node_modules install.
190
+ */
191
+ function assertUiRegistryAvailable() {
192
+ const required = [
193
+ join(UI_REGISTRY_ROOT, 'components'),
194
+ join(UI_REGISTRY_ROOT, 'lib', 'utils.ts'),
195
+ join(UI_REGISTRY_ROOT, 'themes', 'index.css'),
196
+ ];
197
+ const missing = required.filter((p) => !existsSync(p));
198
+ if (missing.length === 0) return;
199
+ throw new Error(
200
+ `@webjsdev/ui registry sources not found at ${UI_REGISTRY_ROOT}.\n` +
201
+ `Missing:\n${missing.map((p) => ` - ${p}`).join('\n')}\n\n` +
202
+ `The scaffold reads component sources from the installed @webjsdev/ui ` +
203
+ `package. If you see this from a fresh \`npm create webjs\`, the ` +
204
+ `published @webjsdev/ui tarball is missing \`packages/registry/\` ` +
205
+ `(check its package.json \`files\` array). Please file an issue at ` +
206
+ `https://github.com/webjsdev/webjs/issues with your @webjsdev/ui ` +
207
+ `version (\`npm ls @webjsdev/ui\`).`,
208
+ );
209
+ }
210
+
170
211
  /**
171
212
  * @param {string} name App directory name
172
213
  * @param {string} cwd Current working directory
@@ -513,6 +554,13 @@ export type ActionResult<T> =
513
554
  await cp(uiSrc, join(utilsDir, 'ui.ts'));
514
555
  }
515
556
 
557
+ // Fail loudly if the @webjsdev/ui registry sources aren't on disk.
558
+ // Without this, downstream copy helpers would silently skip and the
559
+ // generated app would boot to ERR_MODULE_NOT_FOUND on the first page
560
+ // render (the import in app/page.ts below points at a file we didn't
561
+ // write).
562
+ assertUiRegistryAvailable();
563
+
516
564
  // Pre-initialise @webjsdev/ui so the scaffold boots ready for
517
565
  // `webjs ui add <name>`: writes components.json + lib/utils/cn.ts +
518
566
  // app/globals.css (the shadcn theme).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webjsdev/cli",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "type": "module",
5
5
  "description": "webjs CLI - dev, start, create, db",
6
6
  "bin": {