@doubledigit/cli 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.
- package/LICENSE +1 -1
- package/dist/codegen.d.ts +6 -2
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +81 -13
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +36 -3
- package/dist/commands/create.js +2 -2
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +24 -11
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +46 -12
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +163 -0
- package/dist/commands/onboard.d.ts.map +1 -1
- package/dist/commands/onboard.js +6 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +5 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +25 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/lib/marketplace-schema.d.ts +24 -24
- package/dist/lib/onboarding.d.ts +3 -3
- package/dist/lib/onboarding.d.ts.map +1 -1
- package/dist/lib/onboarding.js +282 -237
- package/dist/lib/package-entry.d.ts +6 -0
- package/dist/lib/package-entry.d.ts.map +1 -0
- package/dist/lib/package-entry.js +63 -0
- package/dist/lib/scoped-migrations.d.ts +11 -0
- package/dist/lib/scoped-migrations.d.ts.map +1 -0
- package/dist/lib/scoped-migrations.js +156 -0
- package/dist/lib/validators.d.ts.map +1 -1
- package/dist/lib/validators.js +12 -49
- package/dist/paths.d.ts +4 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +2 -0
- package/dist/scanner.d.ts +4 -0
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +21 -0
- package/package.json +10 -4
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function listPackageEntryCandidates(pkg: Record<string, unknown>, fallbackCandidates?: string[]): string[];
|
|
2
|
+
export declare function resolvePackageEntryPoint(packageDir: string, pkg: Record<string, unknown>, options?: {
|
|
3
|
+
fallbackCandidates?: string[];
|
|
4
|
+
allowDistFallback?: boolean;
|
|
5
|
+
}): string | null;
|
|
6
|
+
//# sourceMappingURL=package-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-entry.d.ts","sourceRoot":"","sources":["../../src/lib/package-entry.ts"],"names":[],"mappings":"AAyBA,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,kBAAkB,GAAE,MAAM,EAAO,GAChC,MAAM,EAAE,CA2BV;AAiBD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,CAAC,EAAE;IACR,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GACA,MAAM,GAAG,IAAI,CAUf"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
function normalizeCandidate(candidate) {
|
|
7
|
+
return candidate.replace(/^\.\//, '');
|
|
8
|
+
}
|
|
9
|
+
function addCandidate(candidates, seen, candidate) {
|
|
10
|
+
if (typeof candidate !== 'string' || candidate.length === 0)
|
|
11
|
+
return;
|
|
12
|
+
const normalized = normalizeCandidate(candidate);
|
|
13
|
+
if (seen.has(normalized))
|
|
14
|
+
return;
|
|
15
|
+
seen.add(normalized);
|
|
16
|
+
candidates.push(normalized);
|
|
17
|
+
}
|
|
18
|
+
export function listPackageEntryCandidates(pkg, fallbackCandidates = []) {
|
|
19
|
+
const candidates = [];
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
addCandidate(candidates, seen, pkg.source);
|
|
22
|
+
const exportsField = pkg.exports;
|
|
23
|
+
if (typeof exportsField === 'string') {
|
|
24
|
+
addCandidate(candidates, seen, exportsField);
|
|
25
|
+
}
|
|
26
|
+
else if (isRecord(exportsField)) {
|
|
27
|
+
const rootExport = exportsField['.'];
|
|
28
|
+
if (typeof rootExport === 'string') {
|
|
29
|
+
addCandidate(candidates, seen, rootExport);
|
|
30
|
+
}
|
|
31
|
+
else if (isRecord(rootExport)) {
|
|
32
|
+
addCandidate(candidates, seen, rootExport.default);
|
|
33
|
+
addCandidate(candidates, seen, rootExport.source);
|
|
34
|
+
addCandidate(candidates, seen, rootExport.import);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
addCandidate(candidates, seen, pkg.main);
|
|
38
|
+
for (const fallback of fallbackCandidates) {
|
|
39
|
+
addCandidate(candidates, seen, fallback);
|
|
40
|
+
}
|
|
41
|
+
return candidates;
|
|
42
|
+
}
|
|
43
|
+
function findExistingEntry(packageDir, candidates, includeDist) {
|
|
44
|
+
for (const candidate of candidates) {
|
|
45
|
+
const resolved = path.resolve(packageDir, candidate);
|
|
46
|
+
if (!fs.existsSync(resolved))
|
|
47
|
+
continue;
|
|
48
|
+
if (!includeDist && resolved.includes(`${path.sep}dist${path.sep}`))
|
|
49
|
+
continue;
|
|
50
|
+
return candidate;
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
export function resolvePackageEntryPoint(packageDir, pkg, options) {
|
|
55
|
+
const candidates = listPackageEntryCandidates(pkg, options?.fallbackCandidates);
|
|
56
|
+
const sourceEntry = findExistingEntry(packageDir, candidates, false);
|
|
57
|
+
if (sourceEntry)
|
|
58
|
+
return sourceEntry;
|
|
59
|
+
if (options?.allowDistFallback === false) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return findExistingEntry(packageDir, candidates, true);
|
|
63
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WorkspacePaths } from '../paths.js';
|
|
2
|
+
export type ScopedMigrationAction = 'create' | 'migrate' | 'status';
|
|
3
|
+
interface ScopedMigrationArgs {
|
|
4
|
+
target: string;
|
|
5
|
+
migrationName?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseScopedMigrationArgs(args: string[]): ScopedMigrationArgs;
|
|
8
|
+
export declare function getScopedMigrationTargets(appConfigs: string[], target: string): string[];
|
|
9
|
+
export declare function runScopedMigrations(paths: WorkspacePaths, action: ScopedMigrationAction, args?: string[]): void;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=scoped-migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoped-migrations.d.ts","sourceRoot":"","sources":["../../src/lib/scoped-migrations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAOpE,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAsB5E;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,EAAE,MAAM,GACb,MAAM,EAAE,CAUV;AAkKD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,GAAE,MAAM,EAAO,QAyBpB"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const CONFIG_SUFFIX = '.config.ts';
|
|
5
|
+
const SHARED_CONFIG = 'shared';
|
|
6
|
+
const SHARED_TARGET = '--shared';
|
|
7
|
+
const ALL_TARGET = '--all';
|
|
8
|
+
export function parseScopedMigrationArgs(args) {
|
|
9
|
+
const [targetOrName, maybeMigrationName] = args;
|
|
10
|
+
if (!targetOrName) {
|
|
11
|
+
return { target: ALL_TARGET };
|
|
12
|
+
}
|
|
13
|
+
if (targetOrName === ALL_TARGET || targetOrName === SHARED_TARGET) {
|
|
14
|
+
return maybeMigrationName
|
|
15
|
+
? {
|
|
16
|
+
target: targetOrName,
|
|
17
|
+
migrationName: maybeMigrationName,
|
|
18
|
+
}
|
|
19
|
+
: { target: targetOrName };
|
|
20
|
+
}
|
|
21
|
+
return maybeMigrationName
|
|
22
|
+
? {
|
|
23
|
+
target: targetOrName,
|
|
24
|
+
migrationName: maybeMigrationName,
|
|
25
|
+
}
|
|
26
|
+
: { target: targetOrName };
|
|
27
|
+
}
|
|
28
|
+
export function getScopedMigrationTargets(appConfigs, target) {
|
|
29
|
+
if (target === SHARED_TARGET) {
|
|
30
|
+
return [SHARED_CONFIG];
|
|
31
|
+
}
|
|
32
|
+
if (target === ALL_TARGET) {
|
|
33
|
+
return [SHARED_CONFIG, ...appConfigs];
|
|
34
|
+
}
|
|
35
|
+
return [target];
|
|
36
|
+
}
|
|
37
|
+
function getAppConfigs(paths) {
|
|
38
|
+
if (!fs.existsSync(paths.payloadConfigsDir)) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
return fs
|
|
42
|
+
.readdirSync(paths.payloadConfigsDir)
|
|
43
|
+
.filter((file) => file.endsWith(CONFIG_SUFFIX))
|
|
44
|
+
.map((file) => file.slice(0, -CONFIG_SUFFIX.length))
|
|
45
|
+
.filter((appKey) => !appKey.startsWith('_') && appKey !== SHARED_CONFIG)
|
|
46
|
+
.sort();
|
|
47
|
+
}
|
|
48
|
+
function getConfigPath(paths, appKey) {
|
|
49
|
+
const configPath = path.join(paths.payloadConfigsDir, `${appKey}${CONFIG_SUFFIX}`);
|
|
50
|
+
if (!fs.existsSync(configPath)) {
|
|
51
|
+
const available = [SHARED_CONFIG, ...getAppConfigs(paths)].join(', ');
|
|
52
|
+
throw new Error(`Unknown scoped migration target "${appKey}". Available targets: ${available || '(none)'}.`);
|
|
53
|
+
}
|
|
54
|
+
return path.relative(paths.mainAppDir, configPath);
|
|
55
|
+
}
|
|
56
|
+
function getAppMigrationDir(paths, appKey) {
|
|
57
|
+
return path.join(paths.extensionsMicroAppsDir, appKey, 'src', 'migrations');
|
|
58
|
+
}
|
|
59
|
+
function getMigrationFiles(dir) {
|
|
60
|
+
if (!fs.existsSync(dir)) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
return fs
|
|
64
|
+
.readdirSync(dir)
|
|
65
|
+
.filter((file) => file.endsWith('.ts') && file !== 'index.ts')
|
|
66
|
+
.sort();
|
|
67
|
+
}
|
|
68
|
+
function formatCommand(args) {
|
|
69
|
+
return ['pnpm', ...args].join(' ');
|
|
70
|
+
}
|
|
71
|
+
function runCommand(paths, args, envOverrides = {}) {
|
|
72
|
+
const startedAt = Date.now();
|
|
73
|
+
const env = Object.entries(envOverrides)
|
|
74
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
75
|
+
.join(' ');
|
|
76
|
+
console.log(` cwd: ${paths.mainAppDir}`);
|
|
77
|
+
console.log(` command: ${formatCommand(args)}`);
|
|
78
|
+
if (env) {
|
|
79
|
+
console.log(` env: ${env}`);
|
|
80
|
+
}
|
|
81
|
+
const result = spawnSync('pnpm', args, {
|
|
82
|
+
cwd: paths.mainAppDir,
|
|
83
|
+
env: {
|
|
84
|
+
...process.env,
|
|
85
|
+
...envOverrides,
|
|
86
|
+
},
|
|
87
|
+
stdio: 'inherit',
|
|
88
|
+
});
|
|
89
|
+
if (result.error) {
|
|
90
|
+
console.error(` failed after ${Date.now() - startedAt}ms`);
|
|
91
|
+
throw result.error;
|
|
92
|
+
}
|
|
93
|
+
if (result.status !== 0) {
|
|
94
|
+
console.error(` exit: ${result.status ?? 1} (${Date.now() - startedAt}ms)`);
|
|
95
|
+
process.exit(result.status ?? 1);
|
|
96
|
+
}
|
|
97
|
+
console.log(` exit: 0 (${Date.now() - startedAt}ms)`);
|
|
98
|
+
}
|
|
99
|
+
function runForConfig(paths, action, label, configPath, migrationName, migrationDir) {
|
|
100
|
+
console.log(`\n==> ${label}: ${action}`);
|
|
101
|
+
console.log(` config: ${configPath}`);
|
|
102
|
+
if (migrationDir) {
|
|
103
|
+
const migrationFiles = getMigrationFiles(migrationDir);
|
|
104
|
+
console.log(` migrationDir: ${migrationDir}`);
|
|
105
|
+
console.log(` migrationFiles: ${migrationFiles.length ? migrationFiles.join(', ') : '(none)'}`);
|
|
106
|
+
}
|
|
107
|
+
if (action === 'create') {
|
|
108
|
+
runCommand(paths, [
|
|
109
|
+
'exec',
|
|
110
|
+
'tsx',
|
|
111
|
+
'scripts/create-scoped-migration.ts',
|
|
112
|
+
configPath,
|
|
113
|
+
...(migrationName ? [migrationName] : []),
|
|
114
|
+
]);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
runCommand(paths, ['exec', 'payload', action === 'status' ? 'migrate:status' : 'migrate'], {
|
|
118
|
+
PAYLOAD_CONFIG_PATH: configPath,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function runShared(paths, action, migrationName) {
|
|
122
|
+
runForConfig(paths, action, SHARED_CONFIG, getConfigPath(paths, SHARED_CONFIG), migrationName, path.join(paths.mainAppDir, 'src', 'migrations', 'shared'));
|
|
123
|
+
}
|
|
124
|
+
function runForApp(paths, action, appKey, migrationName) {
|
|
125
|
+
const configPath = getConfigPath(paths, appKey);
|
|
126
|
+
const migrationDir = getAppMigrationDir(paths, appKey);
|
|
127
|
+
const migrationFiles = getMigrationFiles(migrationDir);
|
|
128
|
+
if (action !== 'create' && !migrationFiles.length) {
|
|
129
|
+
console.log(`\n==> ${appKey}: no migrations found, skipping`);
|
|
130
|
+
console.log(` config: ${configPath}`);
|
|
131
|
+
console.log(` migrationDir: ${migrationDir}`);
|
|
132
|
+
console.log(' migrationFiles: (none)');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
runForConfig(paths, action, appKey, configPath, migrationName, migrationDir);
|
|
136
|
+
}
|
|
137
|
+
export function runScopedMigrations(paths, action, args = []) {
|
|
138
|
+
const { target, migrationName } = parseScopedMigrationArgs(args);
|
|
139
|
+
if (target === SHARED_TARGET) {
|
|
140
|
+
runShared(paths, action, migrationName);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (target === ALL_TARGET) {
|
|
144
|
+
const appConfigs = getAppConfigs(paths);
|
|
145
|
+
const targets = getScopedMigrationTargets(appConfigs, target);
|
|
146
|
+
console.log(`Scoped migration run: ${action} --all`);
|
|
147
|
+
console.log(`Config directory: ${paths.payloadConfigsDir}`);
|
|
148
|
+
console.log(`Targets: ${targets.join(', ')}`);
|
|
149
|
+
runShared(paths, action, migrationName);
|
|
150
|
+
for (const appKey of appConfigs) {
|
|
151
|
+
runForApp(paths, action, appKey, migrationName);
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
runForApp(paths, action, target, migrationName);
|
|
156
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/lib/validators.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/lib/validators.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AA0BD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,MAAM,GACd,gBAAgB,CAWlB;AAMD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,MAAM,GACd,gBAAgB,CAgClB;AAMD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA2E3B;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAEnE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAsBxB;AAMD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,aAAa,GACnB,gBAAgB,CA+ClB;AASD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,GAAG,IAAI,CAIf;AAiCD,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,mBAAmB,CAAC,EAAE,MAAM,GAC3B;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBvC;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,gBAAgB,CAyClB;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,gBAAgB,CAiClB;AAMD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,gBAAgB,CAAC,CAY3B"}
|
package/dist/lib/validators.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import fs from 'node:fs';
|
|
9
9
|
import path from 'node:path';
|
|
10
|
+
import { listPackageEntryCandidates, resolvePackageEntryPoint as resolvePackageEntryCandidate, } from './package-entry.js';
|
|
10
11
|
import { resolveGitHubToken } from './github-auth.js';
|
|
11
12
|
function ok(warnings = []) {
|
|
12
13
|
return { valid: true, errors: [], warnings };
|
|
@@ -230,40 +231,20 @@ export function validateDownloadedPackage(packageDir, kind) {
|
|
|
230
231
|
// 4. Check entry point exists
|
|
231
232
|
const entryPoint = resolvePackageEntryPoint(packageDir, pkg);
|
|
232
233
|
if (!entryPoint) {
|
|
233
|
-
warnings.push('No entry point found (checked
|
|
234
|
+
warnings.push('No entry point found (checked package.json source/exports/main plus common src entry files)');
|
|
234
235
|
}
|
|
235
236
|
return errors.length > 0 ? fail(errors, warnings) : ok(warnings);
|
|
236
237
|
}
|
|
238
|
+
const COMMON_ENTRY_FALLBACKS = [
|
|
239
|
+
'src/index.ts',
|
|
240
|
+
'src/index.tsx',
|
|
241
|
+
'src/micro-app/index.ts',
|
|
242
|
+
'src/micro-app/index.tsx',
|
|
243
|
+
];
|
|
237
244
|
export function resolvePackageEntryPoint(packageDir, pkg) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (fs.existsSync(path.join(packageDir, entry)))
|
|
242
|
-
return entry;
|
|
243
|
-
}
|
|
244
|
-
// Check exports["."] in package.json
|
|
245
|
-
const exports = pkg.exports;
|
|
246
|
-
if (exports && typeof exports === 'object' && '.' in exports) {
|
|
247
|
-
const dotExport = exports['.'];
|
|
248
|
-
const exportPath = typeof dotExport === 'string'
|
|
249
|
-
? dotExport
|
|
250
|
-
: typeof dotExport === 'object' && dotExport !== null
|
|
251
|
-
? dotExport.import ||
|
|
252
|
-
dotExport.default
|
|
253
|
-
: undefined;
|
|
254
|
-
if (typeof exportPath === 'string') {
|
|
255
|
-
const resolved = path.join(packageDir, exportPath);
|
|
256
|
-
if (fs.existsSync(resolved))
|
|
257
|
-
return exportPath;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
const main = pkg.main;
|
|
261
|
-
if (typeof main === 'string') {
|
|
262
|
-
const resolved = path.join(packageDir, main);
|
|
263
|
-
if (fs.existsSync(resolved))
|
|
264
|
-
return main;
|
|
265
|
-
}
|
|
266
|
-
return null;
|
|
245
|
+
return resolvePackageEntryCandidate(packageDir, pkg, {
|
|
246
|
+
fallbackCandidates: COMMON_ENTRY_FALLBACKS,
|
|
247
|
+
});
|
|
267
248
|
}
|
|
268
249
|
const DDAPP_KEY_RE = /key:\s*['"]([^'"]+)['"]/;
|
|
269
250
|
const DDAPP_SLUG_RE = /slugPrefix:\s*['"]([^'"]+)['"]/;
|
|
@@ -278,27 +259,9 @@ function addCandidateEntry(candidates, packageDir, entry) {
|
|
|
278
259
|
function getMicroAppMetadataCandidates(packageDir, pkg, preferredEntryPoint) {
|
|
279
260
|
const candidates = new Set();
|
|
280
261
|
addCandidateEntry(candidates, packageDir, preferredEntryPoint);
|
|
281
|
-
|
|
282
|
-
for (const entry of [
|
|
283
|
-
'src/index.ts',
|
|
284
|
-
'src/index.tsx',
|
|
285
|
-
'src/micro-app/index.ts',
|
|
286
|
-
'src/micro-app/index.tsx',
|
|
287
|
-
]) {
|
|
262
|
+
for (const entry of listPackageEntryCandidates(pkg, COMMON_ENTRY_FALLBACKS)) {
|
|
288
263
|
addCandidateEntry(candidates, packageDir, entry);
|
|
289
264
|
}
|
|
290
|
-
const exports = pkg.exports;
|
|
291
|
-
if (exports && typeof exports === 'object' && '.' in exports) {
|
|
292
|
-
const dotExport = exports['.'];
|
|
293
|
-
if (typeof dotExport === 'string') {
|
|
294
|
-
addCandidateEntry(candidates, packageDir, dotExport);
|
|
295
|
-
}
|
|
296
|
-
else if (typeof dotExport === 'object' && dotExport !== null) {
|
|
297
|
-
addCandidateEntry(candidates, packageDir, dotExport.import);
|
|
298
|
-
addCandidateEntry(candidates, packageDir, dotExport.default);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
addCandidateEntry(candidates, packageDir, pkg.main);
|
|
302
265
|
return [...candidates];
|
|
303
266
|
}
|
|
304
267
|
export function extractMicroAppMetadata(packageDir, pkg, preferredEntryPoint) {
|
package/dist/paths.d.ts
CHANGED
|
@@ -21,8 +21,12 @@ export interface WorkspacePaths {
|
|
|
21
21
|
lockFilePath: string;
|
|
22
22
|
/** Generated micro-apps.ts path */
|
|
23
23
|
microAppsOutputPath: string;
|
|
24
|
+
/** Generated micro-app package list consumed by next.config.ts */
|
|
25
|
+
microAppTranspilePackagesOutputPath: string;
|
|
24
26
|
/** Generated payload-plugins.ts path */
|
|
25
27
|
payloadPluginsOutputPath: string;
|
|
28
|
+
/** Scoped Payload config directory */
|
|
29
|
+
payloadConfigsDir: string;
|
|
26
30
|
/** main-app package.json */
|
|
27
31
|
mainAppPackageJsonPath: string;
|
|
28
32
|
}
|
package/dist/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,2BAA2B,EAAE,MAAM,CAAC;IACpC,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wCAAwC;IACxC,wBAAwB,EAAE,MAAM,CAAC;IACjC,4BAA4B;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAgBD,wBAAgB,qBAAqB,CAAC,GAAG,SAAgB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,2BAA2B,EAAE,MAAM,CAAC;IACpC,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,mCAAmC,EAAE,MAAM,CAAC;IAC5C,wCAAwC;IACxC,wBAAwB,EAAE,MAAM,CAAC;IACjC,sCAAsC;IACtC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4BAA4B;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAgBD,wBAAgB,qBAAqB,CAAC,GAAG,SAAgB,GAAG,cAAc,CAsBzE;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,WAAW,GAAG,gBAAgB,EACpC,IAAI,EAAE,MAAM,GACX,MAAM,CAKR;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,GAAG,gBAAgB,EACpC,IAAI,EAAE,MAAM,GACX,MAAM,CAIR;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,EAAE,CAM/D;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,EAAE,CAO5D;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,WAAW,GAAG,gBAAgB,GAC7C,MAAM,EAAE,CAcV"}
|
package/dist/paths.js
CHANGED
|
@@ -32,7 +32,9 @@ export function resolveWorkspacePaths(cwd = process.cwd()) {
|
|
|
32
32
|
configPath: path.join(mainAppDir, 'dd-apps.config.json'),
|
|
33
33
|
lockFilePath: path.join(root, 'dd-apps.lock.json'),
|
|
34
34
|
microAppsOutputPath: path.join(mainAppDir, 'src', 'lib', 'micro-apps.ts'),
|
|
35
|
+
microAppTranspilePackagesOutputPath: path.join(mainAppDir, 'src', 'lib', 'micro-app-transpile-packages.ts'),
|
|
35
36
|
payloadPluginsOutputPath: path.join(mainAppDir, 'src', 'lib', 'payload-plugins.ts'),
|
|
37
|
+
payloadConfigsDir: path.join(mainAppDir, 'payload-configs'),
|
|
36
38
|
mainAppPackageJsonPath: path.join(mainAppDir, 'package.json'),
|
|
37
39
|
};
|
|
38
40
|
}
|
package/dist/scanner.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface DiscoveredApp {
|
|
|
12
12
|
importName: string;
|
|
13
13
|
/** Absolute path to the package directory */
|
|
14
14
|
dir: string;
|
|
15
|
+
/** Absolute path to the local source entry file used by generated registries */
|
|
16
|
+
entryFile: string;
|
|
15
17
|
}
|
|
16
18
|
export interface DiscoveredPayloadPlugin {
|
|
17
19
|
/** Folder name */
|
|
@@ -22,6 +24,8 @@ export interface DiscoveredPayloadPlugin {
|
|
|
22
24
|
importName: string;
|
|
23
25
|
/** Absolute path to the package directory */
|
|
24
26
|
dir: string;
|
|
27
|
+
/** Absolute path to the local source entry file used by generated registries */
|
|
28
|
+
entryFile: string;
|
|
25
29
|
}
|
|
26
30
|
/** Unified result from scanning the workspace. */
|
|
27
31
|
export interface ScanResult {
|
package/dist/scanner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kDAAkD;AAClD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,cAAc,EAAE,uBAAuB,EAAE,CAAC;CAC3C;AAyGD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAgB/D;AAED,kGAAkG;AAClG,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,EAAE,CAMlE"}
|
package/dist/scanner.js
CHANGED
|
@@ -4,9 +4,20 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
7
|
+
import { resolvePackageEntryPoint } from './lib/package-entry.js';
|
|
7
8
|
function toImportName(key) {
|
|
8
9
|
return key.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
9
10
|
}
|
|
11
|
+
function requireWorkspaceEntryFile(pkgDir, pkg, fallbackCandidates) {
|
|
12
|
+
const entryPoint = resolvePackageEntryPoint(pkgDir, pkg, {
|
|
13
|
+
fallbackCandidates,
|
|
14
|
+
allowDistFallback: false,
|
|
15
|
+
});
|
|
16
|
+
if (entryPoint) {
|
|
17
|
+
return path.resolve(pkgDir, entryPoint);
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`Could not resolve a local source entry file for ${String(pkg.name ?? pkgDir)} at ${pkgDir}`);
|
|
20
|
+
}
|
|
10
21
|
/**
|
|
11
22
|
* Classify a single package directory.
|
|
12
23
|
* Returns the package type or null if unrecognised.
|
|
@@ -25,6 +36,10 @@ function classifyPackage(pkgDir, key) {
|
|
|
25
36
|
npmName: pkg.name,
|
|
26
37
|
importName: toImportName(key),
|
|
27
38
|
dir: pkgDir,
|
|
39
|
+
entryFile: requireWorkspaceEntryFile(pkgDir, pkg, [
|
|
40
|
+
'./src/index.ts',
|
|
41
|
+
'./src/index.tsx',
|
|
42
|
+
]),
|
|
28
43
|
},
|
|
29
44
|
};
|
|
30
45
|
}
|
|
@@ -36,6 +51,12 @@ function classifyPackage(pkgDir, key) {
|
|
|
36
51
|
npmName: pkg.name,
|
|
37
52
|
importName: toImportName(key),
|
|
38
53
|
dir: pkgDir,
|
|
54
|
+
entryFile: requireWorkspaceEntryFile(pkgDir, pkg, [
|
|
55
|
+
'./src/index.tsx',
|
|
56
|
+
'./src/index.ts',
|
|
57
|
+
'./src/micro-app/index.tsx',
|
|
58
|
+
'./src/micro-app/index.ts',
|
|
59
|
+
]),
|
|
39
60
|
},
|
|
40
61
|
};
|
|
41
62
|
}
|
package/package.json
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doubledigit/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "CLI for Double Digit local setup and extension management.",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"homepage": "https://github.com/
|
|
7
|
+
"homepage": "https://github.com/crystalphantom/double-digit",
|
|
8
8
|
"bugs": {
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "https://github.com/crystalphantom/double-digit/issues"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/
|
|
13
|
+
"url": "https://github.com/crystalphantom/double-digit.git",
|
|
14
14
|
"directory": "packages/cli"
|
|
15
15
|
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20.0.0",
|
|
18
|
+
"pnpm": ">=9.0.0"
|
|
19
|
+
},
|
|
16
20
|
"type": "module",
|
|
17
21
|
"main": "./dist/index.js",
|
|
18
22
|
"module": "./dist/index.js",
|
|
@@ -37,12 +41,14 @@
|
|
|
37
41
|
"zod": "^3.23.0"
|
|
38
42
|
},
|
|
39
43
|
"devDependencies": {
|
|
44
|
+
"tsx": "^4.21.0",
|
|
40
45
|
"typescript": "^5.7.0"
|
|
41
46
|
},
|
|
42
47
|
"publishConfig": {
|
|
43
48
|
"access": "public"
|
|
44
49
|
},
|
|
45
50
|
"scripts": {
|
|
51
|
+
"test": "tsx --test test/*.test.ts",
|
|
46
52
|
"build": "tsc -p tsconfig.json",
|
|
47
53
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
48
54
|
}
|