wexts 4.0.0 → 4.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.
Files changed (41) hide show
  1. package/dist/chunk-342VRT25.mjs +504 -0
  2. package/dist/chunk-342VRT25.mjs.map +1 -0
  3. package/dist/chunk-7HNQWJWV.js +504 -0
  4. package/dist/chunk-7HNQWJWV.js.map +1 -0
  5. package/dist/chunk-7SSCNCTW.mjs +137 -0
  6. package/dist/chunk-7SSCNCTW.mjs.map +1 -0
  7. package/dist/chunk-7TLSPR65.mjs +95 -0
  8. package/dist/chunk-7TLSPR65.mjs.map +1 -0
  9. package/dist/chunk-AVMQJWYD.js +95 -0
  10. package/dist/chunk-AVMQJWYD.js.map +1 -0
  11. package/dist/chunk-O4II6N34.js +137 -0
  12. package/dist/chunk-O4II6N34.js.map +1 -0
  13. package/dist/cli/index.d.mts +13 -1
  14. package/dist/cli/index.d.ts +13 -1
  15. package/dist/cli/index.js +438 -54
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/index.mjs +438 -54
  18. package/dist/cli/index.mjs.map +1 -1
  19. package/dist/client/index.js +3 -2
  20. package/dist/client/index.js.map +1 -1
  21. package/dist/client/index.mjs +2 -1
  22. package/dist/codegen/index.js +3 -2
  23. package/dist/codegen/index.js.map +1 -1
  24. package/dist/codegen/index.mjs +2 -1
  25. package/dist/index.d.mts +37 -1
  26. package/dist/index.d.ts +37 -1
  27. package/dist/index.js +22 -8
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +18 -4
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/next/index.js +68 -5
  32. package/dist/next/index.js.map +1 -1
  33. package/dist/next/index.mjs +68 -5
  34. package/dist/next/index.mjs.map +1 -1
  35. package/dist/runtime/index.js +9 -1
  36. package/dist/runtime/index.js.map +1 -1
  37. package/dist/runtime/index.mjs +9 -1
  38. package/dist/runtime/index.mjs.map +1 -1
  39. package/package.json +1 -1
  40. package/templates/nestjs-api/package-lock.json +0 -5623
  41. package/templates/nextjs-web/package-lock.json +0 -3254
@@ -2,6 +2,10 @@
2
2
  import {
3
3
  logger
4
4
  } from "../chunk-JHOVXH3X.mjs";
5
+ import {
6
+ WextsError,
7
+ formatWextsError
8
+ } from "../chunk-7TLSPR65.mjs";
5
9
  import {
6
10
  __dirname,
7
11
  __filename,
@@ -16,8 +20,8 @@ import { spawnSync } from "child_process";
16
20
  import { createRequire } from "module";
17
21
  function createCliProgram() {
18
22
  const program = new Command();
19
- program.name("wexts").description("Wexts - production-focused single-runtime Next.js + NestJS toolkit").version("3.0.3");
20
- program.command("create <project-name>").description("Create a compatibility project from bundled legacy templates").option("-t, --template <template>", "Legacy template to use (monorepo|api|web)", "monorepo").option("--skip-install", "Skip dependency installation", false).action(async (projectName, options) => {
23
+ program.name("wexts").description("Wexts - production-focused single-runtime Next.js + NestJS toolkit").version(readPackageVersion());
24
+ program.command("create <project-name>").description("Create a verified Wexts starter").option("-t, --template <template>", "Template to use (starter|legacy)", "starter").option("--skip-install", "Skip dependency installation", false).action(async (projectName, options) => {
21
25
  await createProject(projectName, options.template, {
22
26
  skipInstall: options.skipInstall
23
27
  });
@@ -33,8 +37,8 @@ function createCliProgram() {
33
37
  useProxy: options.proxy
34
38
  });
35
39
  });
36
- program.command("generate [type] [name]").alias("g").description("Generate RPC manifest/client, or scaffold a minimal RPC service").option("-p, --project <path>", "Path to NestJS project", "./apps/api").option("-o, --output <path>", "Output directory for generated RPC client", "./apps/web/lib/wexts").action(async (type, name, options) => {
37
- if (!type || type === "rpc") {
40
+ program.command("generate [type] [name]").alias("g").description("Generate RPC manifest/client, or scaffold a minimal RPC service").option("-p, --project <path>", "Path to NestJS project", "./apps/api").option("-o, --output <path>", "Output directory for generated RPC client", "./apps/web/lib/wexts").option("--force", "Overwrite generated files if they already exist", false).action(async (type, name, options) => {
41
+ if (!type || type === "rpc" && !name) {
38
42
  const { generateRpcClient } = await import("../codegen/index.mjs");
39
43
  const manifest = await generateRpcClient({
40
44
  projectPath: path.resolve(options.project),
@@ -43,13 +47,19 @@ function createCliProgram() {
43
47
  logger.success(`Generated Wexts RPC client for ${manifest.services.length} service(s).`);
44
48
  return;
45
49
  }
46
- if (type === "service") {
47
- if (!name) throw new Error("Service name is required: wexts generate service hello");
48
- await scaffoldRpcService(path.resolve(options.project), name);
49
- logger.success(`Created RPC service ${name}. Run wexts generate to update the client.`);
50
+ if (isScaffoldGenerator(type)) {
51
+ const targetRoot = type === "config" ? process.cwd() : path.resolve(options.project);
52
+ const changedFiles = await scaffoldGenerator({
53
+ type,
54
+ name,
55
+ targetRoot,
56
+ force: options.force
57
+ });
58
+ for (const file of changedFiles) logger.info(`created ${path.relative(process.cwd(), file)}`);
59
+ logger.success(`Generated ${type}${name ? ` ${name}` : ""}.`);
50
60
  return;
51
61
  }
52
- throw new Error(`Unknown generator "${type}". Supported generators: rpc, service.`);
62
+ throw new Error(`Unknown generator "${type}". Supported generators: rpc, service, module, entity, guard, config.`);
53
63
  });
54
64
  program.command("codegen").description("Alias for wexts generate rpc").option("-p, --project <path>", "Path to NestJS project", "./apps/api").option("-o, --output <path>", "Output directory for generated RPC client", "./apps/web/lib/wexts").action(async (options) => {
55
65
  const { generateRpcClient } = await import("../codegen/index.mjs");
@@ -157,78 +167,438 @@ async function createProject(projectName, template, options) {
157
167
  if (fs.existsSync(projectPath)) {
158
168
  throw new Error(`Directory already exists: ${projectName}`);
159
169
  }
160
- const templatePath = findTemplatePath();
161
- if (!templatePath) {
162
- throw new Error("Template directory not found in package.");
163
- }
164
170
  fs.mkdirSync(projectPath, {
165
171
  recursive: true
166
172
  });
167
- if (template === "monorepo") {
168
- fs.mkdirSync(path.join(projectPath, "apps"), {
169
- recursive: true
170
- });
171
- fs.cpSync(path.join(templatePath, "nestjs-api"), path.join(projectPath, "apps/api"), {
172
- recursive: true
173
- });
174
- fs.cpSync(path.join(templatePath, "nextjs-web"), path.join(projectPath, "apps/web"), {
175
- recursive: true
176
- });
177
- fs.writeFileSync(path.join(projectPath, "pnpm-workspace.yaml"), "packages:\n - 'apps/*'\n");
178
- fs.writeFileSync(path.join(projectPath, "package.json"), JSON.stringify({
173
+ if (template === "starter") {
174
+ await createVerifiedStarter(projectPath, projectName, options.wextsDependency ?? resolveCreateWextsDependency(projectPath));
175
+ } else if (template === "legacy") {
176
+ createLegacyProject(projectPath, projectName);
177
+ } else {
178
+ throw new Error(`Unknown template "${template}". Supported templates: starter, legacy.`);
179
+ }
180
+ if (!options.skipInstall) {
181
+ runCommand(detectPackageManager(projectPath), [
182
+ "install"
183
+ ], projectPath);
184
+ }
185
+ }
186
+ __name(createProject, "createProject");
187
+ async function createVerifiedStarter(projectPath, projectName, wextsDependency) {
188
+ const files = {
189
+ "pnpm-workspace.yaml": "packages:\n - 'apps/*'\n",
190
+ "package.json": JSON.stringify({
179
191
  name: projectName,
192
+ version: "0.1.0",
180
193
  private: true,
181
194
  packageManager: "pnpm@10.22.0",
182
195
  scripts: {
183
196
  dev: "wexts dev",
184
- generate: "wexts generate",
185
- build: "wexts build",
186
- start: "wexts start",
187
- doctor: "wexts doctor"
197
+ generate: "wexts generate -p apps/api -o apps/web/lib/wexts",
198
+ build: "pnpm run generate && tsc -p apps/api/tsconfig.json && next build apps/web",
199
+ start: "wexts start -c ./wexts.runtime.js",
200
+ "vercel-build": "wexts vercel-build -p apps/api -o apps/web/lib/wexts -c ./wexts.runtime.js",
201
+ doctor: "wexts doctor",
202
+ "doctor:security": "wexts doctor --security"
203
+ },
204
+ dependencies: {
205
+ "@nestjs/common": "^11.1.19",
206
+ "@nestjs/core": "^11.1.19",
207
+ "@nestjs/platform-fastify": "^11.1.19",
208
+ next: "16.2.4",
209
+ react: "^19.2.5",
210
+ "react-dom": "^19.2.5",
211
+ "reflect-metadata": "^0.2.2",
212
+ rxjs: "^7.8.1",
213
+ wexts: wextsDependency
188
214
  },
189
215
  devDependencies: {
190
- wexts: "latest"
216
+ "@types/node": "^22.19.1",
217
+ "@types/react": "^19.2.14",
218
+ "@types/react-dom": "^19.2.3",
219
+ typescript: "^5.9.3"
191
220
  }
192
- }, null, 2));
193
- } else if (template === "api") {
194
- fs.cpSync(path.join(templatePath, "nestjs-api"), projectPath, {
221
+ }, null, 2),
222
+ "apps/api/package.json": JSON.stringify({
223
+ name: `${projectName}-api`,
224
+ private: true,
225
+ scripts: {
226
+ "start:dev": "tsc -w -p tsconfig.json"
227
+ }
228
+ }, null, 2),
229
+ "apps/api/tsconfig.json": JSON.stringify({
230
+ compilerOptions: {
231
+ target: "ES2023",
232
+ module: "NodeNext",
233
+ moduleResolution: "NodeNext",
234
+ experimentalDecorators: true,
235
+ emitDecoratorMetadata: true,
236
+ strict: true,
237
+ esModuleInterop: true,
238
+ skipLibCheck: true,
239
+ outDir: "dist",
240
+ rootDir: "src"
241
+ },
242
+ include: [
243
+ "src/**/*.ts"
244
+ ]
245
+ }, null, 2),
246
+ "apps/api/src/hello.service.ts": `import { Injectable } from '@nestjs/common';
247
+ import { RpcMethod, RpcService } from 'wexts/nest';
248
+
249
+ @Injectable()
250
+ @RpcService({ name: 'hello', requireAuth: false })
251
+ export class HelloService {
252
+ @RpcMethod()
253
+ async sayHello(name: string): Promise<string> {
254
+ return \`Hello, \${name}!\`;
255
+ }
256
+ }
257
+ `,
258
+ "apps/web/package.json": JSON.stringify({
259
+ name: `${projectName}-web`,
260
+ private: true,
261
+ scripts: {
262
+ dev: "next dev -p 3000"
263
+ }
264
+ }, null, 2),
265
+ "apps/web/tsconfig.json": JSON.stringify({
266
+ compilerOptions: {
267
+ target: "ES2022",
268
+ lib: [
269
+ "dom",
270
+ "dom.iterable",
271
+ "es2022"
272
+ ],
273
+ allowJs: false,
274
+ skipLibCheck: true,
275
+ strict: true,
276
+ noEmit: true,
277
+ esModuleInterop: true,
278
+ module: "esnext",
279
+ moduleResolution: "bundler",
280
+ resolveJsonModule: true,
281
+ isolatedModules: true,
282
+ jsx: "react-jsx",
283
+ incremental: true,
284
+ plugins: [
285
+ {
286
+ name: "next"
287
+ }
288
+ ]
289
+ },
290
+ include: [
291
+ "next-env.d.ts",
292
+ "**/*.ts",
293
+ "**/*.tsx",
294
+ ".next/types/**/*.ts",
295
+ ".next/dev/types/**/*.ts"
296
+ ],
297
+ exclude: [
298
+ "node_modules"
299
+ ]
300
+ }, null, 2),
301
+ "apps/web/next-env.d.ts": `/// <reference types="next" />
302
+ /// <reference types="next/image-types/global" />
303
+
304
+ // This file is generated by Next.js. Do not edit.
305
+ `,
306
+ "apps/web/next.config.ts": `import type { NextConfig } from 'next';
307
+
308
+ const nextConfig: NextConfig = {
309
+ output: 'standalone',
310
+ };
311
+
312
+ export default nextConfig;
313
+ `,
314
+ "apps/web/app/layout.tsx": `import type { ReactNode } from 'react';
315
+ import { WextsProvider } from '../lib/wexts-provider';
316
+
317
+ export default function RootLayout({ children }: { children: ReactNode }) {
318
+ return (
319
+ <html lang="en">
320
+ <body>
321
+ <WextsProvider>{children}</WextsProvider>
322
+ </body>
323
+ </html>
324
+ );
325
+ }
326
+ `,
327
+ "apps/web/app/page.tsx": `'use client';
328
+
329
+ import { useState } from 'react';
330
+ import { useWexts } from '../lib/wexts-provider';
331
+
332
+ export default function Page() {
333
+ const wexts = useWexts();
334
+ const [message, setMessage] = useState('Not called yet');
335
+
336
+ return (
337
+ <main>
338
+ <h1>Wexts Hello RPC</h1>
339
+ <button
340
+ type="button"
341
+ onClick={async () => {
342
+ setMessage(await wexts.hello.sayHello('Bob'));
343
+ }}
344
+ >
345
+ Call RPC
346
+ </button>
347
+ <p>{message}</p>
348
+ </main>
349
+ );
350
+ }
351
+ `,
352
+ "apps/web/lib/wexts-provider.tsx": `'use client';
353
+
354
+ import { FusionProvider, useWexts as useGeneratedWexts } from 'wexts/next';
355
+ import { createWextsClient, type WextsClient } from './wexts/client';
356
+
357
+ export function WextsProvider({ children }: { children: React.ReactNode }) {
358
+ return (
359
+ <FusionProvider rpcClient={createWextsClient({ baseUrl: '/rpc' })}>
360
+ {children}
361
+ </FusionProvider>
362
+ );
363
+ }
364
+
365
+ export function useWexts(): WextsClient {
366
+ return useGeneratedWexts<WextsClient>();
367
+ }
368
+ `,
369
+ "wexts.runtime.js": `const { HelloService } = require('./apps/api/dist/hello.service.js');
370
+
371
+ module.exports = {
372
+ nextDir: './apps/web',
373
+ rpcManifestPath: './apps/web/lib/wexts/wexts.rpc.manifest.json',
374
+ rpcServices: {
375
+ hello: new HelloService(),
376
+ },
377
+ security: {
378
+ allowedOrigins: ['http://localhost:3000'],
379
+ },
380
+ };
381
+ `,
382
+ "README.md": `# ${projectName}
383
+
384
+ Verified Wexts starter with a generated Hello RPC client.
385
+
386
+ \`\`\`bash
387
+ pnpm install
388
+ pnpm run generate
389
+ pnpm run build
390
+ pnpm run doctor
391
+ pnpm run doctor:security
392
+ pnpm run start
393
+ \`\`\`
394
+ `
395
+ };
396
+ for (const [relativePath, content] of Object.entries(files)) {
397
+ const absolutePath = path.join(projectPath, relativePath);
398
+ fs.mkdirSync(path.dirname(absolutePath), {
195
399
  recursive: true
196
400
  });
197
- } else if (template === "web") {
198
- fs.cpSync(path.join(templatePath, "nextjs-web"), projectPath, {
199
- recursive: true
401
+ fs.writeFileSync(absolutePath, content);
402
+ }
403
+ const { generateRpcClient } = await import("../codegen/index.mjs");
404
+ await generateRpcClient({
405
+ projectPath: path.join(projectPath, "apps/api"),
406
+ outputPath: path.join(projectPath, "apps/web/lib/wexts")
407
+ });
408
+ }
409
+ __name(createVerifiedStarter, "createVerifiedStarter");
410
+ function createLegacyProject(projectPath, projectName) {
411
+ const templatePath = findTemplatePath();
412
+ if (!templatePath) {
413
+ throw new Error("Template directory not found in package.");
414
+ }
415
+ fs.mkdirSync(path.join(projectPath, "apps"), {
416
+ recursive: true
417
+ });
418
+ fs.cpSync(path.join(templatePath, "nestjs-api"), path.join(projectPath, "apps/api"), {
419
+ recursive: true
420
+ });
421
+ fs.cpSync(path.join(templatePath, "nextjs-web"), path.join(projectPath, "apps/web"), {
422
+ recursive: true
423
+ });
424
+ fs.rmSync(path.join(projectPath, "apps/web/package-lock.json"), {
425
+ force: true
426
+ });
427
+ fs.rmSync(path.join(projectPath, "apps/api/package-lock.json"), {
428
+ force: true
429
+ });
430
+ fs.writeFileSync(path.join(projectPath, "pnpm-workspace.yaml"), "packages:\n - 'apps/*'\n");
431
+ fs.writeFileSync(path.join(projectPath, "package.json"), JSON.stringify({
432
+ name: projectName,
433
+ private: true,
434
+ packageManager: "pnpm@10.22.0",
435
+ scripts: {
436
+ dev: "wexts dev",
437
+ generate: "wexts generate",
438
+ build: "wexts build",
439
+ start: "wexts start",
440
+ doctor: "wexts doctor"
441
+ },
442
+ devDependencies: {
443
+ wexts: `^${readPackageVersion()}`
444
+ }
445
+ }, null, 2));
446
+ }
447
+ __name(createLegacyProject, "createLegacyProject");
448
+ function resolveCreateWextsDependency(projectPath) {
449
+ const packageRoot = path.resolve(__dirname, "../..");
450
+ const cwdLocalPackage = path.join(process.cwd(), "node_modules/wexts");
451
+ try {
452
+ if (fs.existsSync(cwdLocalPackage) && fs.realpathSync(cwdLocalPackage) === fs.realpathSync(packageRoot)) {
453
+ return `file:${path.relative(projectPath, cwdLocalPackage)}`;
454
+ }
455
+ } catch {
456
+ }
457
+ return `^${readPackageVersion()}`;
458
+ }
459
+ __name(resolveCreateWextsDependency, "resolveCreateWextsDependency");
460
+ async function scaffoldGenerator(options) {
461
+ if (options.type !== "config" && !options.name) {
462
+ throw new WextsError({
463
+ code: "WEXTS_CLI_GENERATOR_NAME_REQUIRED",
464
+ message: `Generator "${options.type}" requires a name.`,
465
+ suggestedFix: `Run \`wexts generate ${options.type} hello\` or use \`wexts generate config\`.`,
466
+ docsSlug: "cli"
200
467
  });
201
- } else {
202
- throw new Error(`Unknown template "${template}".`);
203
468
  }
204
- if (!options.skipInstall) {
205
- runCommand(detectPackageManager(projectPath), [
206
- "install"
207
- ], projectPath);
469
+ if (options.type === "config") {
470
+ return writeGeneratedFiles(options.targetRoot, [
471
+ {
472
+ relativePath: "wexts.runtime.js",
473
+ content: `/** @type {import('wexts/runtime').WextsRuntimeConfig} */
474
+ module.exports = {
475
+ rootDir: __dirname,
476
+ port: Number(process.env.PORT || 3000),
477
+ rpcManifestPath: 'apps/web/lib/wexts/wexts.rpc.manifest.json',
478
+ security: {
479
+ enabled: true,
480
+ production: process.env.NODE_ENV === 'production',
481
+ allowedOrigins: process.env.WEXTS_ALLOWED_ORIGINS?.split(',').filter(Boolean) || [],
482
+ },
483
+ };
484
+ `
485
+ }
486
+ ], Boolean(options.force));
487
+ }
488
+ const rawName = options.name;
489
+ const name = toKebabCase(rawName);
490
+ const classBase = toPascalCase(name);
491
+ const srcRoot = path.join(options.targetRoot, "src");
492
+ const filesByType = {
493
+ rpc: rpcServiceFiles(name, classBase),
494
+ service: [
495
+ {
496
+ relativePath: path.join("src", name, `${name}.service.ts`),
497
+ content: `import { Injectable } from '@nestjs/common';
498
+
499
+ @Injectable()
500
+ export class ${classBase}Service {
501
+ async execute(): Promise<string> {
502
+ return '${toCamelCase(name)}';
208
503
  }
209
504
  }
210
- __name(createProject, "createProject");
211
- async function scaffoldRpcService(apiProjectPath, rawName) {
212
- const serviceName = toKebabCase(rawName);
213
- const className = `${toPascalCase(serviceName)}Service`;
214
- const dir = path.join(apiProjectPath, "src", serviceName);
215
- fs.mkdirSync(dir, {
505
+ `
506
+ }
507
+ ],
508
+ module: [
509
+ {
510
+ relativePath: path.join("src", name, `${name}.module.ts`),
511
+ content: `import { Module } from '@nestjs/common';
512
+
513
+ @Module({})
514
+ export class ${classBase}Module {}
515
+ `
516
+ }
517
+ ],
518
+ entity: [
519
+ {
520
+ relativePath: path.join("src", name, `${name}.entity.ts`),
521
+ content: `export interface ${classBase}Entity {
522
+ id: string;
523
+ createdAt: Date;
524
+ updatedAt: Date;
525
+ }
526
+ `
527
+ }
528
+ ],
529
+ guard: [
530
+ {
531
+ relativePath: path.join("src", name, `${name}.guard.ts`),
532
+ content: `import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
533
+
534
+ @Injectable()
535
+ export class ${classBase}Guard implements CanActivate {
536
+ canActivate(_context: ExecutionContext): boolean {
537
+ return true;
538
+ }
539
+ }
540
+ `
541
+ }
542
+ ]
543
+ };
544
+ fs.mkdirSync(srcRoot, {
216
545
  recursive: true
217
546
  });
218
- fs.writeFileSync(path.join(dir, `${serviceName}.service.ts`), `import { Injectable } from '@nestjs/common';
547
+ return writeGeneratedFiles(options.targetRoot, filesByType[options.type], Boolean(options.force));
548
+ }
549
+ __name(scaffoldGenerator, "scaffoldGenerator");
550
+ function isScaffoldGenerator(type) {
551
+ return [
552
+ "rpc",
553
+ "service",
554
+ "module",
555
+ "entity",
556
+ "guard",
557
+ "config"
558
+ ].includes(type);
559
+ }
560
+ __name(isScaffoldGenerator, "isScaffoldGenerator");
561
+ function rpcServiceFiles(serviceName, classBase) {
562
+ return [
563
+ {
564
+ relativePath: path.join("src", serviceName, `${serviceName}.service.ts`),
565
+ content: `import { Injectable } from '@nestjs/common';
219
566
  import { RpcMethod, RpcService } from 'wexts/nest';
220
567
 
221
568
  @Injectable()
222
569
  @RpcService({ name: '${toCamelCase(serviceName)}', requireAuth: false })
223
- export class ${className} {
570
+ export class ${classBase}Service {
224
571
  @RpcMethod()
225
572
  async sayHello(name: string): Promise<string> {
226
573
  return \`Hello, \${name}!\`;
227
574
  }
228
575
  }
229
- `);
576
+ `
577
+ }
578
+ ];
579
+ }
580
+ __name(rpcServiceFiles, "rpcServiceFiles");
581
+ function writeGeneratedFiles(root, files, force) {
582
+ const changedFiles = [];
583
+ for (const file of files) {
584
+ const absolutePath = path.join(root, file.relativePath);
585
+ if (fs.existsSync(absolutePath) && !force) {
586
+ throw new WextsError({
587
+ code: "WEXTS_CLI_GENERATOR_FILE_EXISTS",
588
+ message: `Refusing to overwrite existing file: ${absolutePath}`,
589
+ suggestedFix: "Review the file, then rerun with --force if overwriting is intentional.",
590
+ docsSlug: "cli"
591
+ });
592
+ }
593
+ fs.mkdirSync(path.dirname(absolutePath), {
594
+ recursive: true
595
+ });
596
+ fs.writeFileSync(absolutePath, file.content);
597
+ changedFiles.push(absolutePath);
598
+ }
599
+ return changedFiles;
230
600
  }
231
- __name(scaffoldRpcService, "scaffoldRpcService");
601
+ __name(writeGeneratedFiles, "writeGeneratedFiles");
232
602
  function runScript(script, options) {
233
603
  const cwd = options.cwd ?? process.cwd();
234
604
  const packageManager = detectPackageManager(cwd);
@@ -254,7 +624,13 @@ function runCommand(command, args, cwd) {
254
624
  }
255
625
  __name(runCommand, "runCommand");
256
626
  function detectPackageManager(cwd) {
627
+ const packageJsonPath = path.join(cwd, "package.json");
628
+ if (fs.existsSync(packageJsonPath)) {
629
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
630
+ if (pkg.packageManager?.startsWith("pnpm@")) return "pnpm";
631
+ }
257
632
  if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
633
+ if (fs.existsSync(path.join(cwd, "pnpm-workspace.yaml"))) return "pnpm";
258
634
  return "npm";
259
635
  }
260
636
  __name(detectPackageManager, "detectPackageManager");
@@ -267,6 +643,12 @@ function findTemplatePath() {
267
643
  return candidates.find((candidate) => fs.existsSync(candidate));
268
644
  }
269
645
  __name(findTemplatePath, "findTemplatePath");
646
+ function readPackageVersion() {
647
+ const packageJsonPath = path.resolve(__dirname, "../../package.json");
648
+ if (!fs.existsSync(packageJsonPath)) return "0.0.0";
649
+ return JSON.parse(fs.readFileSync(packageJsonPath, "utf8")).version;
650
+ }
651
+ __name(readPackageVersion, "readPackageVersion");
270
652
  function readAllText(cwd, dirs) {
271
653
  let text = "";
272
654
  for (const dir of dirs) {
@@ -323,12 +705,14 @@ __name(loadRuntimeConfig, "loadRuntimeConfig");
323
705
  var invokedAsCli = process.argv[1] && (path.basename(process.argv[1]) === "wexts" || path.basename(process.argv[1]) === "wexts.cjs" || path.resolve(process.argv[1]).includes(`${path.sep}dist${path.sep}cli${path.sep}index`));
324
706
  if (invokedAsCli && !process.env.VITEST) {
325
707
  createCliProgram().parseAsync(process.argv).catch((error) => {
326
- logger.error(error instanceof Error ? error.message : String(error));
708
+ logger.error(formatWextsError(error));
327
709
  process.exit(1);
328
710
  });
329
711
  }
330
712
  export {
331
713
  createCliProgram,
332
- runDoctor
714
+ createProject,
715
+ runDoctor,
716
+ scaffoldGenerator
333
717
  };
334
718
  //# sourceMappingURL=index.mjs.map