@solid-stack/mason 1.0.11 → 1.0.12
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/dist/bin.cjs +158 -93
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +157 -92
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +160 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +158 -93
- package/dist/index.js.map +1 -1
- package/dist/utils/registry.d.ts +18 -0
- package/dist/utils/registry.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var fs3 = require('fs');
|
|
4
|
-
var
|
|
4
|
+
var path3 = require('path');
|
|
5
5
|
var p4 = require('@clack/prompts');
|
|
6
6
|
var pc13 = require('picocolors');
|
|
7
7
|
var url = require('url');
|
|
@@ -31,7 +31,7 @@ function _interopNamespace(e) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
var fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
34
|
-
var
|
|
34
|
+
var path3__default = /*#__PURE__*/_interopDefault(path3);
|
|
35
35
|
var p4__namespace = /*#__PURE__*/_interopNamespace(p4);
|
|
36
36
|
var pc13__default = /*#__PURE__*/_interopDefault(pc13);
|
|
37
37
|
var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
|
|
@@ -104,7 +104,7 @@ function isValidIdentifier(str) {
|
|
|
104
104
|
}
|
|
105
105
|
function writeFileSafely(absolutePath, content, options = {}) {
|
|
106
106
|
const projectRoot = options.projectRoot || process.cwd();
|
|
107
|
-
const relPath =
|
|
107
|
+
const relPath = path3__default.default.relative(projectRoot, absolutePath).replace(/\\/g, "/");
|
|
108
108
|
const existedBefore = fs3__default.default.existsSync(absolutePath);
|
|
109
109
|
if (options.dryRun) {
|
|
110
110
|
return {
|
|
@@ -124,7 +124,7 @@ function writeFileSafely(absolutePath, content, options = {}) {
|
|
|
124
124
|
existedBefore: true
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
|
-
const dir =
|
|
127
|
+
const dir = path3__default.default.dirname(absolutePath);
|
|
128
128
|
if (!fs3__default.default.existsSync(dir)) {
|
|
129
129
|
fs3__default.default.mkdirSync(dir, { recursive: true });
|
|
130
130
|
}
|
|
@@ -155,20 +155,20 @@ function printGeneratedFiles(files, isDryRun = false) {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
function findProjectRoot(startDir = process.cwd()) {
|
|
158
|
-
let current =
|
|
158
|
+
let current = path3__default.default.resolve(startDir);
|
|
159
159
|
while (true) {
|
|
160
|
-
if (fs3__default.default.existsSync(
|
|
160
|
+
if (fs3__default.default.existsSync(path3__default.default.join(current, "package.json"))) {
|
|
161
161
|
return current;
|
|
162
162
|
}
|
|
163
|
-
const parent =
|
|
163
|
+
const parent = path3__default.default.dirname(current);
|
|
164
164
|
if (parent === current) {
|
|
165
|
-
return
|
|
165
|
+
return path3__default.default.resolve(startDir);
|
|
166
166
|
}
|
|
167
167
|
current = parent;
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
function resolveFeaturesDir(projectRoot) {
|
|
171
|
-
return
|
|
171
|
+
return path3__default.default.join(projectRoot, "features");
|
|
172
172
|
}
|
|
173
173
|
function listExistingFeatures(projectRoot) {
|
|
174
174
|
const featuresDir = resolveFeaturesDir(projectRoot);
|
|
@@ -184,14 +184,14 @@ function listDomainInterfaces(projectRoot, featureName) {
|
|
|
184
184
|
const results = [];
|
|
185
185
|
const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
|
|
186
186
|
for (const feat of features) {
|
|
187
|
-
const domainDir =
|
|
187
|
+
const domainDir = path3__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
|
|
188
188
|
if (!fs3__default.default.existsSync(domainDir)) continue;
|
|
189
189
|
try {
|
|
190
190
|
const files = fs3__default.default.readdirSync(domainDir);
|
|
191
191
|
for (const file of files) {
|
|
192
192
|
if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.endsWith(".d.ts")) {
|
|
193
193
|
const name = file.replace(/\.ts$/, "");
|
|
194
|
-
const fullPath =
|
|
194
|
+
const fullPath = path3__default.default.join(domainDir, file);
|
|
195
195
|
if (/^I[A-Z]/.test(name)) {
|
|
196
196
|
results.push({
|
|
197
197
|
name,
|
|
@@ -222,7 +222,7 @@ function listDomainEntities(projectRoot, featureName) {
|
|
|
222
222
|
const results = [];
|
|
223
223
|
const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
|
|
224
224
|
for (const feat of features) {
|
|
225
|
-
const domainDir =
|
|
225
|
+
const domainDir = path3__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
|
|
226
226
|
if (!fs3__default.default.existsSync(domainDir)) continue;
|
|
227
227
|
try {
|
|
228
228
|
const files = fs3__default.default.readdirSync(domainDir);
|
|
@@ -232,7 +232,7 @@ function listDomainEntities(projectRoot, featureName) {
|
|
|
232
232
|
if (!/^I[A-Z]/.test(name)) {
|
|
233
233
|
results.push({
|
|
234
234
|
name,
|
|
235
|
-
fullPath:
|
|
235
|
+
fullPath: path3__default.default.join(domainDir, file),
|
|
236
236
|
feature: feat
|
|
237
237
|
});
|
|
238
238
|
}
|
|
@@ -247,7 +247,7 @@ function listUseCases(projectRoot, featureName) {
|
|
|
247
247
|
const results = [];
|
|
248
248
|
const features = featureName ? [featureName] : listExistingFeatures(projectRoot);
|
|
249
249
|
for (const feat of features) {
|
|
250
|
-
const useCasesDir =
|
|
250
|
+
const useCasesDir = path3__default.default.join(resolveFeaturesDir(projectRoot), feat, "useCases");
|
|
251
251
|
if (!fs3__default.default.existsSync(useCasesDir)) continue;
|
|
252
252
|
try {
|
|
253
253
|
const files = fs3__default.default.readdirSync(useCasesDir);
|
|
@@ -256,7 +256,7 @@ function listUseCases(projectRoot, featureName) {
|
|
|
256
256
|
const name = file.replace(/\.ts$/, "");
|
|
257
257
|
results.push({
|
|
258
258
|
name,
|
|
259
|
-
fullPath:
|
|
259
|
+
fullPath: path3__default.default.join(useCasesDir, file),
|
|
260
260
|
feature: feat
|
|
261
261
|
});
|
|
262
262
|
}
|
|
@@ -352,40 +352,105 @@ async function promptProperties(options = {}) {
|
|
|
352
352
|
return properties;
|
|
353
353
|
}
|
|
354
354
|
var DEFAULT_REGISTRY_BASE = "https://raw.githubusercontent.com/solid-stack-digital/mason-registry/main";
|
|
355
|
+
function normalizeRegistryUrl(urlOrPath, baseDir) {
|
|
356
|
+
let trimmed = urlOrPath.trim();
|
|
357
|
+
const gitSshRegex = /^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/;
|
|
358
|
+
const sshMatch = trimmed.match(gitSshRegex);
|
|
359
|
+
if (sshMatch && sshMatch[1] && sshMatch[2]) {
|
|
360
|
+
return `https://raw.githubusercontent.com/${sshMatch[1]}/${sshMatch[2]}/main`;
|
|
361
|
+
}
|
|
362
|
+
const githubWebRegex = /^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/([^/]+))?\/?$/;
|
|
363
|
+
const webMatch = trimmed.match(githubWebRegex);
|
|
364
|
+
if (webMatch && webMatch[1] && webMatch[2]) {
|
|
365
|
+
const owner = webMatch[1];
|
|
366
|
+
const repo = webMatch[2];
|
|
367
|
+
const branch = webMatch[3] || "main";
|
|
368
|
+
return `https://raw.githubusercontent.com/${owner}/${repo}/${branch}`;
|
|
369
|
+
}
|
|
370
|
+
if (baseDir && (trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed === "." || trimmed === "..")) {
|
|
371
|
+
return path3__default.default.resolve(baseDir, trimmed);
|
|
372
|
+
}
|
|
373
|
+
return trimmed;
|
|
374
|
+
}
|
|
375
|
+
function findLocalRegistry(startDir = process.cwd()) {
|
|
376
|
+
let current = path3__default.default.resolve(startDir);
|
|
377
|
+
while (true) {
|
|
378
|
+
const candidate = path3__default.default.join(current, "mason-registry");
|
|
379
|
+
if (fs3__default.default.existsSync(candidate) && fs3__default.default.existsSync(path3__default.default.join(candidate, "index.json"))) {
|
|
380
|
+
return candidate;
|
|
381
|
+
}
|
|
382
|
+
const parent = path3__default.default.dirname(current);
|
|
383
|
+
if (parent === current) break;
|
|
384
|
+
current = parent;
|
|
385
|
+
}
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
355
388
|
function getRegistryBase(projectRoot, override) {
|
|
389
|
+
const rootDir = projectRoot ? path3__default.default.resolve(projectRoot) : process.cwd();
|
|
356
390
|
if (override && override.trim()) {
|
|
357
|
-
return override.trim();
|
|
391
|
+
return normalizeRegistryUrl(override.trim(), rootDir);
|
|
358
392
|
}
|
|
359
393
|
if (process.env.MASON_REGISTRY_URL && process.env.MASON_REGISTRY_URL.trim()) {
|
|
360
|
-
return process.env.MASON_REGISTRY_URL.trim();
|
|
394
|
+
return normalizeRegistryUrl(process.env.MASON_REGISTRY_URL.trim(), rootDir);
|
|
361
395
|
}
|
|
362
|
-
|
|
363
|
-
|
|
396
|
+
const configLocations = [
|
|
397
|
+
path3__default.default.join(rootDir, "mason.config.json"),
|
|
398
|
+
path3__default.default.join(process.cwd(), "mason.config.json")
|
|
399
|
+
];
|
|
400
|
+
for (const configPath of configLocations) {
|
|
364
401
|
if (fs3__default.default.existsSync(configPath)) {
|
|
365
402
|
try {
|
|
366
403
|
const config = JSON.parse(fs3__default.default.readFileSync(configPath, "utf-8"));
|
|
367
404
|
if (config.registry && typeof config.registry === "string") {
|
|
368
|
-
return config.registry.trim();
|
|
405
|
+
return normalizeRegistryUrl(config.registry.trim(), path3__default.default.dirname(configPath));
|
|
369
406
|
}
|
|
370
407
|
} catch {
|
|
371
408
|
}
|
|
372
409
|
}
|
|
373
410
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
411
|
+
const pkgLocations = [
|
|
412
|
+
path3__default.default.join(rootDir, "package.json"),
|
|
413
|
+
path3__default.default.join(process.cwd(), "package.json")
|
|
414
|
+
];
|
|
415
|
+
for (const pkgPath of pkgLocations) {
|
|
416
|
+
if (fs3__default.default.existsSync(pkgPath)) {
|
|
417
|
+
try {
|
|
418
|
+
const pkg = JSON.parse(fs3__default.default.readFileSync(pkgPath, "utf-8"));
|
|
419
|
+
if (pkg.mason?.registry && typeof pkg.mason.registry === "string") {
|
|
420
|
+
return normalizeRegistryUrl(pkg.mason.registry.trim(), path3__default.default.dirname(pkgPath));
|
|
421
|
+
}
|
|
422
|
+
} catch {
|
|
423
|
+
}
|
|
378
424
|
}
|
|
379
425
|
}
|
|
426
|
+
const localRegistry = findLocalRegistry(rootDir);
|
|
427
|
+
if (localRegistry) {
|
|
428
|
+
return localRegistry;
|
|
429
|
+
}
|
|
380
430
|
return DEFAULT_REGISTRY_BASE;
|
|
381
431
|
}
|
|
382
432
|
async function fetchRegistryFile(registryBase, relPath) {
|
|
383
433
|
const cleanRelPath = relPath.replace(/^\/+/, "");
|
|
384
434
|
if (registryBase.startsWith("http://") || registryBase.startsWith("https://")) {
|
|
385
435
|
const url = `${registryBase.replace(/\/+$/, "")}/${cleanRelPath}`;
|
|
386
|
-
const
|
|
436
|
+
const headers = {};
|
|
437
|
+
const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
|
|
438
|
+
if (token) {
|
|
439
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
440
|
+
}
|
|
441
|
+
const res = await fetch(url, { headers });
|
|
387
442
|
if (!res.ok) {
|
|
388
|
-
|
|
443
|
+
let extraHint = "";
|
|
444
|
+
if (res.status === 404) {
|
|
445
|
+
extraHint = `
|
|
446
|
+
Possible reasons:
|
|
447
|
+
\u2022 If using a private GitHub repository, ensure GITHUB_TOKEN is set in your environment.
|
|
448
|
+
\u2022 If your registry has not yet been pushed to GitHub, point to your local directory:
|
|
449
|
+
- CLI flag: mason import ... --registry /path/to/mason-registry
|
|
450
|
+
- Environment: export MASON_REGISTRY_URL=/path/to/mason-registry
|
|
451
|
+
- Config file: Create mason.config.json with { "registry": "/path/to/mason-registry" }`;
|
|
452
|
+
}
|
|
453
|
+
throw new Error(`Failed to fetch ${cleanRelPath} from ${url} (HTTP ${res.status}: ${res.statusText})${extraHint}`);
|
|
389
454
|
}
|
|
390
455
|
return await res.text();
|
|
391
456
|
}
|
|
@@ -393,7 +458,7 @@ async function fetchRegistryFile(registryBase, relPath) {
|
|
|
393
458
|
if (baseDir.startsWith("file://")) {
|
|
394
459
|
baseDir = url.fileURLToPath(baseDir);
|
|
395
460
|
}
|
|
396
|
-
const filePath =
|
|
461
|
+
const filePath = path3__default.default.resolve(baseDir, cleanRelPath);
|
|
397
462
|
if (!fs3__default.default.existsSync(filePath)) {
|
|
398
463
|
throw new Error(`Registry file not found at ${filePath}`);
|
|
399
464
|
}
|
|
@@ -459,14 +524,14 @@ function findClosestMatch(target, candidates) {
|
|
|
459
524
|
return null;
|
|
460
525
|
}
|
|
461
526
|
function detectPackageManager(projectRoot) {
|
|
462
|
-
if (fs3__default.default.existsSync(
|
|
463
|
-
if (fs3__default.default.existsSync(
|
|
464
|
-
if (fs3__default.default.existsSync(
|
|
527
|
+
if (fs3__default.default.existsSync(path3__default.default.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
528
|
+
if (fs3__default.default.existsSync(path3__default.default.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
529
|
+
if (fs3__default.default.existsSync(path3__default.default.join(projectRoot, "bun.lockb")) || fs3__default.default.existsSync(path3__default.default.join(projectRoot, "bun.lock"))) return "bun";
|
|
465
530
|
return "npm";
|
|
466
531
|
}
|
|
467
532
|
function getMissingNpmPackages(projectRoot, requiredPackages) {
|
|
468
533
|
if (!requiredPackages || requiredPackages.length === 0) return [];
|
|
469
|
-
const pkgJsonPath =
|
|
534
|
+
const pkgJsonPath = path3__default.default.join(projectRoot, "package.json");
|
|
470
535
|
if (!fs3__default.default.existsSync(pkgJsonPath)) {
|
|
471
536
|
return requiredPackages;
|
|
472
537
|
}
|
|
@@ -528,30 +593,30 @@ function getTemplatesDir() {
|
|
|
528
593
|
if (cachedTemplatesDir && fs3__default.default.existsSync(cachedTemplatesDir)) {
|
|
529
594
|
return cachedTemplatesDir;
|
|
530
595
|
}
|
|
531
|
-
const currentDir = typeof __dirname !== "undefined" ? __dirname :
|
|
532
|
-
const cand1 =
|
|
596
|
+
const currentDir = typeof __dirname !== "undefined" ? __dirname : path3__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
597
|
+
const cand1 = path3__default.default.resolve(currentDir, "../../templates");
|
|
533
598
|
if (fs3__default.default.existsSync(cand1)) {
|
|
534
599
|
cachedTemplatesDir = cand1;
|
|
535
600
|
return cand1;
|
|
536
601
|
}
|
|
537
|
-
const cand2 =
|
|
602
|
+
const cand2 = path3__default.default.resolve(currentDir, "../templates");
|
|
538
603
|
if (fs3__default.default.existsSync(cand2)) {
|
|
539
604
|
cachedTemplatesDir = cand2;
|
|
540
605
|
return cand2;
|
|
541
606
|
}
|
|
542
|
-
const cand3 =
|
|
607
|
+
const cand3 = path3__default.default.resolve(currentDir, "templates");
|
|
543
608
|
if (fs3__default.default.existsSync(cand3)) {
|
|
544
609
|
cachedTemplatesDir = cand3;
|
|
545
610
|
return cand3;
|
|
546
611
|
}
|
|
547
612
|
let curr = currentDir;
|
|
548
613
|
while (true) {
|
|
549
|
-
const candTemplates =
|
|
614
|
+
const candTemplates = path3__default.default.join(curr, "templates");
|
|
550
615
|
if (fs3__default.default.existsSync(candTemplates)) {
|
|
551
616
|
cachedTemplatesDir = candTemplates;
|
|
552
617
|
return candTemplates;
|
|
553
618
|
}
|
|
554
|
-
const parent =
|
|
619
|
+
const parent = path3__default.default.dirname(curr);
|
|
555
620
|
if (parent === curr) break;
|
|
556
621
|
curr = parent;
|
|
557
622
|
}
|
|
@@ -559,7 +624,7 @@ function getTemplatesDir() {
|
|
|
559
624
|
}
|
|
560
625
|
var templateCache = /* @__PURE__ */ new Map();
|
|
561
626
|
function loadTemplate(relativePath) {
|
|
562
|
-
const fullPath =
|
|
627
|
+
const fullPath = path3__default.default.isAbsolute(relativePath) ? relativePath : path3__default.default.join(getTemplatesDir(), relativePath);
|
|
563
628
|
return fs3__default.default.readFileSync(fullPath, "utf-8");
|
|
564
629
|
}
|
|
565
630
|
function renderTemplateFile(relativePath, context) {
|
|
@@ -645,8 +710,8 @@ function generateDomainEntityCode(name, kind = "interface", properties = []) {
|
|
|
645
710
|
function generateDomain(options) {
|
|
646
711
|
const projectRoot = options.projectRoot || findProjectRoot();
|
|
647
712
|
const entityName = toPascalCase(options.name);
|
|
648
|
-
const targetDir = options.targetDir ||
|
|
649
|
-
const filePath =
|
|
713
|
+
const targetDir = options.targetDir || path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
|
|
714
|
+
const filePath = path3__default.default.join(targetDir, `${entityName}.ts`);
|
|
650
715
|
const code = generateDomainEntityCode(
|
|
651
716
|
entityName,
|
|
652
717
|
options.kind || "interface",
|
|
@@ -695,8 +760,8 @@ function generateInterfaceCode(ifaceName, kind = "abstractClass", entityName, me
|
|
|
695
760
|
function generateInterface(options) {
|
|
696
761
|
const projectRoot = options.projectRoot || findProjectRoot();
|
|
697
762
|
const ifaceName = ensureInterfacePrefix(options.name);
|
|
698
|
-
const targetDir = options.targetDir ||
|
|
699
|
-
const filePath =
|
|
763
|
+
const targetDir = options.targetDir || path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "domain");
|
|
764
|
+
const filePath = path3__default.default.join(targetDir, `${ifaceName}.ts`);
|
|
700
765
|
const code = generateInterfaceCode(
|
|
701
766
|
ifaceName,
|
|
702
767
|
options.kind || "abstractClass",
|
|
@@ -941,21 +1006,21 @@ function findInterfaceFile(projectRoot, ifaceName, featureName, customPath) {
|
|
|
941
1006
|
];
|
|
942
1007
|
const features = featureName ? [featureName, ...listExistingFeatures(projectRoot).filter((f) => f !== featureName)] : listExistingFeatures(projectRoot);
|
|
943
1008
|
for (const feat of features) {
|
|
944
|
-
const domainDir =
|
|
1009
|
+
const domainDir = path3__default.default.join(resolveFeaturesDir(projectRoot), feat, "domain");
|
|
945
1010
|
if (!fs3__default.default.existsSync(domainDir)) continue;
|
|
946
1011
|
for (const cand of candidateNames) {
|
|
947
|
-
const p1 =
|
|
1012
|
+
const p1 = path3__default.default.join(domainDir, `${cand}.ts`);
|
|
948
1013
|
if (fs3__default.default.existsSync(p1)) {
|
|
949
1014
|
return { filePath: p1, ifaceName: cand, feature: feat };
|
|
950
1015
|
}
|
|
951
1016
|
}
|
|
952
1017
|
}
|
|
953
1018
|
for (const cand of candidateNames) {
|
|
954
|
-
const p1 =
|
|
1019
|
+
const p1 = path3__default.default.join(projectRoot, "domain", `${cand}.ts`);
|
|
955
1020
|
if (fs3__default.default.existsSync(p1)) return { filePath: p1, ifaceName: cand };
|
|
956
|
-
const p22 =
|
|
1021
|
+
const p22 = path3__default.default.join(projectRoot, "src", "domain", `${cand}.ts`);
|
|
957
1022
|
if (fs3__default.default.existsSync(p22)) return { filePath: p22, ifaceName: cand };
|
|
958
|
-
const p32 =
|
|
1023
|
+
const p32 = path3__default.default.join(projectRoot, "interfaces", `${cand}.ts`);
|
|
959
1024
|
if (fs3__default.default.existsSync(p32)) return { filePath: p32, ifaceName: cand };
|
|
960
1025
|
}
|
|
961
1026
|
return null;
|
|
@@ -1055,7 +1120,7 @@ function generateStubCode(stubClassName, ifaceName, entityName, featureName, met
|
|
|
1055
1120
|
const entitiesVar = `${entityVar}s`;
|
|
1056
1121
|
const idKey = `${entityVar}Id`;
|
|
1057
1122
|
const impPath = ifaceImportPath || `../domain/${ifaceName}.js`;
|
|
1058
|
-
const entityImportPath = ifaceImportPath ? `${
|
|
1123
|
+
const entityImportPath = ifaceImportPath ? `${path3__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
|
|
1059
1124
|
const importsByFrom = /* @__PURE__ */ new Map();
|
|
1060
1125
|
for (const imp of domainImports) {
|
|
1061
1126
|
if (imp.name === ifaceName || imp.name === baseEntity) continue;
|
|
@@ -1104,7 +1169,7 @@ function generateConcreteInfraCode(className, ifaceName, dependencies = [], meth
|
|
|
1104
1169
|
if (baseEntity) {
|
|
1105
1170
|
finalMethods = synthesizeCrudMethods(baseEntity);
|
|
1106
1171
|
if (!finalDomainImports.some((imp) => imp.name === baseEntity)) {
|
|
1107
|
-
const importPath = ifaceImportPath ? `${
|
|
1172
|
+
const importPath = ifaceImportPath ? `${path3__default.default.dirname(ifaceImportPath)}/${baseEntity}.js` : `../domain/${baseEntity}.js`;
|
|
1108
1173
|
finalDomainImports.push({
|
|
1109
1174
|
name: baseEntity,
|
|
1110
1175
|
from: importPath,
|
|
@@ -1149,8 +1214,8 @@ function generateInfrastructure(options) {
|
|
|
1149
1214
|
const projectRoot = options.projectRoot || findProjectRoot();
|
|
1150
1215
|
const className = toPascalCase(options.name);
|
|
1151
1216
|
const isFeatureScope = options.scope !== "global" && Boolean(options.feature);
|
|
1152
|
-
const targetDir = options.targetDir || (isFeatureScope ?
|
|
1153
|
-
const filePath =
|
|
1217
|
+
const targetDir = options.targetDir || (isFeatureScope ? path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "infrastructure") : path3__default.default.join(projectRoot, "infrastructure"));
|
|
1218
|
+
const filePath = path3__default.default.join(targetDir, `${className}.ts`);
|
|
1154
1219
|
let code;
|
|
1155
1220
|
if (options.implementsInterface) {
|
|
1156
1221
|
const rawIfaceName = options.implementsInterface;
|
|
@@ -1164,7 +1229,7 @@ function generateInfrastructure(options) {
|
|
|
1164
1229
|
const ifaceFilePath = hierarchy.ifaceFilePath;
|
|
1165
1230
|
let ifaceImportPath;
|
|
1166
1231
|
if (ifaceFilePath) {
|
|
1167
|
-
let rel =
|
|
1232
|
+
let rel = path3__default.default.relative(targetDir, ifaceFilePath).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
1168
1233
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
1169
1234
|
ifaceImportPath = rel;
|
|
1170
1235
|
} else if (isFeatureScope) {
|
|
@@ -1177,8 +1242,8 @@ function generateInfrastructure(options) {
|
|
|
1177
1242
|
if (new RegExp(`\\b${item.name}\\b`).test(allSignatures)) {
|
|
1178
1243
|
let fromPath;
|
|
1179
1244
|
if (imp.specifier.startsWith(".") && ifaceFilePath) {
|
|
1180
|
-
const absTarget =
|
|
1181
|
-
let rel =
|
|
1245
|
+
const absTarget = path3__default.default.resolve(path3__default.default.dirname(ifaceFilePath), imp.specifier);
|
|
1246
|
+
let rel = path3__default.default.relative(targetDir, absTarget).replace(/\\/g, "/");
|
|
1182
1247
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
1183
1248
|
fromPath = rel;
|
|
1184
1249
|
} else {
|
|
@@ -1365,8 +1430,8 @@ function generateUseCase(options) {
|
|
|
1365
1430
|
const files = [];
|
|
1366
1431
|
const projectRoot = options.projectRoot || findProjectRoot();
|
|
1367
1432
|
const ucName = toPascalCase(options.name);
|
|
1368
|
-
const targetDir = options.targetDir ||
|
|
1369
|
-
const filePath =
|
|
1433
|
+
const targetDir = options.targetDir || path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "useCases");
|
|
1434
|
+
const filePath = path3__default.default.join(targetDir, `${ucName}.ts`);
|
|
1370
1435
|
const code = generateUseCaseCode(
|
|
1371
1436
|
ucName,
|
|
1372
1437
|
options.dependencies || [],
|
|
@@ -1382,7 +1447,7 @@ function generateUseCase(options) {
|
|
|
1382
1447
|
})
|
|
1383
1448
|
);
|
|
1384
1449
|
if (options.includeTest) {
|
|
1385
|
-
const testPath =
|
|
1450
|
+
const testPath = path3__default.default.join(targetDir, `${ucName}.test.ts`);
|
|
1386
1451
|
const testCode = generateUseCaseTestCode(ucName, options.dependencies || []);
|
|
1387
1452
|
files.push(
|
|
1388
1453
|
writeFileSafely(testPath, testCode, {
|
|
@@ -1450,9 +1515,9 @@ function generateHttpHandler(options) {
|
|
|
1450
1515
|
const files = [];
|
|
1451
1516
|
const projectRoot = options.projectRoot || findProjectRoot();
|
|
1452
1517
|
const className = toPascalCase(options.name);
|
|
1453
|
-
const pxDir =
|
|
1454
|
-
const handlersDir =
|
|
1455
|
-
const pxIndexPath =
|
|
1518
|
+
const pxDir = path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress");
|
|
1519
|
+
const handlersDir = path3__default.default.join(pxDir, "handlers");
|
|
1520
|
+
const pxIndexPath = path3__default.default.join(pxDir, "index.ts");
|
|
1456
1521
|
if (!fs3__default.default.existsSync(pxIndexPath)) {
|
|
1457
1522
|
const featurePath = options.routePrefix || `/${options.feature.toLowerCase()}`;
|
|
1458
1523
|
const pxIndexContent = renderTemplate(expressIndexTemplate, {
|
|
@@ -1466,7 +1531,7 @@ function generateHttpHandler(options) {
|
|
|
1466
1531
|
})
|
|
1467
1532
|
);
|
|
1468
1533
|
}
|
|
1469
|
-
const handlerFilePath =
|
|
1534
|
+
const handlerFilePath = path3__default.default.join(handlersDir, `${className}.ts`);
|
|
1470
1535
|
const code = generateHttpHandlerCode(
|
|
1471
1536
|
className,
|
|
1472
1537
|
options.method || "get",
|
|
@@ -1487,7 +1552,7 @@ function generateHttpHandler(options) {
|
|
|
1487
1552
|
return files;
|
|
1488
1553
|
}
|
|
1489
1554
|
function updateOrGenerateDiProvider(featureDir, featureName, bindings = [], options = {}) {
|
|
1490
|
-
const providerPath =
|
|
1555
|
+
const providerPath = path3__default.default.join(featureDir, "diProvider.ts");
|
|
1491
1556
|
const pascalFeature = toPascalCase(featureName);
|
|
1492
1557
|
const providerModuleName = `${pascalFeature}Provider`;
|
|
1493
1558
|
if (fs3__default.default.existsSync(providerPath) && !options.overwrite) {
|
|
@@ -1550,7 +1615,7 @@ function generateFeature(options) {
|
|
|
1550
1615
|
const projectRoot = options.projectRoot || findProjectRoot();
|
|
1551
1616
|
const rawName = options.name.trim();
|
|
1552
1617
|
const featureName = toCamelCase(rawName);
|
|
1553
|
-
const targetDir = options.targetDir ||
|
|
1618
|
+
const targetDir = options.targetDir || path3__default.default.join(resolveFeaturesDir(projectRoot), featureName);
|
|
1554
1619
|
const routePath = options.routePath || `/${featureName}`;
|
|
1555
1620
|
const rawEntities = [];
|
|
1556
1621
|
if (options.entityNames && options.entityNames.length > 0) {
|
|
@@ -1571,7 +1636,7 @@ function generateFeature(options) {
|
|
|
1571
1636
|
const domainFile = generateDomain({
|
|
1572
1637
|
name: ent,
|
|
1573
1638
|
feature: featureName,
|
|
1574
|
-
targetDir:
|
|
1639
|
+
targetDir: path3__default.default.join(targetDir, "domain"),
|
|
1575
1640
|
projectRoot,
|
|
1576
1641
|
dryRun: options.dryRun,
|
|
1577
1642
|
overwrite: options.overwrite,
|
|
@@ -1591,7 +1656,7 @@ function generateFeature(options) {
|
|
|
1591
1656
|
const ifaceFile = generateInterface({
|
|
1592
1657
|
name: ifaceName,
|
|
1593
1658
|
feature: featureName,
|
|
1594
|
-
targetDir:
|
|
1659
|
+
targetDir: path3__default.default.join(targetDir, "domain"),
|
|
1595
1660
|
entityName: ent,
|
|
1596
1661
|
projectRoot,
|
|
1597
1662
|
dryRun: options.dryRun,
|
|
@@ -1608,7 +1673,7 @@ function generateFeature(options) {
|
|
|
1608
1673
|
const stubFile = generateInfrastructure({
|
|
1609
1674
|
name: stubName,
|
|
1610
1675
|
feature: featureName,
|
|
1611
|
-
targetDir:
|
|
1676
|
+
targetDir: path3__default.default.join(targetDir, "infrastructure"),
|
|
1612
1677
|
kind: "stub",
|
|
1613
1678
|
implementsInterface: ifaceName,
|
|
1614
1679
|
entityName: ent,
|
|
@@ -1650,7 +1715,7 @@ function generateFeature(options) {
|
|
|
1650
1715
|
const ucFiles = generateUseCase({
|
|
1651
1716
|
name: ucName,
|
|
1652
1717
|
feature: featureName,
|
|
1653
|
-
targetDir:
|
|
1718
|
+
targetDir: path3__default.default.join(targetDir, "useCases"),
|
|
1654
1719
|
dependencies: options.includeInterface !== false ? [ifaceName] : [],
|
|
1655
1720
|
inputProperties: [{ name: idParam, type: "string" }],
|
|
1656
1721
|
outputProperties: [{ name: entVar, type: primaryEntity }],
|
|
@@ -1695,7 +1760,7 @@ function generateFeature(options) {
|
|
|
1695
1760
|
const ucFiles = generateUseCase({
|
|
1696
1761
|
name: ucName,
|
|
1697
1762
|
feature: featureName,
|
|
1698
|
-
targetDir:
|
|
1763
|
+
targetDir: path3__default.default.join(targetDir, "useCases"),
|
|
1699
1764
|
dependencies: deps,
|
|
1700
1765
|
inputProperties: [{ name: entVar, type: ent }],
|
|
1701
1766
|
outputProperties: [{ name: entVar, type: ent }],
|
|
@@ -1728,7 +1793,7 @@ function generateFeature(options) {
|
|
|
1728
1793
|
const ucFiles = generateUseCase({
|
|
1729
1794
|
name: ucName,
|
|
1730
1795
|
feature: featureName,
|
|
1731
|
-
targetDir:
|
|
1796
|
+
targetDir: path3__default.default.join(targetDir, "useCases"),
|
|
1732
1797
|
dependencies: deps,
|
|
1733
1798
|
inputProperties: [{ name: idParam, type: "string" }],
|
|
1734
1799
|
outputProperties: [{ name: entVar, type: ent }],
|
|
@@ -1761,7 +1826,7 @@ function generateFeature(options) {
|
|
|
1761
1826
|
const ucFiles = generateUseCase({
|
|
1762
1827
|
name: ucName,
|
|
1763
1828
|
feature: featureName,
|
|
1764
|
-
targetDir:
|
|
1829
|
+
targetDir: path3__default.default.join(targetDir, "useCases"),
|
|
1765
1830
|
dependencies: deps,
|
|
1766
1831
|
inputProperties: [
|
|
1767
1832
|
{ name: "page", type: "number", optional: true },
|
|
@@ -1805,7 +1870,7 @@ function generateFeature(options) {
|
|
|
1805
1870
|
const ucFiles = generateUseCase({
|
|
1806
1871
|
name: ucName,
|
|
1807
1872
|
feature: featureName,
|
|
1808
|
-
targetDir:
|
|
1873
|
+
targetDir: path3__default.default.join(targetDir, "useCases"),
|
|
1809
1874
|
dependencies: deps,
|
|
1810
1875
|
inputProperties: [{ name: entVar, type: ent }],
|
|
1811
1876
|
outputProperties: [{ name: entVar, type: ent }],
|
|
@@ -1838,7 +1903,7 @@ function generateFeature(options) {
|
|
|
1838
1903
|
const ucFiles = generateUseCase({
|
|
1839
1904
|
name: ucName,
|
|
1840
1905
|
feature: featureName,
|
|
1841
|
-
targetDir:
|
|
1906
|
+
targetDir: path3__default.default.join(targetDir, "useCases"),
|
|
1842
1907
|
dependencies: deps,
|
|
1843
1908
|
inputProperties: [{ name: idParam, type: "string" }],
|
|
1844
1909
|
outputProperties: [{ name: "success", type: "boolean" }],
|
|
@@ -1875,7 +1940,7 @@ function generateFeature(options) {
|
|
|
1875
1940
|
const ucFiles = generateUseCase({
|
|
1876
1941
|
name: ucName,
|
|
1877
1942
|
feature: featureName,
|
|
1878
|
-
targetDir:
|
|
1943
|
+
targetDir: path3__default.default.join(targetDir, "useCases"),
|
|
1879
1944
|
dependencies: customUc.dependencies || [],
|
|
1880
1945
|
inputProperties: customUc.inputProperties || [],
|
|
1881
1946
|
outputProperties: customUc.outputProperties || [],
|
|
@@ -1907,8 +1972,8 @@ function generateFeature(options) {
|
|
|
1907
1972
|
}
|
|
1908
1973
|
}
|
|
1909
1974
|
if (options.includeExpress !== false) {
|
|
1910
|
-
const pxDir =
|
|
1911
|
-
const pxIndexPath =
|
|
1975
|
+
const pxDir = path3__default.default.join(targetDir, "pxExpress");
|
|
1976
|
+
const pxIndexPath = path3__default.default.join(pxDir, "index.ts");
|
|
1912
1977
|
if (!files.some((f) => f.absolutePath === pxIndexPath)) {
|
|
1913
1978
|
const pxIndexContent = renderTemplate(expressIndexTemplate, { routePath });
|
|
1914
1979
|
files.push(
|
|
@@ -1951,7 +2016,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
|
|
|
1951
2016
|
).trim();
|
|
1952
2017
|
}
|
|
1953
2018
|
const normalizedName = toCamelCase(name);
|
|
1954
|
-
const defaultDir =
|
|
2019
|
+
const defaultDir = path3__default.default.relative(projectRoot, path3__default.default.join(resolveFeaturesDir(projectRoot), normalizedName));
|
|
1955
2020
|
let targetDirRel = defaultDir;
|
|
1956
2021
|
if (!flags.yes && !flags.target) {
|
|
1957
2022
|
targetDirRel = handleCancel(
|
|
@@ -1962,7 +2027,7 @@ async function runFeatureCommand(featureNameArg, flags = {}) {
|
|
|
1962
2027
|
})
|
|
1963
2028
|
).trim();
|
|
1964
2029
|
}
|
|
1965
|
-
const targetDir = flags.target ?
|
|
2030
|
+
const targetDir = flags.target ? path3__default.default.resolve(projectRoot, flags.target) : path3__default.default.resolve(projectRoot, targetDirRel);
|
|
1966
2031
|
let includeExpress = flags.express !== void 0 ? Boolean(flags.express) : true;
|
|
1967
2032
|
let routePath = `/${normalizedName}`;
|
|
1968
2033
|
let includeDomain = true;
|
|
@@ -2630,7 +2695,7 @@ async function runInfrastructureCommand(classNameArg, flags = {}) {
|
|
|
2630
2695
|
const infraFile = generateInfrastructure(options);
|
|
2631
2696
|
files.push(infraFile);
|
|
2632
2697
|
if (registerInProvider && scope === "feature" && feature && implementsInterface) {
|
|
2633
|
-
const featureDir =
|
|
2698
|
+
const featureDir = path3__default.default.join(resolveFeaturesDir(projectRoot), feature);
|
|
2634
2699
|
const providerFile = updateOrGenerateDiProvider(
|
|
2635
2700
|
featureDir,
|
|
2636
2701
|
feature,
|
|
@@ -2792,7 +2857,7 @@ async function runInterfaceCommand(interfaceNameArg, flags = {}) {
|
|
|
2792
2857
|
files.push(stubFile);
|
|
2793
2858
|
}
|
|
2794
2859
|
if (registerInProvider && generateStub) {
|
|
2795
|
-
const featureDir =
|
|
2860
|
+
const featureDir = path3__default.default.join(resolveFeaturesDir(projectRoot), feature);
|
|
2796
2861
|
const providerFile = updateOrGenerateDiProvider(
|
|
2797
2862
|
featureDir,
|
|
2798
2863
|
feature,
|
|
@@ -2980,21 +3045,21 @@ function generateInjectable(options) {
|
|
|
2980
3045
|
const className = toPascalCase(options.name);
|
|
2981
3046
|
let targetDir = "";
|
|
2982
3047
|
if (options.customPath) {
|
|
2983
|
-
targetDir =
|
|
3048
|
+
targetDir = path3__default.default.isAbsolute(options.customPath) ? options.customPath : path3__default.default.join(projectRoot, options.customPath);
|
|
2984
3049
|
} else if (options.location === "feature-service" && options.feature) {
|
|
2985
|
-
targetDir =
|
|
3050
|
+
targetDir = path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services");
|
|
2986
3051
|
} else if (options.location === "feature-transformer" && options.feature) {
|
|
2987
|
-
targetDir =
|
|
3052
|
+
targetDir = path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "pxExpress", "transformers");
|
|
2988
3053
|
} else if (options.location === "module") {
|
|
2989
|
-
targetDir =
|
|
3054
|
+
targetDir = path3__default.default.join(projectRoot, "modules", className);
|
|
2990
3055
|
} else {
|
|
2991
|
-
targetDir = options.feature ?
|
|
3056
|
+
targetDir = options.feature ? path3__default.default.join(resolveFeaturesDir(projectRoot), options.feature, "services") : path3__default.default.join(projectRoot, "shared", className.toLowerCase());
|
|
2992
3057
|
}
|
|
2993
|
-
const filePath =
|
|
3058
|
+
const filePath = path3__default.default.join(targetDir, `${className}.ts`);
|
|
2994
3059
|
let ifaceName;
|
|
2995
3060
|
if (options.generateInterface) {
|
|
2996
3061
|
ifaceName = `I${className}`;
|
|
2997
|
-
const ifacePath =
|
|
3062
|
+
const ifacePath = path3__default.default.join(targetDir, `${ifaceName}.ts`);
|
|
2998
3063
|
const ifaceContent = renderTemplate(injectableInterfaceTemplate, { ifaceName });
|
|
2999
3064
|
files.push(
|
|
3000
3065
|
writeFileSafely(ifacePath, ifaceContent, {
|
|
@@ -3309,7 +3374,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3309
3374
|
}
|
|
3310
3375
|
const sharedDeps = manifest.dependencies?.shared || [];
|
|
3311
3376
|
for (const dep of sharedDeps) {
|
|
3312
|
-
const depPath =
|
|
3377
|
+
const depPath = path3__default.default.join(projectRoot, "src", "shared", dep);
|
|
3313
3378
|
if (!fs3__default.default.existsSync(depPath) && !importedModules.has(`shared:${dep}`)) {
|
|
3314
3379
|
p4__namespace.log.info(` \u21B3 Resolving required shared dependency: ${pc13__default.default.cyan(dep)}`);
|
|
3315
3380
|
await importModuleRecursive("shared", dep);
|
|
@@ -3317,7 +3382,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3317
3382
|
}
|
|
3318
3383
|
const featureDeps = manifest.dependencies?.features || [];
|
|
3319
3384
|
for (const dep of featureDeps) {
|
|
3320
|
-
const depPath =
|
|
3385
|
+
const depPath = path3__default.default.join(projectRoot, "src", "features", dep);
|
|
3321
3386
|
if (!fs3__default.default.existsSync(depPath) && !importedModules.has(`feature:${dep}`)) {
|
|
3322
3387
|
p4__namespace.log.info(` \u21B3 Resolving required feature dependency: ${pc13__default.default.cyan(dep)}`);
|
|
3323
3388
|
await importModuleRecursive("feature", dep);
|
|
@@ -3327,21 +3392,21 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3327
3392
|
requiredNpmPackages.add(pkg);
|
|
3328
3393
|
}
|
|
3329
3394
|
const folder = modType === "shared" ? "shared" : "features";
|
|
3330
|
-
const targetDir =
|
|
3395
|
+
const targetDir = path3__default.default.join(projectRoot, "src", folder, modName);
|
|
3331
3396
|
for (const file of manifest.files || []) {
|
|
3332
3397
|
if (file === "registry.json") continue;
|
|
3333
3398
|
const remoteFilePath = `${folder}/${modName}/${file}`;
|
|
3334
|
-
const localFilePath =
|
|
3399
|
+
const localFilePath = path3__default.default.join(targetDir, file);
|
|
3335
3400
|
if (fs3__default.default.existsSync(localFilePath) && !flags.overwrite) {
|
|
3336
|
-
p4__namespace.log.warn(` \u21B3 Skipping existing file: ${pc13__default.default.dim(
|
|
3401
|
+
p4__namespace.log.warn(` \u21B3 Skipping existing file: ${pc13__default.default.dim(path3__default.default.relative(projectRoot, localFilePath))} (use --overwrite to replace)`);
|
|
3337
3402
|
continue;
|
|
3338
3403
|
}
|
|
3339
3404
|
const content = await fetchRegistryFile(registryBase, remoteFilePath);
|
|
3340
3405
|
if (!flags.dryRun) {
|
|
3341
|
-
fs3__default.default.mkdirSync(
|
|
3406
|
+
fs3__default.default.mkdirSync(path3__default.default.dirname(localFilePath), { recursive: true });
|
|
3342
3407
|
fs3__default.default.writeFileSync(localFilePath, content, "utf-8");
|
|
3343
3408
|
}
|
|
3344
|
-
const displayPath =
|
|
3409
|
+
const displayPath = path3__default.default.relative(projectRoot, localFilePath);
|
|
3345
3410
|
totalWrittenFiles.push(displayPath);
|
|
3346
3411
|
p4__namespace.log.message(` ${pc13__default.default.green("+")} ${displayPath}`);
|
|
3347
3412
|
}
|
|
@@ -3484,6 +3549,7 @@ exports.fetchRegistryFile = fetchRegistryFile;
|
|
|
3484
3549
|
exports.fetchRegistryIndex = fetchRegistryIndex;
|
|
3485
3550
|
exports.findClosestMatch = findClosestMatch;
|
|
3486
3551
|
exports.findInterfaceFile = findInterfaceFile;
|
|
3552
|
+
exports.findLocalRegistry = findLocalRegistry;
|
|
3487
3553
|
exports.findProjectRoot = findProjectRoot;
|
|
3488
3554
|
exports.generateConcreteInfraCode = generateConcreteInfraCode;
|
|
3489
3555
|
exports.generateDomain = generateDomain;
|
|
@@ -3520,6 +3586,7 @@ exports.listExistingFeatures = listExistingFeatures;
|
|
|
3520
3586
|
exports.listUseCases = listUseCases;
|
|
3521
3587
|
exports.loadInterfaceHierarchy = loadInterfaceHierarchy;
|
|
3522
3588
|
exports.loadTemplate = loadTemplate;
|
|
3589
|
+
exports.normalizeRegistryUrl = normalizeRegistryUrl;
|
|
3523
3590
|
exports.parseInterfaceMethodsAndImports = parseInterfaceMethodsAndImports;
|
|
3524
3591
|
exports.printBanner = printBanner;
|
|
3525
3592
|
exports.printGeneratedFiles = printGeneratedFiles;
|