@stack-dev/cli 0.1.7 → 0.3.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 (38) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/CHANGELOG.md +17 -0
  3. package/dist/index.js +1105 -743
  4. package/dist/index.mjs +1103 -741
  5. package/package.json +6 -5
  6. package/src/index.ts +11 -10
  7. package/src/packages/cli-app/create-cli-app.ts +74 -0
  8. package/src/packages/cli-app/files/eslint-config-file-generator.ts +11 -0
  9. package/src/packages/cli-app/files/index-file-generator.ts +24 -0
  10. package/src/packages/cli-app/files/prettier-config-file-generator.ts +11 -0
  11. package/src/packages/cli-app/files/tsconfig-file-generator.ts +15 -0
  12. package/src/packages/cli-app/files/tsup-file-generator.ts +20 -0
  13. package/src/packages/cli-app/files/vitest-config-file-generator.ts +19 -0
  14. package/src/packages/cli-app/index.ts +1 -0
  15. package/src/packages/fastify-app/create-fastify-app.ts +79 -0
  16. package/src/packages/fastify-app/files/eslint-config-file-generator.ts +11 -0
  17. package/src/packages/fastify-app/files/index-file-generator.ts +144 -0
  18. package/src/packages/fastify-app/files/prettier-config-file-generator.ts +11 -0
  19. package/src/packages/fastify-app/files/tsconfig-file-generator.ts +15 -0
  20. package/src/packages/fastify-app/files/tsup-file-generator.ts +20 -0
  21. package/src/packages/fastify-app/files/vitest-config-file-generator.ts +19 -0
  22. package/src/packages/fastify-app/index.ts +1 -0
  23. package/src/packages/index.ts +3 -0
  24. package/src/packages/react-package/create-react-package.ts +1 -9
  25. package/src/packages/react-package/styled-components-react-package/create-styled-components-react-package.ts +1 -3
  26. package/src/packages/react-package/{css-react-package/create-css-react-package.ts → unstyled-react-package/create-unstyled-react-package.ts} +8 -7
  27. package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/button-file-generator.ts +2 -3
  28. package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/button-spec-file-generator.ts +0 -10
  29. package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/tsup-config-file-generator.ts +3 -6
  30. package/src/packages/vite-react-app/index.ts +1 -0
  31. package/src/utils/style-type.ts +1 -6
  32. package/src/packages/react-package/create-unstyled-react-package.ts +0 -3
  33. package/src/packages/react-package/css-react-package/files/button-css-module-file-generator.ts +0 -16
  34. /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/eslint-config-file-generator.ts +0 -0
  35. /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/index-file-generator.ts +0 -0
  36. /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/prettier-config-file-generator.ts +0 -0
  37. /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/tsconfig-file-generator.ts +0 -0
  38. /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/vitest-config-file-generator.ts +0 -0
package/dist/index.mjs CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/utils/utils.ts
4
- import fs from "node:fs/promises";
5
- import path from "node:path";
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+ import { prompt as prompt3 } from "enquirer";
6
+
7
+ // package.json
8
+ var version = "0.3.0";
6
9
 
7
10
  // src/package-json/package-json.ts
8
11
  import { haveSameItems, sortKeys } from "@stack-dev/core";
@@ -242,6 +245,8 @@ function getKeyIndex(s) {
242
245
  }
243
246
 
244
247
  // src/utils/utils.ts
248
+ import fs from "node:fs/promises";
249
+ import path from "node:path";
245
250
  async function getDirectoryPackageJson(directory) {
246
251
  const packageJsonPath = getPackageJSONPath(directory);
247
252
  const packageJsonText = await fs.readFile(packageJsonPath, {
@@ -261,6 +266,185 @@ async function fileExists(filepath) {
261
266
  }
262
267
  }
263
268
 
269
+ // src/link-packages.ts
270
+ import fs3 from "node:fs/promises";
271
+ import path3 from "node:path";
272
+
273
+ // src/tsconfig/tsconfig.ts
274
+ import * as JSON52 from "json5";
275
+ import { haveSameItems as haveSameItems2, sortKeys as sortKeys3 } from "@stack-dev/core";
276
+ import { isEqual as isEqual3 } from "lodash";
277
+
278
+ // src/tsconfig/compiler-options.ts
279
+ import { sortKeys as sortKeys2 } from "@stack-dev/core";
280
+ import { isEqual as isEqual2 } from "lodash";
281
+ var CompilerOptions = class _CompilerOptions {
282
+ _additionalData;
283
+ _paths;
284
+ constructor(args) {
285
+ this._paths = args?.paths ?? {};
286
+ this._additionalData = args?.additionalData ?? {};
287
+ }
288
+ get paths() {
289
+ return this._paths;
290
+ }
291
+ get additionalData() {
292
+ return this._additionalData;
293
+ }
294
+ setPaths(paths) {
295
+ return new _CompilerOptions({
296
+ paths,
297
+ additionalData: this._additionalData
298
+ });
299
+ }
300
+ format() {
301
+ const json = {
302
+ paths: this._paths,
303
+ ...this._additionalData
304
+ };
305
+ const ordered = sortKeys2(json, compareKeys);
306
+ return JSON.stringify(ordered, null, 2);
307
+ }
308
+ equals(other) {
309
+ if (other instanceof _CompilerOptions) {
310
+ return isEqual2(this._paths, other._paths) && isEqual2(this._additionalData, other._additionalData);
311
+ } else {
312
+ return false;
313
+ }
314
+ }
315
+ };
316
+ function compareKeys(a, b) {
317
+ return getKeyIndex2(a) - getKeyIndex2(b);
318
+ }
319
+ function getKeyIndex2(s) {
320
+ const order = [
321
+ "target",
322
+ "module",
323
+ "moduleResolution",
324
+ "esModuleInterop",
325
+ "lib",
326
+ "types",
327
+ "strict",
328
+ "allowJs"
329
+ ];
330
+ if (order.every((key) => key !== s)) {
331
+ return Number.MAX_VALUE;
332
+ } else {
333
+ return order.indexOf(s);
334
+ }
335
+ }
336
+
337
+ // src/tsconfig/reference.ts
338
+ var Reference = class _Reference {
339
+ _path;
340
+ constructor(path16) {
341
+ this._path = path16;
342
+ }
343
+ get path() {
344
+ return this._path;
345
+ }
346
+ equals(other) {
347
+ if (other instanceof _Reference) {
348
+ return this._path === other._path;
349
+ } else {
350
+ return false;
351
+ }
352
+ }
353
+ };
354
+
355
+ // src/tsconfig/tsconfig.ts
356
+ var TSConfig = class _TSConfig {
357
+ _compilerOptions;
358
+ _references;
359
+ _additionalData;
360
+ constructor(args) {
361
+ this._compilerOptions = args?.compilerOptions ?? new CompilerOptions();
362
+ this._references = args?.references ?? [];
363
+ this._additionalData = args?.additionalData ?? {};
364
+ }
365
+ get compilerOptions() {
366
+ return this._compilerOptions;
367
+ }
368
+ addReference(reference) {
369
+ return new _TSConfig({
370
+ compilerOptions: this._compilerOptions,
371
+ references: [...this._references, reference],
372
+ additionalData: this._additionalData
373
+ });
374
+ }
375
+ setCompilerOptions(compilerOptions) {
376
+ return new _TSConfig({
377
+ compilerOptions,
378
+ references: this._references,
379
+ additionalData: this._additionalData
380
+ });
381
+ }
382
+ static parse(s) {
383
+ const json = JSON52.parse(s);
384
+ const references = _TSConfig.parseReferences(json);
385
+ const compilerOptions = new CompilerOptions({
386
+ paths: json.compilerOptions?.paths,
387
+ ...json.compilerOptions
388
+ });
389
+ const additionalData = { ...json };
390
+ delete additionalData["compilerOptions"];
391
+ delete additionalData["references"];
392
+ return new _TSConfig({
393
+ compilerOptions,
394
+ references,
395
+ additionalData
396
+ });
397
+ }
398
+ static parseReferences(json) {
399
+ if (typeof json === "object" && json !== null && "references" in json && json.references instanceof Array) {
400
+ return json.references.map(
401
+ (r) => new Reference(r.path)
402
+ );
403
+ } else {
404
+ return [];
405
+ }
406
+ }
407
+ format() {
408
+ const compilerOptions = JSON52.parse(this.compilerOptions.format());
409
+ const json = {
410
+ compilerOptions,
411
+ references: this._references.map((r) => ({ path: r.path })),
412
+ ...this._additionalData
413
+ };
414
+ const ordered = sortKeys3(json, compareKeys2);
415
+ return JSON.stringify(ordered, null, 2);
416
+ }
417
+ equals(other) {
418
+ if (other instanceof _TSConfig) {
419
+ const sameReferences = haveSameItems2(
420
+ this._references,
421
+ other._references,
422
+ (r1, r2) => r1.equals(r2)
423
+ );
424
+ return this._compilerOptions.equals(other._compilerOptions) && sameReferences && isEqual3(this._additionalData, other._additionalData);
425
+ } else {
426
+ return false;
427
+ }
428
+ }
429
+ };
430
+ function compareKeys2(a, b) {
431
+ return getKeyIndex3(a) - getKeyIndex3(b);
432
+ }
433
+ function getKeyIndex3(s) {
434
+ const order = [
435
+ "extends",
436
+ "compilerOptions",
437
+ "include",
438
+ "exclude",
439
+ "references"
440
+ ];
441
+ if (order.every((key) => key !== s)) {
442
+ return Number.MAX_VALUE;
443
+ } else {
444
+ return order.indexOf(s);
445
+ }
446
+ }
447
+
264
448
  // src/utils/workspace.ts
265
449
  import fs2 from "node:fs/promises";
266
450
  import path2 from "path";
@@ -309,8 +493,42 @@ async function getNamespace(directory = process.cwd()) {
309
493
  return `@${result}`;
310
494
  }
311
495
 
312
- // src/packages/library-package/create-library-package.ts
313
- import path4 from "node:path";
496
+ // src/link-packages.ts
497
+ async function linkPackages(current, target, development) {
498
+ await updatePackageJSON(current, target, development);
499
+ await updateTSConfig(current, target);
500
+ }
501
+ async function updatePackageJSON(current, target, development) {
502
+ const namespace = await getNamespace();
503
+ const packageJSON = await getDirectoryPackageJson(current.directory);
504
+ const updated = addDependency(packageJSON, target, development);
505
+ const packageJSONPath = getPackageJSONPath(current.directory);
506
+ await fs3.writeFile(packageJSONPath, updated.format(namespace));
507
+ }
508
+ function addDependency(packageJSON, target, development) {
509
+ const dependency = new Dependency(target.name, "workspace:*");
510
+ if (development) {
511
+ return packageJSON.addDevDependency(dependency);
512
+ } else {
513
+ return packageJSON.addDependency(dependency);
514
+ }
515
+ }
516
+ async function updateTSConfig(current, target) {
517
+ const tsconfigPath = path3.join(current.directory, "tsconfig.json");
518
+ const tsconfigContents = await fs3.readFile(tsconfigPath, "utf8");
519
+ const tsconfig = TSConfig.parse(tsconfigContents);
520
+ const targetDirectory = path3.join(target.directory, "src", "index.ts");
521
+ const updatedPaths = {
522
+ ...tsconfig.compilerOptions.paths,
523
+ [target.name]: [path3.relative(current.directory, targetDirectory)]
524
+ };
525
+ const updatedCompilerOptions = tsconfig.compilerOptions.setPaths(updatedPaths);
526
+ const updated = tsconfig.setCompilerOptions(updatedCompilerOptions);
527
+ await fs3.writeFile(tsconfigPath, updated.format());
528
+ }
529
+
530
+ // src/packages/cli-app/create-cli-app.ts
531
+ import path5 from "path";
314
532
 
315
533
  // src/file-generator/package-json-generator.ts
316
534
  var PackageJsonGenerator = class {
@@ -329,8 +547,8 @@ var PackageJsonGenerator = class {
329
547
  };
330
548
 
331
549
  // src/utils/package-generator.ts
332
- import fs3 from "node:fs/promises";
333
- import path3 from "node:path";
550
+ import fs4 from "node:fs/promises";
551
+ import path4 from "node:path";
334
552
  var PackageGenerator = class {
335
553
  _root;
336
554
  _packageJson;
@@ -342,15 +560,15 @@ var PackageGenerator = class {
342
560
  }
343
561
  async generate() {
344
562
  const all = [this._packageJson, ...this._fileGenerators];
345
- await fs3.mkdir(this._root, { recursive: true });
563
+ await fs4.mkdir(this._root, { recursive: true });
346
564
  await Promise.all(all.map((gen) => this.write(gen)));
347
565
  }
348
566
  async write(fileGenerator) {
349
567
  const contents = await fileGenerator.generate();
350
- const filepath = path3.join(this._root, fileGenerator.filepath);
351
- const directory = path3.dirname(filepath);
352
- await fs3.mkdir(directory, { recursive: true });
353
- await fs3.writeFile(filepath, contents);
568
+ const filepath = path4.join(this._root, fileGenerator.filepath);
569
+ const directory = path4.dirname(filepath);
570
+ await fs4.mkdir(directory, { recursive: true });
571
+ await fs4.writeFile(filepath, contents);
354
572
  }
355
573
  };
356
574
 
@@ -370,30 +588,7 @@ var FileGeneratorImp = class {
370
588
  }
371
589
  };
372
590
 
373
- // src/packages/library-package/files/add-file-generator.ts
374
- var ADD_TS = `export function add(n1: number, n2: number): number {
375
- return n1 + n2;
376
- }
377
- `;
378
- var ADD_FILE_GENERATOR = new FileGeneratorImp("src/add.ts", ADD_TS);
379
-
380
- // src/packages/library-package/files/add-spec-file-generator.ts
381
- var ADD_SPEC_TS = `import { describe, it, expect } from 'vitest';
382
-
383
- import { add } from '../add';
384
-
385
- describe('add', () => {
386
- it('adds two numbers', () => {
387
- expect(add(2, 3)).toBe(5);
388
- });
389
- });
390
- `;
391
- var ADD_SPEC_FILE_GENERATOR = new FileGeneratorImp(
392
- "src/spec/add.spec.ts",
393
- ADD_SPEC_TS
394
- );
395
-
396
- // src/packages/library-package/files/eslint-config-file-generator.ts
591
+ // src/packages/cli-app/files/eslint-config-file-generator.ts
397
592
  var ESLINT_CONFIG = `import base from '@stack-dev/eslint-config/base.mjs';
398
593
 
399
594
  export default [...base, { ignores: ['**/dist/**'] }];
@@ -403,25 +598,40 @@ var ESLINT_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
403
598
  ESLINT_CONFIG
404
599
  );
405
600
 
406
- // src/packages/library-package/files/index-file-generator.ts
407
- var INDEX_TS = `export * from './add';
408
- `;
409
- var INDEX_FILE_GENERATOR = new FileGeneratorImp(
410
- "src/index.ts",
411
- INDEX_TS
412
- );
601
+ // src/packages/cli-app/files/index-file-generator.ts
602
+ var INDEX = `import { Command } from "commander";;
413
603
 
414
- // src/packages/library-package/files/prettier-config-file-generator.ts
415
- var PRETTIER_CONFIG = `import base from '@stack-dev/prettier-config/base.mjs';
604
+ const program = new Command();
416
605
 
417
- export default base;
418
- `;
606
+ program
607
+ .name('string-util')
608
+ .description('CLI to some JavaScript string utilities')
609
+ .version('0.8.0');
610
+
611
+ program.command('split')
612
+ .description('Split a string into substrings and display as an array')
613
+ .argument('<string>', 'string to split')
614
+ .option('--first', 'display just the first substring')
615
+ .option('-s, --separator <char>', 'separator character', ',')
616
+ .action((str, options) => {
617
+ const limit = options.first ? 1 : undefined;
618
+ console.log(str.split(options.separator, limit));
619
+ });
620
+
621
+ program.parse();`;
622
+ var INDEX_FILE_GENERATOR = new FileGeneratorImp("src/index.ts", INDEX);
623
+
624
+ // src/packages/cli-app/files/prettier-config-file-generator.ts
625
+ var PRETTIER_CONFIG = `import base from '@stack-dev/prettier-config/base.mjs';
626
+
627
+ export default base;
628
+ `;
419
629
  var PRETTIER_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
420
630
  "prettier.config.mjs",
421
631
  PRETTIER_CONFIG
422
632
  );
423
633
 
424
- // src/packages/library-package/files/tsconfig-file-generator.ts
634
+ // src/packages/cli-app/files/tsconfig-file-generator.ts
425
635
  var TSCONFIG = `{
426
636
  "extends": "@stack-dev/typescript-config/tsconfig.base.json",
427
637
  "compilerOptions": {
@@ -435,29 +645,26 @@ var TSCONFIG_FILE_GENERATOR = new FileGeneratorImp(
435
645
  TSCONFIG
436
646
  );
437
647
 
438
- // src/packages/library-package/files/tsup-config-file-generator.ts
439
- var TSUP_CONFIG = `import { defineConfig } from 'tsup';
648
+ // src/packages/cli-app/files/tsup-file-generator.ts
649
+ var TSUP = `import { defineConfig } from "tsup";
440
650
 
441
651
  export default defineConfig({
442
- entry: ['src/index.ts'],
443
- format: ['esm', 'cjs'],
444
- dts: true,
652
+ entry: ["src/index.ts"],
653
+ format: ["esm"],
654
+ dts: false,
445
655
  sourcemap: true,
446
656
  clean: true,
447
- target: 'esnext',
657
+ target: "esnext",
448
658
  outExtension({ format }) {
449
659
  return {
450
- js: format === 'esm' ? '.mjs' : '.js',
660
+ js: format === "esm" ? ".mjs" : ".js",
451
661
  };
452
662
  },
453
663
  });
454
664
  `;
455
- var TSUP_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
456
- "tsup.config.ts",
457
- TSUP_CONFIG
458
- );
665
+ var TSUP_FILE_GENERATOR = new FileGeneratorImp("tsup.config.ts", TSUP);
459
666
 
460
- // src/packages/library-package/files/vitest-config-file-generator.ts
667
+ // src/packages/cli-app/files/vitest-config-file-generator.ts
461
668
  var VITEST_CONFIG = `import { defineConfig } from 'vitest/config';
462
669
 
463
670
  export default defineConfig({
@@ -475,193 +682,220 @@ var VITEST_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
475
682
  VITEST_CONFIG
476
683
  );
477
684
 
478
- // src/packages/library-package/create-library-package.ts
479
- async function createLibraryPackage(name) {
685
+ // src/packages/cli-app/create-cli-app.ts
686
+ async function createCliApp(name) {
480
687
  const rootDir = await getWorkspaceRoot();
481
- const directory = path4.join(rootDir, "packages", name);
688
+ const directory = path5.join(rootDir, "apps", name);
482
689
  const namespace = await getNamespace(rootDir);
483
690
  const packageName = `${namespace}/${name}`;
484
- console.log(`\u2728 Creating config package: ${packageName}`);
691
+ console.log(`\u{1F680} Creating CLI App: ${packageName}`);
485
692
  const generator = new PackageGenerator(
486
693
  directory,
487
- makePackageGenerator(packageName, namespace),
694
+ makeAppPackageGenerator(packageName, namespace),
488
695
  [
489
696
  INDEX_FILE_GENERATOR,
490
- ADD_FILE_GENERATOR,
491
- ADD_SPEC_FILE_GENERATOR,
492
- TSUP_CONFIG_FILE_GENERATOR,
493
697
  TSCONFIG_FILE_GENERATOR,
698
+ TSUP_FILE_GENERATOR,
494
699
  PRETTIER_CONFIG_FILE_GENERATOR,
495
700
  ESLINT_CONFIG_FILE_GENERATOR,
496
701
  VITEST_CONFIG_FILE_GENERATOR
497
702
  ]
498
703
  );
499
704
  await generator.generate();
500
- console.log(`\u2705 Config package created at: ${directory}`);
501
705
  }
502
- function makePackageGenerator(packageName, namespace) {
706
+ function makeAppPackageGenerator(packageName, namespace) {
503
707
  const packageJsonModel = new PackageJSON({
504
708
  name: packageName,
709
+ peerDependencies: [
710
+ new Dependency("typescript", "^5.9.3"),
711
+ new Dependency("@types/node", "^25.0.3")
712
+ ],
713
+ dependencies: [new Dependency("commander", "14.0.2")],
505
714
  devDependencies: [
506
715
  new Dependency(`${namespace}/eslint-config`, "workspace:*"),
507
716
  new Dependency(`${namespace}/prettier-config`, "workspace:*"),
508
717
  new Dependency(`${namespace}/typescript-config`, "workspace:*"),
718
+ new Dependency("tsup", "^8.5.1"),
719
+ new Dependency("tsx", "^4.21.0"),
509
720
  new Dependency("eslint", "^9.32.0"),
510
721
  new Dependency("prettier", "^3.6.2"),
511
- new Dependency("prettier-plugin-organize-imports", "^4.2.0"),
512
- new Dependency("tsup", "^7.3.0"),
513
- new Dependency("vitest", "^3.2.4"),
514
- new Dependency("@vitest/coverage-v8", "^3.2.4")
722
+ new Dependency("vitest", "^3.2.4")
515
723
  ],
516
724
  additionalData: {
517
725
  version: "0.1.0",
518
726
  private: true,
519
- main: "dist/index.js",
520
- module: "dist/index.mjs",
521
- types: "dist/index.d.ts",
522
- exports: {
523
- ".": {
524
- development: "./src/index.ts",
525
- import: "./dist/index.mjs",
526
- require: "./dist/index.js",
527
- types: "./dist/index.d.ts"
528
- }
529
- },
727
+ type: "module",
530
728
  scripts: {
531
- build: "tsup",
532
- lint: "eslint",
729
+ dev: "tsx watch src/index.ts",
730
+ build: "tsup src/index.ts",
731
+ start: "node dist/index.mjs",
732
+ lint: "eslint .",
533
733
  format: "prettier . --write",
534
734
  test: "vitest run",
535
735
  "test:watch": "vitest"
536
- },
537
- sideEffects: false
736
+ }
538
737
  }
539
738
  });
540
739
  return new PackageJsonGenerator(packageJsonModel, namespace);
541
740
  }
542
741
 
543
- // src/packages/react-package/create-tailwind-react-package.ts
544
- async function createTailwindReactPackage(name) {
545
- throw new Error("Not implemented.");
546
- }
547
- var STYLED_BUTTON = `import React from 'react';
742
+ // src/packages/fastify-app/create-fastify-app.ts
743
+ import path6 from "path";
548
744
 
549
- interface ButtonProps {
550
- label: string;
551
- onClick?: () => void;
552
- }
745
+ // src/packages/fastify-app/files/eslint-config-file-generator.ts
746
+ var ESLINT_CONFIG2 = `import base from '@stack-dev/eslint-config/base.mjs';
553
747
 
554
- export function TailwindButton(props: ButtonProps) {
555
- const {label, onClick} = props;
556
-
557
- return (
558
- <button
559
- onClick={onClick}
560
- className="my-lib-bg-blue-600 my-lib-text-white my-lib-p-[10px] my-lib-border-none my-lib-rounded my-lib-cursor-pointer hover:my-lib-brightness-110"
561
- >
562
- {label}
563
- </button>
564
- );
565
- };`;
566
- var STYLED_BUTTON_FILE_GENERATOR = new FileGeneratorImp(
567
- "styled-button.ts",
568
- STYLED_BUTTON
748
+ export default [...base, { ignores: ['**/dist/**'] }];
749
+ `;
750
+ var ESLINT_CONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
751
+ "eslint.config.mjs",
752
+ ESLINT_CONFIG2
569
753
  );
570
754
 
571
- // src/packages/react-package/create-unstyled-react-package.ts
572
- async function createUnstyledReactPackage(name) {
573
- throw new Error("Not implemented.");
574
- }
755
+ // src/packages/fastify-app/files/index-file-generator.ts
756
+ var INDEX2 = `import Fastify from "fastify";
757
+ import fastifySwagger from "@fastify/swagger";
758
+ import fastifySwaggerUI from "@fastify/swagger-ui";
575
759
 
576
- // src/packages/react-package/css-react-package/create-css-react-package.ts
577
- import path5 from "path";
760
+ const fastify = Fastify({
761
+ logger: {
762
+ transport: {
763
+ target: "pino-pretty",
764
+ },
765
+ serializers: {
766
+ res(reply) {
767
+ // The default
768
+ return {
769
+ statusCode: reply.statusCode,
770
+ };
771
+ },
772
+ req(request) {
773
+ return {
774
+ method: request.method,
775
+ url: request.url,
776
+ path: request.routeOptions.url,
777
+ parameters: request.params,
778
+ // Including headers in the log could violate privacy laws,
779
+ // e.g., GDPR. Use the "redact" option to remove sensitive
780
+ // fields. It could also leak authentication data in the logs.
781
+ headers: request.headers,
782
+ };
783
+ },
784
+ },
785
+ },
786
+ });
578
787
 
579
- // src/packages/react-package/css-react-package/files/button-css-module-file-generator.ts
580
- var BUTTON_CSS_MODULE = `.styledButton {
581
- background: blue;
582
- color: white;
583
- padding: 10px;
584
- border: none;
585
- border-radius: 4px;
586
- cursor: pointer;
587
- }
588
- `;
589
- var BUTTON_CSS_MODULE_FILE_GENERATOR = new FileGeneratorImp(
590
- "src/button.module.css",
591
- BUTTON_CSS_MODULE
592
- );
788
+ await registerSwagger();
593
789
 
594
- // src/packages/react-package/css-react-package/files/button-file-generator.ts
595
- var BUTTON = `import React from 'react';
596
- import * as styles from './button.module.css';
790
+ registerRoutes();
597
791
 
598
- export function Button(props: HTMLAttributes<HTMLButtonElement>) {
599
- return <button className={styles.styledButton} {...props} />;
600
- }
601
- `;
602
- var BUTTON_FILE_GENERATOR = new FileGeneratorImp(
603
- "src/button.tsx",
604
- BUTTON
605
- );
792
+ function registerRoutes() {
793
+ fastify.get("/", async (request, reply) => {
794
+ return { hello: "world", docs: "/docs" };
795
+ });
606
796
 
607
- // src/packages/react-package/css-react-package/files/button-spec-file-generator.ts
608
- var BUTTON_SPEC = `import { render, screen, fireEvent } from '@testing-library/react';
609
- import { Button } from './button';
797
+ fastify.get<{
798
+ Params: { a: string; b: string };
799
+ }>(
800
+ "/add/:a/:b",
801
+ {
802
+ schema: {
803
+ params: {
804
+ type: "object",
805
+ properties: {
806
+ a: { type: "string" },
807
+ b: { type: "string" },
808
+ },
809
+ required: ["a", "b"],
810
+ },
811
+ response: {
812
+ 200: {
813
+ type: "object",
814
+ properties: {
815
+ result: { type: "number" },
816
+ },
817
+ },
818
+ },
819
+ },
820
+ },
821
+ async (request, reply) => {
822
+ // request.params.a should now be recognized as a string
823
+ const a = Number(request.params.a);
824
+ const b = Number(request.params.b);
610
825
 
611
- describe('Button', () => {
612
- it('renders the label correctly', () => {
613
- render(<Button>Click Me</Button>);
614
- expect(screen.getByText('Click Me')).toBeDefined();
615
- });
826
+ return { result: a + b };
827
+ }
828
+ );
829
+ }
616
830
 
617
- it('is a button element', () => {
618
- render(<Button>Submit</Button>);
619
- const buttonElement = screen.getByRole('button');
620
- expect(buttonElement.tagName).toBe('BUTTON');
831
+ async function registerSwagger() {
832
+ await fastify.register(fastifySwagger, {
833
+ openapi: {
834
+ openapi: "3.0.0",
835
+ info: {
836
+ title: "Test swagger",
837
+ description: "Testing the Fastify swagger API",
838
+ version: "0.1.0",
839
+ },
840
+ servers: [
841
+ {
842
+ url: "http://localhost:3000",
843
+ description: "Development server",
844
+ },
845
+ ],
846
+ components: {
847
+ securitySchemes: {
848
+ apiKey: {
849
+ type: "apiKey",
850
+ name: "apiKey",
851
+ in: "header",
852
+ },
853
+ },
854
+ },
855
+ externalDocs: {
856
+ url: "https://swagger.io",
857
+ description: "Find more info here",
858
+ },
859
+ },
621
860
  });
622
861
 
623
- /* Note: Testing for specific CSS classes with CSS Modules is tricky
624
- because class names are mangled (e.g., _styledButton_123).
625
- Usually, we just test that the class attribute exists.
626
- */
627
- it('applies a class name', () => {
628
- render(<Button>Styled</Button>);
629
- const buttonElement = screen.getByRole('button');
630
- expect(buttonElement.className).toBeTruthy();
862
+ await fastify.register(fastifySwaggerUI, {
863
+ routePrefix: "/docs",
864
+ uiConfig: {
865
+ docExpansion: "list",
866
+ deepLinking: false,
867
+ },
868
+ uiHooks: {
869
+ onRequest: function (request, reply, next) {
870
+ next();
871
+ },
872
+ preHandler: function (request, reply, next) {
873
+ next();
874
+ },
875
+ },
876
+ staticCSP: true,
877
+ transformStaticCSP: (header) => header,
878
+ transformSpecification: (swaggerObject, request, reply) => {
879
+ return swaggerObject;
880
+ },
881
+ transformSpecificationClone: true,
631
882
  });
632
- });
633
- `;
634
- var BUTTON_SPEC_FILE_GENERATOR = new FileGeneratorImp(
635
- "src/button.spec.tsx",
636
- BUTTON_SPEC
637
- );
638
-
639
- // src/packages/react-package/css-react-package/files/eslint-config-file-generator.ts
640
- var ESLINT_CONFIG2 = `import base from '@stack-dev/eslint-config/base.mjs';
641
- import react from '@stack-dev/eslint-config/react.mjs';
883
+ }
642
884
 
643
- export default [
644
- ...base,
645
- ...react,
646
- {
647
- ignores: ['**/dist/**', '**/coverage/**']
885
+ async function start() {
886
+ try {
887
+ await fastify.listen({ port: 3000 });
888
+ } catch (err) {
889
+ fastify.log.error(err);
890
+ process.exit(1);
648
891
  }
649
- ];
650
- `;
651
- var ESLINT_CONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
652
- "eslint.config.mjs",
653
- ESLINT_CONFIG2
654
- );
892
+ }
655
893
 
656
- // src/packages/react-package/css-react-package/files/index-file-generator.ts
657
- var INDEX_TS2 = `export * from './button';
894
+ start();
658
895
  `;
659
- var INDEX_FILE_GENERATOR2 = new FileGeneratorImp(
660
- "src/index.ts",
661
- INDEX_TS2
662
- );
896
+ var INDEX_FILE_GENERATOR2 = new FileGeneratorImp("src/index.ts", INDEX2);
663
897
 
664
- // src/packages/react-package/css-react-package/files/prettier-config-file-generator.ts
898
+ // src/packages/fastify-app/files/prettier-config-file-generator.ts
665
899
  var PRETTIER_CONFIG2 = `import base from '@stack-dev/prettier-config/base.mjs';
666
900
 
667
901
  export default base;
@@ -671,9 +905,9 @@ var PRETTIER_CONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
671
905
  PRETTIER_CONFIG2
672
906
  );
673
907
 
674
- // src/packages/react-package/css-react-package/files/tsconfig-file-generator.ts
908
+ // src/packages/fastify-app/files/tsconfig-file-generator.ts
675
909
  var TSCONFIG2 = `{
676
- "extends": "@stack-dev/typescript-config/tsconfig.react.json",
910
+ "extends": "@stack-dev/typescript-config/tsconfig.base.json",
677
911
  "compilerOptions": {
678
912
  "outDir": "dist"
679
913
  },
@@ -685,43 +919,35 @@ var TSCONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
685
919
  TSCONFIG2
686
920
  );
687
921
 
688
- // src/packages/react-package/css-react-package/files/tsup-config-file-generator.ts
689
- var TSUP_CONFIG2 = `import { defineConfig } from 'tsup';
922
+ // src/packages/fastify-app/files/tsup-file-generator.ts
923
+ var TSUP2 = `import { defineConfig } from "tsup";
690
924
 
691
925
  export default defineConfig({
692
- entry: ['src/index.ts'],
693
- format: ['cjs', 'esm'],
694
- dts: true,
695
- minify: true,
926
+ entry: ["src/index.ts"],
927
+ format: ["esm"],
928
+ dts: false,
929
+ sourcemap: true,
696
930
  clean: true,
697
- injectStyle: true,
698
- external: ['react', 'react-dom'],
931
+ target: "esnext",
699
932
  outExtension({ format }) {
700
933
  return {
701
- js: format === 'esm' ? '.mjs' : '.js',
934
+ js: format === "esm" ? ".mjs" : ".js",
702
935
  };
703
936
  },
704
937
  });
705
938
  `;
706
- var TSUP_CONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
707
- "tsup.config.ts",
708
- TSUP_CONFIG2
709
- );
939
+ var TSUP_FILE_GENERATOR2 = new FileGeneratorImp("tsup.config.ts", TSUP2);
710
940
 
711
- // src/packages/react-package/css-react-package/files/vitest-config-file-generator.ts
941
+ // src/packages/fastify-app/files/vitest-config-file-generator.ts
712
942
  var VITEST_CONFIG2 = `import { defineConfig } from 'vitest/config';
713
- import react from '@vitejs/plugin-react';
714
943
 
715
944
  export default defineConfig({
716
- plugins: [react()],
717
945
  test: {
718
946
  globals: true,
719
- environment: 'jsdom',
720
947
  coverage: {
721
948
  provider: 'v8',
722
- reporter: ['text', 'json', 'html'],
723
949
  },
724
- css: true,
950
+ environment: 'node',
725
951
  },
726
952
  });
727
953
  `;
@@ -730,126 +956,278 @@ var VITEST_CONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
730
956
  VITEST_CONFIG2
731
957
  );
732
958
 
733
- // src/packages/react-package/css-react-package/create-css-react-package.ts
734
- async function createCssReactPackage(name) {
959
+ // src/packages/fastify-app/create-fastify-app.ts
960
+ async function createFastifyApp(name) {
735
961
  const rootDir = await getWorkspaceRoot();
736
- const directory = path5.join(rootDir, "packages", name);
962
+ const directory = path6.join(rootDir, "apps", name);
737
963
  const namespace = await getNamespace(rootDir);
738
964
  const packageName = `${namespace}/${name}`;
739
- console.log(`\u2728 Creating CSS Modules React library: ${packageName}`);
965
+ console.log(`\u{1F680} Creating Fastify App: ${packageName}`);
740
966
  const generator = new PackageGenerator(
741
967
  directory,
742
- makePackageGenerator2(packageName, namespace),
968
+ makeAppPackageGenerator2(packageName, namespace),
743
969
  [
744
970
  INDEX_FILE_GENERATOR2,
745
- BUTTON_FILE_GENERATOR,
746
- BUTTON_CSS_MODULE_FILE_GENERATOR,
747
- BUTTON_SPEC_FILE_GENERATOR,
748
- TSUP_CONFIG_FILE_GENERATOR2,
749
971
  TSCONFIG_FILE_GENERATOR2,
972
+ TSUP_FILE_GENERATOR2,
750
973
  PRETTIER_CONFIG_FILE_GENERATOR2,
751
974
  ESLINT_CONFIG_FILE_GENERATOR2,
752
975
  VITEST_CONFIG_FILE_GENERATOR2
753
976
  ]
754
977
  );
755
978
  await generator.generate();
756
- console.log(`\u2705 Library created at: ${directory}`);
757
979
  }
758
- function makePackageGenerator2(packageName, namespace) {
980
+ function makeAppPackageGenerator2(packageName, namespace) {
759
981
  const packageJsonModel = new PackageJSON({
760
982
  name: packageName,
761
983
  peerDependencies: [
762
- new Dependency("react", ">=18"),
763
- new Dependency("react-dom", ">=18")
984
+ new Dependency("typescript", "^5.9.3"),
985
+ new Dependency("@types/node", "^25.0.3")
986
+ ],
987
+ dependencies: [
988
+ new Dependency("fastify", "^5.6.2"),
989
+ new Dependency("@fastify/swagger", "^9.6.1"),
990
+ new Dependency("@fastify/swagger-ui", "^5.2.3"),
991
+ new Dependency("pino-pretty", "^13.1.3")
764
992
  ],
765
993
  devDependencies: [
766
994
  new Dependency(`${namespace}/eslint-config`, "workspace:*"),
767
995
  new Dependency(`${namespace}/prettier-config`, "workspace:*"),
768
996
  new Dependency(`${namespace}/typescript-config`, "workspace:*"),
769
- // Development React binaries
770
- new Dependency("react", "^18.3.1"),
771
- new Dependency("react-dom", "^18.3.1"),
772
- new Dependency("@types/react", "^18.3.1"),
773
- new Dependency("@types/react-dom", "^18.3.1"),
774
- // Linting & Formatting
997
+ new Dependency("tsup", "^8.5.1"),
998
+ new Dependency("tsx", "^4.21.0"),
775
999
  new Dependency("eslint", "^9.32.0"),
776
1000
  new Dependency("prettier", "^3.6.2"),
777
- new Dependency("prettier-plugin-organize-imports", "^4.2.0"),
778
- // Build
779
- new Dependency("tsup", "^8.0.0"),
780
- new Dependency("postcss", "^8.4.0"),
781
- // Testing
782
- new Dependency("vitest", "^3.2.4"),
783
- new Dependency("@vitest/coverage-v8", "^3.2.4"),
784
- new Dependency("@testing-library/react", "^16.0.0"),
785
- new Dependency("@testing-library/jest-dom", "^6.0.0"),
786
- new Dependency("jsdom", "^25.0.0")
1001
+ new Dependency("vitest", "^3.2.4")
787
1002
  ],
788
1003
  additionalData: {
789
1004
  version: "0.1.0",
790
1005
  private: true,
791
- main: "dist/index.js",
792
- module: "dist/index.mjs",
793
- types: "dist/index.d.ts",
794
- exports: {
795
- ".": {
796
- development: "./src/index.ts",
797
- import: "./dist/index.mjs",
798
- require: "./dist/index.js",
799
- types: "./dist/index.d.ts"
800
- },
801
- "./index.css": "./dist/index.css"
802
- },
1006
+ type: "module",
803
1007
  scripts: {
804
- build: "tsup",
1008
+ dev: "tsx watch src/index.ts",
1009
+ build: "tsup src/index.ts",
1010
+ start: "node dist/index.mjs",
805
1011
  lint: "eslint .",
806
1012
  format: "prettier . --write",
807
1013
  test: "vitest run",
808
1014
  "test:watch": "vitest"
809
- },
810
- sideEffects: ["**/*.css"]
1015
+ }
811
1016
  }
812
1017
  });
813
1018
  return new PackageJsonGenerator(packageJsonModel, namespace);
814
1019
  }
815
1020
 
816
- // src/packages/react-package/styled-components-react-package/create-styled-components-react-package.ts
817
- import path6 from "path";
818
-
819
- // src/packages/react-package/styled-components-react-package/files/button-file-generator.ts
820
- var BUTTON2 = `import React, { HTMLAttributes } from 'react';
821
- import styled from 'styled-components';
822
-
823
- // This is your "Styled" version of the button
824
- // No more imports, no more "empty objects"
825
- const StyledButton = styled.button\`
826
- background-color: #007bff;
827
- color: white;
828
- padding: 10px 20px;
829
- border: none;
830
- border-radius: 4px;
831
- cursor: pointer;
832
- font-size: 16px;
833
-
834
- &:hover {
835
- background-color: #0056b3;
836
- }
837
- \`;
1021
+ // src/packages/library-package/create-library-package.ts
1022
+ import path7 from "node:path";
838
1023
 
839
- export function Button(props: HTMLAttributes<HTMLButtonElement>) {
840
- return <StyledButton {...props} />;
1024
+ // src/packages/library-package/files/add-file-generator.ts
1025
+ var ADD_TS = `export function add(n1: number, n2: number): number {
1026
+ return n1 + n2;
841
1027
  }
842
1028
  `;
843
- var BUTTON_FILE_GENERATOR2 = new FileGeneratorImp(
844
- "src/button.tsx",
845
- BUTTON2
846
- );
1029
+ var ADD_FILE_GENERATOR = new FileGeneratorImp("src/add.ts", ADD_TS);
847
1030
 
848
- // src/packages/react-package/styled-components-react-package/files/button-spec-file-generator.ts
849
- var BUTTON_SPEC2 = `import { render, screen, fireEvent } from '@testing-library/react';
850
- import { Button } from './button';
1031
+ // src/packages/library-package/files/add-spec-file-generator.ts
1032
+ var ADD_SPEC_TS = `import { describe, it, expect } from 'vitest';
851
1033
 
852
- describe('Button', () => {
1034
+ import { add } from '../add';
1035
+
1036
+ describe('add', () => {
1037
+ it('adds two numbers', () => {
1038
+ expect(add(2, 3)).toBe(5);
1039
+ });
1040
+ });
1041
+ `;
1042
+ var ADD_SPEC_FILE_GENERATOR = new FileGeneratorImp(
1043
+ "src/spec/add.spec.ts",
1044
+ ADD_SPEC_TS
1045
+ );
1046
+
1047
+ // src/packages/library-package/files/eslint-config-file-generator.ts
1048
+ var ESLINT_CONFIG3 = `import base from '@stack-dev/eslint-config/base.mjs';
1049
+
1050
+ export default [...base, { ignores: ['**/dist/**'] }];
1051
+ `;
1052
+ var ESLINT_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1053
+ "eslint.config.mjs",
1054
+ ESLINT_CONFIG3
1055
+ );
1056
+
1057
+ // src/packages/library-package/files/index-file-generator.ts
1058
+ var INDEX_TS = `export * from './add';
1059
+ `;
1060
+ var INDEX_FILE_GENERATOR3 = new FileGeneratorImp(
1061
+ "src/index.ts",
1062
+ INDEX_TS
1063
+ );
1064
+
1065
+ // src/packages/library-package/files/prettier-config-file-generator.ts
1066
+ var PRETTIER_CONFIG3 = `import base from '@stack-dev/prettier-config/base.mjs';
1067
+
1068
+ export default base;
1069
+ `;
1070
+ var PRETTIER_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1071
+ "prettier.config.mjs",
1072
+ PRETTIER_CONFIG3
1073
+ );
1074
+
1075
+ // src/packages/library-package/files/tsconfig-file-generator.ts
1076
+ var TSCONFIG3 = `{
1077
+ "extends": "@stack-dev/typescript-config/tsconfig.base.json",
1078
+ "compilerOptions": {
1079
+ "outDir": "dist"
1080
+ },
1081
+ "include": ["src"]
1082
+ }
1083
+ `;
1084
+ var TSCONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1085
+ "tsconfig.json",
1086
+ TSCONFIG3
1087
+ );
1088
+
1089
+ // src/packages/library-package/files/tsup-config-file-generator.ts
1090
+ var TSUP_CONFIG = `import { defineConfig } from 'tsup';
1091
+
1092
+ export default defineConfig({
1093
+ entry: ['src/index.ts'],
1094
+ format: ['esm', 'cjs'],
1095
+ dts: true,
1096
+ sourcemap: true,
1097
+ clean: true,
1098
+ target: 'esnext',
1099
+ outExtension({ format }) {
1100
+ return {
1101
+ js: format === 'esm' ? '.mjs' : '.js',
1102
+ };
1103
+ },
1104
+ });
1105
+ `;
1106
+ var TSUP_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
1107
+ "tsup.config.ts",
1108
+ TSUP_CONFIG
1109
+ );
1110
+
1111
+ // src/packages/library-package/files/vitest-config-file-generator.ts
1112
+ var VITEST_CONFIG3 = `import { defineConfig } from 'vitest/config';
1113
+
1114
+ export default defineConfig({
1115
+ test: {
1116
+ globals: true,
1117
+ coverage: {
1118
+ provider: 'v8',
1119
+ },
1120
+ environment: 'node',
1121
+ },
1122
+ });
1123
+ `;
1124
+ var VITEST_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1125
+ "vitest.config.ts",
1126
+ VITEST_CONFIG3
1127
+ );
1128
+
1129
+ // src/packages/library-package/create-library-package.ts
1130
+ async function createLibraryPackage(name) {
1131
+ const rootDir = await getWorkspaceRoot();
1132
+ const directory = path7.join(rootDir, "packages", name);
1133
+ const namespace = await getNamespace(rootDir);
1134
+ const packageName = `${namespace}/${name}`;
1135
+ console.log(`\u2728 Creating config package: ${packageName}`);
1136
+ const generator = new PackageGenerator(
1137
+ directory,
1138
+ makePackageGenerator(packageName, namespace),
1139
+ [
1140
+ INDEX_FILE_GENERATOR3,
1141
+ ADD_FILE_GENERATOR,
1142
+ ADD_SPEC_FILE_GENERATOR,
1143
+ TSUP_CONFIG_FILE_GENERATOR,
1144
+ TSCONFIG_FILE_GENERATOR3,
1145
+ PRETTIER_CONFIG_FILE_GENERATOR3,
1146
+ ESLINT_CONFIG_FILE_GENERATOR3,
1147
+ VITEST_CONFIG_FILE_GENERATOR3
1148
+ ]
1149
+ );
1150
+ await generator.generate();
1151
+ console.log(`\u2705 Config package created at: ${directory}`);
1152
+ }
1153
+ function makePackageGenerator(packageName, namespace) {
1154
+ const packageJsonModel = new PackageJSON({
1155
+ name: packageName,
1156
+ devDependencies: [
1157
+ new Dependency(`${namespace}/eslint-config`, "workspace:*"),
1158
+ new Dependency(`${namespace}/prettier-config`, "workspace:*"),
1159
+ new Dependency(`${namespace}/typescript-config`, "workspace:*"),
1160
+ new Dependency("eslint", "^9.32.0"),
1161
+ new Dependency("prettier", "^3.6.2"),
1162
+ new Dependency("prettier-plugin-organize-imports", "^4.2.0"),
1163
+ new Dependency("tsup", "^7.3.0"),
1164
+ new Dependency("vitest", "^3.2.4"),
1165
+ new Dependency("@vitest/coverage-v8", "^3.2.4")
1166
+ ],
1167
+ additionalData: {
1168
+ version: "0.1.0",
1169
+ private: true,
1170
+ main: "dist/index.js",
1171
+ module: "dist/index.mjs",
1172
+ types: "dist/index.d.ts",
1173
+ exports: {
1174
+ ".": {
1175
+ development: "./src/index.ts",
1176
+ import: "./dist/index.mjs",
1177
+ require: "./dist/index.js",
1178
+ types: "./dist/index.d.ts"
1179
+ }
1180
+ },
1181
+ scripts: {
1182
+ build: "tsup",
1183
+ lint: "eslint",
1184
+ format: "prettier . --write",
1185
+ test: "vitest run",
1186
+ "test:watch": "vitest"
1187
+ },
1188
+ sideEffects: false
1189
+ }
1190
+ });
1191
+ return new PackageJsonGenerator(packageJsonModel, namespace);
1192
+ }
1193
+
1194
+ // src/packages/react-package/styled-components-react-package/create-styled-components-react-package.ts
1195
+ import path8 from "path";
1196
+
1197
+ // src/packages/react-package/styled-components-react-package/files/button-file-generator.ts
1198
+ var BUTTON = `import React, { HTMLAttributes } from 'react';
1199
+ import styled from 'styled-components';
1200
+
1201
+ // This is your "Styled" version of the button
1202
+ // No more imports, no more "empty objects"
1203
+ const StyledButton = styled.button\`
1204
+ background-color: #007bff;
1205
+ color: white;
1206
+ padding: 10px 20px;
1207
+ border: none;
1208
+ border-radius: 4px;
1209
+ cursor: pointer;
1210
+ font-size: 16px;
1211
+
1212
+ &:hover {
1213
+ background-color: #0056b3;
1214
+ }
1215
+ \`;
1216
+
1217
+ export function Button(props: HTMLAttributes<HTMLButtonElement>) {
1218
+ return <StyledButton {...props} />;
1219
+ }
1220
+ `;
1221
+ var BUTTON_FILE_GENERATOR = new FileGeneratorImp(
1222
+ "src/button.tsx",
1223
+ BUTTON
1224
+ );
1225
+
1226
+ // src/packages/react-package/styled-components-react-package/files/button-spec-file-generator.ts
1227
+ var BUTTON_SPEC = `import { render, screen, fireEvent } from '@testing-library/react';
1228
+ import { Button } from './button';
1229
+
1230
+ describe('Button', () => {
853
1231
  it('renders the label correctly', () => {
854
1232
  render(<Button>Click Me</Button>);
855
1233
  expect(screen.getByText('Click Me')).toBeDefined();
@@ -872,13 +1250,13 @@ describe('Button', () => {
872
1250
  });
873
1251
  });
874
1252
  `;
875
- var BUTTON_SPEC_FILE_GENERATOR2 = new FileGeneratorImp(
1253
+ var BUTTON_SPEC_FILE_GENERATOR = new FileGeneratorImp(
876
1254
  "src/button.spec.tsx",
877
- BUTTON_SPEC2
1255
+ BUTTON_SPEC
878
1256
  );
879
1257
 
880
1258
  // src/packages/react-package/styled-components-react-package/files/eslint-config-file-generator.ts
881
- var ESLINT_CONFIG3 = `import base from '@stack-dev/eslint-config/base.mjs';
1259
+ var ESLINT_CONFIG4 = `import base from '@stack-dev/eslint-config/base.mjs';
882
1260
  import react from '@stack-dev/eslint-config/react.mjs';
883
1261
 
884
1262
  export default [
@@ -889,31 +1267,31 @@ export default [
889
1267
  }
890
1268
  ];
891
1269
  `;
892
- var ESLINT_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1270
+ var ESLINT_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
893
1271
  "eslint.config.mjs",
894
- ESLINT_CONFIG3
1272
+ ESLINT_CONFIG4
895
1273
  );
896
1274
 
897
1275
  // src/packages/react-package/styled-components-react-package/files/index-file-generator.ts
898
- var INDEX_TS3 = `export * from './button';
1276
+ var INDEX_TS2 = `export * from './button';
899
1277
  `;
900
- var INDEX_FILE_GENERATOR3 = new FileGeneratorImp(
1278
+ var INDEX_FILE_GENERATOR4 = new FileGeneratorImp(
901
1279
  "src/index.ts",
902
- INDEX_TS3
1280
+ INDEX_TS2
903
1281
  );
904
1282
 
905
1283
  // src/packages/react-package/styled-components-react-package/files/prettier-config-file-generator.ts
906
- var PRETTIER_CONFIG3 = `import base from '@stack-dev/prettier-config/base.mjs';
1284
+ var PRETTIER_CONFIG4 = `import base from '@stack-dev/prettier-config/base.mjs';
907
1285
 
908
1286
  export default base;
909
1287
  `;
910
- var PRETTIER_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1288
+ var PRETTIER_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
911
1289
  "prettier.config.mjs",
912
- PRETTIER_CONFIG3
1290
+ PRETTIER_CONFIG4
913
1291
  );
914
1292
 
915
1293
  // src/packages/react-package/styled-components-react-package/files/tsconfig-file-generator.ts
916
- var TSCONFIG3 = `{
1294
+ var TSCONFIG4 = `{
917
1295
  "extends": "@stack-dev/typescript-config/tsconfig.react.json",
918
1296
  "compilerOptions": {
919
1297
  "outDir": "dist"
@@ -921,13 +1299,13 @@ var TSCONFIG3 = `{
921
1299
  "include": ["src"]
922
1300
  }
923
1301
  `;
924
- var TSCONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1302
+ var TSCONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
925
1303
  "tsconfig.json",
926
- TSCONFIG3
1304
+ TSCONFIG4
927
1305
  );
928
1306
 
929
1307
  // src/packages/react-package/styled-components-react-package/files/tsup-config-file-generator.ts
930
- var TSUP_CONFIG3 = `import { defineConfig } from 'tsup';
1308
+ var TSUP_CONFIG2 = `import { defineConfig } from 'tsup';
931
1309
 
932
1310
  export default defineConfig({
933
1311
  entry: ['src/index.ts'],
@@ -941,13 +1319,13 @@ export default defineConfig({
941
1319
  };
942
1320
  },
943
1321
  });`;
944
- var TSUP_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1322
+ var TSUP_CONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
945
1323
  "tsup.config.ts",
946
- TSUP_CONFIG3
1324
+ TSUP_CONFIG2
947
1325
  );
948
1326
 
949
1327
  // src/packages/react-package/styled-components-react-package/files/vitest-config-file-generator.ts
950
- var VITEST_CONFIG3 = `import { defineConfig } from 'vitest/config';
1328
+ var VITEST_CONFIG4 = `import { defineConfig } from 'vitest/config';
951
1329
  import react from '@vitejs/plugin-react';
952
1330
 
953
1331
  export default defineConfig({
@@ -963,38 +1341,36 @@ export default defineConfig({
963
1341
  },
964
1342
  });
965
1343
  `;
966
- var VITEST_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1344
+ var VITEST_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
967
1345
  "vitest.config.ts",
968
- VITEST_CONFIG3
1346
+ VITEST_CONFIG4
969
1347
  );
970
1348
 
971
1349
  // src/packages/react-package/styled-components-react-package/create-styled-components-react-package.ts
972
1350
  async function createStyledComponentsReactPackage(name) {
973
1351
  const rootDir = await getWorkspaceRoot();
974
- const directory = path6.join(rootDir, "packages", name);
1352
+ const directory = path8.join(rootDir, "packages", name);
975
1353
  const namespace = await getNamespace(rootDir);
976
1354
  const packageName = `${namespace}/${name}`;
977
- console.log(
978
- `\u2728 Creating Styled Components Modules React library: ${packageName}`
979
- );
1355
+ console.log(`\u2728 Creating Styled Components React library: ${packageName}`);
980
1356
  const generator = new PackageGenerator(
981
1357
  directory,
982
- makePackageGenerator3(packageName, namespace),
1358
+ makePackageGenerator2(packageName, namespace),
983
1359
  [
984
- INDEX_FILE_GENERATOR3,
985
- BUTTON_FILE_GENERATOR2,
986
- BUTTON_SPEC_FILE_GENERATOR2,
987
- TSUP_CONFIG_FILE_GENERATOR3,
988
- TSCONFIG_FILE_GENERATOR3,
989
- PRETTIER_CONFIG_FILE_GENERATOR3,
990
- ESLINT_CONFIG_FILE_GENERATOR3,
991
- VITEST_CONFIG_FILE_GENERATOR3
1360
+ INDEX_FILE_GENERATOR4,
1361
+ BUTTON_FILE_GENERATOR,
1362
+ BUTTON_SPEC_FILE_GENERATOR,
1363
+ TSUP_CONFIG_FILE_GENERATOR2,
1364
+ TSCONFIG_FILE_GENERATOR4,
1365
+ PRETTIER_CONFIG_FILE_GENERATOR4,
1366
+ ESLINT_CONFIG_FILE_GENERATOR4,
1367
+ VITEST_CONFIG_FILE_GENERATOR4
992
1368
  ]
993
1369
  );
994
1370
  await generator.generate();
995
1371
  console.log(`\u2705 Library created at: ${directory}`);
996
1372
  }
997
- function makePackageGenerator3(packageName, namespace) {
1373
+ function makePackageGenerator2(packageName, namespace) {
998
1374
  const packageJsonModel = new PackageJSON({
999
1375
  name: packageName,
1000
1376
  // Peer deps are crucial for Styled Components to prevent "Multiple instances" errors
@@ -1061,417 +1437,232 @@ function makePackageGenerator3(packageName, namespace) {
1061
1437
  return new PackageJsonGenerator(packageJsonModel, namespace);
1062
1438
  }
1063
1439
 
1064
- // src/packages/react-package/create-react-package.ts
1065
- async function createReactPackage(name, style) {
1066
- switch (style) {
1067
- case "tailwind":
1068
- await createTailwindReactPackage(name);
1069
- break;
1070
- case "css-modules":
1071
- await createCssReactPackage(name);
1072
- break;
1073
- case "styled-components":
1074
- await createStyledComponentsReactPackage(name);
1075
- break;
1076
- case "none":
1077
- await createUnstyledReactPackage(name);
1078
- break;
1079
- }
1080
- }
1440
+ // src/packages/react-package/unstyled-react-package/create-unstyled-react-package.ts
1441
+ import path9 from "path";
1081
1442
 
1082
- // src/packages/create-config-package.ts
1083
- import path7 from "node:path";
1084
- async function createConfigPackage(name) {
1085
- const rootDir = await getWorkspaceRoot();
1086
- const directory = path7.join(rootDir, "configs", name);
1087
- const namespace = await getNamespace(rootDir);
1088
- const packageName = `${namespace}/${name}`;
1089
- const packageJsonModel = new PackageJSON({
1090
- name: packageName,
1091
- additionalData: {
1092
- version: "0.1.0",
1093
- private: true
1094
- }
1095
- });
1096
- const generator = new PackageGenerator(
1097
- directory,
1098
- new PackageJsonGenerator(packageJsonModel, namespace),
1099
- []
1100
- );
1101
- await generator.generate();
1102
- }
1443
+ // src/packages/react-package/unstyled-react-package/files/button-file-generator.ts
1444
+ var BUTTON2 = `import React, { HTMLAttributes } from 'react';
1103
1445
 
1104
- // src/utils/package.ts
1105
- import { glob } from "fast-glob";
1106
- import path8 from "node:path";
1107
- async function getCurrentPackage(directory = process.cwd()) {
1108
- const packageRoot = await getPackageRoot(directory);
1109
- const packageJson = await getDirectoryPackageJson(packageRoot);
1110
- return getPackageByName(packageJson.name);
1111
- }
1112
- async function getPackageRoot(directory = process.cwd()) {
1113
- const parent = path8.dirname(directory);
1114
- if (parent === directory) {
1115
- throw new Error("Not a package.");
1116
- }
1117
- if (await isPackageRoot(directory)) {
1118
- return directory;
1119
- }
1120
- return getPackageRoot(parent);
1121
- }
1122
- async function getPackageByName(name) {
1123
- const all = await getAllPackages();
1124
- const match = all.find((p) => p.name === name);
1125
- if (match === void 0) {
1126
- throw new Error(`No package with name "${name}".`);
1127
- }
1128
- return match;
1129
- }
1130
- async function getAllPackages(directory = process.cwd()) {
1131
- const workspaceRoot = await getWorkspaceRoot(directory);
1132
- const workspaceFile = await getDirectoryWorkspaceFile(workspaceRoot);
1133
- const results = [];
1134
- for (const seg of workspaceFile.packages) {
1135
- const packageType = getPackageType(seg);
1136
- const packageJsonPaths = await glob(`${workspaceRoot}/${seg}/package.json`);
1137
- const packageDirectories = packageJsonPaths.map((p) => path8.dirname(p));
1138
- for (const directory2 of packageDirectories) {
1139
- const name = (await getDirectoryPackageJson(directory2)).name;
1140
- results.push({
1141
- name,
1142
- directory: directory2,
1143
- type: packageType
1144
- });
1145
- }
1146
- }
1147
- return results;
1148
- }
1149
- function getPackageType(segment) {
1150
- if (segment.startsWith("app")) {
1151
- return "App";
1152
- } else if (segment.startsWith("config")) {
1153
- return "Config";
1154
- } else if (segment.startsWith("package") || segment.startsWith("lib")) {
1155
- return "Library";
1156
- } else {
1157
- return "Unknown";
1158
- }
1159
- }
1160
- function comparePackages(a, b) {
1161
- const packageTypeDifference = comparePackageTypes(a.type, b.type);
1162
- if (packageTypeDifference !== 0) {
1163
- return packageTypeDifference;
1164
- } else {
1165
- return a.name.localeCompare(b.name);
1166
- }
1167
- }
1168
- function comparePackageTypes(a, b) {
1169
- return getPackageTypeIndex(a) - getPackageTypeIndex(b);
1170
- }
1171
- function getPackageTypeIndex(packageType) {
1172
- switch (packageType) {
1173
- case "Library":
1174
- return 0;
1175
- case "Config":
1176
- return 1;
1177
- case "App":
1178
- return 2;
1179
- case "Unknown":
1180
- return 3;
1181
- }
1182
- }
1183
- async function isPackageRoot(directory) {
1184
- return await fileExists(path8.join(directory, "package.json"));
1446
+ export function Button(props: HTMLAttributes<HTMLButtonElement>) {
1447
+ return <button {...props} />;
1185
1448
  }
1449
+ `;
1450
+ var BUTTON_FILE_GENERATOR2 = new FileGeneratorImp(
1451
+ "src/button.tsx",
1452
+ BUTTON2
1453
+ );
1186
1454
 
1187
- // src/utils/package-type.ts
1188
- import { prompt } from "enquirer";
1189
- var packageTypes = [
1190
- "library",
1191
- "config",
1192
- "react",
1193
- "vite",
1194
- "fastify",
1195
- "next",
1196
- "cli"
1197
- ];
1198
- async function pickPackageType(options) {
1199
- if (options?.type && isPackageType(options.type)) {
1200
- return options.type;
1201
- } else if (options?.type && !isPackageType(options.type)) {
1202
- throw new Error(
1203
- `--type setting "${options.type}" is invalid, must be one of ${packageTypes.join(", ")}.`
1204
- );
1205
- }
1206
- const response = await prompt({
1207
- type: "select",
1208
- name: "type",
1209
- message: "What kind of package do you want?",
1210
- choices: [...packageTypes]
1455
+ // src/packages/react-package/unstyled-react-package/files/button-spec-file-generator.ts
1456
+ var BUTTON_SPEC2 = `import { render, screen, fireEvent } from '@testing-library/react';
1457
+ import { Button } from './button';
1458
+
1459
+ describe('Button', () => {
1460
+ it('renders the label correctly', () => {
1461
+ render(<Button>Click Me</Button>);
1462
+ expect(screen.getByText('Click Me')).toBeDefined();
1211
1463
  });
1212
- if (!isPackageType(response.type)) {
1213
- throw new Error(
1214
- `Type "${response.type}" is invalid, must be one of ${packageTypes.join(", ")}.`
1215
- );
1216
- }
1217
- return response.type;
1218
- }
1219
- function isPackageType(s) {
1220
- return packageTypes.some((p) => p === s);
1221
- }
1222
1464
 
1223
- // src/utils/style-type.ts
1224
- import { prompt as prompt2 } from "enquirer";
1225
- var styleTypes = [
1226
- "tailwind",
1227
- "css-modules",
1228
- "styled-components",
1229
- "none"
1230
- ];
1231
- async function pickStyleType(options) {
1232
- if (options?.style && isStyleType(options?.style)) {
1233
- return options?.style;
1234
- } else if (options?.style && !isStyleType(options?.style)) {
1235
- throw new Error(
1236
- `--style setting "${options.style}" is invalid, must be one of ${styleTypes.join(", ")}.`
1237
- );
1238
- }
1239
- const response = await prompt2({
1240
- type: "select",
1241
- name: "type",
1242
- message: "What kind of style do you want?",
1243
- choices: [...styleTypes]
1465
+ it('is a button element', () => {
1466
+ render(<Button>Submit</Button>);
1467
+ const buttonElement = screen.getByRole('button');
1468
+ expect(buttonElement.tagName).toBe('BUTTON');
1244
1469
  });
1245
- if (!isStyleType(response.type)) {
1246
- throw new Error(
1247
- `Type "${response.type}" is invalid, must be one of ${styleTypes.join(", ")}.`
1248
- );
1249
- }
1250
- return response.type;
1251
- }
1252
- function isStyleType(s) {
1253
- return styleTypes.some((p) => p === s);
1254
- }
1470
+ });
1471
+ `;
1472
+ var BUTTON_SPEC_FILE_GENERATOR2 = new FileGeneratorImp(
1473
+ "src/button.spec.tsx",
1474
+ BUTTON_SPEC2
1475
+ );
1255
1476
 
1256
- // src/index.ts
1257
- import { Command } from "commander";
1258
- import { prompt as prompt3 } from "enquirer";
1477
+ // src/packages/react-package/unstyled-react-package/files/eslint-config-file-generator.ts
1478
+ var ESLINT_CONFIG5 = `import base from '@stack-dev/eslint-config/base.mjs';
1479
+ import react from '@stack-dev/eslint-config/react.mjs';
1259
1480
 
1260
- // package.json
1261
- var version = "0.1.7";
1481
+ export default [
1482
+ ...base,
1483
+ ...react,
1484
+ {
1485
+ ignores: ['**/dist/**', '**/coverage/**']
1486
+ }
1487
+ ];
1488
+ `;
1489
+ var ESLINT_CONFIG_FILE_GENERATOR5 = new FileGeneratorImp(
1490
+ "eslint.config.mjs",
1491
+ ESLINT_CONFIG5
1492
+ );
1262
1493
 
1263
- // src/link-packages.ts
1264
- import fs4 from "node:fs/promises";
1265
- import path9 from "node:path";
1494
+ // src/packages/react-package/unstyled-react-package/files/index-file-generator.ts
1495
+ var INDEX_TS3 = `export * from './button';
1496
+ `;
1497
+ var INDEX_FILE_GENERATOR5 = new FileGeneratorImp(
1498
+ "src/index.ts",
1499
+ INDEX_TS3
1500
+ );
1266
1501
 
1267
- // src/tsconfig/tsconfig.ts
1268
- import * as JSON52 from "json5";
1269
- import { haveSameItems as haveSameItems2, sortKeys as sortKeys3 } from "@stack-dev/core";
1270
- import { isEqual as isEqual3 } from "lodash";
1502
+ // src/packages/react-package/unstyled-react-package/files/prettier-config-file-generator.ts
1503
+ var PRETTIER_CONFIG5 = `import base from '@stack-dev/prettier-config/base.mjs';
1271
1504
 
1272
- // src/tsconfig/compiler-options.ts
1273
- import { sortKeys as sortKeys2 } from "@stack-dev/core";
1274
- import { isEqual as isEqual2 } from "lodash";
1275
- var CompilerOptions = class _CompilerOptions {
1276
- _additionalData;
1277
- _paths;
1278
- constructor(args) {
1279
- this._paths = args?.paths ?? {};
1280
- this._additionalData = args?.additionalData ?? {};
1281
- }
1282
- get paths() {
1283
- return this._paths;
1284
- }
1285
- get additionalData() {
1286
- return this._additionalData;
1287
- }
1288
- setPaths(paths) {
1289
- return new _CompilerOptions({
1290
- paths,
1291
- additionalData: this._additionalData
1292
- });
1293
- }
1294
- format() {
1295
- const json = {
1296
- paths: this._paths,
1297
- ...this._additionalData
1298
- };
1299
- const ordered = sortKeys2(json, compareKeys);
1300
- return JSON.stringify(ordered, null, 2);
1301
- }
1302
- equals(other) {
1303
- if (other instanceof _CompilerOptions) {
1304
- return isEqual2(this._paths, other._paths) && isEqual2(this._additionalData, other._additionalData);
1305
- } else {
1306
- return false;
1307
- }
1308
- }
1309
- };
1310
- function compareKeys(a, b) {
1311
- return getKeyIndex2(a) - getKeyIndex2(b);
1312
- }
1313
- function getKeyIndex2(s) {
1314
- const order = [
1315
- "target",
1316
- "module",
1317
- "moduleResolution",
1318
- "esModuleInterop",
1319
- "lib",
1320
- "types",
1321
- "strict",
1322
- "allowJs"
1323
- ];
1324
- if (order.every((key) => key !== s)) {
1325
- return Number.MAX_VALUE;
1326
- } else {
1327
- return order.indexOf(s);
1328
- }
1505
+ export default base;
1506
+ `;
1507
+ var PRETTIER_CONFIG_FILE_GENERATOR5 = new FileGeneratorImp(
1508
+ "prettier.config.mjs",
1509
+ PRETTIER_CONFIG5
1510
+ );
1511
+
1512
+ // src/packages/react-package/unstyled-react-package/files/tsconfig-file-generator.ts
1513
+ var TSCONFIG5 = `{
1514
+ "extends": "@stack-dev/typescript-config/tsconfig.react.json",
1515
+ "compilerOptions": {
1516
+ "outDir": "dist"
1517
+ },
1518
+ "include": ["src"]
1329
1519
  }
1520
+ `;
1521
+ var TSCONFIG_FILE_GENERATOR5 = new FileGeneratorImp(
1522
+ "tsconfig.json",
1523
+ TSCONFIG5
1524
+ );
1330
1525
 
1331
- // src/tsconfig/reference.ts
1332
- var Reference = class _Reference {
1333
- _path;
1334
- constructor(path14) {
1335
- this._path = path14;
1336
- }
1337
- get path() {
1338
- return this._path;
1339
- }
1340
- equals(other) {
1341
- if (other instanceof _Reference) {
1342
- return this._path === other._path;
1343
- } else {
1344
- return false;
1345
- }
1346
- }
1347
- };
1526
+ // src/packages/react-package/unstyled-react-package/files/tsup-config-file-generator.ts
1527
+ var TSUP_CONFIG3 = `import { defineConfig } from 'tsup';
1348
1528
 
1349
- // src/tsconfig/tsconfig.ts
1350
- var TSConfig = class _TSConfig {
1351
- _compilerOptions;
1352
- _references;
1353
- _additionalData;
1354
- constructor(args) {
1355
- this._compilerOptions = args?.compilerOptions ?? new CompilerOptions();
1356
- this._references = args?.references ?? [];
1357
- this._additionalData = args?.additionalData ?? {};
1358
- }
1359
- get compilerOptions() {
1360
- return this._compilerOptions;
1361
- }
1362
- addReference(reference) {
1363
- return new _TSConfig({
1364
- compilerOptions: this._compilerOptions,
1365
- references: [...this._references, reference],
1366
- additionalData: this._additionalData
1367
- });
1368
- }
1369
- setCompilerOptions(compilerOptions) {
1370
- return new _TSConfig({
1371
- compilerOptions,
1372
- references: this._references,
1373
- additionalData: this._additionalData
1374
- });
1375
- }
1376
- static parse(s) {
1377
- const json = JSON52.parse(s);
1378
- const references = _TSConfig.parseReferences(json);
1379
- const compilerOptions = new CompilerOptions({
1380
- paths: json.compilerOptions?.paths,
1381
- ...json.compilerOptions
1382
- });
1383
- const additionalData = { ...json };
1384
- delete additionalData["compilerOptions"];
1385
- delete additionalData["references"];
1386
- return new _TSConfig({
1387
- compilerOptions,
1388
- references,
1389
- additionalData
1390
- });
1391
- }
1392
- static parseReferences(json) {
1393
- if (typeof json === "object" && json !== null && "references" in json && json.references instanceof Array) {
1394
- return json.references.map(
1395
- (r) => new Reference(r.path)
1396
- );
1397
- } else {
1398
- return [];
1399
- }
1400
- }
1401
- format() {
1402
- const compilerOptions = JSON52.parse(this.compilerOptions.format());
1403
- const json = {
1404
- compilerOptions,
1405
- references: this._references.map((r) => ({ path: r.path })),
1406
- ...this._additionalData
1529
+ export default defineConfig({
1530
+ entry: ['src/index.ts'],
1531
+ format: ['esm', 'cjs'],
1532
+ dts: true,
1533
+ clean: true,
1534
+ external: ['react', 'react-dom', 'styled-components'],
1535
+ outExtension({ format }) {
1536
+ return {
1537
+ js: format === 'esm' ? '.mjs' : '.js',
1407
1538
  };
1408
- const ordered = sortKeys3(json, compareKeys2);
1409
- return JSON.stringify(ordered, null, 2);
1410
- }
1411
- equals(other) {
1412
- if (other instanceof _TSConfig) {
1413
- const sameReferences = haveSameItems2(
1414
- this._references,
1415
- other._references,
1416
- (r1, r2) => r1.equals(r2)
1417
- );
1418
- return this._compilerOptions.equals(other._compilerOptions) && sameReferences && isEqual3(this._additionalData, other._additionalData);
1419
- } else {
1420
- return false;
1539
+ },
1540
+ });`;
1541
+ var TSUP_CONFIG_FILE_GENERATOR3 = new FileGeneratorImp(
1542
+ "tsup.config.ts",
1543
+ TSUP_CONFIG3
1544
+ );
1545
+
1546
+ // src/packages/react-package/unstyled-react-package/files/vitest-config-file-generator.ts
1547
+ var VITEST_CONFIG5 = `import { defineConfig } from 'vitest/config';
1548
+ import react from '@vitejs/plugin-react';
1549
+
1550
+ export default defineConfig({
1551
+ plugins: [react()],
1552
+ test: {
1553
+ globals: true,
1554
+ environment: 'jsdom',
1555
+ coverage: {
1556
+ provider: 'v8',
1557
+ reporter: ['text', 'json', 'html'],
1558
+ },
1559
+ css: true,
1560
+ },
1561
+ });
1562
+ `;
1563
+ var VITEST_CONFIG_FILE_GENERATOR5 = new FileGeneratorImp(
1564
+ "vitest.config.ts",
1565
+ VITEST_CONFIG5
1566
+ );
1567
+
1568
+ // src/packages/react-package/unstyled-react-package/create-unstyled-react-package.ts
1569
+ async function createUnstyledReactPackage(name) {
1570
+ const rootDir = await getWorkspaceRoot();
1571
+ const directory = path9.join(rootDir, "packages", name);
1572
+ const namespace = await getNamespace(rootDir);
1573
+ const packageName = `${namespace}/${name}`;
1574
+ console.log(`\u2728 Creating Un-styled React library: ${packageName}`);
1575
+ const generator = new PackageGenerator(
1576
+ directory,
1577
+ makePackageGenerator3(packageName, namespace),
1578
+ [
1579
+ INDEX_FILE_GENERATOR5,
1580
+ BUTTON_FILE_GENERATOR2,
1581
+ BUTTON_SPEC_FILE_GENERATOR2,
1582
+ TSUP_CONFIG_FILE_GENERATOR3,
1583
+ TSCONFIG_FILE_GENERATOR5,
1584
+ PRETTIER_CONFIG_FILE_GENERATOR5,
1585
+ ESLINT_CONFIG_FILE_GENERATOR5,
1586
+ VITEST_CONFIG_FILE_GENERATOR5
1587
+ ]
1588
+ );
1589
+ await generator.generate();
1590
+ console.log(`\u2705 Library created at: ${directory}`);
1591
+ }
1592
+ function makePackageGenerator3(packageName, namespace) {
1593
+ const packageJsonModel = new PackageJSON({
1594
+ name: packageName,
1595
+ // Peer deps are crucial for Styled Components to prevent "Multiple instances" errors
1596
+ peerDependencies: [
1597
+ new Dependency("react", ">=18"),
1598
+ new Dependency("react-dom", ">=18")
1599
+ ],
1600
+ devDependencies: [
1601
+ new Dependency(`${namespace}/eslint-config`, "workspace:*"),
1602
+ new Dependency(`${namespace}/prettier-config`, "workspace:*"),
1603
+ new Dependency(`${namespace}/typescript-config`, "workspace:*"),
1604
+ // Development React binaries
1605
+ new Dependency("react", "^18.3.1"),
1606
+ new Dependency("react-dom", "^18.3.1"),
1607
+ new Dependency("@types/react", "^18.3.1"),
1608
+ new Dependency("@types/react-dom", "^18.3.1"),
1609
+ // Linting & Formatting
1610
+ new Dependency("eslint", "^9.32.0"),
1611
+ new Dependency("prettier", "^3.6.2"),
1612
+ new Dependency("prettier-plugin-organize-imports", "^4.2.0"),
1613
+ // Build
1614
+ new Dependency("tsup", "^8.0.0"),
1615
+ // Testing
1616
+ new Dependency("vitest", "^3.2.4"),
1617
+ new Dependency("@vitest/coverage-v8", "^3.2.4"),
1618
+ new Dependency("@testing-library/react", "^16.0.0"),
1619
+ new Dependency("@testing-library/jest-dom", "^6.0.0"),
1620
+ new Dependency("jsdom", "^25.0.0")
1621
+ ],
1622
+ additionalData: {
1623
+ version: "0.1.0",
1624
+ private: true,
1625
+ type: "module",
1626
+ // Added this to ensure ESM consistency
1627
+ main: "dist/index.js",
1628
+ module: "dist/index.mjs",
1629
+ types: "dist/index.d.ts",
1630
+ exports: {
1631
+ ".": {
1632
+ development: "./src/index.ts",
1633
+ import: "./dist/index.mjs",
1634
+ require: "./dist/index.js",
1635
+ types: "./dist/index.d.ts"
1636
+ }
1637
+ // Removed './index.css' as it's no longer produced by Styled Components
1638
+ },
1639
+ scripts: {
1640
+ build: "tsup",
1641
+ dev: "tsup --watch",
1642
+ // Helpful for local lib dev
1643
+ lint: "eslint .",
1644
+ format: "prettier . --write",
1645
+ test: "vitest run",
1646
+ "test:watch": "vitest"
1647
+ },
1648
+ // Set to false or removed because Styled Components are pure JS/TS
1649
+ sideEffects: false
1421
1650
  }
1422
- }
1423
- };
1424
- function compareKeys2(a, b) {
1425
- return getKeyIndex3(a) - getKeyIndex3(b);
1426
- }
1427
- function getKeyIndex3(s) {
1428
- const order = [
1429
- "extends",
1430
- "compilerOptions",
1431
- "include",
1432
- "exclude",
1433
- "references"
1434
- ];
1435
- if (order.every((key) => key !== s)) {
1436
- return Number.MAX_VALUE;
1437
- } else {
1438
- return order.indexOf(s);
1439
- }
1651
+ });
1652
+ return new PackageJsonGenerator(packageJsonModel, namespace);
1440
1653
  }
1441
1654
 
1442
- // src/link-packages.ts
1443
- async function linkPackages(current, target, development) {
1444
- await updatePackageJSON(current, target, development);
1445
- await updateTSConfig(current, target);
1446
- }
1447
- async function updatePackageJSON(current, target, development) {
1448
- const namespace = await getNamespace();
1449
- const packageJSON = await getDirectoryPackageJson(current.directory);
1450
- const updated = addDependency(packageJSON, target, development);
1451
- const packageJSONPath = getPackageJSONPath(current.directory);
1452
- await fs4.writeFile(packageJSONPath, updated.format(namespace));
1453
- }
1454
- function addDependency(packageJSON, target, development) {
1455
- const dependency = new Dependency(target.name, "workspace:*");
1456
- if (development) {
1457
- return packageJSON.addDevDependency(dependency);
1458
- } else {
1459
- return packageJSON.addDependency(dependency);
1655
+ // src/packages/react-package/create-react-package.ts
1656
+ async function createReactPackage(name, style) {
1657
+ switch (style) {
1658
+ case "styled-components":
1659
+ await createStyledComponentsReactPackage(name);
1660
+ break;
1661
+ case "none":
1662
+ await createUnstyledReactPackage(name);
1663
+ break;
1460
1664
  }
1461
1665
  }
1462
- async function updateTSConfig(current, target) {
1463
- const tsconfigPath = path9.join(current.directory, "tsconfig.json");
1464
- const tsconfigContents = await fs4.readFile(tsconfigPath, "utf8");
1465
- const tsconfig = TSConfig.parse(tsconfigContents);
1466
- const targetDirectory = path9.join(target.directory, "src", "index.ts");
1467
- const updatedPaths = {
1468
- ...tsconfig.compilerOptions.paths,
1469
- [target.name]: [path9.relative(current.directory, targetDirectory)]
1470
- };
1471
- const updatedCompilerOptions = tsconfig.compilerOptions.setPaths(updatedPaths);
1472
- const updated = tsconfig.setCompilerOptions(updatedCompilerOptions);
1473
- await fs4.writeFile(tsconfigPath, updated.format());
1474
- }
1475
1666
 
1476
1667
  // src/packages/vite-react-app/create-vite-react-app.ts
1477
1668
  import path10 from "path";
@@ -1552,27 +1743,27 @@ export function App() {
1552
1743
  var APP_FILE_GENERATOR = new FileGeneratorImp("src/App.tsx", APP);
1553
1744
 
1554
1745
  // src/packages/vite-react-app/files/eslint-config-file-generator.ts
1555
- var ESLINT_CONFIG4 = `import base from '@stack-dev/eslint-config/base.mjs';
1746
+ var ESLINT_CONFIG6 = `import base from '@stack-dev/eslint-config/base.mjs';
1556
1747
 
1557
1748
  export default [...base, { ignores: ['**/dist/**'] }];
1558
1749
  `;
1559
- var ESLINT_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
1750
+ var ESLINT_CONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
1560
1751
  "eslint.config.mjs",
1561
- ESLINT_CONFIG4
1752
+ ESLINT_CONFIG6
1562
1753
  );
1563
1754
 
1564
1755
  // src/packages/vite-react-app/files/prettier-config-file-generator.ts
1565
- var PRETTIER_CONFIG4 = `import base from '@stack-dev/prettier-config/base.mjs';
1756
+ var PRETTIER_CONFIG6 = `import base from '@stack-dev/prettier-config/base.mjs';
1566
1757
 
1567
1758
  export default base;
1568
1759
  `;
1569
- var PRETTIER_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
1760
+ var PRETTIER_CONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
1570
1761
  "prettier.config.mjs",
1571
- PRETTIER_CONFIG4
1762
+ PRETTIER_CONFIG6
1572
1763
  );
1573
1764
 
1574
1765
  // src/packages/vite-react-app/files/tsconfig-file-generator.ts
1575
- var TSCONFIG4 = `{
1766
+ var TSCONFIG6 = `{
1576
1767
  "extends": "@stack-dev/typescript-config/tsconfig.react.json",
1577
1768
  "compilerOptions": {
1578
1769
  "outDir": "dist"
@@ -1580,13 +1771,13 @@ var TSCONFIG4 = `{
1580
1771
  "include": ["src"]
1581
1772
  }
1582
1773
  `;
1583
- var TSCONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
1774
+ var TSCONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
1584
1775
  "tsconfig.json",
1585
- TSCONFIG4
1776
+ TSCONFIG6
1586
1777
  );
1587
1778
 
1588
1779
  // src/packages/vite-react-app/files/vitest-config-file-generator.ts
1589
- var VITEST_CONFIG4 = `import { defineConfig } from 'vitest/config';
1780
+ var VITEST_CONFIG6 = `import { defineConfig } from 'vitest/config';
1590
1781
 
1591
1782
  export default defineConfig({
1592
1783
  test: {
@@ -1598,9 +1789,9 @@ export default defineConfig({
1598
1789
  },
1599
1790
  });
1600
1791
  `;
1601
- var VITEST_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
1792
+ var VITEST_CONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
1602
1793
  "vitest.config.ts",
1603
- VITEST_CONFIG4
1794
+ VITEST_CONFIG6
1604
1795
  );
1605
1796
 
1606
1797
  // src/packages/vite-react-app/create-vite-react-app.ts
@@ -1612,21 +1803,21 @@ async function createViteReactApp(name) {
1612
1803
  console.log(`\u{1F680} Creating Vite React App: ${packageName}`);
1613
1804
  const generator = new PackageGenerator(
1614
1805
  directory,
1615
- makeAppPackageGenerator(packageName, namespace),
1806
+ makeAppPackageGenerator3(packageName, namespace),
1616
1807
  [
1617
1808
  VITE_CONFIG_FILE_GENERATOR,
1618
1809
  INDEX_HTML_FILE_GENERATOR,
1619
1810
  MAIN_FILE_GENERATOR,
1620
1811
  APP_FILE_GENERATOR,
1621
- TSCONFIG_FILE_GENERATOR4,
1622
- PRETTIER_CONFIG_FILE_GENERATOR4,
1623
- ESLINT_CONFIG_FILE_GENERATOR4,
1624
- VITEST_CONFIG_FILE_GENERATOR4
1812
+ TSCONFIG_FILE_GENERATOR6,
1813
+ PRETTIER_CONFIG_FILE_GENERATOR6,
1814
+ ESLINT_CONFIG_FILE_GENERATOR6,
1815
+ VITEST_CONFIG_FILE_GENERATOR6
1625
1816
  ]
1626
1817
  );
1627
1818
  await generator.generate();
1628
1819
  }
1629
- function makeAppPackageGenerator(packageName, namespace) {
1820
+ function makeAppPackageGenerator3(packageName, namespace) {
1630
1821
  const packageJsonModel = new PackageJSON({
1631
1822
  name: packageName,
1632
1823
  dependencies: [
@@ -1662,9 +1853,31 @@ function makeAppPackageGenerator(packageName, namespace) {
1662
1853
  return new PackageJsonGenerator(packageJsonModel, namespace);
1663
1854
  }
1664
1855
 
1856
+ // src/packages/create-config-package.ts
1857
+ import path11 from "node:path";
1858
+ async function createConfigPackage(name) {
1859
+ const rootDir = await getWorkspaceRoot();
1860
+ const directory = path11.join(rootDir, "configs", name);
1861
+ const namespace = await getNamespace(rootDir);
1862
+ const packageName = `${namespace}/${name}`;
1863
+ const packageJsonModel = new PackageJSON({
1864
+ name: packageName,
1865
+ additionalData: {
1866
+ version: "0.1.0",
1867
+ private: true
1868
+ }
1869
+ });
1870
+ const generator = new PackageGenerator(
1871
+ directory,
1872
+ new PackageJsonGenerator(packageJsonModel, namespace),
1873
+ []
1874
+ );
1875
+ await generator.generate();
1876
+ }
1877
+
1665
1878
  // src/unlink-packages.ts
1666
1879
  import fs5 from "node:fs/promises";
1667
- import path11 from "node:path";
1880
+ import path12 from "node:path";
1668
1881
  async function unlinkPackages(current, target) {
1669
1882
  await updatePackageJSON2(current, target);
1670
1883
  await updateTSConfig2(current, target);
@@ -1677,7 +1890,7 @@ async function updatePackageJSON2(current, target) {
1677
1890
  await fs5.writeFile(packageJSONPath, updated.format(namespace));
1678
1891
  }
1679
1892
  async function updateTSConfig2(current, target) {
1680
- const tsconfigPath = path11.join(current.directory, "tsconfig.json");
1893
+ const tsconfigPath = path12.join(current.directory, "tsconfig.json");
1681
1894
  const tsconfigContents = await fs5.readFile(tsconfigPath, "utf8");
1682
1895
  const tsconfig = TSConfig.parse(tsconfigContents);
1683
1896
  const updatedPaths = Object.fromEntries(
@@ -1690,9 +1903,156 @@ async function updateTSConfig2(current, target) {
1690
1903
  await fs5.writeFile(tsconfigPath, updated.format());
1691
1904
  }
1692
1905
 
1906
+ // src/utils/package.ts
1907
+ import { glob } from "fast-glob";
1908
+ import path13 from "node:path";
1909
+ async function getCurrentPackage(directory = process.cwd()) {
1910
+ const packageRoot = await getPackageRoot(directory);
1911
+ const packageJson = await getDirectoryPackageJson(packageRoot);
1912
+ return getPackageByName(packageJson.name);
1913
+ }
1914
+ async function getPackageRoot(directory = process.cwd()) {
1915
+ const parent = path13.dirname(directory);
1916
+ if (parent === directory) {
1917
+ throw new Error("Not a package.");
1918
+ }
1919
+ if (await isPackageRoot(directory)) {
1920
+ return directory;
1921
+ }
1922
+ return getPackageRoot(parent);
1923
+ }
1924
+ async function getPackageByName(name) {
1925
+ const all = await getAllPackages();
1926
+ const match = all.find((p) => p.name === name);
1927
+ if (match === void 0) {
1928
+ throw new Error(`No package with name "${name}".`);
1929
+ }
1930
+ return match;
1931
+ }
1932
+ async function getAllPackages(directory = process.cwd()) {
1933
+ const workspaceRoot = await getWorkspaceRoot(directory);
1934
+ const workspaceFile = await getDirectoryWorkspaceFile(workspaceRoot);
1935
+ const results = [];
1936
+ for (const seg of workspaceFile.packages) {
1937
+ const packageType = getPackageType(seg);
1938
+ const packageJsonPaths = await glob(`${workspaceRoot}/${seg}/package.json`);
1939
+ const packageDirectories = packageJsonPaths.map((p) => path13.dirname(p));
1940
+ for (const directory2 of packageDirectories) {
1941
+ const name = (await getDirectoryPackageJson(directory2)).name;
1942
+ results.push({
1943
+ name,
1944
+ directory: directory2,
1945
+ type: packageType
1946
+ });
1947
+ }
1948
+ }
1949
+ return results;
1950
+ }
1951
+ function getPackageType(segment) {
1952
+ if (segment.startsWith("app")) {
1953
+ return "App";
1954
+ } else if (segment.startsWith("config")) {
1955
+ return "Config";
1956
+ } else if (segment.startsWith("package") || segment.startsWith("lib")) {
1957
+ return "Library";
1958
+ } else {
1959
+ return "Unknown";
1960
+ }
1961
+ }
1962
+ function comparePackages(a, b) {
1963
+ const packageTypeDifference = comparePackageTypes(a.type, b.type);
1964
+ if (packageTypeDifference !== 0) {
1965
+ return packageTypeDifference;
1966
+ } else {
1967
+ return a.name.localeCompare(b.name);
1968
+ }
1969
+ }
1970
+ function comparePackageTypes(a, b) {
1971
+ return getPackageTypeIndex(a) - getPackageTypeIndex(b);
1972
+ }
1973
+ function getPackageTypeIndex(packageType) {
1974
+ switch (packageType) {
1975
+ case "Library":
1976
+ return 0;
1977
+ case "Config":
1978
+ return 1;
1979
+ case "App":
1980
+ return 2;
1981
+ case "Unknown":
1982
+ return 3;
1983
+ }
1984
+ }
1985
+ async function isPackageRoot(directory) {
1986
+ return await fileExists(path13.join(directory, "package.json"));
1987
+ }
1988
+
1989
+ // src/utils/package-type.ts
1990
+ import { prompt } from "enquirer";
1991
+ var packageTypes = [
1992
+ "library",
1993
+ "config",
1994
+ "react",
1995
+ "vite",
1996
+ "fastify",
1997
+ "next",
1998
+ "cli"
1999
+ ];
2000
+ async function pickPackageType(options) {
2001
+ if (options?.type && isPackageType(options.type)) {
2002
+ return options.type;
2003
+ } else if (options?.type && !isPackageType(options.type)) {
2004
+ throw new Error(
2005
+ `--type setting "${options.type}" is invalid, must be one of ${packageTypes.join(", ")}.`
2006
+ );
2007
+ }
2008
+ const response = await prompt({
2009
+ type: "select",
2010
+ name: "type",
2011
+ message: "What kind of package do you want?",
2012
+ choices: [...packageTypes]
2013
+ });
2014
+ if (!isPackageType(response.type)) {
2015
+ throw new Error(
2016
+ `Type "${response.type}" is invalid, must be one of ${packageTypes.join(", ")}.`
2017
+ );
2018
+ }
2019
+ return response.type;
2020
+ }
2021
+ function isPackageType(s) {
2022
+ return packageTypes.some((p) => p === s);
2023
+ }
2024
+
2025
+ // src/utils/style-type.ts
2026
+ import { prompt as prompt2 } from "enquirer";
2027
+ var styleTypes = ["styled-components", "none"];
2028
+ async function pickStyleType(options) {
2029
+ if (options?.style && isStyleType(options?.style)) {
2030
+ return options?.style;
2031
+ } else if (options?.style && !isStyleType(options?.style)) {
2032
+ throw new Error(
2033
+ `--style setting "${options.style}" is invalid, must be one of ${styleTypes.join(", ")}.`
2034
+ );
2035
+ }
2036
+ const response = await prompt2({
2037
+ type: "select",
2038
+ name: "type",
2039
+ message: "What kind of style do you want?",
2040
+ choices: [...styleTypes]
2041
+ });
2042
+ if (!isStyleType(response.type)) {
2043
+ throw new Error(
2044
+ `Type "${response.type}" is invalid, must be one of ${styleTypes.join(", ")}.`
2045
+ );
2046
+ }
2047
+ return response.type;
2048
+ }
2049
+ function isStyleType(s) {
2050
+ return styleTypes.some((p) => p === s);
2051
+ }
2052
+
1693
2053
  // src/workspace/create-workspace.ts
1694
2054
  import fs6 from "fs/promises";
1695
- import path13 from "path";
2055
+ import path15 from "path";
1696
2056
 
1697
2057
  // src/workspace/root-package.ts
1698
2058
  async function makeRootPackage(directory, name) {
@@ -1879,7 +2239,7 @@ vite.config.ts.timestamp-*
1879
2239
  `;
1880
2240
 
1881
2241
  // src/workspace/typescript-config.ts
1882
- import path12 from "path";
2242
+ import path14 from "path";
1883
2243
  async function makeTypescriptConfig(directory, namespace) {
1884
2244
  const packageJsonModel = new PackageJSON({
1885
2245
  name: `${namespace}/typescript-config`,
@@ -1890,7 +2250,7 @@ async function makeTypescriptConfig(directory, namespace) {
1890
2250
  files: ["*.json"]
1891
2251
  }
1892
2252
  });
1893
- const fullPath = path12.join(directory, "configs/typescript-config");
2253
+ const fullPath = path14.join(directory, "configs/typescript-config");
1894
2254
  return new PackageGenerator(
1895
2255
  fullPath,
1896
2256
  new PackageJsonGenerator(packageJsonModel, namespace),
@@ -1954,7 +2314,7 @@ var NODE = new FileGeneratorImp(
1954
2314
  async function createWorkspace(name, directory) {
1955
2315
  await validateNotInWorkspace(directory);
1956
2316
  console.log(`\u2728 Creating workspace: @${name}`);
1957
- const fullPath = path13.join(directory, name);
2317
+ const fullPath = path15.join(directory, name);
1958
2318
  await fs6.mkdir(fullPath, { recursive: true });
1959
2319
  const namespace = `@${name}`;
1960
2320
  const PACKAGES = [
@@ -1962,9 +2322,9 @@ async function createWorkspace(name, directory) {
1962
2322
  await makeTypescriptConfig(fullPath, namespace)
1963
2323
  ];
1964
2324
  await Promise.all(PACKAGES.map((p) => p.generate()));
1965
- await fs6.mkdir(path13.join(fullPath, "apps"));
1966
- await fs6.mkdir(path13.join(fullPath, "configs"));
1967
- await fs6.mkdir(path13.join(fullPath, "packages"));
2325
+ await fs6.mkdir(path15.join(fullPath, "apps"));
2326
+ await fs6.mkdir(path15.join(fullPath, "configs"));
2327
+ await fs6.mkdir(path15.join(fullPath, "packages"));
1968
2328
  console.log(`\u2705 Workspace created at: ${fullPath}`);
1969
2329
  console.log("");
1970
2330
  console.log(`Run "cd ${fullPath}" followed by "pnpm install"`);
@@ -2006,8 +2366,10 @@ program.command("g <name>").description("Generate a new package or app").option(
2006
2366
  await createViteReactApp(name);
2007
2367
  break;
2008
2368
  case "cli":
2369
+ await createCliApp(name);
2009
2370
  break;
2010
2371
  case "fastify":
2372
+ await createFastifyApp(name);
2011
2373
  break;
2012
2374
  case "next":
2013
2375
  break;
@@ -2018,7 +2380,7 @@ program.command("g <name>").description("Generate a new package or app").option(
2018
2380
  program.command("link [name]").alias("l").option("-D, --dev", "Whether to link as a devDependency.", false).description("Link to the specified package").action(async (name, options) => {
2019
2381
  name = name ?? await promptForPackageToLinkTo();
2020
2382
  const development = options.dev ?? false;
2021
- if (!isValidPackageName(name)) {
2383
+ if (!await isValidPackageName(name)) {
2022
2384
  throw new Error(`Package name "${name}" is not a valid option.`);
2023
2385
  }
2024
2386
  const current = await getCurrentPackage();