@jointhedots/gear 1.1.12 → 1.1.14
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 -9
- package/esm/builder/build-application.js +6 -5
- package/esm/builder/build-library.js +11 -9
- package/esm/builder/build-target.js +7 -143
- package/esm/builder/helpers/emit-bundle-manifest.js +29 -0
- package/esm/builder/{esbuild-plugins.js → helpers/emit-esmodules.js} +71 -31
- package/esm/builder/helpers/emit-package-manifest.js +19 -0
- package/esm/builder/helpers/emit-static-assets.js +47 -0
- package/esm/builder/helpers/emit-typescript-definition.js +325 -0
- package/esm/builder/helpers/task.js +9 -0
- package/esm/model/helpers/create-manifests.js +43 -22
- package/esm/model/helpers/discover-workspace.js +39 -21
- package/esm/model/workspace.js +7 -9
- package/esm/utils/file.js +53 -29
- package/package.json +5 -4
- package/esm/builder/emit-dts.js +0 -388
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import Fs from 'fs';
|
|
2
|
+
import Os from 'os';
|
|
3
|
+
import Path from 'path';
|
|
4
|
+
import Ts from 'typescript';
|
|
5
|
+
import { execFileSync } from 'child_process';
|
|
6
|
+
import { BuildTask } from "./task.js";
|
|
7
|
+
import { BuildTarget } from "../build-target.js";
|
|
8
|
+
import { Library } from "../../model/workspace.js";
|
|
9
|
+
import { file } from "../../utils/file.js";
|
|
10
|
+
import { create_export_map } from "../../model/helpers/create-manifests.js";
|
|
11
|
+
const eol = Os.EOL;
|
|
12
|
+
const indent = " ";
|
|
13
|
+
const DTSLEN = '.d.ts'.length;
|
|
14
|
+
function normalizeFileName(filename) {
|
|
15
|
+
return filename.replaceAll(Path.sep, "/");
|
|
16
|
+
}
|
|
17
|
+
function isDtsFilename(filename) {
|
|
18
|
+
return filename.slice(-DTSLEN) === '.d.ts';
|
|
19
|
+
}
|
|
20
|
+
function getError(diagnostics) {
|
|
21
|
+
let message = 'Declaration generation failed';
|
|
22
|
+
diagnostics.forEach(function (diagnostic) {
|
|
23
|
+
if (diagnostic.file) {
|
|
24
|
+
const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
25
|
+
message +=
|
|
26
|
+
`\n${diagnostic.file.fileName}(${position.line + 1},${position.character + 1}): ` +
|
|
27
|
+
`error TS${diagnostic.code}: ${diagnostic.messageText}`;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
message += `\nerror TS${diagnostic.code}: ${diagnostic.messageText}`;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const error = new Error(message);
|
|
34
|
+
error.name = 'EmitterError';
|
|
35
|
+
return error;
|
|
36
|
+
}
|
|
37
|
+
function processTree(sourceFile, replacer) {
|
|
38
|
+
let code = '';
|
|
39
|
+
let cursorPosition = 0;
|
|
40
|
+
function skip(node) {
|
|
41
|
+
cursorPosition = node.end;
|
|
42
|
+
}
|
|
43
|
+
function readThrough(node) {
|
|
44
|
+
code += sourceFile.text.slice(cursorPosition, node.pos);
|
|
45
|
+
cursorPosition = node.pos;
|
|
46
|
+
}
|
|
47
|
+
function visit(node) {
|
|
48
|
+
readThrough(node);
|
|
49
|
+
const replacement = replacer(node);
|
|
50
|
+
if (replacement != null) {
|
|
51
|
+
code += replacement;
|
|
52
|
+
skip(node);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
Ts.forEachChild(node, visit);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
visit(sourceFile);
|
|
59
|
+
code += sourceFile.text.slice(cursorPosition);
|
|
60
|
+
return code;
|
|
61
|
+
}
|
|
62
|
+
function isNodeKindImportType(value) {
|
|
63
|
+
return value && value.kind === Ts.SyntaxKind.ImportType;
|
|
64
|
+
}
|
|
65
|
+
function isNodeKindImportDeclaration(value) {
|
|
66
|
+
return value && value.kind === Ts.SyntaxKind.ImportDeclaration;
|
|
67
|
+
}
|
|
68
|
+
function isNodeKindExternalModuleReference(value) {
|
|
69
|
+
return value && value.kind === Ts.SyntaxKind.ExternalModuleReference;
|
|
70
|
+
}
|
|
71
|
+
function isNodeKindStringLiteral(value) {
|
|
72
|
+
return value && value.kind === Ts.SyntaxKind.StringLiteral;
|
|
73
|
+
}
|
|
74
|
+
function isNodeKindExportDeclaration(value) {
|
|
75
|
+
return value && value.kind === Ts.SyntaxKind.ExportDeclaration;
|
|
76
|
+
}
|
|
77
|
+
class TypescriptProject {
|
|
78
|
+
baseDir;
|
|
79
|
+
compilerOptions;
|
|
80
|
+
dtsDir;
|
|
81
|
+
constructor(baseDir, tsconfig, outDir) {
|
|
82
|
+
this.baseDir = Path.resolve(baseDir);
|
|
83
|
+
const { config, error } = Ts.parseConfigFileTextToJson("tsconfig.json", tsconfig);
|
|
84
|
+
if (error)
|
|
85
|
+
throw getError([error]);
|
|
86
|
+
const configParsed = Ts.parseJsonConfigFileContent(config, Ts.sys, baseDir);
|
|
87
|
+
if (configParsed.errors?.length)
|
|
88
|
+
throw getError(configParsed.errors);
|
|
89
|
+
const compilerOptions = configParsed.options;
|
|
90
|
+
compilerOptions.outDir = compilerOptions.outDir || outDir;
|
|
91
|
+
this.compilerOptions = compilerOptions;
|
|
92
|
+
// Create a temp directory for tsgo to emit .d.ts into
|
|
93
|
+
this.dtsDir = Fs.mkdtempSync(Path.join(Os.tmpdir(), 'gear-dts-'));
|
|
94
|
+
}
|
|
95
|
+
/** Run tsgo to emit .d.ts files into dtsDir. Returns stderr output. */
|
|
96
|
+
emitWithTsgo() {
|
|
97
|
+
const tsgoPath = Path.resolve('node_modules/.bin/tsgo');
|
|
98
|
+
const args = [
|
|
99
|
+
'-p', Path.join(this.baseDir, 'tsconfig.json'),
|
|
100
|
+
'--declaration',
|
|
101
|
+
'--emitDeclarationOnly',
|
|
102
|
+
'--skipLibCheck',
|
|
103
|
+
'--outDir', this.dtsDir,
|
|
104
|
+
];
|
|
105
|
+
try {
|
|
106
|
+
execFileSync(tsgoPath, args, {
|
|
107
|
+
cwd: this.baseDir,
|
|
108
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
109
|
+
timeout: 120_000,
|
|
110
|
+
shell: true,
|
|
111
|
+
});
|
|
112
|
+
return '';
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
// tsgo may exit non-zero on type errors but still emit .d.ts files
|
|
116
|
+
return e.stderr?.toString() || e.message || '';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Recursively collect all .d.ts files emitted by tsgo */
|
|
120
|
+
getEmittedDtsFiles() {
|
|
121
|
+
const results = [];
|
|
122
|
+
function walk(dir) {
|
|
123
|
+
for (const entry of Fs.readdirSync(dir, { withFileTypes: true })) {
|
|
124
|
+
const full = Path.join(dir, entry.name);
|
|
125
|
+
if (entry.isDirectory())
|
|
126
|
+
walk(full);
|
|
127
|
+
else if (isDtsFilename(entry.name))
|
|
128
|
+
results.push(full);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (Fs.existsSync(this.dtsDir))
|
|
132
|
+
walk(this.dtsDir);
|
|
133
|
+
return results;
|
|
134
|
+
}
|
|
135
|
+
/** Clean up temp directory */
|
|
136
|
+
cleanup() {
|
|
137
|
+
try {
|
|
138
|
+
Fs.rmSync(this.dtsDir, { recursive: true, force: true });
|
|
139
|
+
}
|
|
140
|
+
catch { }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export function createTypescriptProject(baseDir, tsconfig, outDir) {
|
|
144
|
+
return new TypescriptProject(baseDir, tsconfig, outDir);
|
|
145
|
+
}
|
|
146
|
+
export function generateTypescriptDefinition(options) {
|
|
147
|
+
const project = options.project;
|
|
148
|
+
const baseDir = project.baseDir;
|
|
149
|
+
const dtsDir = project.dtsDir;
|
|
150
|
+
function isExcludedPath(fileName) {
|
|
151
|
+
return fileName.includes('/node_modules/') || fileName.includes('\\node_modules\\');
|
|
152
|
+
}
|
|
153
|
+
// Compute baseUrl prefix to strip from module paths
|
|
154
|
+
const normalizedBaseDir = normalizeFileName(Path.resolve(baseDir)) + "/";
|
|
155
|
+
const normalizedDtsDir = normalizeFileName(Path.resolve(dtsDir)) + "/";
|
|
156
|
+
let baseUrlPrefix = '';
|
|
157
|
+
if (project.compilerOptions.baseUrl) {
|
|
158
|
+
const absoluteBaseUrl = Path.resolve(baseDir, project.compilerOptions.baseUrl);
|
|
159
|
+
const normalizedBaseUrl = normalizeFileName(absoluteBaseUrl);
|
|
160
|
+
baseUrlPrefix = normalizedBaseUrl.slice(normalizedBaseDir.length);
|
|
161
|
+
if (baseUrlPrefix && !baseUrlPrefix.endsWith('/')) {
|
|
162
|
+
baseUrlPrefix += '/';
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function stripBaseUrlPrefix(modulePath) {
|
|
166
|
+
if (baseUrlPrefix && modulePath.startsWith(baseUrlPrefix)) {
|
|
167
|
+
return modulePath.slice(baseUrlPrefix.length);
|
|
168
|
+
}
|
|
169
|
+
return modulePath;
|
|
170
|
+
}
|
|
171
|
+
const outputParts = [];
|
|
172
|
+
if (options.externs) {
|
|
173
|
+
options.externs.forEach(function (path) {
|
|
174
|
+
outputParts.push(`/// <reference path="${path}" />` + eol);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (options.types) {
|
|
178
|
+
options.types.forEach(function (type) {
|
|
179
|
+
outputParts.push(`/// <reference types="${type}" />` + eol);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// Map source-relative paths to internal: module IDs for ALL emitted files
|
|
183
|
+
const internalsMap = {};
|
|
184
|
+
const dtsFiles = project.getEmittedDtsFiles();
|
|
185
|
+
for (const dtsPath of dtsFiles) {
|
|
186
|
+
const normalizedDts = normalizeFileName(Path.resolve(dtsPath));
|
|
187
|
+
if (!normalizedDts.startsWith(normalizedDtsDir))
|
|
188
|
+
continue;
|
|
189
|
+
const relativeDts = normalizedDts.slice(normalizedDtsDir.length);
|
|
190
|
+
const relativeSource = relativeDts.replace(/\.d\.ts$/, '');
|
|
191
|
+
const strippedSource = stripBaseUrlPrefix(relativeSource);
|
|
192
|
+
const moduleId = `${options.prefix}:${strippedSource}`;
|
|
193
|
+
internalsMap[relativeSource] = moduleId;
|
|
194
|
+
internalsMap[strippedSource] = moduleId;
|
|
195
|
+
if (strippedSource.endsWith('/index')) {
|
|
196
|
+
internalsMap[strippedSource.slice(0, -6)] = moduleId;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Build public export map: maps export entry ID to internal module ID
|
|
200
|
+
const publicReexports = [];
|
|
201
|
+
if (options.exports) {
|
|
202
|
+
for (const entry of Object.values(options.exports)) {
|
|
203
|
+
const fileName = entry.source;
|
|
204
|
+
if (isExcludedPath(fileName))
|
|
205
|
+
continue;
|
|
206
|
+
const normalizedSource = normalizeFileName(Path.resolve(fileName));
|
|
207
|
+
if (!normalizedSource.startsWith(normalizedBaseDir))
|
|
208
|
+
continue;
|
|
209
|
+
const shortName = normalizedSource.slice(normalizedBaseDir.length);
|
|
210
|
+
const shortNameNoExt = shortName.replace(/\.(ts|tsx|js|jsx)$/, '');
|
|
211
|
+
const strippedShortNameNoExt = stripBaseUrlPrefix(shortNameNoExt);
|
|
212
|
+
const internalId = internalsMap[shortNameNoExt] ||
|
|
213
|
+
internalsMap[strippedShortNameNoExt] ||
|
|
214
|
+
internalsMap[shortName];
|
|
215
|
+
if (internalId) {
|
|
216
|
+
publicReexports.push({ id: entry.id, internalId });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Unified module ID normalization
|
|
221
|
+
function normalizeModuleId(moduleId) {
|
|
222
|
+
moduleId = moduleId.replace(/\.(d\.ts|ts|tsx|js|jsx)$/, '');
|
|
223
|
+
moduleId = stripBaseUrlPrefix(moduleId);
|
|
224
|
+
const remapped = internalsMap[moduleId] ||
|
|
225
|
+
internalsMap[moduleId + "/index"] ||
|
|
226
|
+
internalsMap[moduleId + "/index.ts"];
|
|
227
|
+
return remapped || moduleId;
|
|
228
|
+
}
|
|
229
|
+
function isExternalModule(moduleId) {
|
|
230
|
+
return !internalsMap[moduleId];
|
|
231
|
+
}
|
|
232
|
+
// Process each emitted .d.ts file as internal: module
|
|
233
|
+
for (const dtsPath of dtsFiles) {
|
|
234
|
+
const normalizedDts = normalizeFileName(Path.resolve(dtsPath));
|
|
235
|
+
if (!normalizedDts.startsWith(normalizedDtsDir))
|
|
236
|
+
continue;
|
|
237
|
+
const relativeDts = normalizedDts.slice(normalizedDtsDir.length);
|
|
238
|
+
const relativeSource = relativeDts.replace(/\.d\.ts$/, '');
|
|
239
|
+
const data = Fs.readFileSync(dtsPath, 'utf-8');
|
|
240
|
+
const declFile = Ts.createSourceFile(dtsPath, data, Ts.ScriptTarget.Latest, true);
|
|
241
|
+
writeDeclaration(declFile, relativeSource);
|
|
242
|
+
}
|
|
243
|
+
// Emit public re-export modules
|
|
244
|
+
for (const { id, internalId } of publicReexports) {
|
|
245
|
+
outputParts.push(`declare module '${id}' {${eol}`);
|
|
246
|
+
outputParts.push(`${indent}export * from '${internalId}';${eol}`);
|
|
247
|
+
outputParts.push(`}${eol}${eol}`);
|
|
248
|
+
}
|
|
249
|
+
function writeDeclaration(declarationFile, rawSourceModuleId) {
|
|
250
|
+
const moduleDeclId = normalizeModuleId(rawSourceModuleId);
|
|
251
|
+
outputParts.push(`declare module '${moduleDeclId}' {${eol}${indent}`);
|
|
252
|
+
function resolveModuleImport(moduleId) {
|
|
253
|
+
let resolved;
|
|
254
|
+
if (moduleId.charAt(0) === '.') {
|
|
255
|
+
resolved = normalizeFileName(Path.join(Path.dirname(rawSourceModuleId), moduleId));
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
resolved = moduleId;
|
|
259
|
+
if (isExternalModule(resolved))
|
|
260
|
+
return resolved;
|
|
261
|
+
}
|
|
262
|
+
return normalizeModuleId(resolved);
|
|
263
|
+
}
|
|
264
|
+
const content = processTree(declarationFile, function (node) {
|
|
265
|
+
if (isNodeKindExternalModuleReference(node)) {
|
|
266
|
+
const expression = node.expression;
|
|
267
|
+
const resolved = resolveModuleImport(expression.text);
|
|
268
|
+
return ` require('${resolved}')`;
|
|
269
|
+
}
|
|
270
|
+
else if (isNodeKindImportDeclaration(node) && !node.importClause) {
|
|
271
|
+
return '';
|
|
272
|
+
}
|
|
273
|
+
else if (node.kind === Ts.SyntaxKind.DeclareKeyword) {
|
|
274
|
+
return '';
|
|
275
|
+
}
|
|
276
|
+
else if (isNodeKindStringLiteral(node) && node.parent &&
|
|
277
|
+
(isNodeKindExportDeclaration(node.parent) || isNodeKindImportDeclaration(node.parent) || isNodeKindImportType(node.parent?.parent))) {
|
|
278
|
+
const resolved = resolveModuleImport(node.text);
|
|
279
|
+
if (resolved) {
|
|
280
|
+
return ` '${resolved}'`;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
const chunks = content.replaceAll("\r", "").split("\n").map(c => c.trimEnd());
|
|
285
|
+
while (chunks.length > 0 && chunks[chunks.length - 1] === "")
|
|
286
|
+
chunks.pop();
|
|
287
|
+
outputParts.push(chunks.join(eol + indent) + eol);
|
|
288
|
+
outputParts.push('}' + eol + eol);
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
dts: outputParts.join(''),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
export class TypescriptDefinitionTask extends BuildTask {
|
|
295
|
+
library;
|
|
296
|
+
constructor(target, library) {
|
|
297
|
+
super(target);
|
|
298
|
+
this.library = library;
|
|
299
|
+
}
|
|
300
|
+
async execute() {
|
|
301
|
+
const lib = this.library;
|
|
302
|
+
const { storage } = this.target;
|
|
303
|
+
try {
|
|
304
|
+
const configText = file.read.text(Path.join(lib.path, "./tsconfig.json"))
|
|
305
|
+
|| file.read.text("./tsconfig.json");
|
|
306
|
+
const project = createTypescriptProject(lib.path, configText, storage.getBaseDirFS());
|
|
307
|
+
const stderr = project.emitWithTsgo();
|
|
308
|
+
if (stderr) {
|
|
309
|
+
this.log.warn(stderr);
|
|
310
|
+
}
|
|
311
|
+
const { dts } = generateTypescriptDefinition({
|
|
312
|
+
project,
|
|
313
|
+
prefix: lib.name,
|
|
314
|
+
exclude: ["node_modules/**/*"],
|
|
315
|
+
exports: create_export_map(lib, lib.bundle),
|
|
316
|
+
});
|
|
317
|
+
file.write.text(storage.getBaseDirFS() + "/types.d.ts", dts);
|
|
318
|
+
project.cleanup();
|
|
319
|
+
}
|
|
320
|
+
catch (e) {
|
|
321
|
+
this.log.error("no 'type.d.ts' will be generated for the package:" + e.message);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=emit-typescript-definition.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
|
|
47
|
+
export function create_bundle_manifest(lib, bun) {
|
|
48
|
+
if (!bun)
|
|
49
|
+
return null;
|
|
47
50
|
const entries = create_export_map(lib, bun);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
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] = {
|
|
100
|
+
pkg_manif.exports[exp.exported] = {
|
|
101
|
+
import: `./${exp.filename}`,
|
|
102
|
+
types: "./types.d.ts",
|
|
103
|
+
};
|
|
83
104
|
}
|
|
84
105
|
}
|
|
85
|
-
return
|
|
106
|
+
return pkg_manif;
|
|
86
107
|
}
|
|
87
108
|
//# sourceMappingURL=create-manifests.js.map
|
|
@@ -3,7 +3,7 @@ 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 {
|
|
6
|
+
import { create_bundle_manifest } from "./create-manifests.js";
|
|
7
7
|
import { Bundle, Library, Workspace } from "../workspace.js";
|
|
8
8
|
import { file, make_canonical_path, make_normalized_dirname, make_normalized_path, make_relative_path } from "../../utils/file.js";
|
|
9
9
|
import { findConfigFile, is_config_filename, readConfigFile, readSingletonConfigFile } from "./config-loader.js";
|
|
@@ -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);
|
|
@@ -118,6 +118,19 @@ async function discover_library_components(lib, path, subdir = false) {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
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];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return value;
|
|
133
|
+
}
|
|
121
134
|
function make_library_bundle_manifest(lib, file_desc) {
|
|
122
135
|
let $id = file_desc?.$id;
|
|
123
136
|
if ($id) {
|
|
@@ -131,26 +144,22 @@ function make_library_bundle_manifest(lib, file_desc) {
|
|
|
131
144
|
lib.log.info(`Bundle '${$id}' named from library '${lib.name}'`);
|
|
132
145
|
}
|
|
133
146
|
const data = {
|
|
134
|
-
alias: lib.name,
|
|
135
147
|
package: lib.get_id(),
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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", {}),
|
|
139
152
|
};
|
|
140
153
|
if (file_desc?.data) {
|
|
141
154
|
data.alias = file_desc.data.alias ?? data.alias;
|
|
142
|
-
if (file_desc.data.
|
|
143
|
-
|
|
144
|
-
if (Array.isArray(distribueds))
|
|
145
|
-
distribueds.forEach(dist => data.redistribueds[dist] = "*");
|
|
146
|
-
else
|
|
147
|
-
Object.assign(data.redistribueds, distribueds);
|
|
155
|
+
if (file_desc.data.distribueds) {
|
|
156
|
+
Object.assign(data.distribueds, file_desc.data.distribueds);
|
|
148
157
|
}
|
|
149
|
-
if (file_desc.data.namespaces) {
|
|
150
|
-
data.namespaces
|
|
158
|
+
if (Array.isArray(file_desc.data.namespaces)) {
|
|
159
|
+
data.namespaces.push(...file_desc.data.namespaces);
|
|
151
160
|
}
|
|
152
|
-
if (file_desc.data.dependencies) {
|
|
153
|
-
data.dependencies
|
|
161
|
+
if (Array.isArray(file_desc.data.dependencies)) {
|
|
162
|
+
data.dependencies.push(...file_desc.data.dependencies);
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
165
|
const manifest = {
|
|
@@ -203,9 +212,9 @@ async function discover_library(ws, location, installed) {
|
|
|
203
212
|
ws.libraries.push(lib);
|
|
204
213
|
ws.log.info(`+ 📚 library: ${installed ? "⏬" : "🐣"} ${lib.get_id()} (${make_relative_path(ws.path, location)})`);
|
|
205
214
|
// Setup library infos from bundle manifest
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
215
|
+
setup_library_bundle(lib, manifest_desc);
|
|
216
|
+
// Analyze library deployment manifest (supports json/yaml/yml/toml, singleton)
|
|
217
|
+
if (manifest_desc?.data?.components) {
|
|
209
218
|
for (const pub of manifest_desc.data.components) {
|
|
210
219
|
const fpath = lib_path + "/" + (pub.ref ?? pub.id);
|
|
211
220
|
await discover_component(lib, fpath);
|
|
@@ -270,14 +279,23 @@ export async function discover_workspace(ws) {
|
|
|
270
279
|
if (!package_lock) {
|
|
271
280
|
throw new Error(`Package lock not found for '${ws.name}'`);
|
|
272
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
|
+
}
|
|
273
292
|
await discover_workspace_libraries(ws);
|
|
274
293
|
for (const location in package_lock.packages) {
|
|
275
294
|
await discover_library(ws, location, true);
|
|
276
295
|
}
|
|
277
296
|
for (const bun of ws.bundles) {
|
|
278
297
|
if (bun.source) {
|
|
279
|
-
|
|
280
|
-
bun.manifest = manifs.bundle;
|
|
298
|
+
bun.manifest = create_bundle_manifest(bun.source, bun);
|
|
281
299
|
}
|
|
282
300
|
}
|
|
283
301
|
show_constants(ws);
|
package/esm/model/workspace.js
CHANGED
|
@@ -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 {
|
|
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 {
|
|
11
|
+
import { create_bundle_manifest } from "./helpers/create-manifests.js";
|
|
14
12
|
export class WorkspaceItem {
|
|
15
13
|
workspace;
|
|
16
14
|
log;
|
|
@@ -51,13 +49,13 @@ export class Library extends WorkspaceItem {
|
|
|
51
49
|
return base ? prefix + "." + base : prefix;
|
|
52
50
|
}
|
|
53
51
|
resolve_entry_path(entryId, baseDir) {
|
|
54
|
-
const fpath =
|
|
52
|
+
const fpath = make_normalized_path(Path.resolve(baseDir, entryId));
|
|
55
53
|
if (entryId.startsWith("."))
|
|
56
54
|
return fpath;
|
|
57
55
|
const parts = entryId.split("/");
|
|
58
56
|
for (const search_path of this.search_directories) {
|
|
59
57
|
if (Fs.existsSync(search_path + "/" + parts[0])) {
|
|
60
|
-
return
|
|
58
|
+
return make_normalized_path(search_path + "/" + entryId);
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
if (Fs.existsSync(fpath))
|
|
@@ -94,8 +92,7 @@ export class Bundle extends WorkspaceItem {
|
|
|
94
92
|
}
|
|
95
93
|
resolve_export(ref) {
|
|
96
94
|
if (!this.manifest) {
|
|
97
|
-
|
|
98
|
-
this.manifest = manifs.bundle;
|
|
95
|
+
this.manifest = create_bundle_manifest(this.source, this);
|
|
99
96
|
this.configured = true;
|
|
100
97
|
}
|
|
101
98
|
return this.exports?.[ref];
|
|
@@ -110,6 +107,7 @@ export class Workspace {
|
|
|
110
107
|
bundles = [];
|
|
111
108
|
libraries = [];
|
|
112
109
|
constants = {};
|
|
110
|
+
resolved_versions = {};
|
|
113
111
|
search_directories = [];
|
|
114
112
|
ignored_directories = new Set();
|
|
115
113
|
logger = new Logger();
|