@jointhedots/gear 1.1.11 → 1.1.13

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.
@@ -1,11 +1,13 @@
1
+ import Path from "node:path";
1
2
  import { Bundle, Library } from "../model/workspace.js";
2
3
  import { StorageFiles } from "../model/storage.js";
3
- import { BuildTarget, BundleManifestTask } from "./build-target.js";
4
- import { TypescriptDefinitionTask } from "./emit-dts.js";
5
- import Path from "node:path";
4
+ import { BuildTarget } from "./build-target.js";
5
+ import { TypescriptDefinitionTask } from "./helpers/emit-typescript-definition.js";
6
+ import { PackageManifestTask } from "./helpers/emit-package-manifest.js";
6
7
  import { PathQualifier } from "./helpers/path-helpers.js";
7
- import { create_manifests } from "../model/helpers/create-manifests.js";
8
- import { DependencyDeduplicationPlugin, collectLibraryGraph } from "./esbuild-plugins.js";
8
+ import { create_export_map } from "../model/helpers/create-manifests.js";
9
+ import { DependencyDeduplicationPlugin, collectLibraryGraph } from "./helpers/emit-esmodules.js";
10
+ import { BundleManifestTask } from "./helpers/emit-bundle-manifest.js";
9
11
  export var PathStatus;
10
12
  (function (PathStatus) {
11
13
  PathStatus[PathStatus["Unknown"] = undefined] = "Unknown";
@@ -18,16 +20,16 @@ export function create_bundle_target(opts) {
18
20
  const { bundle, library, storage } = opts;
19
21
  const lib = library;
20
22
  const target = new BuildTarget(bundle.id, storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
21
- const manifs = create_manifests(lib, bundle, opts.version);
22
23
  // Prepare esm setup
23
24
  target.esmodules.set_root(lib.path);
24
25
  // Add bundle package.json
25
- target.assets.add_static_json("package.json", manifs.package);
26
+ target.tasks.push(new PackageManifestTask(target, lib, opts.version));
26
27
  // Add bundle types.d.ts
27
28
  target.tasks.push(new TypescriptDefinitionTask(target, lib));
28
29
  // Add bundle exporteds
29
- for (const exp_id in manifs.entries) {
30
- const exp = manifs.entries[exp_id];
30
+ const entries = create_export_map(lib, lib.bundle);
31
+ for (const exp_id in entries) {
32
+ const exp = entries[exp_id];
31
33
  target.esmodules.add_entry(exp.basename, exp.source);
32
34
  }
33
35
  // Add bundle content
@@ -1,12 +1,13 @@
1
- import { Library, matchComponentSelection } from "../model/workspace.js";
2
- import { StorageFiles } from "../model/storage.js";
3
- import { BuildTarget, BuildTask, BundleManifestTask } from "./build-target.js";
4
1
  import Path from "node:path";
5
- import Fs from "node:fs";
6
2
  import Sharp from "sharp";
7
3
  import MIME from 'mime';
4
+ import { Library, matchComponentSelection } from "../model/workspace.js";
5
+ import { StorageFiles } from "../model/storage.js";
6
+ import { BuildTarget } from "./build-target.js";
8
7
  import { build_app_composable_host } from "./build-app-host.js";
9
- import { DependencyDeduplicationPlugin } from "./esbuild-plugins.js";
8
+ import { DependencyDeduplicationPlugin } from "./helpers/emit-esmodules.js";
9
+ import { BundleManifestTask } from "./helpers/emit-bundle-manifest.js";
10
+ import { BuildTask } from "./helpers/task.js";
10
11
  function collect_app_libraries(app) {
11
12
  const libs = [app.library];
12
13
  function collect_library_deps(lib) {
@@ -1,25 +1,27 @@
1
+ import Path from "node:path";
2
+ import ChildProcess from "child_process";
1
3
  import { Library } from "../model/workspace.js";
2
4
  import { StorageFiles } from "../model/storage.js";
3
- import ChildProcess from "child_process";
4
- import { BuildTarget, BundleManifestTask } from "./build-target.js";
5
- import { TypescriptDefinitionTask } from "./emit-dts.js";
6
- import Path from "node:path";
7
- import { create_manifests } from "../model/helpers/create-manifests.js";
5
+ import { BuildTarget } from "./build-target.js";
6
+ import { TypescriptDefinitionTask } from "./helpers/emit-typescript-definition.js";
7
+ import { PackageManifestTask } from "./helpers/emit-package-manifest.js";
8
+ import { create_export_map } from "../model/helpers/create-manifests.js";
9
+ import { BundleManifestTask } from "./helpers/emit-bundle-manifest.js";
8
10
  export function create_library_target(opts) {
9
11
  const lib = opts.library;
10
12
  const target = new BuildTarget(lib.name, opts.storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
11
- const manifs = create_manifests(lib, lib.bundle, opts.version);
12
13
  // Prepare esm setup
13
14
  target.esmodules.set_root(lib.path);
14
15
  // Add bundle exporteds
15
- for (const exp_id in manifs.entries) {
16
- const exp = manifs.entries[exp_id];
16
+ const entries = create_export_map(lib, lib.bundle);
17
+ for (const exp_id in entries) {
18
+ const exp = entries[exp_id];
17
19
  target.esmodules.add_entry(exp.basename, exp.source);
18
20
  }
19
21
  // Add library types.d.ts
20
22
  target.tasks.push(new TypescriptDefinitionTask(target, lib));
21
23
  // Add library package.json
22
- target.assets.add_static_json("package.json", manifs.package);
24
+ target.tasks.push(new PackageManifestTask(target, lib, opts.version));
23
25
  // Add bundle content
24
26
  const { bundle } = lib;
25
27
  if (bundle) {
@@ -1,145 +1,8 @@
1
- import Path from "node:path";
2
- import MIME from 'mime';
3
- import { makeComponentPublication } from "../model/component.js";
4
- import { Bundle, Library, Workspace } from "../model/workspace.js";
5
- import { create_esbuild_context } from "../builder/esbuild-plugins.js";
6
- import { copyToStorageStream } from "../model/storage.js";
7
- import * as esbuild from 'esbuild';
8
- import { computeNameHashID } from "../utils/normalized-name.js";
9
- export class BuildTask {
10
- target;
11
- constructor(target) {
12
- this.target = target;
13
- }
14
- get log() { return this.target.log; }
15
- async init() { }
16
- }
17
- export class BundleManifestTask extends BuildTask {
18
- target;
19
- bundle;
20
- constructor(target, bundle) {
21
- super(target);
22
- this.target = target;
23
- this.bundle = bundle;
24
- }
25
- async execute() {
26
- const { target, bundle } = this;
27
- const { manifest } = bundle;
28
- const tx = this.target.edit();
29
- // Emit static components manifest
30
- const components = [];
31
- for (const manif of target.components.values()) {
32
- const pub = makeComponentPublication(manif);
33
- pub.ref = await tx.commitContent(JSON.stringify(manif, null, 2), MIME.getType(".json"));
34
- components.push(pub);
35
- }
36
- manifest.data.components = components;
37
- // Emit bundle manifest
38
- await tx.commitFile(`bundle.manifest.json`, JSON.stringify(manifest, null, 2));
39
- }
40
- }
41
- export class AssetsTask extends BuildTask {
42
- assets = [];
43
- statics = {};
44
- add_entry(entry, baseDir, library) {
45
- let asset = null;
46
- if (typeof entry === "string") {
47
- const from = library.resolve_entry_path(entry, baseDir);
48
- if (!from)
49
- throw new Error(`In '${baseDir}', cannot found asset from: '${entry}'`);
50
- asset = { from, to: Path.basename(entry) };
51
- }
52
- else {
53
- const from = library.resolve_entry_path(entry.from, baseDir);
54
- if (!from)
55
- throw new Error(`In '${baseDir}', cannot found asset from: '${entry.from}'`);
56
- asset = { from, to: entry.to };
57
- }
58
- this.log.info(`+ 📎 assets '${library.name}': ${asset.from} -> ${asset.to}`);
59
- this.assets.push(asset);
60
- }
61
- add_static_text(name, data) {
62
- this.statics[name] = data;
63
- }
64
- add_static_json(name, data) {
65
- this.statics[name] = JSON.stringify(data, null, 2);
66
- }
67
- async execute() {
68
- const tx = this.target.edit();
69
- for (const key in this.statics) {
70
- tx.commitFile(key, this.statics[key], MIME.getType(key));
71
- }
72
- for (const asset of this.assets) {
73
- if (typeof asset === "string") {
74
- copyToStorageStream(tx, asset, asset);
75
- }
76
- else {
77
- copyToStorageStream(tx, asset.to, asset.from);
78
- }
79
- }
80
- }
81
- }
82
- export class ESModulesTask extends BuildTask {
83
- entries = {};
84
- imports = {};
85
- internals = new Map();
86
- plugins = [];
87
- context = null;
88
- transaction = null;
89
- polyfilled = true;
90
- rootPath = null;
91
- set_root(path) {
92
- this.rootPath = path;
93
- }
94
- add_entry(name, path) {
95
- this.entries[name] = path;
96
- this.imports[path] = name;
97
- }
98
- add_entry_typescript(code, name) {
99
- const id = computeNameHashID(code);
100
- if (!name)
101
- name = id;
102
- this.internals.set(id, code);
103
- this.add_entry(name, id);
104
- return name;
105
- }
106
- add_resource_entry(resource, baseDir, library) {
107
- if (typeof resource === "string") {
108
- const parts = resource.split("#");
109
- const file = library.resolve_entry_path(parts[0], baseDir);
110
- if (file) {
111
- let named = this.imports[file];
112
- if (!named) {
113
- named = library.make_file_id("lambda", file);
114
- this.add_entry(named, file);
115
- }
116
- return `./${named}.js#${parts[1] || "default"}`;
117
- }
118
- else {
119
- throw new Error(`${library.name}: Cannot resolve file: ${parts[0]}`);
120
- }
121
- }
122
- else {
123
- return resource;
124
- }
125
- }
126
- async execute() {
127
- if (this.context) {
128
- const prev_ctx = this.context;
129
- this.context = null;
130
- await prev_ctx.dispose();
131
- }
132
- const { target } = this;
133
- this.context = await create_esbuild_context(this, target.devmode);
134
- if (target.watch) {
135
- await this.context.watch();
136
- }
137
- else {
138
- await this.context.rebuild();
139
- await this.context.dispose();
140
- }
141
- }
142
- }
1
+ import {} from "../model/component.js";
2
+ import { Library, Workspace } from "../model/workspace.js";
3
+ import { ESModulesTask } from "./helpers/emit-esmodules.js";
4
+ import {} from "../model/storage.js";
5
+ import { AssetsTask } from "./helpers/emit-static-assets.js";
143
6
  export class BuildTarget {
144
7
  name;
145
8
  storage;
@@ -0,0 +1,29 @@
1
+ import { makeComponentPublication } from "../../model/component.js";
2
+ import { BuildTarget } from "../build-target.js";
3
+ import { BuildTask } from "./task.js";
4
+ import MIME from 'mime';
5
+ export class BundleManifestTask extends BuildTask {
6
+ target;
7
+ bundle;
8
+ constructor(target, bundle) {
9
+ super(target);
10
+ this.target = target;
11
+ this.bundle = bundle;
12
+ }
13
+ async execute() {
14
+ const { target, bundle } = this;
15
+ const { manifest } = bundle;
16
+ const tx = this.target.edit();
17
+ // Emit static components manifest
18
+ const components = [];
19
+ for (const manif of target.components.values()) {
20
+ const pub = makeComponentPublication(manif);
21
+ pub.ref = await tx.commitContent(JSON.stringify(manif, null, 2), MIME.getType(".json"));
22
+ components.push(pub);
23
+ }
24
+ manifest.data.components = components;
25
+ // Emit bundle manifest
26
+ await tx.commitFile(`bundle.manifest.json`, JSON.stringify(manifest, null, 2));
27
+ }
28
+ }
29
+ //# sourceMappingURL=emit-bundle-manifest.js.map
@@ -5,9 +5,10 @@ import MIME from 'mime';
5
5
  import postcss from 'postcss';
6
6
  import * as esbuild from 'esbuild';
7
7
  import { sassPlugin } from 'esbuild-sass-plugin';
8
- import { ESModulesTask } from "./build-target.js";
9
- import { PackageRootDir } from "../utils/file.js";
10
- import { Library } from "../model/workspace.js";
8
+ import { PackageRootDir, resolve_normalized_suffixed_path } from "../../utils/file.js";
9
+ import { Library } from "../../model/workspace.js";
10
+ import { computeNameHashID } from "../../utils/normalized-name.js";
11
+ import { BuildTask } from "./task.js";
11
12
  const VirtualOutDir = Path.normalize('X:/');
12
13
  function getEsbuildLogLevel(mode) {
13
14
  switch (mode) {
@@ -486,30 +487,6 @@ export function ESModuleResolverPlugin(opts, tsconfigPaths) {
486
487
  ".ts": "ts", ".tsx": "tsx", ".js": "js", ".jsx": "jsx",
487
488
  ".json": "json", ".txt": "text", ".md": "text", ".css": "css",
488
489
  };
489
- const FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json'];
490
- /** Resolve a file path with extension probing */
491
- function resolveFilePath(importPath, baseDir) {
492
- const resolved = Path.resolve(baseDir, importPath);
493
- // Check if exact path exists
494
- if (Fs.existsSync(resolved) && Fs.statSync(resolved).isFile()) {
495
- return resolved;
496
- }
497
- // Try with common extensions
498
- for (const ext of FILE_EXTENSIONS) {
499
- const withExt = resolved + ext;
500
- if (Fs.existsSync(withExt))
501
- return withExt;
502
- }
503
- // Try index files in directory
504
- if (Fs.existsSync(resolved) && Fs.statSync(resolved).isDirectory()) {
505
- for (const ext of FILE_EXTENSIONS) {
506
- const indexPath = Path.join(resolved, `index${ext}`);
507
- if (Fs.existsSync(indexPath))
508
- return indexPath;
509
- }
510
- }
511
- return null;
512
- }
513
490
  return {
514
491
  name: 'esm-resolver',
515
492
  setup(build) {
@@ -546,14 +523,16 @@ export function ESModuleResolverPlugin(opts, tsconfigPaths) {
546
523
  // 3. Handle relative/absolute file paths (entry points and local imports)
547
524
  if (args.path.startsWith(".") || args.path.startsWith("/") || Path.isAbsolute(args.path)) {
548
525
  const baseDir = args.resolveDir || workspaceRoot;
549
- const resolved = resolveFilePath(args.path, baseDir);
526
+ const resolved = resolve_normalized_suffixed_path(baseDir, args.path);
550
527
  if (resolved) {
551
528
  return { path: resolved, namespace: "file" };
552
529
  }
553
530
  }
554
531
  // 4. Resolve tsconfig path aliases (e.g. @app/* -> ./src/*)
555
532
  if (tsconfigPaths?.hasAliases) {
556
- const resolved = tsconfigPaths.resolve(args.path, resolveFilePath);
533
+ const resolved = tsconfigPaths.resolve(args.path, (importPath, baseDir) => {
534
+ return resolve_normalized_suffixed_path(baseDir, importPath);
535
+ });
557
536
  if (resolved) {
558
537
  return { path: resolved, namespace: "file" };
559
538
  }
@@ -572,4 +551,65 @@ export function ESModuleResolverPlugin(opts, tsconfigPaths) {
572
551
  },
573
552
  };
574
553
  }
575
- //# sourceMappingURL=esbuild-plugins.js.map
554
+ export class ESModulesTask extends BuildTask {
555
+ entries = {};
556
+ imports = {};
557
+ internals = new Map();
558
+ plugins = [];
559
+ context = null;
560
+ transaction = null;
561
+ polyfilled = true;
562
+ rootPath = null;
563
+ set_root(path) {
564
+ this.rootPath = path;
565
+ }
566
+ add_entry(name, path) {
567
+ this.entries[name] = path;
568
+ this.imports[path] = name;
569
+ }
570
+ add_entry_typescript(code, name) {
571
+ const id = computeNameHashID(code);
572
+ if (!name)
573
+ name = id;
574
+ this.internals.set(id, code);
575
+ this.add_entry(name, id);
576
+ return name;
577
+ }
578
+ add_resource_entry(resource, baseDir, library) {
579
+ if (typeof resource === "string") {
580
+ const parts = resource.split("#");
581
+ const file = library.resolve_entry_path(parts[0], baseDir);
582
+ if (file) {
583
+ let named = this.imports[file];
584
+ if (!named) {
585
+ named = library.make_file_id("lambda", file);
586
+ this.add_entry(named, file);
587
+ }
588
+ return `./${named}.js#${parts[1] || "default"}`;
589
+ }
590
+ else {
591
+ throw new Error(`${library.name}: Cannot resolve file: ${parts[0]}`);
592
+ }
593
+ }
594
+ else {
595
+ return resource;
596
+ }
597
+ }
598
+ async execute() {
599
+ if (this.context) {
600
+ const prev_ctx = this.context;
601
+ this.context = null;
602
+ await prev_ctx.dispose();
603
+ }
604
+ const { target } = this;
605
+ this.context = await create_esbuild_context(this, target.devmode);
606
+ if (target.watch) {
607
+ await this.context.watch();
608
+ }
609
+ else {
610
+ await this.context.rebuild();
611
+ await this.context.dispose();
612
+ }
613
+ }
614
+ }
615
+ //# sourceMappingURL=emit-esmodules.js.map
@@ -0,0 +1,19 @@
1
+ import { BuildTask } from "./task.js";
2
+ import { create_export_map, create_package_manifest } from "../../model/helpers/create-manifests.js";
3
+ import { console } from "node:inspector";
4
+ export class PackageManifestTask extends BuildTask {
5
+ library;
6
+ version;
7
+ constructor(target, library, version) {
8
+ super(target);
9
+ this.library = library;
10
+ this.version = version;
11
+ }
12
+ async execute() {
13
+ const { library, version } = this;
14
+ const pkg = create_package_manifest(library, library.bundle, version);
15
+ const tx = this.target.edit();
16
+ tx.commitFile("package.json", JSON.stringify(pkg, null, 2));
17
+ }
18
+ }
19
+ //# sourceMappingURL=emit-package-manifest.js.map
@@ -0,0 +1,47 @@
1
+ import Path from "node:path";
2
+ import MIME from 'mime';
3
+ import { Library } from "../../model/workspace.js";
4
+ import { copyToStorageStream } from "../../model/storage.js";
5
+ import { BuildTask } from "./task.js";
6
+ export class AssetsTask extends BuildTask {
7
+ assets = [];
8
+ statics = {};
9
+ add_entry(entry, baseDir, library) {
10
+ let asset = null;
11
+ if (typeof entry === "string") {
12
+ const from = library.resolve_entry_path(entry, baseDir);
13
+ if (!from)
14
+ throw new Error(`In '${baseDir}', cannot found asset from: '${entry}'`);
15
+ asset = { from, to: Path.basename(entry) };
16
+ }
17
+ else {
18
+ const from = library.resolve_entry_path(entry.from, baseDir);
19
+ if (!from)
20
+ throw new Error(`In '${baseDir}', cannot found asset from: '${entry.from}'`);
21
+ asset = { from, to: entry.to };
22
+ }
23
+ this.log.info(`+ 📎 assets '${library.name}': ${asset.from} -> ${asset.to}`);
24
+ this.assets.push(asset);
25
+ }
26
+ add_static_text(name, data) {
27
+ this.statics[name] = data;
28
+ }
29
+ add_static_json(name, data) {
30
+ this.statics[name] = JSON.stringify(data, null, 2);
31
+ }
32
+ async execute() {
33
+ const tx = this.target.edit();
34
+ for (const key in this.statics) {
35
+ tx.commitFile(key, this.statics[key], MIME.getType(key));
36
+ }
37
+ for (const asset of this.assets) {
38
+ if (typeof asset === "string") {
39
+ copyToStorageStream(tx, asset, asset);
40
+ }
41
+ else {
42
+ copyToStorageStream(tx, asset.to, asset.from);
43
+ }
44
+ }
45
+ }
46
+ }
47
+ //# sourceMappingURL=emit-static-assets.js.map
@@ -2,9 +2,11 @@ import * as Glob from 'glob';
2
2
  import Os from 'os';
3
3
  import Path from 'path';
4
4
  import Ts from 'typescript';
5
- import { BuildTarget, BuildTask } from './build-target.js';
6
- import { Library } from '../model/workspace.js';
7
- import { file } from '../utils/file.js';
5
+ import { BuildTask } from "./task.js";
6
+ import { BuildTarget } from "../build-target.js";
7
+ import { Library } from "../../model/workspace.js";
8
+ import { file } from "../../utils/file.js";
9
+ import { create_export_map } from "../../model/helpers/create-manifests.js";
8
10
  const eol = Os.EOL;
9
11
  const indent = " ";
10
12
  const DTSLEN = '.d.ts'.length;
@@ -178,44 +180,42 @@ export function generateTypescriptDefinition(options) {
178
180
  const sourcesMap = {};
179
181
  const internalsMap = {};
180
182
  project.getSourceFiles().some(function (sourceFile) {
181
- if (sourceFile.fileName.indexOf(normalizedBaseDir) !== 0)
183
+ const { fileName } = sourceFile;
184
+ if (fileName.indexOf(normalizedBaseDir) !== 0)
182
185
  return;
183
- if (excludesMap[sourceFile.fileName])
186
+ if (excludesMap[fileName])
184
187
  return;
185
- const shortName = sourceFile.fileName.slice(normalizedBaseDir.length);
186
- const shortNameNoExt = shortName.slice(0, -Path.extname(sourceFile.fileName).length);
188
+ const shortName = fileName.slice(normalizedBaseDir.length);
189
+ const shortNameNoExt = shortName.slice(0, -Path.extname(fileName).length);
187
190
  const strippedShortName = stripBaseUrlPrefix(shortName);
188
191
  const strippedShortNameNoExt = stripBaseUrlPrefix(shortNameNoExt);
189
- let moduleId = `${options.prefix}/${strippedShortNameNoExt}`;
192
+ const moduleId = `${options.prefix}/${strippedShortNameNoExt}`;
190
193
  internalsMap[shortName] = moduleId;
191
194
  internalsMap[shortNameNoExt] = moduleId;
192
195
  internalsMap[strippedShortName] = moduleId;
193
196
  internalsMap[strippedShortNameNoExt] = moduleId;
194
- sourcesMap[sourceFile.fileName] = true;
197
+ sourcesMap[fileName] = true;
195
198
  });
196
199
  // Build reverse map from internal paths to export names
197
200
  // e.g., "src/Inputs" -> "./Inputs" means internal path "src/Inputs" exports as "prefix/Inputs"
198
201
  // Store as [internalPrefix, exportName] pairs for prefix matching
199
202
  if (options.exports) {
200
- for (const [exportPath, value] of Object.entries(options.exports)) {
201
- const exported = typeof value === 'string' ? value : (value.import || value.default || value.types || '');
202
- if (!exported)
203
+ for (const entry of Object.values(options.exports)) {
204
+ const fileName = entry.source;
205
+ if (fileName.indexOf(normalizedBaseDir) !== 0)
203
206
  continue;
204
- let exportId = exportPath.replace(/^\.\//, '').replace(/\/$/, '');
205
- if (exportId === '.')
206
- exportId = options.prefix;
207
- else
208
- exportId = `${options.prefix}/${exportId}`;
209
- // Normalize internal path: remove leading ./, strip extensions
210
- const internalPath = normalizeFileName(exported);
211
- let shortNameNoExt = internalPath.replace(/^\.\//, '').replace(/\.(ts|tsx|js|jsx)$/, '');
212
- if (shortNameNoExt.endsWith('/index'))
213
- shortNameNoExt = shortNameNoExt.slice(0, -6);
207
+ if (excludesMap[fileName])
208
+ continue;
209
+ const shortName = fileName.slice(normalizedBaseDir.length);
210
+ const shortNameNoExt = shortName.slice(0, -Path.extname(fileName).length);
211
+ const strippedShortName = stripBaseUrlPrefix(shortName);
214
212
  const strippedShortNameNoExt = stripBaseUrlPrefix(shortNameNoExt);
215
- //this.log.info(shortNameNoExt, "->", exportId)
216
- //this.log.info(strippedShortNameNoExt, "->", exportId)
217
- internalsMap[shortNameNoExt] = exportId;
218
- internalsMap[strippedShortNameNoExt] = exportId;
213
+ const moduleId = entry.id;
214
+ internalsMap[shortName] = moduleId;
215
+ internalsMap[shortNameNoExt] = moduleId;
216
+ internalsMap[strippedShortName] = moduleId;
217
+ internalsMap[strippedShortNameNoExt] = moduleId;
218
+ sourcesMap[fileName] = true;
219
219
  }
220
220
  }
221
221
  // Unified module ID normalization: strip extensions, baseUrl prefix, and remap to exports
@@ -224,18 +224,11 @@ export function generateTypescriptDefinition(options) {
224
224
  moduleId = moduleId.replace(/\.(d\.ts|ts|tsx|js|jsx)$/, '');
225
225
  // Strip baseUrl prefix
226
226
  moduleId = stripBaseUrlPrefix(moduleId);
227
- // Strip index suffix
228
- if (moduleId === "index") {
229
- return options.prefix;
230
- }
231
- if (moduleId.endsWith("/index")) {
232
- moduleId = moduleId.slice(0, -6);
233
- }
234
227
  // Apply resolved prefix
235
- if (internalsMap[moduleId]) {
236
- moduleId = internalsMap[moduleId];
237
- }
238
- return moduleId;
228
+ const remapped = internalsMap[moduleId] ||
229
+ internalsMap[moduleId + "/index"] ||
230
+ internalsMap[moduleId + "/index.ts"];
231
+ return remapped || moduleId;
239
232
  }
240
233
  // Generate source files
241
234
  project.getSourceFiles().some(function (sourceFile) {
@@ -312,6 +305,9 @@ export function generateTypescriptDefinition(options) {
312
305
  const resolved = resolveModuleImport(expression.text);
313
306
  return ` require('${resolved}')`;
314
307
  }
308
+ else if (isNodeKindImportDeclaration(node) && !node.importClause) {
309
+ return '';
310
+ }
315
311
  else if (node.kind === Ts.SyntaxKind.DeclareKeyword) {
316
312
  return '';
317
313
  }
@@ -375,7 +371,7 @@ export class TypescriptDefinitionTask extends BuildTask {
375
371
  project,
376
372
  prefix: lib.name,
377
373
  exclude: ["node_modules/**/*"],
378
- exports: lib.descriptor.exports || {},
374
+ exports: create_export_map(lib, lib.bundle),
379
375
  });
380
376
  file.write.text(storage.getBaseDirFS() + "/types.d.ts", dts);
381
377
  logDiagnostics(this.log, diagnostics);
@@ -385,4 +381,4 @@ export class TypescriptDefinitionTask extends BuildTask {
385
381
  }
386
382
  }
387
383
  }
388
- //# sourceMappingURL=emit-dts.js.map
384
+ //# sourceMappingURL=emit-typescript-definition.js.map
@@ -0,0 +1,9 @@
1
+ export class BuildTask {
2
+ target;
3
+ constructor(target) {
4
+ this.target = target;
5
+ }
6
+ get log() { return this.target.log; }
7
+ async init() { }
8
+ }
9
+ //# sourceMappingURL=task.js.map
@@ -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 findConfigFiles(dir, baseName, fnames) {
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
- return results;
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 paths = findConfigFiles(dir, baseName, fnames);
92
- if (paths.length === 0)
93
- return undefined;
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,10 +1,11 @@
1
1
  import Path from "node:path";
2
2
  import { makeComponentPublication } from "../component.js";
3
+ import { resolve_normalized_suffixed_path } from "../../utils/file.js";
3
4
  function add_export_entry(exports, lib, key, value, baseDir) {
4
5
  const basename = key.startsWith("./") ? key.slice(2) : key;
5
6
  const filename = lib.make_file_id("export", basename);
6
7
  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 entry = source_ref ? resolve_normalized_suffixed_path(lib.resolve_entry_path(source_ref, baseDir), ".") : null;
8
9
  const id = `${lib.name}${basename === "." ? "" : "/" + basename}`;
9
10
  exports[id] = {
10
11
  id,
@@ -14,7 +15,7 @@ function add_export_entry(exports, lib, key, value, baseDir) {
14
15
  source: entry,
15
16
  };
16
17
  }
17
- function create_export_map(lib, bun) {
18
+ export function create_export_map(lib, bun) {
18
19
  const exports = {};
19
20
  if (bun) {
20
21
  for (const id in bun.distribueds) {
@@ -43,26 +44,28 @@ function create_export_map(lib, bun) {
43
44
  }
44
45
  return exports;
45
46
  }
46
- export function create_manifests(lib, bun, build_version) {
47
+ export function create_bundle_manifest(lib, bun) {
48
+ if (!bun)
49
+ return null;
47
50
  const entries = create_export_map(lib, bun);
48
- let bundle_manif = null;
49
- if (bun) {
50
- bundle_manif = bun.manifest;
51
- const components = [];
52
- for (const comp of bun.components.values()) {
53
- components.push(makeComponentPublication(comp));
54
- }
55
- bundle_manif.data = {
56
- baseline: bun.id + "-v0",
57
- components: components,
58
- exports: {},
59
- };
60
- for (const id in entries) {
61
- const exp = entries[id];
62
- bundle_manif.data.exports[id] = exp.filename;
63
- }
51
+ const bundle_manif = bun.manifest;
52
+ const components = [];
53
+ for (const comp of bun.components.values()) {
54
+ components.push(makeComponentPublication(comp));
55
+ }
56
+ bundle_manif.data = {
57
+ baseline: bun.id + "-v0",
58
+ components: components,
59
+ exports: {},
60
+ };
61
+ for (const id in entries) {
62
+ const exp = entries[id];
63
+ bundle_manif.data.exports[id] = exp.filename;
64
64
  }
65
- // Add bundle package.json
65
+ return bundle_manif;
66
+ }
67
+ export function create_package_manifest(lib, bun, build_version) {
68
+ const entries = create_export_map(lib, bun);
66
69
  const pkg_manif = {
67
70
  ...lib.descriptor,
68
71
  name: lib.name,
@@ -74,14 +77,32 @@ export function create_manifests(lib, bun, build_version) {
74
77
  devDependencies: undefined,
75
78
  optionalDependencies: undefined,
76
79
  };
80
+ if (pkg_manif.dependencies) {
81
+ const resolved = lib.workspace.resolved_versions;
82
+ for (const dep in pkg_manif.dependencies) {
83
+ if (pkg_manif.dependencies[dep] === "*") {
84
+ const dep_resolved = resolved[dep];
85
+ if (dep_resolved) {
86
+ const [major, minor] = dep_resolved.split(".");
87
+ pkg_manif.dependencies[dep] = `^${major}.${minor}.0`;
88
+ }
89
+ else {
90
+ lib.log.warn(`Library dependency '${dep}' is versioned as * but not updatable to locked version`);
91
+ }
92
+ }
93
+ }
94
+ }
77
95
  for (const id in entries) {
78
96
  const exp = entries[id];
79
97
  if (exp.exported) {
80
98
  if (!pkg_manif.exports)
81
99
  pkg_manif.exports = {};
82
- pkg_manif.exports[exp.exported] = { import: `./${exp.filename}`, types: "./types.d.ts" };
100
+ pkg_manif.exports[exp.exported] = {
101
+ import: `./${exp.filename}`,
102
+ types: "./types.d.ts",
103
+ };
83
104
  }
84
105
  }
85
- return { package: pkg_manif, bundle: bundle_manif, entries };
106
+ return pkg_manif;
86
107
  }
87
108
  //# sourceMappingURL=create-manifests.js.map
@@ -3,11 +3,11 @@ import Fsp from "node:fs/promises";
3
3
  import { readJsonFile } from "../storage.js";
4
4
  import { checkComponentManifest } from "../component.js";
5
5
  import { makeNormalizedName, NameStyle } from "../../utils/normalized-name.js";
6
- import { create_manifests } from "./create-manifests.js";
6
+ import { create_bundle_manifest } 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
11
  function is_ignored_dir(ws, path) {
12
12
  const normalized_path = make_normalized_path(path);
13
13
  for (const ignored of ws.ignored_directories) {
@@ -18,8 +18,8 @@ function is_ignored_dir(ws, path) {
18
18
  return false;
19
19
  }
20
20
  function setup_library_bundle(lib, bundle_desc) {
21
- const manif = make_library_bundle_manifest(lib, bundle_desc);
22
21
  const ws = lib.workspace;
22
+ const manif = make_library_bundle_manifest(lib, bundle_desc);
23
23
  let bun = ws.get_bundle(manif.$id);
24
24
  if (!bun) {
25
25
  bun = new Bundle(manif, lib.path, ws, lib);
@@ -97,7 +97,9 @@ async function discover_library_components(lib, path, subdir = false) {
97
97
  const fstat = await Fsp.stat(fpath);
98
98
  if (fstat.isDirectory()) {
99
99
  if (!exclude_dirs.includes(fname)) {
100
- await discover_library_components(lib, fpath, true);
100
+ if (await discover_library(lib.workspace, fpath, lib.installed) === Discovered.None) {
101
+ await discover_library_components(lib, fpath, true);
102
+ }
101
103
  }
102
104
  }
103
105
  else if (fstat.isFile()) {
@@ -115,15 +117,19 @@ async function discover_library_components(lib, path, subdir = false) {
115
117
  }
116
118
  }
117
119
  }
118
- // Analyze library deployment manifest (supports json/yaml/yml/toml, singleton)
119
- const manifest_result = await readSingletonConfigFile(path, "bundle.manifest", fnames);
120
- if (manifest_result) {
121
- const manifest = manifest_result.data;
122
- for (const pub of manifest.data.components) {
123
- const fpath = path + "/" + (pub.ref ?? pub.id);
124
- await discover_component(lib, fpath);
120
+ }
121
+ export function collect_declarations_field(lib, key, value) {
122
+ for (const decl of lib.declarations.values()) {
123
+ if (typeof decl[key] === typeof value) {
124
+ if (Array.isArray(value))
125
+ value.push(...decl[key]);
126
+ else if (typeof value === "object")
127
+ Object.assign(value, decl[key]);
128
+ else
129
+ value = decl[key];
125
130
  }
126
131
  }
132
+ return value;
127
133
  }
128
134
  function make_library_bundle_manifest(lib, file_desc) {
129
135
  let $id = file_desc?.$id;
@@ -138,26 +144,22 @@ function make_library_bundle_manifest(lib, file_desc) {
138
144
  lib.log.info(`Bundle '${$id}' named from library '${lib.name}'`);
139
145
  }
140
146
  const data = {
141
- alias: lib.name,
142
147
  package: lib.get_id(),
143
- namespaces: [],
144
- dependencies: [],
145
- redistribueds: {},
148
+ alias: collect_declarations_field(lib, "alias", lib.name),
149
+ namespaces: collect_declarations_field(lib, "namespaces", []),
150
+ dependencies: collect_declarations_field(lib, "dependencies", []),
151
+ distribueds: collect_declarations_field(lib, "distribueds", {}),
146
152
  };
147
153
  if (file_desc?.data) {
148
154
  data.alias = file_desc.data.alias ?? data.alias;
149
- if (file_desc.data.redistribueds) {
150
- const distribueds = file_desc.data.redistribueds;
151
- if (Array.isArray(distribueds))
152
- distribueds.forEach(dist => data.redistribueds[dist] = "*");
153
- else
154
- Object.assign(data.redistribueds, distribueds);
155
+ if (file_desc.data.distribueds) {
156
+ Object.assign(data.distribueds, file_desc.data.distribueds);
155
157
  }
156
- if (file_desc.data.namespaces) {
157
- data.namespaces = file_desc.data.namespaces;
158
+ if (Array.isArray(file_desc.data.namespaces)) {
159
+ data.namespaces.push(...file_desc.data.namespaces);
158
160
  }
159
- if (file_desc.data.dependencies) {
160
- data.dependencies = file_desc.data.dependencies;
161
+ if (Array.isArray(file_desc.data.dependencies)) {
162
+ data.dependencies.push(...file_desc.data.dependencies);
161
163
  }
162
164
  }
163
165
  const manifest = {
@@ -174,53 +176,71 @@ function make_library_bundle_manifest(lib, file_desc) {
174
176
  };
175
177
  return manifest;
176
178
  }
179
+ var Discovered;
180
+ (function (Discovered) {
181
+ Discovered[Discovered["None"] = 0] = "None";
182
+ Discovered[Discovered["Ignored"] = 1] = "Ignored";
183
+ Discovered[Discovered["Registered"] = 2] = "Registered";
184
+ })(Discovered || (Discovered = {}));
177
185
  async function discover_library(ws, location, installed) {
178
186
  const lib_path = make_canonical_path(ws.path, location);
179
187
  if (is_ignored_dir(ws, lib_path))
180
- return false;
188
+ return Discovered.Ignored;
189
+ const package_path = lib_path + "/package.json";
190
+ const manifest_path = findConfigFile(lib_path, "bundle.manifest");
191
+ if (!file.exists(package_path) && !file.exists(manifest_path))
192
+ return Discovered.None;
181
193
  const lib_not_exists = ws.libraries.reduce((r, lib) => r && lib.path !== lib_path, true);
182
- if (lib_not_exists) {
183
- const lib_desc = await readJsonFile(lib_path + "/package.json");
184
- if (!lib_desc?.name)
185
- return false;
186
- const bundle_result = await readSingletonConfigFile(lib_path, "bundle.component");
187
- const bundle_desc = bundle_result?.data;
188
- if (bundle_desc || !installed) {
189
- const other = ws.get_library(lib_desc.name);
190
- if (other) {
191
- if (lib_path.includes(other.path)) {
192
- ws.log.info(`ignore library build at ${lib_path}`);
193
- return false;
194
- }
195
- else {
196
- throw new Error(`library '${lib_desc.name}' declared multiple times\n - ${other.path}\n - ${lib_path}`);
197
- }
194
+ if (!lib_not_exists)
195
+ return Discovered.Ignored;
196
+ const lib_desc = await readJsonFile(package_path);
197
+ if (!lib_desc?.name)
198
+ return Discovered.Ignored;
199
+ const manifest_desc = await readConfigFile(manifest_path);
200
+ if (manifest_desc || !installed) {
201
+ const other = ws.get_library(lib_desc.name);
202
+ if (other) {
203
+ if (lib_path.includes(other.path)) {
204
+ ws.log.info(`ignore library build at ${lib_path}`);
205
+ return Discovered.Ignored;
198
206
  }
199
- const lib = new Library(lib_desc.name, lib_path, lib_desc, ws);
200
- ws.libraries.push(lib);
201
- ws.log.info(`+ 📚 library: ${lib.get_id()} (${make_relative_path(ws.path, location)})`);
202
- if (bundle_desc) {
203
- setup_library_bundle(lib, bundle_desc);
207
+ else {
208
+ throw new Error(`library '${lib_desc.name}' declared multiple times\n - ${other.path}\n - ${lib_path}`);
204
209
  }
205
- const lib_search_path = lib_path + "/node_modules";
206
- if (Fs.existsSync(lib_search_path)) {
207
- lib.search_directories.push(lib_search_path);
210
+ }
211
+ const lib = new Library(lib_desc.name, lib_path, lib_desc, ws, installed);
212
+ ws.libraries.push(lib);
213
+ ws.log.info(`+ 📚 library: ${installed ? "⏬" : "🐣"} ${lib.get_id()} (${make_relative_path(ws.path, location)})`);
214
+ // Setup library infos from bundle manifest
215
+ setup_library_bundle(lib, manifest_desc);
216
+ // Analyze library deployment manifest (supports json/yaml/yml/toml, singleton)
217
+ if (manifest_desc?.data?.components) {
218
+ for (const pub of manifest_desc.data.components) {
219
+ const fpath = lib_path + "/" + (pub.ref ?? pub.id);
220
+ await discover_component(lib, fpath);
208
221
  }
209
- await discover_library_components(lib, lib_path);
210
- return true;
211
222
  }
223
+ // Setup node search directory
224
+ const lib_search_path = lib_path + "/node_modules";
225
+ if (Fs.existsSync(lib_search_path)) {
226
+ lib.search_directories.push(lib_search_path);
227
+ }
228
+ // Collect library declaration
229
+ await discover_library_components(lib, lib_path);
230
+ return Discovered.Registered;
212
231
  }
213
- return false;
232
+ return Discovered.None;
214
233
  }
215
234
  async function discover_workspace_libraries(ws) {
216
235
  async function walk(dir) {
217
- await discover_library(ws, dir, false);
218
- for (const entry of Fs.readdirSync(dir, { withFileTypes: true })) {
219
- if (entry.name === "node_modules")
220
- continue;
221
- const fullPath = dir + "/" + entry.name;
222
- if (entry.isDirectory()) {
223
- await walk(fullPath);
236
+ if (await discover_library(ws, dir, false) === Discovered.None) {
237
+ for (const entry of Fs.readdirSync(dir, { withFileTypes: true })) {
238
+ if (entry.name === "node_modules")
239
+ continue;
240
+ const fullPath = dir + "/" + entry.name;
241
+ if (entry.isDirectory()) {
242
+ await walk(fullPath);
243
+ }
224
244
  }
225
245
  }
226
246
  }
@@ -259,14 +279,23 @@ export async function discover_workspace(ws) {
259
279
  if (!package_lock) {
260
280
  throw new Error(`Package lock not found for '${ws.name}'`);
261
281
  }
282
+ for (const location in package_lock.packages) {
283
+ let pkg = package_lock.packages[location];
284
+ if (location.startsWith("node_modules/")) {
285
+ if (pkg.link) {
286
+ pkg = package_lock.packages[pkg.resolved];
287
+ }
288
+ const name = location.replace(/^.*node_modules\//, "");
289
+ ws.resolved_versions[name] = pkg.version;
290
+ }
291
+ }
262
292
  await discover_workspace_libraries(ws);
263
293
  for (const location in package_lock.packages) {
264
294
  await discover_library(ws, location, true);
265
295
  }
266
296
  for (const bun of ws.bundles) {
267
297
  if (bun.source) {
268
- const manifs = create_manifests(bun.source, bun);
269
- bun.manifest = manifs.bundle;
298
+ bun.manifest = create_bundle_manifest(bun.source, bun);
270
299
  }
271
300
  }
272
301
  show_constants(ws);
@@ -1,16 +1,14 @@
1
1
  import Fs from "node:fs";
2
- import Fsp from "node:fs/promises";
3
2
  import Path from "node:path";
4
3
  import Process from "node:process";
4
+ import DotEnv from "dotenv";
5
5
  import { readJsonFile } from "./storage.js";
6
6
  import {} from "./component.js";
7
- import { topologicalSort } from "../utils/graph-ordering.js";
8
- import DotEnv from "dotenv";
9
7
  import { computeNameHashID, makeNormalizedName, NameStyle } from "../utils/normalized-name.js";
10
- import { make_relative_path } from "../utils/file.js";
8
+ import { make_normalized_path } from "../utils/file.js";
11
9
  import { Logger, Log } from "./helpers/logger.js";
12
10
  import { discover_workspace } from "./helpers/discover-workspace.js";
13
- import { create_manifests } from "./helpers/create-manifests.js";
11
+ import { create_bundle_manifest } from "./helpers/create-manifests.js";
14
12
  export class WorkspaceItem {
15
13
  workspace;
16
14
  log;
@@ -25,17 +23,19 @@ export class Library extends WorkspaceItem {
25
23
  path;
26
24
  descriptor;
27
25
  workspace;
26
+ installed;
28
27
  bundle = null;
29
28
  declarations = new Map();
30
29
  applications = new Map();
31
30
  externals = {};
32
31
  search_directories = null;
33
- constructor(name, path, descriptor, workspace) {
32
+ constructor(name, path, descriptor, workspace, installed) {
34
33
  super(workspace, `lib:${name}`);
35
34
  this.name = name;
36
35
  this.path = path;
37
36
  this.descriptor = descriptor;
38
37
  this.workspace = workspace;
38
+ this.installed = installed;
39
39
  this.search_directories = workspace.search_directories.slice();
40
40
  Object.assign(this.externals, descriptor.peerDependencies, descriptor.dependencies);
41
41
  }
@@ -49,13 +49,13 @@ export class Library extends WorkspaceItem {
49
49
  return base ? prefix + "." + base : prefix;
50
50
  }
51
51
  resolve_entry_path(entryId, baseDir) {
52
- const fpath = make_relative_path(Process.cwd(), Path.resolve(baseDir, entryId));
52
+ const fpath = make_normalized_path(Path.resolve(baseDir, entryId));
53
53
  if (entryId.startsWith("."))
54
54
  return fpath;
55
55
  const parts = entryId.split("/");
56
56
  for (const search_path of this.search_directories) {
57
57
  if (Fs.existsSync(search_path + "/" + parts[0])) {
58
- return make_relative_path(Process.cwd(), search_path + "/" + entryId);
58
+ return make_normalized_path(search_path + "/" + entryId);
59
59
  }
60
60
  }
61
61
  if (Fs.existsSync(fpath))
@@ -92,8 +92,7 @@ export class Bundle extends WorkspaceItem {
92
92
  }
93
93
  resolve_export(ref) {
94
94
  if (!this.manifest) {
95
- const manifs = create_manifests(this.source, this);
96
- this.manifest = manifs.bundle;
95
+ this.manifest = create_bundle_manifest(this.source, this);
97
96
  this.configured = true;
98
97
  }
99
98
  return this.exports?.[ref];
@@ -108,6 +107,7 @@ export class Workspace {
108
107
  bundles = [];
109
108
  libraries = [];
110
109
  constants = {};
110
+ resolved_versions = {};
111
111
  search_directories = [];
112
112
  ignored_directories = new Set();
113
113
  logger = new Logger();
package/esm/utils/file.js CHANGED
@@ -1,22 +1,22 @@
1
1
  import Path from "path";
2
- import fs from "fs";
2
+ import Fs from "fs";
3
3
  import { fileURLToPath } from "url";
4
4
  export const PackageRootDir = Path.resolve(fileURLToPath(import.meta.url), "../../..");
5
5
  export const file = {
6
6
  exists(path) {
7
- return fs.existsSync(path) && fs.lstatSync(path).isFile();
7
+ return Fs.existsSync(path) && Fs.lstatSync(path).isFile();
8
8
  },
9
9
  copy: {
10
10
  toFile(src, dest) {
11
11
  dest = Path.resolve(dest);
12
12
  directory.make(Path.dirname(dest));
13
- fs.copyFileSync(src, dest);
13
+ Fs.copyFileSync(src, dest);
14
14
  return dest;
15
15
  },
16
16
  toDir(src, dest) {
17
17
  dest = Path.resolve(dest, Path.basename(src));
18
18
  directory.make(Path.dirname(dest));
19
- fs.copyFileSync(src, dest);
19
+ Fs.copyFileSync(src, dest);
20
20
  return dest;
21
21
  }
22
22
  },
@@ -24,22 +24,22 @@ export const file = {
24
24
  toFile(src, dest) {
25
25
  dest = Path.resolve(dest);
26
26
  directory.make(Path.dirname(dest));
27
- fs.copyFileSync(src, dest);
28
- fs.unlinkSync(src);
27
+ Fs.copyFileSync(src, dest);
28
+ Fs.unlinkSync(src);
29
29
  return dest;
30
30
  },
31
31
  toDir(src, dest) {
32
32
  dest = Path.resolve(dest, Path.basename(src));
33
33
  directory.make(Path.dirname(dest));
34
- fs.copyFileSync(src, dest);
35
- fs.unlinkSync(src);
34
+ Fs.copyFileSync(src, dest);
35
+ Fs.unlinkSync(src);
36
36
  return dest;
37
37
  },
38
38
  },
39
39
  read: {
40
40
  json(path) {
41
41
  try {
42
- return JSON.parse(fs.readFileSync(path).toString());
42
+ return JSON.parse(Fs.readFileSync(path).toString());
43
43
  }
44
44
  catch (e) {
45
45
  return undefined;
@@ -47,7 +47,7 @@ export const file = {
47
47
  },
48
48
  text(path) {
49
49
  try {
50
- return fs.readFileSync(path).toString();
50
+ return Fs.readFileSync(path).toString();
51
51
  }
52
52
  catch (e) {
53
53
  return undefined;
@@ -57,11 +57,11 @@ export const file = {
57
57
  write: {
58
58
  json(path, data) {
59
59
  directory.make(Path.dirname(path));
60
- fs.writeFileSync(path, JSON.stringify(data, null, 2));
60
+ Fs.writeFileSync(path, JSON.stringify(data, null, 2));
61
61
  },
62
62
  text(path, data) {
63
63
  directory.make(Path.dirname(path));
64
- fs.writeFileSync(path, Array.isArray(data) ? data.join("\n") : data.toString());
64
+ Fs.writeFileSync(path, Array.isArray(data) ? data.join("\n") : data.toString());
65
65
  }
66
66
  },
67
67
  find: {
@@ -69,30 +69,30 @@ export const file = {
69
69
  let previous, current = Path.resolve(base);
70
70
  do {
71
71
  previous = current;
72
- if (fs.existsSync(Path.join(current, subpath)))
72
+ if (Fs.existsSync(Path.join(current, subpath)))
73
73
  return current;
74
74
  current = Path.dirname(current);
75
75
  } while (current != previous);
76
76
  }
77
77
  },
78
78
  remove(path) {
79
- if (fs.existsSync(path)) {
80
- fs.unlinkSync(path);
79
+ if (Fs.existsSync(path)) {
80
+ Fs.unlinkSync(path);
81
81
  }
82
82
  },
83
83
  };
84
84
  export const directory = {
85
85
  exists(path) {
86
- return fs.existsSync(path) && fs.lstatSync(path).isDirectory();
86
+ return Fs.existsSync(path) && Fs.lstatSync(path).isDirectory();
87
87
  },
88
88
  filenames(path, recursive) {
89
89
  try {
90
90
  if (recursive) {
91
91
  function* walkSync(dir) {
92
- const files = fs.readdirSync(dir);
92
+ const files = Fs.readdirSync(dir);
93
93
  for (const file of files) {
94
94
  const pathToFile = Path.join(dir, file);
95
- const isDirectory = fs.statSync(pathToFile).isDirectory();
95
+ const isDirectory = Fs.statSync(pathToFile).isDirectory();
96
96
  if (isDirectory) {
97
97
  yield* walkSync(pathToFile);
98
98
  }
@@ -108,7 +108,7 @@ export const directory = {
108
108
  return _Result;
109
109
  }
110
110
  else
111
- return fs.readdirSync(path) || [];
111
+ return Fs.readdirSync(path) || [];
112
112
  }
113
113
  catch (e) {
114
114
  return [];
@@ -116,9 +116,9 @@ export const directory = {
116
116
  },
117
117
  copy(src, dest, filter) {
118
118
  if (directory.exists(src)) {
119
- for (const name of fs.readdirSync(src)) {
119
+ for (const name of Fs.readdirSync(src)) {
120
120
  const path = Path.join(src, name);
121
- const stats = fs.lstatSync(path);
121
+ const stats = Fs.lstatSync(path);
122
122
  const destination = Path.join(dest, name);
123
123
  if (stats.isDirectory()) {
124
124
  directory.copy(path, destination, filter);
@@ -130,15 +130,15 @@ export const directory = {
130
130
  }
131
131
  },
132
132
  make(path) {
133
- if (path && !fs.existsSync(path)) {
134
- fs.mkdirSync(path, { recursive: true });
133
+ if (path && !Fs.existsSync(path)) {
134
+ Fs.mkdirSync(path, { recursive: true });
135
135
  }
136
136
  },
137
137
  remove(path, onlyInner) {
138
- if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
139
- fs.readdirSync(path).forEach(function (entry) {
138
+ if (Fs.existsSync(path) && Fs.lstatSync(path).isDirectory()) {
139
+ Fs.readdirSync(path).forEach(function (entry) {
140
140
  var entry_path = Path.join(path, entry);
141
- if (fs.lstatSync(entry_path).isDirectory()) {
141
+ if (Fs.lstatSync(entry_path).isDirectory()) {
142
142
  directory.remove(entry_path);
143
143
  }
144
144
  else {
@@ -151,7 +151,7 @@ export const directory = {
151
151
  }
152
152
  });
153
153
  if (!onlyInner) {
154
- fs.rmdirSync(path);
154
+ Fs.rmdirSync(path);
155
155
  }
156
156
  }
157
157
  },
@@ -180,12 +180,36 @@ export function make_normalized_dirname(baseDir, ...path) {
180
180
  export function make_canonical_path(baseDir, ...path) {
181
181
  let targetPath = Path.resolve(baseDir, ...path);
182
182
  try {
183
- const stats = fs.lstatSync(targetPath);
183
+ const stats = Fs.lstatSync(targetPath);
184
184
  if (stats.isSymbolicLink()) {
185
- targetPath = fs.readlinkSync(targetPath);
185
+ targetPath = Fs.readlinkSync(targetPath);
186
186
  }
187
187
  }
188
188
  catch (err) { }
189
189
  return make_normalized_path(targetPath);
190
190
  }
191
+ const FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json'];
192
+ /** Resolve a file path with extension probing */
193
+ export function resolve_normalized_suffixed_path(baseDir, path, exts = FILE_EXTENSIONS) {
194
+ const resolved = make_normalized_path(baseDir, path);
195
+ // Check if exact path exists
196
+ if (Fs.existsSync(resolved) && Fs.statSync(resolved).isFile()) {
197
+ return resolved;
198
+ }
199
+ // Try with common extensions
200
+ for (const ext of exts) {
201
+ const withExt = resolved + ext;
202
+ if (Fs.existsSync(withExt))
203
+ return withExt;
204
+ }
205
+ // Try index files in directory
206
+ if (Fs.existsSync(resolved) && Fs.statSync(resolved).isDirectory()) {
207
+ for (const ext of exts) {
208
+ const indexPath = make_normalized_path(resolved, `index${ext}`);
209
+ if (Fs.existsSync(indexPath))
210
+ return indexPath;
211
+ }
212
+ }
213
+ return null;
214
+ }
191
215
  //# sourceMappingURL=file.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jointhedots/gear",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "jointhedots-gear": "esm/cli.js"
@@ -19,10 +19,13 @@
19
19
  ":build:ui": "node --enable-source-maps --watch-path=esm esm/cli make --buns jointhedots.ui --ws ../jointhedots-core/packages/jointhedots-ui",
20
20
  ":build:cortex": "node --enable-source-maps --watch-path=esm esm/cli make --buns @jointhedots/cortex --devmode --ws ../jointhedots-core/packages/jointhedots-cortex",
21
21
  ":build:libs": "node --enable-source-maps --watch-path=esm esm/cli make --libs @jointhedots/core,@jointhedots/ui --devmode --ws ../jointhedots-core",
22
+ ":build:lib:core": "node --enable-source-maps --watch-path=esm esm/cli make --libs @jointhedots/core --devmode --ws ../jointhedots-core/packages/jointhedots-core",
23
+ ":build:lib:ui": "node --enable-source-maps --watch-path=esm esm/cli make --libs @jointhedots/ui --devmode --ws ../jointhedots-core/packages/jointhedots-ui",
22
24
  ":build:app": "node --enable-source-maps --watch-path=esm esm/cli make --apps playground:ui --ws ../jointhedots-core",
23
25
  "serve:mono": "node --enable-source-maps --watch-path=esm esm/cli serve --app playground:ui --devmode --port 3002 --ws ../jointhedots-core",
24
26
  "serve:host": "node --enable-source-maps --watch-path=esm esm/cli serve --app playground:ui:host --port 3002 --ws ../jointhedots-core",
25
27
  "serve:sfe": "node --enable-source-maps --watch-path=esm esm/cli serve --app sfe-demo --devmode --ws ../sf-explorer-app",
28
+ "serve:demo": "node --enable-source-maps --watch-path=esm esm/cli serve --app sfe-demo --devmode --ws ../sf-explorer-demo",
26
29
  "make:sfe": "node --enable-source-maps --watch-path=esm esm/cli make --libs @sf-explorer/app --devmode --ws ../sf-explorer-app",
27
30
  "prepublishOnly": "node scripts/prepublish.mjs"
28
31
  },