@jointhedots/gear 1.1.10 → 1.1.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/esm/builder/build-app-bundle.js +3 -2
- package/esm/builder/build-app-host.js +2 -0
- package/esm/builder/build-application.js +2 -0
- package/esm/builder/build-library.js +3 -2
- package/esm/builder/build-target.js +18 -3
- package/esm/builder/esbuild-plugins.js +88 -11
- package/esm/commands/init.js +13 -0
- package/esm/commands/make.js +5 -1
- package/esm/commands/publish.js +4 -1
- package/esm/commands/serve.js +5 -2
- package/esm/model/helpers/config-loader.js +10 -10
- package/esm/model/helpers/create-manifests.js +26 -12
- package/esm/model/helpers/discover-workspace.js +71 -44
- package/esm/model/helpers/logger.js +25 -1
- package/esm/model/workspace.js +30 -8
- package/package.json +5 -3
- package/readme.md +136 -0
- package/schemas/declaration.schema.json +76 -0
- package/esm/builder/build-app-bundle.js.map +0 -1
- package/esm/builder/build-app-host.js.map +0 -1
- package/esm/builder/build-application.js.map +0 -1
- package/esm/builder/build-library.js.map +0 -1
- package/esm/builder/build-target.js.map +0 -1
- package/esm/builder/emit-dts.js.map +0 -1
- package/esm/builder/esbuild-plugins.js.map +0 -1
- package/esm/builder/helpers/path-helpers.js.map +0 -1
- package/esm/cli.js.map +0 -1
- package/esm/commands/init.js.map +0 -1
- package/esm/commands/make.js.map +0 -1
- package/esm/commands/publish.js.map +0 -1
- package/esm/commands/run.js.map +0 -1
- package/esm/commands/serve.js.map +0 -1
- package/esm/model/component.js.map +0 -1
- package/esm/model/helpers/config-loader.js.map +0 -1
- package/esm/model/helpers/create-manifests.js.map +0 -1
- package/esm/model/helpers/discover-workspace.js.map +0 -1
- package/esm/model/helpers/logger.js.map +0 -1
- package/esm/model/helpers/package-npm.js.map +0 -1
- package/esm/model/storage.js.map +0 -1
- package/esm/model/workspace.js.map +0 -1
- package/esm/publish/publish_aws_s3.js.map +0 -1
- package/esm/utils/file.js.map +0 -1
- package/esm/utils/graph-ordering.js.map +0 -1
- package/esm/utils/normalized-name.js.map +0 -1
|
@@ -19,15 +19,16 @@ export function create_bundle_target(opts) {
|
|
|
19
19
|
const lib = library;
|
|
20
20
|
const target = new BuildTarget(bundle.id, storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
21
21
|
const manifs = create_manifests(lib, bundle, opts.version);
|
|
22
|
+
// Prepare esm setup
|
|
23
|
+
target.esmodules.set_root(lib.path);
|
|
22
24
|
// Add bundle package.json
|
|
23
25
|
target.assets.add_static_json("package.json", manifs.package);
|
|
24
26
|
// Add bundle types.d.ts
|
|
25
27
|
target.tasks.push(new TypescriptDefinitionTask(target, lib));
|
|
26
28
|
// Add bundle exporteds
|
|
27
|
-
const { esmodules } = target;
|
|
28
29
|
for (const exp_id in manifs.entries) {
|
|
29
30
|
const exp = manifs.entries[exp_id];
|
|
30
|
-
esmodules.add_entry(exp.basename, exp.source);
|
|
31
|
+
target.esmodules.add_entry(exp.basename, exp.source);
|
|
31
32
|
}
|
|
32
33
|
// Add bundle content
|
|
33
34
|
if (bundle) {
|
|
@@ -12,6 +12,8 @@ function create_application_composable_target(opts) {
|
|
|
12
12
|
const bundle = lib.bundle;
|
|
13
13
|
const ws = lib.workspace;
|
|
14
14
|
const target = new BuildTarget(name, opts.storage, ws, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
15
|
+
// Prepare esm setup
|
|
16
|
+
target.esmodules.set_root(lib.path);
|
|
15
17
|
// Generate hotreload assets
|
|
16
18
|
const html_injects = [];
|
|
17
19
|
if (opts.devserver) {
|
|
@@ -36,6 +36,8 @@ export function create_application_monolith_target(opts) {
|
|
|
36
36
|
const target = new BuildTarget(name, opts.storage, ws, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
37
37
|
const libs = collect_app_libraries(app);
|
|
38
38
|
target.log.info(`+ 🧭 app-library-graph: ${libs.map(lib => `${lib.name}@${lib.descriptor.version}`).join(", ")}`);
|
|
39
|
+
// Prepare esm setup
|
|
40
|
+
target.esmodules.set_root(lib.path);
|
|
39
41
|
// Generate hotreload assets
|
|
40
42
|
const html_injects = [];
|
|
41
43
|
if (opts.devserver) {
|
|
@@ -9,11 +9,12 @@ export function create_library_target(opts) {
|
|
|
9
9
|
const lib = opts.library;
|
|
10
10
|
const target = new BuildTarget(lib.name, opts.storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
|
|
11
11
|
const manifs = create_manifests(lib, lib.bundle, opts.version);
|
|
12
|
+
// Prepare esm setup
|
|
13
|
+
target.esmodules.set_root(lib.path);
|
|
12
14
|
// Add bundle exporteds
|
|
13
|
-
const { esmodules } = target;
|
|
14
15
|
for (const exp_id in manifs.entries) {
|
|
15
16
|
const exp = manifs.entries[exp_id];
|
|
16
|
-
esmodules.add_entry(exp.basename, exp.source);
|
|
17
|
+
target.esmodules.add_entry(exp.basename, exp.source);
|
|
17
18
|
}
|
|
18
19
|
// Add library types.d.ts
|
|
19
20
|
target.tasks.push(new TypescriptDefinitionTask(target, lib));
|
|
@@ -87,6 +87,10 @@ export class ESModulesTask extends BuildTask {
|
|
|
87
87
|
context = null;
|
|
88
88
|
transaction = null;
|
|
89
89
|
polyfilled = true;
|
|
90
|
+
rootPath = null;
|
|
91
|
+
set_root(path) {
|
|
92
|
+
this.rootPath = path;
|
|
93
|
+
}
|
|
90
94
|
add_entry(name, path) {
|
|
91
95
|
this.entries[name] = path;
|
|
92
96
|
this.imports[path] = name;
|
|
@@ -194,17 +198,28 @@ export class BuildTarget {
|
|
|
194
198
|
}
|
|
195
199
|
this.components.set(id, manifest);
|
|
196
200
|
}
|
|
201
|
+
async chrona(task) {
|
|
202
|
+
const name = task.constructor.name;
|
|
203
|
+
const start = Date.now();
|
|
204
|
+
await task.execute();
|
|
205
|
+
const elapsed = (Date.now() - start) / 1000;
|
|
206
|
+
this.log.info(`⏱ ${name} completed in ${elapsed.toFixed(2)}s`);
|
|
207
|
+
}
|
|
197
208
|
async build() {
|
|
209
|
+
const buildStartTime = Date.now();
|
|
198
210
|
if (this.clean)
|
|
199
211
|
this.storage.clean();
|
|
200
212
|
// Make assets
|
|
201
|
-
await this.assets
|
|
213
|
+
await this.chrona(this.assets);
|
|
202
214
|
// Make generic tasks
|
|
203
215
|
for (const task of this.tasks) {
|
|
204
|
-
await
|
|
216
|
+
await this.chrona(task);
|
|
205
217
|
}
|
|
206
218
|
// Make esmodules
|
|
207
|
-
await this.esmodules
|
|
219
|
+
await this.chrona(this.esmodules);
|
|
220
|
+
// Trace time
|
|
221
|
+
const buildTime = (Date.now() - buildStartTime) / 1000;
|
|
222
|
+
this.log.info(`Build completed in ${buildTime.toFixed(2)}s`);
|
|
208
223
|
if (this.watch) {
|
|
209
224
|
await new Promise((resolve) => {
|
|
210
225
|
process.on('SIGQUIT', () => resolve(null));
|
|
@@ -9,6 +9,17 @@ import { ESModulesTask } from "./build-target.js";
|
|
|
9
9
|
import { PackageRootDir } from "../utils/file.js";
|
|
10
10
|
import { Library } from "../model/workspace.js";
|
|
11
11
|
const VirtualOutDir = Path.normalize('X:/');
|
|
12
|
+
function getEsbuildLogLevel(mode) {
|
|
13
|
+
switch (mode) {
|
|
14
|
+
case "verbose":
|
|
15
|
+
return "debug";
|
|
16
|
+
case "debug":
|
|
17
|
+
return "info";
|
|
18
|
+
case "normal":
|
|
19
|
+
default:
|
|
20
|
+
return "silent";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
12
23
|
export async function create_esbuild_context(task, devmode) {
|
|
13
24
|
const ws = task.target.workspace;
|
|
14
25
|
// Define modules mapping - using @jspm/core polyfills (same as Vite)
|
|
@@ -40,6 +51,7 @@ export async function create_esbuild_context(task, devmode) {
|
|
|
40
51
|
}
|
|
41
52
|
return result;
|
|
42
53
|
}
|
|
54
|
+
const tsconfig = new TSConfig(task.rootPath, ws.path);
|
|
43
55
|
const modules_mapping = {
|
|
44
56
|
task,
|
|
45
57
|
routeds: {
|
|
@@ -74,13 +86,14 @@ export async function create_esbuild_context(task, devmode) {
|
|
|
74
86
|
format: 'esm',
|
|
75
87
|
target: 'es2022',
|
|
76
88
|
platform: "browser",
|
|
89
|
+
tsconfig: tsconfig.configFile ?? undefined,
|
|
77
90
|
sourcemap: devmode ? "linked" : false,
|
|
78
91
|
minify: devmode ? false : true,
|
|
79
92
|
bundle: true,
|
|
80
93
|
splitting: true,
|
|
81
94
|
treeShaking: true,
|
|
82
95
|
write: false,
|
|
83
|
-
logLevel:
|
|
96
|
+
logLevel: getEsbuildLogLevel(ws.logger.mode),
|
|
84
97
|
chunkNames: "chunk.[hash]",
|
|
85
98
|
jsx: "automatic",
|
|
86
99
|
jsxImportSource: "react",
|
|
@@ -94,8 +107,8 @@ export async function create_esbuild_context(task, devmode) {
|
|
|
94
107
|
...workspace_constants,
|
|
95
108
|
},
|
|
96
109
|
plugins: [
|
|
110
|
+
ESModuleResolverPlugin(modules_mapping, tsconfig),
|
|
97
111
|
...task.plugins,
|
|
98
|
-
ESModuleResolverPlugin(modules_mapping),
|
|
99
112
|
StyleSheetPlugin(task),
|
|
100
113
|
StoragePlugin(task),
|
|
101
114
|
],
|
|
@@ -245,11 +258,10 @@ export function StoragePlugin(task) {
|
|
|
245
258
|
return {
|
|
246
259
|
name: "dipatch-files",
|
|
247
260
|
setup: (build) => {
|
|
248
|
-
|
|
261
|
+
let buildStartTime = 0;
|
|
249
262
|
build.onStart(() => {
|
|
250
263
|
task.log.clear();
|
|
251
|
-
|
|
252
|
-
buildStartTime = performance.now();
|
|
264
|
+
buildStartTime = Date.now();
|
|
253
265
|
});
|
|
254
266
|
build.onEnd(async (result) => {
|
|
255
267
|
if (result.errors.length > 0) {
|
|
@@ -262,7 +274,7 @@ export function StoragePlugin(task) {
|
|
|
262
274
|
task.log.warn(warning);
|
|
263
275
|
}
|
|
264
276
|
if (result.outputFiles) {
|
|
265
|
-
const storeStart =
|
|
277
|
+
const storeStart = Date.now();
|
|
266
278
|
const tx = task.target.edit();
|
|
267
279
|
for (const file of result.outputFiles) {
|
|
268
280
|
if (file.path.startsWith(VirtualOutDir)) {
|
|
@@ -275,9 +287,9 @@ export function StoragePlugin(task) {
|
|
|
275
287
|
}
|
|
276
288
|
}
|
|
277
289
|
task.target.store();
|
|
278
|
-
const storeTime = (
|
|
279
|
-
const buildTime = (
|
|
280
|
-
task.log.info(`Build
|
|
290
|
+
const storeTime = (Date.now() - storeStart) / 1000;
|
|
291
|
+
const buildTime = (Date.now() - buildStartTime) / 1000;
|
|
292
|
+
task.log.info(`Build ES modules in ${result.outputFiles.length} file(s) (compile: ${buildTime.toFixed(2)}s, store: ${storeTime.toFixed(2)}s)`);
|
|
281
293
|
}
|
|
282
294
|
return null;
|
|
283
295
|
});
|
|
@@ -389,7 +401,7 @@ export function DependencyDeduplicationPlugin(libraries, rootNodeModules, log) {
|
|
|
389
401
|
const is = isSingletonPackage(result.path, pkg);
|
|
390
402
|
singletonCache.set(pkg, is);
|
|
391
403
|
if (is)
|
|
392
|
-
log.
|
|
404
|
+
log.debug(`[dedup] singleton: ${pkg}`);
|
|
393
405
|
}
|
|
394
406
|
// Singleton → force root resolution
|
|
395
407
|
if (singletonCache.get(pkg)) {
|
|
@@ -411,7 +423,65 @@ export function DependencyDeduplicationPlugin(libraries, rootNodeModules, log) {
|
|
|
411
423
|
}
|
|
412
424
|
};
|
|
413
425
|
}
|
|
414
|
-
|
|
426
|
+
/**
|
|
427
|
+
* Parses tsconfig.json compilerOptions (paths + baseUrl) and exposes resolved alias patterns.
|
|
428
|
+
* Looks for tsconfig.json in libraryPath first, then workspacePath as fallback.
|
|
429
|
+
*/
|
|
430
|
+
export class TSConfig {
|
|
431
|
+
baseUrl = null;
|
|
432
|
+
patterns = [];
|
|
433
|
+
configFile = null;
|
|
434
|
+
configData = null;
|
|
435
|
+
constructor(libraryPath, workspacePath) {
|
|
436
|
+
const tsconfigFile = [libraryPath, workspacePath]
|
|
437
|
+
.filter(Boolean)
|
|
438
|
+
.map(dir => Path.join(dir, 'tsconfig.json'))
|
|
439
|
+
.find(f => Fs.existsSync(f));
|
|
440
|
+
if (!tsconfigFile)
|
|
441
|
+
return;
|
|
442
|
+
try {
|
|
443
|
+
const raw = Fs.readFileSync(tsconfigFile, 'utf-8');
|
|
444
|
+
const cleaned = raw.replace(/^\s*\/\/.*$/gm, '').replace(/,\s*([}\]])/g, '$1');
|
|
445
|
+
const tsconfig = JSON.parse(cleaned);
|
|
446
|
+
const opts = tsconfig.compilerOptions;
|
|
447
|
+
if (!opts?.paths)
|
|
448
|
+
return;
|
|
449
|
+
this.configData = tsconfig;
|
|
450
|
+
this.configFile = tsconfigFile;
|
|
451
|
+
this.baseUrl = Path.resolve(Path.dirname(tsconfigFile), opts.baseUrl || '.');
|
|
452
|
+
for (const [alias, targets] of Object.entries(opts.paths)) {
|
|
453
|
+
for (const target of targets) {
|
|
454
|
+
const prefix = alias === '*' ? '' : alias.endsWith('/*') ? alias.slice(0, -2) : alias;
|
|
455
|
+
const targetPath = target.endsWith('/*') ? target.slice(0, -2) : target;
|
|
456
|
+
this.patterns.push([prefix, Path.resolve(this.baseUrl, targetPath)]);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
catch { }
|
|
461
|
+
}
|
|
462
|
+
get hasAliases() {
|
|
463
|
+
return this.patterns.length > 0;
|
|
464
|
+
}
|
|
465
|
+
/** Resolve an import path against tsconfig path aliases. Returns the resolved file path or null. */
|
|
466
|
+
resolve(importPath, resolveFilePath) {
|
|
467
|
+
for (const [prefix, dir] of this.patterns) {
|
|
468
|
+
if (prefix === '') {
|
|
469
|
+
// Wildcard "*" pattern: try resolving the full import path under the target dir
|
|
470
|
+
const resolved = resolveFilePath('./' + importPath, dir);
|
|
471
|
+
if (resolved)
|
|
472
|
+
return resolved;
|
|
473
|
+
}
|
|
474
|
+
else if (importPath === prefix || importPath.startsWith(prefix + '/')) {
|
|
475
|
+
const rest = importPath.slice(prefix.length);
|
|
476
|
+
const resolved = resolveFilePath('.' + rest, dir);
|
|
477
|
+
if (resolved)
|
|
478
|
+
return resolved;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
export function ESModuleResolverPlugin(opts, tsconfigPaths) {
|
|
415
485
|
const internalLoaders = {
|
|
416
486
|
".ts": "ts", ".tsx": "tsx", ".js": "js", ".jsx": "jsx",
|
|
417
487
|
".json": "json", ".txt": "text", ".md": "text", ".css": "css",
|
|
@@ -481,6 +551,13 @@ export function ESModuleResolverPlugin(opts) {
|
|
|
481
551
|
return { path: resolved, namespace: "file" };
|
|
482
552
|
}
|
|
483
553
|
}
|
|
554
|
+
// 4. Resolve tsconfig path aliases (e.g. @app/* -> ./src/*)
|
|
555
|
+
if (tsconfigPaths?.hasAliases) {
|
|
556
|
+
const resolved = tsconfigPaths.resolve(args.path, resolveFilePath);
|
|
557
|
+
if (resolved) {
|
|
558
|
+
return { path: resolved, namespace: "file" };
|
|
559
|
+
}
|
|
560
|
+
}
|
|
484
561
|
});
|
|
485
562
|
// Loader for internal modules
|
|
486
563
|
build.onLoad({ filter: /.*/, namespace: 'internal' }, (args) => {
|
package/esm/commands/init.js
CHANGED
|
@@ -36,6 +36,19 @@ export function command_init() {
|
|
|
36
36
|
],
|
|
37
37
|
"url": "./node_modules/@jointhedots/gear/schemas/component.schema.json"
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
"fileMatch": [
|
|
41
|
+
"declaration.json",
|
|
42
|
+
"*.declaration.json",
|
|
43
|
+
"declaration.yaml",
|
|
44
|
+
"*.declaration.yaml",
|
|
45
|
+
"declaration.yml",
|
|
46
|
+
"*.declaration.yml",
|
|
47
|
+
"declaration.toml",
|
|
48
|
+
"*.declaration.toml",
|
|
49
|
+
],
|
|
50
|
+
"url": "./node_modules/@jointhedots/gear/schemas/declaration.schema.json"
|
|
51
|
+
},
|
|
39
52
|
]
|
|
40
53
|
});
|
|
41
54
|
}
|
package/esm/commands/make.js
CHANGED
|
@@ -61,7 +61,11 @@ export function command_make() {
|
|
|
61
61
|
default: "./dist",
|
|
62
62
|
}),
|
|
63
63
|
handler: async (argv) => {
|
|
64
|
-
const ws = await open_workspace(
|
|
64
|
+
const ws = await open_workspace({
|
|
65
|
+
workspace_path: argv.ws,
|
|
66
|
+
devmode: argv.devmode,
|
|
67
|
+
ignored_directory: Path.resolve(argv.dist),
|
|
68
|
+
});
|
|
65
69
|
if (argv.devmode)
|
|
66
70
|
ws.log.warn("Use devmode");
|
|
67
71
|
let version = argv.versioned;
|
package/esm/commands/publish.js
CHANGED
|
@@ -25,7 +25,10 @@ export function command_publish() {
|
|
|
25
25
|
}),
|
|
26
26
|
handler: async (argv) => {
|
|
27
27
|
const outputDir = Path.resolve(argv.dist);
|
|
28
|
-
const ws = await open_workspace(
|
|
28
|
+
const ws = await open_workspace({
|
|
29
|
+
workspace_path: ".",
|
|
30
|
+
devmode: false,
|
|
31
|
+
});
|
|
29
32
|
await publish_aws_s3(argv.app, ws, argv.bucket, argv.region, outputDir);
|
|
30
33
|
}
|
|
31
34
|
};
|
package/esm/commands/serve.js
CHANGED
|
@@ -38,10 +38,13 @@ export function command_serve() {
|
|
|
38
38
|
default: "./dist",
|
|
39
39
|
}),
|
|
40
40
|
handler: async (argv) => {
|
|
41
|
-
const ws = await open_workspace(
|
|
41
|
+
const ws = await open_workspace({
|
|
42
|
+
workspace_path: argv.ws,
|
|
43
|
+
devmode: argv.devmode,
|
|
44
|
+
});
|
|
42
45
|
const app = ws.get_application(argv.app);
|
|
43
46
|
if (!app)
|
|
44
|
-
throw new Error(`Application '${argv.app}' not exists
|
|
47
|
+
throw new Error(`Application '${argv.app}' not exists.`);
|
|
45
48
|
if (argv.devmode)
|
|
46
49
|
ws.log.warn("Use devmode");
|
|
47
50
|
let version = argv.versioned;
|
|
@@ -67,7 +67,7 @@ export function readConfigFileSync(path) {
|
|
|
67
67
|
* Find config files matching a base name (e.g. "bundle.component") in a directory.
|
|
68
68
|
* Returns all matching paths across supported extensions.
|
|
69
69
|
*/
|
|
70
|
-
export function
|
|
70
|
+
export function findConfigFile(dir, baseName, fnames) {
|
|
71
71
|
const results = [];
|
|
72
72
|
for (const ext of config_extensions) {
|
|
73
73
|
const fname = baseName + ext;
|
|
@@ -80,7 +80,12 @@ export function findConfigFiles(dir, baseName, fnames) {
|
|
|
80
80
|
results.push(`${dir}/${fname}`);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
if (results.length === 0)
|
|
84
|
+
return undefined;
|
|
85
|
+
if (results.length > 1) {
|
|
86
|
+
throw new Error(`Multiple config files found for '${baseName}': ${results.join(", ")}. Only one format is allowed.`);
|
|
87
|
+
}
|
|
88
|
+
return results[0];
|
|
84
89
|
}
|
|
85
90
|
/**
|
|
86
91
|
* Read a singleton config file (exactly one format must exist).
|
|
@@ -88,13 +93,8 @@ export function findConfigFiles(dir, baseName, fnames) {
|
|
|
88
93
|
* Returns `undefined` if no matching file exists.
|
|
89
94
|
*/
|
|
90
95
|
export async function readSingletonConfigFile(dir, baseName, fnames) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (paths.length > 1) {
|
|
95
|
-
throw new Error(`Multiple config files found for '${baseName}': ${paths.join(", ")}. Only one format is allowed.`);
|
|
96
|
-
}
|
|
97
|
-
const data = await readConfigFile(paths[0]);
|
|
98
|
-
return data !== undefined ? { data, path: paths[0] } : undefined;
|
|
96
|
+
const path = findConfigFile(dir, baseName, fnames);
|
|
97
|
+
const data = await readConfigFile(path);
|
|
98
|
+
return data !== undefined ? { data, path } : undefined;
|
|
99
99
|
}
|
|
100
100
|
//# sourceMappingURL=config-loader.js.map
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
import Path from "node:path";
|
|
1
2
|
import { makeComponentPublication } from "../component.js";
|
|
3
|
+
function add_export_entry(exports, lib, key, value, baseDir) {
|
|
4
|
+
const basename = key.startsWith("./") ? key.slice(2) : key;
|
|
5
|
+
const filename = lib.make_file_id("export", basename);
|
|
6
|
+
const source_ref = typeof value === "string" ? value : value?.import ?? value?.default ?? value?.require;
|
|
7
|
+
const entry = source_ref ? lib.resolve_entry_path(source_ref, baseDir) : null;
|
|
8
|
+
const id = `${lib.name}${basename === "." ? "" : "/" + basename}`;
|
|
9
|
+
exports[id] = {
|
|
10
|
+
id,
|
|
11
|
+
exported: key,
|
|
12
|
+
basename: filename,
|
|
13
|
+
filename: `${filename}.js`,
|
|
14
|
+
source: entry,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
2
17
|
function create_export_map(lib, bun) {
|
|
3
18
|
const exports = {};
|
|
4
19
|
if (bun) {
|
|
@@ -13,19 +28,18 @@ function create_export_map(lib, bun) {
|
|
|
13
28
|
};
|
|
14
29
|
}
|
|
15
30
|
}
|
|
16
|
-
for (const key in lib.descriptor.exports) {
|
|
31
|
+
for (const key in (lib.descriptor.exports || {})) {
|
|
17
32
|
const exp = lib.descriptor.exports[key];
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
33
|
+
add_export_entry(exports, lib, key, exp, lib.path);
|
|
34
|
+
}
|
|
35
|
+
for (const [decl_path, declaration] of lib.declarations) {
|
|
36
|
+
if (!declaration.exports)
|
|
37
|
+
continue;
|
|
38
|
+
const decl_base_dir = Path.dirname(decl_path);
|
|
39
|
+
for (const key in declaration.exports) {
|
|
40
|
+
const exp = declaration.exports[key];
|
|
41
|
+
add_export_entry(exports, lib, key, exp, decl_base_dir);
|
|
42
|
+
}
|
|
29
43
|
}
|
|
30
44
|
return exports;
|
|
31
45
|
}
|
|
@@ -5,9 +5,18 @@ import { checkComponentManifest } from "../component.js";
|
|
|
5
5
|
import { makeNormalizedName, NameStyle } from "../../utils/normalized-name.js";
|
|
6
6
|
import { create_manifests } from "./create-manifests.js";
|
|
7
7
|
import { Bundle, Library, Workspace } from "../workspace.js";
|
|
8
|
-
import { make_canonical_path, make_normalized_dirname, make_normalized_path, make_relative_path } from "../../utils/file.js";
|
|
9
|
-
import { is_config_filename, readConfigFile, readSingletonConfigFile } from "./config-loader.js";
|
|
10
|
-
const exclude_dirs = ["node_modules"];
|
|
8
|
+
import { file, make_canonical_path, make_normalized_dirname, make_normalized_path, make_relative_path } from "../../utils/file.js";
|
|
9
|
+
import { findConfigFile, is_config_filename, readConfigFile, readSingletonConfigFile } from "./config-loader.js";
|
|
10
|
+
const exclude_dirs = ["node_modules", ".git"];
|
|
11
|
+
function is_ignored_dir(ws, path) {
|
|
12
|
+
const normalized_path = make_normalized_path(path);
|
|
13
|
+
for (const ignored of ws.ignored_directories) {
|
|
14
|
+
if (normalized_path === ignored || normalized_path.startsWith(ignored + "/")) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
11
20
|
function setup_library_bundle(lib, bundle_desc) {
|
|
12
21
|
const manif = make_library_bundle_manifest(lib, bundle_desc);
|
|
13
22
|
const ws = lib.workspace;
|
|
@@ -88,7 +97,9 @@ async function discover_library_components(lib, path, subdir = false) {
|
|
|
88
97
|
const fstat = await Fsp.stat(fpath);
|
|
89
98
|
if (fstat.isDirectory()) {
|
|
90
99
|
if (!exclude_dirs.includes(fname)) {
|
|
91
|
-
await
|
|
100
|
+
if (await discover_library(lib.workspace, fpath, lib.installed) === Discovered.None) {
|
|
101
|
+
await discover_library_components(lib, fpath, true);
|
|
102
|
+
}
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
105
|
else if (fstat.isFile()) {
|
|
@@ -106,15 +117,6 @@ async function discover_library_components(lib, path, subdir = false) {
|
|
|
106
117
|
}
|
|
107
118
|
}
|
|
108
119
|
}
|
|
109
|
-
// Analyze library deployment manifest (supports json/yaml/yml/toml, singleton)
|
|
110
|
-
const manifest_result = await readSingletonConfigFile(path, "bundle.manifest", fnames);
|
|
111
|
-
if (manifest_result) {
|
|
112
|
-
const manifest = manifest_result.data;
|
|
113
|
-
for (const pub of manifest.data.components) {
|
|
114
|
-
const fpath = path + "/" + (pub.ref ?? pub.id);
|
|
115
|
-
await discover_component(lib, fpath);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
120
|
}
|
|
119
121
|
function make_library_bundle_manifest(lib, file_desc) {
|
|
120
122
|
let $id = file_desc?.$id;
|
|
@@ -165,46 +167,71 @@ function make_library_bundle_manifest(lib, file_desc) {
|
|
|
165
167
|
};
|
|
166
168
|
return manifest;
|
|
167
169
|
}
|
|
168
|
-
|
|
170
|
+
var Discovered;
|
|
171
|
+
(function (Discovered) {
|
|
172
|
+
Discovered[Discovered["None"] = 0] = "None";
|
|
173
|
+
Discovered[Discovered["Ignored"] = 1] = "Ignored";
|
|
174
|
+
Discovered[Discovered["Registered"] = 2] = "Registered";
|
|
175
|
+
})(Discovered || (Discovered = {}));
|
|
176
|
+
async function discover_library(ws, location, installed) {
|
|
169
177
|
const lib_path = make_canonical_path(ws.path, location);
|
|
178
|
+
if (is_ignored_dir(ws, lib_path))
|
|
179
|
+
return Discovered.Ignored;
|
|
180
|
+
const package_path = lib_path + "/package.json";
|
|
181
|
+
const manifest_path = findConfigFile(lib_path, "bundle.manifest");
|
|
182
|
+
if (!file.exists(package_path) && !file.exists(manifest_path))
|
|
183
|
+
return Discovered.None;
|
|
170
184
|
const lib_not_exists = ws.libraries.reduce((r, lib) => r && lib.path !== lib_path, true);
|
|
171
|
-
if (lib_not_exists)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
throw new Error(`library '${lib_desc.name}' declared multiple times\n - ${other.path}\n - ${lib_path}`);
|
|
184
|
-
}
|
|
185
|
+
if (!lib_not_exists)
|
|
186
|
+
return Discovered.Ignored;
|
|
187
|
+
const lib_desc = await readJsonFile(package_path);
|
|
188
|
+
if (!lib_desc?.name)
|
|
189
|
+
return Discovered.Ignored;
|
|
190
|
+
const manifest_desc = await readConfigFile(manifest_path);
|
|
191
|
+
if (manifest_desc || !installed) {
|
|
192
|
+
const other = ws.get_library(lib_desc.name);
|
|
193
|
+
if (other) {
|
|
194
|
+
if (lib_path.includes(other.path)) {
|
|
195
|
+
ws.log.info(`ignore library build at ${lib_path}`);
|
|
196
|
+
return Discovered.Ignored;
|
|
185
197
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (bundle_desc) {
|
|
189
|
-
setup_library_bundle(lib, bundle_desc);
|
|
198
|
+
else {
|
|
199
|
+
throw new Error(`library '${lib_desc.name}' declared multiple times\n - ${other.path}\n - ${lib_path}`);
|
|
190
200
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
201
|
+
}
|
|
202
|
+
const lib = new Library(lib_desc.name, lib_path, lib_desc, ws, installed);
|
|
203
|
+
ws.libraries.push(lib);
|
|
204
|
+
ws.log.info(`+ 📚 library: ${installed ? "⏬" : "🐣"} ${lib.get_id()} (${make_relative_path(ws.path, location)})`);
|
|
205
|
+
// Setup library infos from bundle manifest
|
|
206
|
+
if (manifest_desc) {
|
|
207
|
+
setup_library_bundle(lib, manifest_desc);
|
|
208
|
+
// Analyze library deployment manifest (supports json/yaml/yml/toml, singleton)
|
|
209
|
+
for (const pub of manifest_desc.data.components) {
|
|
210
|
+
const fpath = lib_path + "/" + (pub.ref ?? pub.id);
|
|
211
|
+
await discover_component(lib, fpath);
|
|
194
212
|
}
|
|
195
|
-
await discover_library_components(lib, lib_path);
|
|
196
213
|
}
|
|
214
|
+
// Setup node search directory
|
|
215
|
+
const lib_search_path = lib_path + "/node_modules";
|
|
216
|
+
if (Fs.existsSync(lib_search_path)) {
|
|
217
|
+
lib.search_directories.push(lib_search_path);
|
|
218
|
+
}
|
|
219
|
+
// Collect library declaration
|
|
220
|
+
await discover_library_components(lib, lib_path);
|
|
221
|
+
return Discovered.Registered;
|
|
197
222
|
}
|
|
223
|
+
return Discovered.None;
|
|
198
224
|
}
|
|
199
225
|
async function discover_workspace_libraries(ws) {
|
|
200
226
|
async function walk(dir) {
|
|
201
|
-
await discover_library(ws, dir)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
227
|
+
if (await discover_library(ws, dir, false) === Discovered.None) {
|
|
228
|
+
for (const entry of Fs.readdirSync(dir, { withFileTypes: true })) {
|
|
229
|
+
if (entry.name === "node_modules")
|
|
230
|
+
continue;
|
|
231
|
+
const fullPath = dir + "/" + entry.name;
|
|
232
|
+
if (entry.isDirectory()) {
|
|
233
|
+
await walk(fullPath);
|
|
234
|
+
}
|
|
208
235
|
}
|
|
209
236
|
}
|
|
210
237
|
}
|
|
@@ -245,7 +272,7 @@ export async function discover_workspace(ws) {
|
|
|
245
272
|
}
|
|
246
273
|
await discover_workspace_libraries(ws);
|
|
247
274
|
for (const location in package_lock.packages) {
|
|
248
|
-
await discover_library(ws, location);
|
|
275
|
+
await discover_library(ws, location, true);
|
|
249
276
|
}
|
|
250
277
|
for (const bun of ws.bundles) {
|
|
251
278
|
if (bun.source) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Process from "node:process";
|
|
1
2
|
export class Log {
|
|
2
3
|
id;
|
|
3
4
|
entries = [];
|
|
@@ -41,7 +42,12 @@ export class Log {
|
|
|
41
42
|
}
|
|
42
43
|
export class Logger {
|
|
43
44
|
loggers = new Map();
|
|
44
|
-
|
|
45
|
+
mode;
|
|
46
|
+
silentKinds;
|
|
47
|
+
constructor(mode = getLogModeFromEnv()) {
|
|
48
|
+
this.mode = mode;
|
|
49
|
+
this.silentKinds = getSilentKinds(mode);
|
|
50
|
+
}
|
|
45
51
|
get(id) {
|
|
46
52
|
let logger = this.loggers.get(id);
|
|
47
53
|
if (!logger) {
|
|
@@ -63,6 +69,24 @@ export class Logger {
|
|
|
63
69
|
this.loggers.clear();
|
|
64
70
|
}
|
|
65
71
|
}
|
|
72
|
+
function getLogModeFromEnv() {
|
|
73
|
+
const value = Process.env.JTDGEAR_LOG_MODE?.trim().toLowerCase();
|
|
74
|
+
if (value === "debug" || value === "verbose" || value === "normal") {
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
return "normal";
|
|
78
|
+
}
|
|
79
|
+
function getSilentKinds(mode) {
|
|
80
|
+
switch (mode) {
|
|
81
|
+
case "verbose":
|
|
82
|
+
return new Set();
|
|
83
|
+
case "debug":
|
|
84
|
+
return new Set(["trace"]);
|
|
85
|
+
case "normal":
|
|
86
|
+
default:
|
|
87
|
+
return new Set(["trace", "debug"]);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
66
90
|
export function stringifyLocation(loc) {
|
|
67
91
|
if (!loc)
|
|
68
92
|
return "";
|