@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.
- package/esm/builder/build-app-bundle.js +11 -12
- package/esm/builder/build-app-host.js +48 -6
- package/esm/builder/build-application.js +4 -5
- package/esm/builder/build-library.js +5 -3
- package/esm/builder/build-target.js +6 -6
- package/esm/builder/helpers/emit-bundle-manifest.js +1 -1
- package/esm/builder/helpers/emit-components-dts.js +66 -0
- package/esm/builder/helpers/emit-esmodules.js +1 -1
- package/esm/builder/helpers/emit-package-manifest.js +1 -1
- package/esm/builder/helpers/emit-static-assets.js +2 -2
- package/esm/builder/helpers/emit-typescript-definition.js +36 -17
- package/esm/cli.js +2 -0
- package/esm/commands/install.js +67 -0
- package/esm/commands/make.js +6 -5
- package/esm/commands/publish.js +1 -1
- package/esm/commands/serve.js +3 -3
- package/esm/publish/publish_aws_s3.js +2 -2
- package/esm/utils/normalized-name.js +11 -9
- package/esm/{model → workspace}/helpers/create-manifests.js +7 -1
- package/esm/{model → workspace}/helpers/discover-workspace.js +134 -154
- package/esm/workspace/packager.js +53 -0
- package/esm/workspace/packagers/packager-standard.js +64 -0
- package/esm/{model → workspace}/storage.js +15 -10
- package/esm/{model → workspace}/workspace.js +23 -14
- package/package.json +7 -3
- /package/esm/{model → workspace}/component.js +0 -0
- /package/esm/{model → workspace}/helpers/config-loader.js +0 -0
- /package/esm/{model → workspace}/helpers/lockfile.js +0 -0
- /package/esm/{model → workspace}/helpers/logger.js +0 -0
- /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 "../
|
|
3
|
-
import { StorageFiles } from "../
|
|
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 "../
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
173
|
-
const
|
|
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 "../
|
|
2
|
-
import { StorageFiles } from "../
|
|
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
|
-
|
|
143
|
-
|
|
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 "../
|
|
5
|
-
import { StorageFiles } from "../
|
|
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
|
|
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 =
|
|
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 "../
|
|
4
|
-
import { StorageFiles } from "../
|
|
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 "../
|
|
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 "../
|
|
2
|
-
import { Library, Workspace } from "../
|
|
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 "../
|
|
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,
|
|
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,
|
|
97
|
+
function createComponentDuplicateMessage(id, library) {
|
|
98
98
|
const duplicates = [];
|
|
99
99
|
const libs = [];
|
|
100
|
-
for (const bun of
|
|
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}`);
|
|
@@ -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 "../../
|
|
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 "../../
|
|
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 "../../
|
|
4
|
-
import { copyToStorageStream } from "../../
|
|
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 "../../
|
|
9
|
+
import { Library } from "../../workspace/workspace.js";
|
|
10
10
|
import { file } from "../../utils/file.js";
|
|
11
|
-
import { create_export_map } from "../../
|
|
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)
|
|
218
|
+
const value = prefix + normalizeModuleId(resolved.slice(normalizedBaseDir.length));
|
|
196
219
|
resolveCache.set(moduleId, value);
|
|
197
220
|
return value;
|
|
198
221
|
}
|
|
199
222
|
}
|
|
200
|
-
//
|
|
201
|
-
|
|
202
|
-
|
|
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 =
|
|
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)
|
|
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
|
|
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
|
package/esm/commands/make.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import Path from 'node:path';
|
|
2
2
|
import {} from "yargs";
|
|
3
|
-
import { StorageFiles } from "../
|
|
4
|
-
import { Bundle, Library, open_workspace } from "../
|
|
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 "../
|
|
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
|
|
92
|
-
|
|
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) {
|
package/esm/commands/publish.js
CHANGED
|
@@ -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 "../
|
|
4
|
+
import { open_workspace } from "../workspace/workspace.js";
|
|
5
5
|
export function command_publish() {
|
|
6
6
|
return {
|
|
7
7
|
command: 'publish',
|
package/esm/commands/serve.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import Path from 'node:path';
|
|
2
2
|
import {} from "yargs";
|
|
3
|
-
import { StorageFiles } from "../
|
|
4
|
-
import { open_workspace, Workspace } from "../
|
|
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 "../
|
|
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 "../
|
|
5
|
+
import { StorageFiles } from "../workspace/storage.js";
|
|
6
6
|
import { build_application } from "../builder/build-application.js";
|
|
7
|
-
import { Workspace } from "../
|
|
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);
|