@stack-dev/cli 0.1.7 → 0.2.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.
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +6 -0
- package/dist/index.js +1105 -743
- package/dist/index.mjs +1103 -741
- package/package.json +2 -2
- package/src/index.ts +11 -10
- package/src/packages/cli-app/create-cli-app.ts +74 -0
- package/src/packages/cli-app/files/eslint-config-file-generator.ts +11 -0
- package/src/packages/cli-app/files/index-file-generator.ts +24 -0
- package/src/packages/cli-app/files/prettier-config-file-generator.ts +11 -0
- package/src/packages/cli-app/files/tsconfig-file-generator.ts +15 -0
- package/src/packages/cli-app/files/tsup-file-generator.ts +20 -0
- package/src/packages/cli-app/files/vitest-config-file-generator.ts +19 -0
- package/src/packages/cli-app/index.ts +1 -0
- package/src/packages/fastify-app/create-fastify-app.ts +79 -0
- package/src/packages/fastify-app/files/eslint-config-file-generator.ts +11 -0
- package/src/packages/fastify-app/files/index-file-generator.ts +144 -0
- package/src/packages/fastify-app/files/prettier-config-file-generator.ts +11 -0
- package/src/packages/fastify-app/files/tsconfig-file-generator.ts +15 -0
- package/src/packages/fastify-app/files/tsup-file-generator.ts +20 -0
- package/src/packages/fastify-app/files/vitest-config-file-generator.ts +19 -0
- package/src/packages/fastify-app/index.ts +1 -0
- package/src/packages/index.ts +3 -0
- package/src/packages/react-package/create-react-package.ts +1 -9
- package/src/packages/react-package/styled-components-react-package/create-styled-components-react-package.ts +1 -3
- package/src/packages/react-package/{css-react-package/create-css-react-package.ts → unstyled-react-package/create-unstyled-react-package.ts} +8 -7
- package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/button-file-generator.ts +2 -3
- package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/button-spec-file-generator.ts +0 -10
- package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/tsup-config-file-generator.ts +3 -6
- package/src/packages/vite-react-app/index.ts +1 -0
- package/src/utils/style-type.ts +1 -6
- package/src/packages/react-package/create-unstyled-react-package.ts +0 -3
- package/src/packages/react-package/css-react-package/files/button-css-module-file-generator.ts +0 -16
- /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/eslint-config-file-generator.ts +0 -0
- /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/index-file-generator.ts +0 -0
- /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/prettier-config-file-generator.ts +0 -0
- /package/src/packages/react-package/{css-react-package → unstyled-react-package}/files/tsconfig-file-generator.ts +0 -0
- /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/
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { prompt as prompt3 } from "enquirer";
|
|
6
|
+
|
|
7
|
+
// package.json
|
|
8
|
+
var version = "0.2.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
|
|
313
|
-
|
|
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
|
|
333
|
-
import
|
|
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
|
|
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 =
|
|
351
|
-
const directory =
|
|
352
|
-
await
|
|
353
|
-
await
|
|
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/
|
|
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/
|
|
407
|
-
var
|
|
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
|
-
|
|
415
|
-
var PRETTIER_CONFIG = `import base from '@stack-dev/prettier-config/base.mjs';
|
|
604
|
+
const program = new Command();
|
|
416
605
|
|
|
417
|
-
|
|
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/
|
|
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/
|
|
439
|
-
var
|
|
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: [
|
|
443
|
-
format: [
|
|
444
|
-
dts:
|
|
652
|
+
entry: ["src/index.ts"],
|
|
653
|
+
format: ["esm"],
|
|
654
|
+
dts: false,
|
|
445
655
|
sourcemap: true,
|
|
446
656
|
clean: true,
|
|
447
|
-
target:
|
|
657
|
+
target: "esnext",
|
|
448
658
|
outExtension({ format }) {
|
|
449
659
|
return {
|
|
450
|
-
js: format ===
|
|
660
|
+
js: format === "esm" ? ".mjs" : ".js",
|
|
451
661
|
};
|
|
452
662
|
},
|
|
453
663
|
});
|
|
454
664
|
`;
|
|
455
|
-
var
|
|
456
|
-
"tsup.config.ts",
|
|
457
|
-
TSUP_CONFIG
|
|
458
|
-
);
|
|
665
|
+
var TSUP_FILE_GENERATOR = new FileGeneratorImp("tsup.config.ts", TSUP);
|
|
459
666
|
|
|
460
|
-
// src/packages/
|
|
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/
|
|
479
|
-
async function
|
|
685
|
+
// src/packages/cli-app/create-cli-app.ts
|
|
686
|
+
async function createCliApp(name) {
|
|
480
687
|
const rootDir = await getWorkspaceRoot();
|
|
481
|
-
const directory =
|
|
688
|
+
const directory = path5.join(rootDir, "apps", name);
|
|
482
689
|
const namespace = await getNamespace(rootDir);
|
|
483
690
|
const packageName = `${namespace}/${name}`;
|
|
484
|
-
console.log(`\
|
|
691
|
+
console.log(`\u{1F680} Creating CLI App: ${packageName}`);
|
|
485
692
|
const generator = new PackageGenerator(
|
|
486
693
|
directory,
|
|
487
|
-
|
|
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
|
|
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("
|
|
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
|
-
|
|
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
|
-
|
|
532
|
-
|
|
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/
|
|
544
|
-
|
|
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
|
-
|
|
550
|
-
|
|
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
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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/
|
|
572
|
-
|
|
573
|
-
|
|
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
|
-
|
|
577
|
-
|
|
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
|
-
|
|
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
|
-
|
|
595
|
-
var BUTTON = `import React from 'react';
|
|
596
|
-
import * as styles from './button.module.css';
|
|
790
|
+
registerRoutes();
|
|
597
791
|
|
|
598
|
-
|
|
599
|
-
|
|
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
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
});
|
|
826
|
+
return { result: a + b };
|
|
827
|
+
}
|
|
828
|
+
);
|
|
829
|
+
}
|
|
616
830
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
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
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
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
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
{
|
|
647
|
-
|
|
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
|
-
|
|
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/
|
|
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/
|
|
908
|
+
// src/packages/fastify-app/files/tsconfig-file-generator.ts
|
|
675
909
|
var TSCONFIG2 = `{
|
|
676
|
-
"extends": "@stack-dev/typescript-config/tsconfig.
|
|
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/
|
|
689
|
-
var
|
|
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: [
|
|
693
|
-
format: [
|
|
694
|
-
dts:
|
|
695
|
-
|
|
926
|
+
entry: ["src/index.ts"],
|
|
927
|
+
format: ["esm"],
|
|
928
|
+
dts: false,
|
|
929
|
+
sourcemap: true,
|
|
696
930
|
clean: true,
|
|
697
|
-
|
|
698
|
-
external: ['react', 'react-dom'],
|
|
931
|
+
target: "esnext",
|
|
699
932
|
outExtension({ format }) {
|
|
700
933
|
return {
|
|
701
|
-
js: format ===
|
|
934
|
+
js: format === "esm" ? ".mjs" : ".js",
|
|
702
935
|
};
|
|
703
936
|
},
|
|
704
937
|
});
|
|
705
938
|
`;
|
|
706
|
-
var
|
|
707
|
-
"tsup.config.ts",
|
|
708
|
-
TSUP_CONFIG2
|
|
709
|
-
);
|
|
939
|
+
var TSUP_FILE_GENERATOR2 = new FileGeneratorImp("tsup.config.ts", TSUP2);
|
|
710
940
|
|
|
711
|
-
// src/packages/
|
|
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
|
-
|
|
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/
|
|
734
|
-
async function
|
|
959
|
+
// src/packages/fastify-app/create-fastify-app.ts
|
|
960
|
+
async function createFastifyApp(name) {
|
|
735
961
|
const rootDir = await getWorkspaceRoot();
|
|
736
|
-
const directory =
|
|
962
|
+
const directory = path6.join(rootDir, "apps", name);
|
|
737
963
|
const namespace = await getNamespace(rootDir);
|
|
738
964
|
const packageName = `${namespace}/${name}`;
|
|
739
|
-
console.log(`\
|
|
965
|
+
console.log(`\u{1F680} Creating Fastify App: ${packageName}`);
|
|
740
966
|
const generator = new PackageGenerator(
|
|
741
967
|
directory,
|
|
742
|
-
|
|
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
|
|
980
|
+
function makeAppPackageGenerator2(packageName, namespace) {
|
|
759
981
|
const packageJsonModel = new PackageJSON({
|
|
760
982
|
name: packageName,
|
|
761
983
|
peerDependencies: [
|
|
762
|
-
new Dependency("
|
|
763
|
-
new Dependency("
|
|
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
|
-
|
|
770
|
-
new Dependency("
|
|
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("
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
817
|
-
import
|
|
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
|
-
|
|
840
|
-
|
|
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
|
|
844
|
-
"src/button.tsx",
|
|
845
|
-
BUTTON2
|
|
846
|
-
);
|
|
1029
|
+
var ADD_FILE_GENERATOR = new FileGeneratorImp("src/add.ts", ADD_TS);
|
|
847
1030
|
|
|
848
|
-
// src/packages/
|
|
849
|
-
var
|
|
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
|
-
|
|
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
|
|
1253
|
+
var BUTTON_SPEC_FILE_GENERATOR = new FileGeneratorImp(
|
|
876
1254
|
"src/button.spec.tsx",
|
|
877
|
-
|
|
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
|
|
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
|
|
1270
|
+
var ESLINT_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
|
|
893
1271
|
"eslint.config.mjs",
|
|
894
|
-
|
|
1272
|
+
ESLINT_CONFIG4
|
|
895
1273
|
);
|
|
896
1274
|
|
|
897
1275
|
// src/packages/react-package/styled-components-react-package/files/index-file-generator.ts
|
|
898
|
-
var
|
|
1276
|
+
var INDEX_TS2 = `export * from './button';
|
|
899
1277
|
`;
|
|
900
|
-
var
|
|
1278
|
+
var INDEX_FILE_GENERATOR4 = new FileGeneratorImp(
|
|
901
1279
|
"src/index.ts",
|
|
902
|
-
|
|
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
|
|
1284
|
+
var PRETTIER_CONFIG4 = `import base from '@stack-dev/prettier-config/base.mjs';
|
|
907
1285
|
|
|
908
1286
|
export default base;
|
|
909
1287
|
`;
|
|
910
|
-
var
|
|
1288
|
+
var PRETTIER_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
|
|
911
1289
|
"prettier.config.mjs",
|
|
912
|
-
|
|
1290
|
+
PRETTIER_CONFIG4
|
|
913
1291
|
);
|
|
914
1292
|
|
|
915
1293
|
// src/packages/react-package/styled-components-react-package/files/tsconfig-file-generator.ts
|
|
916
|
-
var
|
|
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
|
|
1302
|
+
var TSCONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
|
|
925
1303
|
"tsconfig.json",
|
|
926
|
-
|
|
1304
|
+
TSCONFIG4
|
|
927
1305
|
);
|
|
928
1306
|
|
|
929
1307
|
// src/packages/react-package/styled-components-react-package/files/tsup-config-file-generator.ts
|
|
930
|
-
var
|
|
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
|
|
1322
|
+
var TSUP_CONFIG_FILE_GENERATOR2 = new FileGeneratorImp(
|
|
945
1323
|
"tsup.config.ts",
|
|
946
|
-
|
|
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
|
|
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
|
|
1344
|
+
var VITEST_CONFIG_FILE_GENERATOR4 = new FileGeneratorImp(
|
|
967
1345
|
"vitest.config.ts",
|
|
968
|
-
|
|
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 =
|
|
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
|
-
|
|
1358
|
+
makePackageGenerator2(packageName, namespace),
|
|
983
1359
|
[
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
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
|
|
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
|
-
|
|
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/
|
|
1083
|
-
import
|
|
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
|
-
|
|
1105
|
-
|
|
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/
|
|
1188
|
-
import {
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
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
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
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
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
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/
|
|
1257
|
-
|
|
1258
|
-
import
|
|
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
|
-
|
|
1261
|
-
|
|
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/
|
|
1264
|
-
|
|
1265
|
-
|
|
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/
|
|
1268
|
-
|
|
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
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
}
|
|
1285
|
-
|
|
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/
|
|
1332
|
-
var
|
|
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
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
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
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
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/
|
|
1443
|
-
async function
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
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
|
|
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
|
|
1750
|
+
var ESLINT_CONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
|
|
1560
1751
|
"eslint.config.mjs",
|
|
1561
|
-
|
|
1752
|
+
ESLINT_CONFIG6
|
|
1562
1753
|
);
|
|
1563
1754
|
|
|
1564
1755
|
// src/packages/vite-react-app/files/prettier-config-file-generator.ts
|
|
1565
|
-
var
|
|
1756
|
+
var PRETTIER_CONFIG6 = `import base from '@stack-dev/prettier-config/base.mjs';
|
|
1566
1757
|
|
|
1567
1758
|
export default base;
|
|
1568
1759
|
`;
|
|
1569
|
-
var
|
|
1760
|
+
var PRETTIER_CONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
|
|
1570
1761
|
"prettier.config.mjs",
|
|
1571
|
-
|
|
1762
|
+
PRETTIER_CONFIG6
|
|
1572
1763
|
);
|
|
1573
1764
|
|
|
1574
1765
|
// src/packages/vite-react-app/files/tsconfig-file-generator.ts
|
|
1575
|
-
var
|
|
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
|
|
1774
|
+
var TSCONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
|
|
1584
1775
|
"tsconfig.json",
|
|
1585
|
-
|
|
1776
|
+
TSCONFIG6
|
|
1586
1777
|
);
|
|
1587
1778
|
|
|
1588
1779
|
// src/packages/vite-react-app/files/vitest-config-file-generator.ts
|
|
1589
|
-
var
|
|
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
|
|
1792
|
+
var VITEST_CONFIG_FILE_GENERATOR6 = new FileGeneratorImp(
|
|
1602
1793
|
"vitest.config.ts",
|
|
1603
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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(
|
|
1966
|
-
await fs6.mkdir(
|
|
1967
|
-
await fs6.mkdir(
|
|
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();
|