domain-driver 0.1.0 → 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.
Files changed (77) hide show
  1. package/README.md +138 -146
  2. package/dist/commands/action.js +118 -0
  3. package/dist/commands/component.js +18 -19
  4. package/dist/commands/container.js +10 -31
  5. package/dist/commands/controller.js +85 -0
  6. package/dist/commands/feature.js +59 -51
  7. package/dist/commands/hints.js +28 -0
  8. package/dist/commands/hook.js +10 -111
  9. package/dist/commands/repository.js +17 -115
  10. package/dist/commands/resolve.js +61 -0
  11. package/dist/commands/schema.js +22 -69
  12. package/dist/commands/service.js +15 -113
  13. package/dist/commands/sides.js +34 -0
  14. package/dist/commands/target.js +32 -0
  15. package/dist/commands/types.js +9 -17
  16. package/dist/commands/write.js +66 -0
  17. package/dist/index.js +109 -94
  18. package/dist/init/content.js +73 -0
  19. package/dist/init/init.js +60 -0
  20. package/dist/init/markers.js +21 -0
  21. package/dist/postinstall.js +80 -0
  22. package/dist/stack/detect.js +125 -0
  23. package/dist/stack/profiles/nest.js +18 -0
  24. package/dist/stack/profiles/next-frontend.js +28 -0
  25. package/dist/stack/profiles/next-fullstack.js +44 -0
  26. package/dist/stack/profiles/node.js +17 -0
  27. package/dist/stack/profiles/react.js +19 -0
  28. package/dist/stack/registry.js +63 -0
  29. package/dist/stack/types.js +24 -0
  30. package/dist/templates/actions.js +68 -0
  31. package/dist/templates/backend/server-repository.js +22 -0
  32. package/dist/templates/context.js +52 -0
  33. package/dist/templates/controllers/express.js +60 -0
  34. package/dist/templates/controllers/fastify.js +54 -0
  35. package/dist/templates/controllers/generic.js +30 -0
  36. package/dist/templates/controllers/hono.js +52 -0
  37. package/dist/templates/controllers/nest.js +63 -0
  38. package/dist/templates/controllers/next-action-route.js +40 -0
  39. package/dist/templates/controllers/next-route.js +62 -0
  40. package/dist/templates/controllers/node.js +46 -0
  41. package/dist/templates/controllers/shape.js +28 -0
  42. package/dist/templates/frontend/client-repository.js +38 -0
  43. package/dist/templates/frontend/component.js +18 -0
  44. package/dist/templates/frontend/container.js +28 -0
  45. package/{src/commands/hook.ts → dist/templates/frontend/hook.js} +28 -41
  46. package/dist/templates/frontend/page.js +26 -0
  47. package/dist/templates/nest/dto.js +12 -0
  48. package/dist/templates/nest/injectable.js +4 -0
  49. package/dist/templates/nest/module.js +41 -0
  50. package/dist/templates/service.js +40 -0
  51. package/dist/templates/shared/schema.js +13 -0
  52. package/dist/templates/shared/types.js +12 -0
  53. package/dist/templates/signatures.js +15 -0
  54. package/dist/utils/alias.js +80 -0
  55. package/dist/utils/fs.js +70 -0
  56. package/dist/utils/imports.js +61 -0
  57. package/dist/utils/naming.js +31 -0
  58. package/dist/utils/paths.js +44 -0
  59. package/package.json +27 -6
  60. package/scripts/postinstall.js +7 -0
  61. package/.github/workflows/publish.yml +0 -28
  62. package/dist/utils.js +0 -132
  63. package/src/__tests__/utils.test.ts +0 -128
  64. package/src/commands/__tests__/feature.test.ts +0 -85
  65. package/src/commands/__tests__/imports.test.ts +0 -115
  66. package/src/commands/__tests__/individual.test.ts +0 -137
  67. package/src/commands/component.ts +0 -33
  68. package/src/commands/container.ts +0 -42
  69. package/src/commands/feature.ts +0 -74
  70. package/src/commands/repository.ts +0 -95
  71. package/src/commands/schema.ts +0 -47
  72. package/src/commands/service.ts +0 -93
  73. package/src/commands/types.ts +0 -25
  74. package/src/index.ts +0 -126
  75. package/src/utils.ts +0 -115
  76. package/tsconfig.json +0 -13
  77. package/vitest.config.ts +0 -7
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INJECTABLE_IMPORT = void 0;
4
+ exports.INJECTABLE_IMPORT = "import { Injectable } from '@nestjs/common';";
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderModule = renderModule;
4
+ const actions_1 = require("../actions");
5
+ function classNames(entity, suffix) {
6
+ return actions_1.ACTIONS.map((action) => `${action}${entity}${suffix}`);
7
+ }
8
+ function importLines(ctx, fromFile, entity, layer, suffix) {
9
+ return actions_1.ACTIONS.map((action) => {
10
+ const name = `${action}${entity}${suffix}`;
11
+ const target = ctx.importLayer(fromFile, layer, `${action}${entity}.${suffix.toLowerCase()}`);
12
+ return `import { ${name} } from '${target}';`;
13
+ }).join('\n');
14
+ }
15
+ function list(names) {
16
+ if (names.length === 0)
17
+ return '[]';
18
+ return `[\n${names.map((name) => ` ${name},`).join('\n')}\n ]`;
19
+ }
20
+ function renderModule(ctx, entity, fromFile, populated) {
21
+ const controllers = populated ? classNames(entity, 'Controller') : [];
22
+ const providers = populated ? [...classNames(entity, 'Service'), ...classNames(entity, 'Repository')] : [];
23
+ const imports = [
24
+ "import { Module } from '@nestjs/common';",
25
+ ...(populated
26
+ ? [
27
+ importLines(ctx, fromFile, entity, 'controller', 'Controller'),
28
+ importLines(ctx, fromFile, entity, 'serverService', 'Service'),
29
+ importLines(ctx, fromFile, entity, 'serverRepository', 'Repository'),
30
+ ]
31
+ : []),
32
+ ].join('\n');
33
+ return `${imports}
34
+
35
+ @Module({
36
+ controllers: ${list(controllers)},
37
+ providers: ${list(providers)},
38
+ })
39
+ export class ${entity}Module {}
40
+ `;
41
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderService = renderService;
4
+ const injectable_1 = require("./nest/injectable");
5
+ const signatures_1 = require("./signatures");
6
+ function renderService(ctx, spec, entity, fromFile, side) {
7
+ const repositoryClass = `${spec.name}Repository`;
8
+ const serviceClass = `${spec.name}Service`;
9
+ const repositoryLayer = side === 'client' ? 'clientRepository' : 'serverRepository';
10
+ const repositoryPath = ctx.importLayer(fromFile, repositoryLayer, `${spec.name}.repository`);
11
+ const injectable = side === 'server' && ctx.profile.name === 'nest';
12
+ const imports = [
13
+ ...(injectable ? [injectable_1.INJECTABLE_IMPORT] : []),
14
+ ...(0, signatures_1.domainImports)(ctx, fromFile, spec, entity),
15
+ `import { ${repositoryClass} } from '${repositoryPath}';`,
16
+ ].join('\n');
17
+ if (injectable) {
18
+ return `${imports}
19
+
20
+ @Injectable()
21
+ export class ${serviceClass} {
22
+ constructor(private readonly repository: ${repositoryClass}) {}
23
+
24
+ async handle(${spec.params}): ${spec.returns} {
25
+ return this.repository.handle(${spec.args});
26
+ }
27
+ }
28
+ `;
29
+ }
30
+ return `${imports}
31
+
32
+ const repository = new ${repositoryClass}();
33
+
34
+ export class ${serviceClass} {
35
+ async handle(${spec.params}): ${spec.returns} {
36
+ return repository.handle(${spec.args});
37
+ }
38
+ }
39
+ `;
40
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderSchema = renderSchema;
4
+ function renderSchema(name, label) {
5
+ return `import { z } from 'zod';
6
+
7
+ export const ${name}Schema = z.object({
8
+ // add ${label} fields here
9
+ });
10
+
11
+ export type ${name} = z.infer<typeof ${name}Schema>;
12
+ `;
13
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderTypes = renderTypes;
4
+ function renderTypes(entity) {
5
+ return `export interface ${entity} {
6
+ id: string;
7
+ // add ${entity} fields here
8
+ createdAt: string;
9
+ updatedAt: string;
10
+ }
11
+ `;
12
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.domainImports = domainImports;
4
+ function domainImports(ctx, fromFile, spec, entity) {
5
+ const lines = [];
6
+ if (spec.usesEntityType) {
7
+ const typePath = ctx.importLayer(fromFile, 'types', `${entity}.types`);
8
+ lines.push(`import { ${entity} } from '${typePath}';`);
9
+ }
10
+ if (spec.schema !== null) {
11
+ const schemaPath = ctx.importLayer(fromFile, 'schema', `${spec.schema}.schema`);
12
+ lines.push(`import { ${spec.schema} } from '${schemaPath}';`);
13
+ }
14
+ return lines;
15
+ }
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resetAliasCache = resetAliasCache;
37
+ exports.detectAlias = detectAlias;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const WILDCARD_TARGET = /^(?:\.\/)?(.*?)\/?\*$/;
41
+ let cached;
42
+ function resetAliasCache() {
43
+ cached = undefined;
44
+ }
45
+ function detectAlias() {
46
+ if (cached !== undefined)
47
+ return cached;
48
+ cached = readAlias(path.join(process.cwd(), 'tsconfig.json'));
49
+ return cached;
50
+ }
51
+ function readAlias(tsconfigPath) {
52
+ if (!fs.existsSync(tsconfigPath))
53
+ return null;
54
+ try {
55
+ const raw = fs.readFileSync(tsconfigPath, 'utf-8');
56
+ const stripped = raw.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
57
+ const tsconfig = JSON.parse(stripped);
58
+ return findWildcardAlias(tsconfig.compilerOptions?.paths ?? {});
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ function findWildcardAlias(paths) {
65
+ for (const [key, targets] of Object.entries(paths)) {
66
+ if (!key.endsWith('/*'))
67
+ continue;
68
+ const root = targets.map(aliasRoot).find((candidate) => candidate !== null);
69
+ if (root !== undefined && root !== null) {
70
+ return Object.freeze({ prefix: key.slice(0, -1), root });
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+ function aliasRoot(target) {
76
+ const match = WILDCARD_TARGET.exec(target);
77
+ if (!match)
78
+ return null;
79
+ return match[1] === '' ? '.' : match[1];
80
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.writeFileSafe = writeFileSafe;
37
+ exports.mkdirSafe = mkdirSafe;
38
+ exports.fileExists = fileExists;
39
+ exports.isDirectory = isDirectory;
40
+ exports.readTextFile = readTextFile;
41
+ const fs = __importStar(require("fs"));
42
+ function writeFileSafe(filePath, content) {
43
+ try {
44
+ fs.writeFileSync(filePath, content);
45
+ }
46
+ catch (error) {
47
+ const message = error instanceof Error ? error.message : 'Unknown error';
48
+ throw new Error(`Failed to write ${filePath}: ${message}`);
49
+ }
50
+ }
51
+ function mkdirSafe(dirPath) {
52
+ try {
53
+ fs.mkdirSync(dirPath, { recursive: true });
54
+ }
55
+ catch (error) {
56
+ const message = error instanceof Error ? error.message : 'Unknown error';
57
+ throw new Error(`Failed to create directory ${dirPath}: ${message}`);
58
+ }
59
+ }
60
+ function fileExists(filePath) {
61
+ return fs.existsSync(filePath);
62
+ }
63
+ function isDirectory(target) {
64
+ return fs.existsSync(target) && fs.statSync(target).isDirectory();
65
+ }
66
+ function readTextFile(filePath) {
67
+ if (!fs.existsSync(filePath))
68
+ return null;
69
+ return fs.readFileSync(filePath, 'utf-8');
70
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveImport = resolveImport;
37
+ const path = __importStar(require("path"));
38
+ const alias_1 = require("./alias");
39
+ function resolveImport(fromFile, toFile) {
40
+ const target = stripExtension(toFile);
41
+ const aliased = aliasImport(target);
42
+ if (aliased !== null)
43
+ return aliased;
44
+ const relative = toPosix(path.relative(path.dirname(fromFile), target));
45
+ return relative.startsWith('.') ? relative : `./${relative}`;
46
+ }
47
+ function aliasImport(target) {
48
+ const alias = (0, alias_1.detectAlias)();
49
+ if (!alias)
50
+ return null;
51
+ const rootAbs = path.resolve(process.cwd(), alias.root);
52
+ const relative = path.relative(rootAbs, target);
53
+ const inside = relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative);
54
+ return inside ? `${alias.prefix}${toPosix(relative)}` : null;
55
+ }
56
+ function stripExtension(file) {
57
+ return file.replace(/\.tsx?$/, '');
58
+ }
59
+ function toPosix(target) {
60
+ return target.split(path.sep).join('/');
61
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toPascalCase = toPascalCase;
4
+ exports.lowerFirst = lowerFirst;
5
+ exports.validateFeatureName = validateFeatureName;
6
+ exports.upperFirst = upperFirst;
7
+ exports.toKebabCase = toKebabCase;
8
+ const FEATURE_NAME_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
9
+ function toPascalCase(name) {
10
+ return name
11
+ .split('-')
12
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
13
+ .join('');
14
+ }
15
+ function lowerFirst(name) {
16
+ return name.charAt(0).toLowerCase() + name.slice(1);
17
+ }
18
+ function validateFeatureName(name) {
19
+ if (!FEATURE_NAME_PATTERN.test(name)) {
20
+ throw new Error(`Feature name "${name}" must be kebab-case, for example coffee-type.`);
21
+ }
22
+ }
23
+ function upperFirst(name) {
24
+ return name.charAt(0).toUpperCase() + name.slice(1);
25
+ }
26
+ function toKebabCase(name) {
27
+ return name
28
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
29
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
30
+ .toLowerCase();
31
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.featureDir = featureDir;
37
+ exports.apiRouteDir = apiRouteDir;
38
+ const path = __importStar(require("path"));
39
+ function featureDir(stack, feature) {
40
+ return path.join(process.cwd(), stack.featureRoot, feature);
41
+ }
42
+ function apiRouteDir(stack, feature) {
43
+ return path.join(process.cwd(), stack.featureRoot, 'api', feature);
44
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "domain-driver",
3
- "version": "0.1.0",
4
- "description": "CLI scaffolding tool for domain-driven development in Next.js",
5
- "main": "index.js",
3
+ "version": "0.2.0",
4
+ "description": "CLI scaffolding tool for domain-driven feature folders in Next.js, React, Node, and NestJS projects, with per-action files, bespoke actions, and agent guidance",
5
+ "main": "dist/index.js",
6
6
  "bin": {
7
7
  "domain-driver": "./dist/index.js"
8
8
  },
@@ -10,15 +10,36 @@
10
10
  "type": "git",
11
11
  "url": "https://github.com/IsaacHatilima/domain-driver"
12
12
  },
13
+ "files": [
14
+ "dist",
15
+ "scripts/postinstall.js"
16
+ ],
13
17
  "scripts": {
14
- "build": "tsc",
15
- "test": "vitest run"
18
+ "build": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\" && tsc",
19
+ "test": "vitest run",
20
+ "test:coverage": "vitest run --coverage",
21
+ "postinstall": "node ./scripts/postinstall.js"
16
22
  },
17
- "keywords": [],
23
+ "keywords": [
24
+ "cli",
25
+ "scaffolding",
26
+ "domain-driven",
27
+ "nextjs",
28
+ "react",
29
+ "nestjs",
30
+ "node",
31
+ "express",
32
+ "fastify",
33
+ "hono"
34
+ ],
18
35
  "author": "Isaac Hatilima",
19
36
  "license": "MIT",
37
+ "engines": {
38
+ "node": ">=18"
39
+ },
20
40
  "devDependencies": {
21
41
  "@types/node": "^25.4.0",
42
+ "@vitest/coverage-v8": "^4.1.2",
22
43
  "typescript": "^5.9.3",
23
44
  "vitest": "^4.1.2"
24
45
  },
@@ -0,0 +1,7 @@
1
+ // Runs after `npm install` in a consuming project. Never fails the install:
2
+ // dist/ may be absent on a fresh clone, and init may throw for any reason.
3
+ try {
4
+ require('../dist/postinstall.js').run();
5
+ } catch (_error) {
6
+ // intentionally silent
7
+ }
@@ -1,28 +0,0 @@
1
- name: Publish to npm
2
-
3
- on:
4
- push:
5
- branches:
6
- - master
7
- tags:
8
- - 'v*'
9
-
10
- jobs:
11
- publish:
12
- runs-on: ubuntu-latest
13
- permissions:
14
- id-token: write
15
-
16
- steps:
17
- - uses: actions/checkout@v4
18
-
19
- - uses: actions/setup-node@v4
20
- with:
21
- node-version: '18'
22
- registry-url: 'https://registry.npmjs.org'
23
-
24
- - run: npm install
25
- - run: npm run build
26
- - run: npm publish --provenance --access public
27
- env:
28
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/dist/utils.js DELETED
@@ -1,132 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.toPascalCase = toPascalCase;
37
- exports.featureBasePath = featureBasePath;
38
- exports.ensureFeatureExists = ensureFeatureExists;
39
- exports.writeFileSafe = writeFileSafe;
40
- exports.mkdirSafe = mkdirSafe;
41
- exports.fileExists = fileExists;
42
- exports.detectAlias = detectAlias;
43
- exports.resetAliasCache = resetAliasCache;
44
- exports.resolveImport = resolveImport;
45
- const fs = __importStar(require("fs"));
46
- const path = __importStar(require("path"));
47
- function toPascalCase(name) {
48
- return name
49
- .split('-')
50
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
51
- .join('');
52
- }
53
- function featureBasePath(feature) {
54
- return path.join(process.cwd(), 'app', feature);
55
- }
56
- function ensureFeatureExists(feature, subdir) {
57
- const base = path.join(featureBasePath(feature), subdir);
58
- if (!fs.existsSync(base)) {
59
- throw new Error(`Feature "${feature}" does not exist. Run: domain-driver make:feature ${feature}`);
60
- }
61
- return base;
62
- }
63
- function writeFileSafe(filePath, content) {
64
- try {
65
- fs.writeFileSync(filePath, content);
66
- }
67
- catch (error) {
68
- const message = error instanceof Error ? error.message : 'Unknown error';
69
- throw new Error(`Failed to write ${filePath}: ${message}`);
70
- }
71
- }
72
- function mkdirSafe(dirPath) {
73
- try {
74
- fs.mkdirSync(dirPath, { recursive: true });
75
- }
76
- catch (error) {
77
- const message = error instanceof Error ? error.message : 'Unknown error';
78
- throw new Error(`Failed to create directory ${dirPath}: ${message}`);
79
- }
80
- }
81
- function fileExists(filePath) {
82
- return fs.existsSync(filePath);
83
- }
84
- let cachedAlias;
85
- function detectAlias() {
86
- if (cachedAlias)
87
- return cachedAlias;
88
- const tsconfigPath = path.join(process.cwd(), 'tsconfig.json');
89
- if (!fs.existsSync(tsconfigPath)) {
90
- cachedAlias = { alias: null, appDir: 'app' };
91
- return cachedAlias;
92
- }
93
- try {
94
- const raw = fs.readFileSync(tsconfigPath, 'utf-8');
95
- const stripped = raw.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
96
- const tsconfig = JSON.parse(stripped);
97
- const paths = tsconfig?.compilerOptions?.paths;
98
- if (paths) {
99
- for (const [key, values] of Object.entries(paths)) {
100
- const targets = values;
101
- const hasAppMapping = targets.some((v) => v === './app/*' || v === 'app/*' || v === './src/app/*' || v === 'src/app/*');
102
- if (hasAppMapping && key.endsWith('/*')) {
103
- const prefix = key.slice(0, -1);
104
- const appDir = targets[0].replace('/*', '').replace('./', '');
105
- cachedAlias = { alias: prefix, appDir };
106
- return cachedAlias;
107
- }
108
- const hasSrcMapping = targets.some((v) => v === './src/*' || v === 'src/*' || v === './*');
109
- if (hasSrcMapping && key.endsWith('/*')) {
110
- const prefix = key.slice(0, -1);
111
- cachedAlias = { alias: prefix, appDir: 'app' };
112
- return cachedAlias;
113
- }
114
- }
115
- }
116
- }
117
- catch {
118
- // tsconfig parse failed, fall back to relative imports
119
- }
120
- cachedAlias = { alias: null, appDir: 'app' };
121
- return cachedAlias;
122
- }
123
- function resetAliasCache() {
124
- cachedAlias = undefined;
125
- }
126
- function resolveImport(fromFeature, relativePath, fromRoot = false) {
127
- const { alias } = detectAlias();
128
- if (alias) {
129
- return `${alias}app/${fromFeature}/${relativePath}`;
130
- }
131
- return fromRoot ? `./${relativePath}` : `../${relativePath}`;
132
- }