@jointhedots/gear 1.1.17 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/esm/builder/build-app-bundle.js +11 -12
  2. package/esm/builder/build-app-host.js +48 -6
  3. package/esm/builder/build-application.js +4 -5
  4. package/esm/builder/build-library.js +5 -3
  5. package/esm/builder/build-target.js +6 -6
  6. package/esm/builder/helpers/emit-bundle-manifest.js +1 -1
  7. package/esm/builder/helpers/emit-components-dts.js +66 -0
  8. package/esm/builder/helpers/emit-esmodules.js +1 -1
  9. package/esm/builder/helpers/emit-package-manifest.js +1 -1
  10. package/esm/builder/helpers/emit-static-assets.js +2 -2
  11. package/esm/builder/helpers/emit-typescript-definition.js +36 -17
  12. package/esm/cli.js +2 -0
  13. package/esm/commands/install.js +67 -0
  14. package/esm/commands/make.js +6 -5
  15. package/esm/commands/publish.js +1 -1
  16. package/esm/commands/serve.js +3 -3
  17. package/esm/publish/publish_aws_s3.js +2 -2
  18. package/esm/utils/normalized-name.js +11 -9
  19. package/esm/{model → workspace}/helpers/create-manifests.js +7 -1
  20. package/esm/{model → workspace}/helpers/discover-workspace.js +134 -154
  21. package/esm/workspace/packager.js +53 -0
  22. package/esm/workspace/packagers/packager-standard.js +64 -0
  23. package/esm/{model → workspace}/storage.js +15 -10
  24. package/esm/{model → workspace}/workspace.js +23 -14
  25. package/package.json +7 -3
  26. /package/esm/{model → workspace}/component.js +0 -0
  27. /package/esm/{model → workspace}/helpers/config-loader.js +0 -0
  28. /package/esm/{model → workspace}/helpers/lockfile.js +0 -0
  29. /package/esm/{model → workspace}/helpers/logger.js +0 -0
  30. /package/esm/{model → workspace}/helpers/package-npm.js +0 -0
@@ -1,11 +1,11 @@
1
1
  import Path from "node:path";
2
- import { Bundle, Library } from "../model/workspace.js";
3
- import { StorageFiles } from "../model/storage.js";
2
+ import { Bundle, Library } from "../workspace/workspace.js";
3
+ import { StorageFiles } from "../workspace/storage.js";
4
4
  import { BuildTarget } from "./build-target.js";
5
5
  import { TypescriptDefinitionTask } from "./helpers/emit-typescript-definition.js";
6
6
  import { PackageManifestTask } from "./helpers/emit-package-manifest.js";
7
7
  import { PathQualifier } from "./helpers/path-helpers.js";
8
- import { create_export_map } from "../model/helpers/create-manifests.js";
8
+ import { create_export_map } from "../workspace/helpers/create-manifests.js";
9
9
  import { DependencyDeduplicationPlugin, collectLibraryGraph } from "./helpers/emit-esmodules.js";
10
10
  import { BundleManifestTask } from "./helpers/emit-bundle-manifest.js";
11
11
  export var PathStatus;
@@ -17,8 +17,7 @@ export var PathStatus;
17
17
  PathStatus[PathStatus["ExternalBundle"] = 4] = "ExternalBundle";
18
18
  })(PathStatus || (PathStatus = {}));
19
19
  export function create_bundle_target(opts) {
20
- const { bundle, library, storage } = opts;
21
- const lib = library;
20
+ const { bundle, library: lib, storage } = opts;
22
21
  const target = new BuildTarget(bundle.id, storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
23
22
  // Prepare esm setup
24
23
  target.esmodules.set_root(lib.path);
@@ -84,7 +83,7 @@ export function create_bundle_target(opts) {
84
83
  paths_qualifier.set(dep, PathStatus.ExternalBundle);
85
84
  }
86
85
  }
87
- for (const xbun of lib.workspace.bundles) {
86
+ for (const xbun of lib.shelve) {
88
87
  if (xbun !== bundle) {
89
88
  paths_qualifier.set(xbun.id, xbun);
90
89
  paths_qualifier.set(xbun.alias, xbun);
@@ -120,14 +119,14 @@ export function create_bundle_target(opts) {
120
119
  }
121
120
  let state = paths_qualifier.check(path);
122
121
  if (state === PathStatus.Dependency || state === PathStatus.External) {
123
- //target.log.info(`External: ${path} <- ${importer}`)
122
+ //target.log.warn(`External: ${path} <- ${importer}`)
124
123
  return { external: true };
125
124
  }
126
125
  if (state === PathStatus.ExternalBundle) {
127
126
  throw new Error(`ExternalBundle: ${path} <- ${importer}`);
128
127
  }
129
128
  if (state instanceof Bundle) {
130
- //target.log.info(`Bundle: ${state.id} <- ${importer}`)
129
+ //target.log.warn(`Bundle: ${state.id} <- ${importer}`)
131
130
  const entry_id = state.resolve_export(path);
132
131
  if (!entry_id) {
133
132
  return { errors: [{ text: `Bundle '${state.id}' do not distribute expected entry: ${path}` }] };
@@ -148,7 +147,7 @@ export function create_bundle_target(opts) {
148
147
  namespace: "external-bundle-proxy",
149
148
  };
150
149
  }
151
- //target.log.trace(`Internal: ${path} <- ${importer}`)
150
+ //target.log.warn(`Internal: ${path} <- ${importer}`)
152
151
  });
153
152
  // Load virtual proxy modules for external bundle references
154
153
  build.onLoad({ filter: /.*/, namespace: "external-bundle-proxy" }, (args) => {
@@ -169,9 +168,8 @@ export function create_bundle_target(opts) {
169
168
  }
170
169
  });
171
170
  // Register esbuild plugin for dependency deduplication (graph-based + singleton)
172
- const ws = library.workspace;
173
- const rootNodeModules = ws.search_directories[0] || Path.join(ws.path, 'node_modules');
174
- const libGraph = collectLibraryGraph(library);
171
+ const rootNodeModules = lib.search_directories[0] || Path.join(lib.path, 'node_modules');
172
+ const libGraph = collectLibraryGraph(lib);
175
173
  target.esmodules.plugins.push(DependencyDeduplicationPlugin(libGraph, rootNodeModules, target.log));
176
174
  return target;
177
175
  }
@@ -191,6 +189,7 @@ export async function build_app_composable_bundle(opts) {
191
189
  });
192
190
  target.log.info(`Build bundle: ${target.name}`);
193
191
  await target.build();
192
+ return target;
194
193
  }
195
194
  else {
196
195
  bundle.log.info(`Prebuild bundle: ${opts.bundle.id}`);
@@ -1,12 +1,50 @@
1
- import { Bundle, matchComponentSelection, Workspace, } from "../model/workspace.js";
2
- import { StorageFiles } from "../model/storage.js";
1
+ import { Bundle, matchComponentSelection, Workspace, } from "../workspace/workspace.js";
2
+ import { StorageFiles } from "../workspace/storage.js";
3
3
  import { BuildTarget } from "./build-target.js";
4
4
  import { build_app_composable_bundle } from "./build-app-bundle.js";
5
5
  import Path from "node:path";
6
6
  import { PWAPackageTask, WebviewTask } from "./build-application.js";
7
+ import { makeComponentPublication } from "../workspace/component.js";
7
8
  import { topologicalSort } from "../utils/graph-ordering.js";
9
+ import { BuildTask } from "./helpers/task.js";
10
+ export class ShelveManifestTask extends BuildTask {
11
+ target;
12
+ bundles;
13
+ constructor(target, bundles) {
14
+ super(target);
15
+ this.target = target;
16
+ this.bundles = bundles;
17
+ }
18
+ async execute() {
19
+ const { bundles } = this;
20
+ // Emit static components manifest
21
+ const namespaces = new Set();
22
+ const components = [];
23
+ for (const bundle of bundles) {
24
+ const pub = makeComponentPublication(bundle.manifest);
25
+ const nss = bundle.manifest.type === "bundle" && bundle.manifest.data?.["namespaces"];
26
+ if (Array.isArray(nss)) {
27
+ for (const ns of nss) {
28
+ namespaces.add(ns);
29
+ }
30
+ }
31
+ components.push(pub);
32
+ }
33
+ // Emit bundle manifest
34
+ const tx = this.target.edit();
35
+ const manifest = {
36
+ $id: ".",
37
+ type: "bundle",
38
+ data: {
39
+ namespaces: Array.from(namespaces),
40
+ components,
41
+ }
42
+ };
43
+ await tx.commitFile(`bundle.manifest.json`, JSON.stringify(manifest, null, 2));
44
+ }
45
+ }
8
46
  function create_application_composable_target(opts) {
9
- const { app, version } = opts;
47
+ const { app, bundles, version } = opts;
10
48
  const { type, name, webviews, modules, assets, components } = app.descriptor;
11
49
  const lib = app.library;
12
50
  const bundle = lib.bundle;
@@ -24,6 +62,8 @@ function create_application_composable_target(opts) {
24
62
  html_injects.push(`<link rel="manifest" href="/manifest.json">`);
25
63
  html_injects.push(`<link rel="icon" type="image/webp" href="favicon.webp" />`);
26
64
  target.tasks.push(new PWAPackageTask(target, app));
65
+ // Generate shelve manifest
66
+ target.tasks.push(new ShelveManifestTask(target, bundles));
27
67
  // Add application webviews
28
68
  for (const name in webviews) {
29
69
  const { title, favicon } = webviews[name];
@@ -103,9 +143,9 @@ export async function build_app_composable_host(opts) {
103
143
  if (shelveBundles.missing.length > 0) {
104
144
  ws.log.warn(`Missing bundle dependencies: ${shelveBundles.missing.join(", ")}`);
105
145
  }
106
- await Promise.all(shelvePendings);
107
146
  const target = create_application_composable_target({
108
147
  app,
148
+ bundles: await Promise.all(shelveBundles),
109
149
  storage: opts.storage,
110
150
  version: opts.version,
111
151
  devmode: opts.devmode,
@@ -139,8 +179,10 @@ export class BundleSelector {
139
179
  this.selected.set(bun.id, bun);
140
180
  // Recursively add dependencies
141
181
  const deps = bun.dependencies;
142
- for (const depId of deps) {
143
- this.add(depId);
182
+ if (deps) {
183
+ for (const depId of deps) {
184
+ this.add(depId);
185
+ }
144
186
  }
145
187
  if (bun.source) {
146
188
  for (const depId in bun.source.descriptor?.dependencies) {
@@ -1,8 +1,8 @@
1
1
  import Path from "node:path";
2
2
  import Sharp from "sharp";
3
3
  import MIME from 'mime';
4
- import { Library, matchComponentSelection } from "../model/workspace.js";
5
- import { StorageFiles } from "../model/storage.js";
4
+ import { Library, matchComponentSelection } from "../workspace/workspace.js";
5
+ import { StorageFiles } from "../workspace/storage.js";
6
6
  import { BuildTarget } from "./build-target.js";
7
7
  import { build_app_composable_host } from "./build-app-host.js";
8
8
  import { DependencyDeduplicationPlugin } from "./helpers/emit-esmodules.js";
@@ -33,8 +33,7 @@ export function create_application_monolith_target(opts) {
33
33
  const { app, version } = opts;
34
34
  const { type, name, webviews, modules, assets, components } = app.descriptor;
35
35
  const lib = app.library;
36
- const ws = lib.workspace;
37
- const target = new BuildTarget(name, opts.storage, ws, opts.devmode == true, opts.watch == true, opts.clean == true);
36
+ const target = new BuildTarget(name, opts.storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
38
37
  const libs = collect_app_libraries(app);
39
38
  target.log.info(`+ 🧭 app-library-graph: ${libs.map(lib => `${lib.name}@${lib.descriptor.version}`).join(", ")}`);
40
39
  // Prepare esm setup
@@ -152,7 +151,7 @@ export function create_application_monolith_target(opts) {
152
151
  }
153
152
  }
154
153
  // Register esbuild plugin for dependency deduplication (graph-based + singleton)
155
- const rootNodeModules = ws.search_directories[0] || Path.join(ws.path, 'node_modules');
154
+ const rootNodeModules = lib.search_directories[0] || Path.join(lib.path, 'node_modules');
156
155
  target.esmodules.plugins.push(DependencyDeduplicationPlugin(libs, rootNodeModules, target.log));
157
156
  return target;
158
157
  }
@@ -1,12 +1,13 @@
1
1
  import Path from "node:path";
2
2
  import ChildProcess from "child_process";
3
- import { Library } from "../model/workspace.js";
4
- import { StorageFiles } from "../model/storage.js";
3
+ import { Library } from "../workspace/workspace.js";
4
+ import { StorageFiles } from "../workspace/storage.js";
5
5
  import { BuildTarget } from "./build-target.js";
6
6
  import { TypescriptDefinitionTask } from "./helpers/emit-typescript-definition.js";
7
7
  import { PackageManifestTask } from "./helpers/emit-package-manifest.js";
8
- import { create_export_map } from "../model/helpers/create-manifests.js";
8
+ import { create_export_map } from "../workspace/helpers/create-manifests.js";
9
9
  import { BundleManifestTask } from "./helpers/emit-bundle-manifest.js";
10
+ import { ComponentsDtsTask } from "./helpers/emit-components-dts.js";
10
11
  export function create_library_target(opts) {
11
12
  const lib = opts.library;
12
13
  const target = new BuildTarget(lib.name, opts.storage, lib.workspace, opts.devmode == true, opts.watch == true, opts.clean == true);
@@ -22,6 +23,7 @@ export function create_library_target(opts) {
22
23
  target.tasks.push(new TypescriptDefinitionTask(target, lib));
23
24
  // Add library package.json
24
25
  target.tasks.push(new PackageManifestTask(target, lib, opts.version));
26
+ target.tasks.push(new ComponentsDtsTask(target, lib.bundle));
25
27
  // Add bundle content
26
28
  const { bundle } = lib;
27
29
  if (bundle) {
@@ -1,7 +1,7 @@
1
- import {} from "../model/component.js";
2
- import { Library, Workspace } from "../model/workspace.js";
1
+ import {} from "../workspace/component.js";
2
+ import { Library, Workspace } from "../workspace/workspace.js";
3
3
  import { ESModulesTask } from "./helpers/emit-esmodules.js";
4
- import {} from "../model/storage.js";
4
+ import {} from "../workspace/storage.js";
5
5
  import { AssetsTask } from "./helpers/emit-static-assets.js";
6
6
  export class BuildTarget {
7
7
  name;
@@ -39,7 +39,7 @@ export class BuildTarget {
39
39
  add_component(descriptor, baseDir, library) {
40
40
  const id = descriptor.$id;
41
41
  if (this.components.has(id)) {
42
- throw new Error(createComponentDuplicateMessage(id, this.workspace));
42
+ throw new Error(createComponentDuplicateMessage(id, library));
43
43
  }
44
44
  const manifest = {
45
45
  ...descriptor,
@@ -94,10 +94,10 @@ export class BuildTarget {
94
94
  }
95
95
  }
96
96
  }
97
- function createComponentDuplicateMessage(id, workspace) {
97
+ function createComponentDuplicateMessage(id, library) {
98
98
  const duplicates = [];
99
99
  const libs = [];
100
- for (const bun of workspace.bundles) {
100
+ for (const bun of library.shelve) {
101
101
  for (const [cpath, cmanifest] of bun.components.entries()) {
102
102
  if (cmanifest.$id === id) {
103
103
  duplicates.push(`\n - ${cpath}`);
@@ -1,4 +1,4 @@
1
- import { makeComponentPublication } from "../../model/component.js";
1
+ import { makeComponentPublication } from "../../workspace/component.js";
2
2
  import { BuildTarget } from "../build-target.js";
3
3
  import { BuildTask } from "./task.js";
4
4
  import MIME from 'mime';
@@ -0,0 +1,66 @@
1
+ import { join } from "node:path";
2
+ import { makeComponentPublication } from "../../workspace/component.js";
3
+ import { BuildTarget } from "../build-target.js";
4
+ import { BuildTask } from "./task.js";
5
+ import MIME from 'mime';
6
+ export class ComponentsDtsTask extends BuildTask {
7
+ target;
8
+ bundle;
9
+ constructor(target, bundle) {
10
+ super(target);
11
+ this.target = target;
12
+ this.bundle = bundle;
13
+ }
14
+ async execute() {
15
+ const { target, bundle } = this;
16
+ const tx = this.target.edit();
17
+ const chunks = [];
18
+ // Emit static components manifest
19
+ for (const manif of target.components.values()) {
20
+ chunks.push("\n");
21
+ generate_component_apis(manif, chunks);
22
+ chunks.push("\n");
23
+ }
24
+ // Emit bundle manifest
25
+ const dts = chunks.join("");
26
+ await tx.commitFile(`components.d.ts`, dts);
27
+ //console.log(dts)
28
+ }
29
+ }
30
+ function generate_component_apis(manif, chunks) {
31
+ for (const service in manif.apis) {
32
+ const generator = components_dts_generators[service];
33
+ if (generator) {
34
+ generator(manif, chunks);
35
+ }
36
+ }
37
+ }
38
+ function generate_view_react(manif, chunks) {
39
+ const props = manif.specs?.view?.properties;
40
+ chunks.push(`declare module 'view.react:${manif.$id}' {\n`);
41
+ chunks.push(` import type { ReactComponentType, ReactComponentDescriptor } from "@jointhedots/core/interfaces/react"\n`);
42
+ if (props && Object.keys(props).length > 0) {
43
+ chunks.push(` export type Props = {\n`);
44
+ for (const key of Object.keys(props)) {
45
+ chunks.push(` ${key}?: any\n`);
46
+ }
47
+ chunks.push(` }\n`);
48
+ chunks.push(` export type Component = ReactComponentType<Props>\n`);
49
+ }
50
+ else {
51
+ chunks.push(` export type Component = ReactComponentType\n`);
52
+ }
53
+ chunks.push(` export type Descriptor = ReactComponentDescriptor\n`);
54
+ chunks.push(`}\n`);
55
+ }
56
+ function generate_commands(manif, chunks) {
57
+ chunks.push(`declare module 'commands:${manif.$id}' {\n`);
58
+ chunks.push(` import type { CommandsService, Cmdlet } from "@jointhedots/core/interfaces/commands"\n`);
59
+ chunks.push(` export type Service = CommandsService\n`);
60
+ chunks.push(`}\n`);
61
+ }
62
+ const components_dts_generators = {
63
+ "view.react": generate_view_react,
64
+ "commands": generate_commands,
65
+ };
66
+ //# sourceMappingURL=emit-components-dts.js.map
@@ -6,7 +6,7 @@ import postcss from 'postcss';
6
6
  import * as esbuild from 'esbuild';
7
7
  import { sassPlugin } from 'esbuild-sass-plugin';
8
8
  import { PackageRootDir, resolve_normalized_suffixed_path } from "../../utils/file.js";
9
- import { Library } from "../../model/workspace.js";
9
+ import { Library } from "../../workspace/workspace.js";
10
10
  import { computeNameHashID } from "../../utils/normalized-name.js";
11
11
  import { BuildTask } from "./task.js";
12
12
  const VirtualOutDir = process.platform === 'win32' ? 'X:\\' : '/_/';
@@ -1,5 +1,5 @@
1
1
  import { BuildTask } from "./task.js";
2
- import { create_export_map, create_package_manifest } from "../../model/helpers/create-manifests.js";
2
+ import { create_export_map, create_package_manifest } from "../../workspace/helpers/create-manifests.js";
3
3
  import { console } from "node:inspector";
4
4
  export class PackageManifestTask extends BuildTask {
5
5
  library;
@@ -1,7 +1,7 @@
1
1
  import Path from "node:path";
2
2
  import MIME from 'mime';
3
- import { Library } from "../../model/workspace.js";
4
- import { copyToStorageStream } from "../../model/storage.js";
3
+ import { Library } from "../../workspace/workspace.js";
4
+ import { copyToStorageStream } from "../../workspace/storage.js";
5
5
  import { BuildTask } from "./task.js";
6
6
  export class AssetsTask extends BuildTask {
7
7
  assets = [];
@@ -6,12 +6,16 @@ import { execFile } from 'child_process';
6
6
  import { promisify } from 'util';
7
7
  import { BuildTask } from "./task.js";
8
8
  import { BuildTarget } from "../build-target.js";
9
- import { Library } from "../../model/workspace.js";
9
+ import { Library } from "../../workspace/workspace.js";
10
10
  import { file } from "../../utils/file.js";
11
- import { create_export_map } from "../../model/helpers/create-manifests.js";
11
+ import { create_export_map } from "../../workspace/helpers/create-manifests.js";
12
12
  const eol = Os.EOL;
13
13
  const indent = " ";
14
14
  const DTSLEN = '.d.ts'.length;
15
+ const EXT_RE = /\.(d\.ts|tsx?|jsx?|mjs|json)$/;
16
+ function normalizeModuleId(id) {
17
+ return id.replace(EXT_RE, '').replace(/\/index$/, '');
18
+ }
15
19
  function normalizeFileName(filename) {
16
20
  return filename.replaceAll(Path.sep, "/");
17
21
  }
@@ -75,6 +79,19 @@ function isNodeKindStringLiteral(value) {
75
79
  function isNodeKindExportDeclaration(value) {
76
80
  return value && value.kind === Ts.SyntaxKind.ExportDeclaration;
77
81
  }
82
+ function hasDefaultExport(sourceFile) {
83
+ return sourceFile.statements.some(stmt => {
84
+ if (stmt.kind === Ts.SyntaxKind.ExportAssignment)
85
+ return !stmt.isExportEquals;
86
+ const mods = Ts.canHaveModifiers(stmt) ? Ts.getModifiers(stmt) : undefined;
87
+ if (mods?.some(m => m.kind === Ts.SyntaxKind.ExportKeyword) && mods?.some(m => m.kind === Ts.SyntaxKind.DefaultKeyword))
88
+ return true;
89
+ if (isNodeKindExportDeclaration(stmt) && stmt.exportClause && Ts.isNamedExports(stmt.exportClause)) {
90
+ return stmt.exportClause.elements.some(e => e.name.text === 'default');
91
+ }
92
+ return false;
93
+ });
94
+ }
78
95
  class TypescriptProject {
79
96
  baseDir;
80
97
  compilerOptions;
@@ -147,6 +164,7 @@ export function generateTypescriptDefinition(options) {
147
164
  const normalizedBaseDir = normalizeFileName(Path.resolve(baseDir)) + "/";
148
165
  const normalizedDtsDir = normalizeFileName(Path.resolve(project.dtsDir)) + "/";
149
166
  const resolveCache = new Map();
167
+ const modulesWithDefault = new Set();
150
168
  const outputParts = [];
151
169
  if (options.externs) {
152
170
  options.externs.forEach(function (path) {
@@ -173,17 +191,22 @@ export function generateTypescriptDefinition(options) {
173
191
  // Emit public re-export modules
174
192
  if (options.exports) {
175
193
  for (const entry of Object.values(options.exports)) {
194
+ if (!entry.source)
195
+ continue;
176
196
  const internalId = resolveInternalModuleImport(entry.source);
177
- if (internalId) {
197
+ if (internalId.startsWith(prefix)) {
178
198
  outputParts.push(`declare module '${entry.id}' {${eol}`);
179
199
  outputParts.push(`${indent}export * from '${internalId}';${eol}`);
200
+ if (modulesWithDefault.has(internalId)) {
201
+ outputParts.push(`${indent}export { default } from '${internalId}';${eol}`);
202
+ }
180
203
  outputParts.push(`}${eol}${eol}`);
181
204
  }
182
205
  }
183
206
  }
184
207
  function resolveInternalModuleImport(moduleId, importDir = "") {
185
208
  if (moduleId.charAt(0) === '.') {
186
- return prefix + normalizeFileName(Path.join(importDir, moduleId));
209
+ return prefix + normalizeModuleId(normalizeFileName(Path.join(importDir, moduleId)));
187
210
  }
188
211
  if (resolveCache.has(moduleId))
189
212
  return resolveCache.get(moduleId);
@@ -192,29 +215,25 @@ export function generateTypescriptDefinition(options) {
192
215
  if (result.resolvedModule && !result.resolvedModule.isExternalLibraryImport) {
193
216
  const resolved = normalizeFileName(result.resolvedModule.resolvedFileName);
194
217
  if (resolved.startsWith(normalizedBaseDir)) {
195
- const value = prefix + resolved.slice(normalizedBaseDir.length).replace(/\.(d\.ts|tsx?|jsx?)$/, '');
218
+ const value = prefix + normalizeModuleId(resolved.slice(normalizedBaseDir.length));
196
219
  resolveCache.set(moduleId, value);
197
220
  return value;
198
221
  }
199
222
  }
200
- // Check if moduleId is already an internal path relative to baseDir
201
- const absolute = normalizeFileName(Path.resolve(baseDir, importDir, moduleId));
202
- if (absolute.startsWith(normalizedBaseDir)) {
203
- const value = prefix + absolute.slice(normalizedBaseDir.length);
204
- resolveCache.set(moduleId, value);
205
- return value;
206
- }
207
- resolveCache.set(moduleId, null);
208
- return null;
223
+ // Not resolved as internal keep the original module specifier
224
+ resolveCache.set(moduleId, moduleId);
225
+ return moduleId;
209
226
  }
210
227
  function writeDeclaration(declarationFile, rawSourceModuleId) {
211
- const moduleDeclId = resolveInternalModuleImport(rawSourceModuleId);
228
+ const moduleDeclId = prefix + normalizeModuleId(rawSourceModuleId);
212
229
  const moduleDir = Path.dirname(rawSourceModuleId);
230
+ if (hasDefaultExport(declarationFile))
231
+ modulesWithDefault.add(moduleDeclId);
213
232
  outputParts.push(`declare module '${moduleDeclId}' {${eol}${indent}`);
214
233
  const content = processTree(declarationFile, function (node) {
215
234
  if (isNodeKindExternalModuleReference(node)) {
216
235
  const expression = node.expression;
217
- const resolved = resolveInternalModuleImport(expression.text, moduleDir) ?? expression.text;
236
+ const resolved = resolveInternalModuleImport(expression.text, moduleDir);
218
237
  return ` require('${resolved}')`;
219
238
  }
220
239
  else if (isNodeKindImportDeclaration(node) && !node.importClause) {
@@ -226,7 +245,7 @@ export function generateTypescriptDefinition(options) {
226
245
  else if (isNodeKindStringLiteral(node) && node.parent &&
227
246
  (isNodeKindExportDeclaration(node.parent) || isNodeKindImportDeclaration(node.parent) || isNodeKindImportType(node.parent?.parent))) {
228
247
  const resolved = resolveInternalModuleImport(node.text, moduleDir);
229
- if (resolved != null) {
248
+ if (resolved !== node.text) {
230
249
  return ` '${resolved}'`;
231
250
  }
232
251
  }
package/esm/cli.js CHANGED
@@ -4,6 +4,7 @@ import Yargs from "yargs";
4
4
  import { hideBin } from 'yargs/helpers';
5
5
  import { command_run } from "./commands/run.js";
6
6
  import { command_init } from "./commands/init.js";
7
+ import { command_install } from "./commands/install.js";
7
8
  import { command_make } from "./commands/make.js";
8
9
  import { command_serve } from "./commands/serve.js";
9
10
  import { command_publish } from "./commands/publish.js";
@@ -17,6 +18,7 @@ function command_fail() {
17
18
  }
18
19
  Yargs(hideBin(Process.argv)).scriptName("jointhedots-gear")
19
20
  .command(command_init())
21
+ .command(command_install())
20
22
  .command(command_make())
21
23
  .command(command_serve())
22
24
  .command(command_publish())
@@ -0,0 +1,67 @@
1
+ import Path from 'node:path';
2
+ import Fs from 'node:fs';
3
+ import {} from "yargs";
4
+ import { open_workspace } from "../workspace/workspace.js";
5
+ import { makeComponentPublication } from "../workspace/component.js";
6
+ import { BundleSelector } from "../builder/build-app-host.js";
7
+ export function command_install() {
8
+ return {
9
+ command: 'install',
10
+ describe: 'Install workspace bundles and emit a shelve manifest',
11
+ builder: (yargs) => yargs
12
+ .strict()
13
+ .option("ws", {
14
+ type: "string",
15
+ default: ".",
16
+ describe: "Workspace directory"
17
+ })
18
+ .option("dist", {
19
+ type: "string",
20
+ default: ".",
21
+ describe: "Output directory"
22
+ }),
23
+ handler: async (argv) => {
24
+ const ws = await open_workspace({
25
+ workspace_path: argv.ws,
26
+ devmode: false,
27
+ ignored_directory: Path.resolve(argv.dist),
28
+ });
29
+ // Select all workspace bundles
30
+ const selector = new BundleSelector(ws);
31
+ for (const lib of ws.libraries) {
32
+ selector.add(lib.bundle);
33
+ }
34
+ if (selector.missing.length > 0) {
35
+ ws.log.warn(`Missing bundle dependencies: ${selector.missing.join(", ")}`);
36
+ }
37
+ // Build shelve manifest indexing all bundles
38
+ const namespaces = new Set();
39
+ const components = [];
40
+ for (const bundle of selector) {
41
+ const pub = makeComponentPublication(bundle.manifest);
42
+ const nss = bundle.manifest.type === "bundle" && bundle.manifest.data?.["namespaces"];
43
+ if (Array.isArray(nss)) {
44
+ for (const ns of nss) {
45
+ namespaces.add(ns);
46
+ }
47
+ }
48
+ components.push(pub);
49
+ }
50
+ const manifest = {
51
+ $id: ".",
52
+ type: "bundle",
53
+ data: {
54
+ namespaces: Array.from(namespaces),
55
+ components,
56
+ }
57
+ };
58
+ // Write bundle.manifest.json to dist
59
+ const distDir = Path.resolve(argv.dist);
60
+ Fs.mkdirSync(distDir, { recursive: true });
61
+ const manifestPath = Path.join(distDir, "bundle.manifest.json");
62
+ Fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
63
+ ws.log.success(`Shelve manifest written to ${manifestPath}`);
64
+ }
65
+ };
66
+ }
67
+ //# sourceMappingURL=install.js.map
@@ -1,12 +1,12 @@
1
1
  import Path from 'node:path';
2
2
  import {} from "yargs";
3
- import { StorageFiles } from "../model/storage.js";
4
- import { Bundle, Library, open_workspace } from "../model/workspace.js";
3
+ import { StorageFiles } from "../workspace/storage.js";
4
+ import { Bundle, Library, open_workspace } from "../workspace/workspace.js";
5
5
  import { build_application } from "../builder/build-application.js";
6
6
  import { build_app_composable_bundle } from "../builder/build-app-bundle.js";
7
7
  import { build_library } from "../builder/build-library.js";
8
8
  import { makeNormalizedName, NameStyle } from '../utils/normalized-name.js';
9
- import { resolvePackageVersion } from "../model/helpers/package-npm.js";
9
+ import { resolvePackageVersion } from "../workspace/helpers/package-npm.js";
10
10
  export function command_make() {
11
11
  return {
12
12
  command: 'make',
@@ -88,8 +88,9 @@ export function command_make() {
88
88
  }
89
89
  const bundles = [];
90
90
  if (argv.bundles === "*") {
91
- for (const bundle of ws.bundles) {
92
- bundles.push(bundle);
91
+ for (const lib of ws.libraries) {
92
+ if (lib.bundle)
93
+ bundles.push(lib.bundle);
93
94
  }
94
95
  }
95
96
  else if (argv.bundles) {
@@ -1,7 +1,7 @@
1
1
  import Path from 'node:path';
2
2
  import {} from "yargs";
3
3
  import { publish_aws_s3 } from '../publish/publish_aws_s3.js';
4
- import { open_workspace } from "../model/workspace.js";
4
+ import { open_workspace } from "../workspace/workspace.js";
5
5
  export function command_publish() {
6
6
  return {
7
7
  command: 'publish',
@@ -1,11 +1,11 @@
1
1
  import Path from 'node:path';
2
2
  import {} from "yargs";
3
- import { StorageFiles } from "../model/storage.js";
4
- import { open_workspace, Workspace } from "../model/workspace.js";
3
+ import { StorageFiles } from "../workspace/storage.js";
4
+ import { open_workspace, Workspace } from "../workspace/workspace.js";
5
5
  import { build_application } from "../builder/build-application.js";
6
6
  import { makeNormalizedName, NameStyle } from '../utils/normalized-name.js';
7
7
  import Express from 'express';
8
- import { resolvePackageVersion } from "../model/helpers/package-npm.js";
8
+ import { resolvePackageVersion } from "../workspace/helpers/package-npm.js";
9
9
  export function command_serve() {
10
10
  return {
11
11
  command: 'serve',
@@ -2,9 +2,9 @@ import Fs from "node:fs";
2
2
  import Path from "node:path";
3
3
  import * as AWS from "@aws-sdk/client-s3";
4
4
  import MIME from "mime";
5
- import { StorageFiles } from "../model/storage.js";
5
+ import { StorageFiles } from "../workspace/storage.js";
6
6
  import { build_application } from "../builder/build-application.js";
7
- import { Workspace } from "../model/workspace.js";
7
+ import { Workspace } from "../workspace/workspace.js";
8
8
  export async function publish_aws_s3(appname, ws, bucket, region, outputDir) {
9
9
  const storage = new StorageFiles(ws.name, outputDir);
10
10
  const app = ws.get_application(appname);