@jointhedots/gear 1.1.14 → 1.1.16
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/browser-modules/asap-raw.js +1 -1
- package/browser-modules/process.js +1 -1
- package/browser-modules/side-effects.js +211 -2
- package/esm/builder/helpers/emit-esmodules.js +13 -6
- package/esm/builder/helpers/emit-typescript-definition.js +48 -101
- package/esm/model/helpers/discover-workspace.js +8 -17
- package/esm/model/helpers/lockfile.js +108 -0
- package/package.json +1 -1
|
@@ -38,7 +38,7 @@ function flush() {
|
|
|
38
38
|
flushing = false;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
var scope = typeof globalThis !== "undefined" ? globalThis : (typeof self !== "undefined" ? self :
|
|
41
|
+
var scope = typeof globalThis !== "undefined" ? globalThis : (typeof self !== "undefined" ? self : globalThis);
|
|
42
42
|
var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
|
|
43
43
|
|
|
44
44
|
if (typeof BrowserMutationObserver === "function") {
|
|
@@ -4,5 +4,214 @@
|
|
|
4
4
|
import './process.js'
|
|
5
5
|
import './buffer.js'
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
|
|
7
|
+
// Add Node.js-specific API to W3C ReadableStream
|
|
8
|
+
{
|
|
9
|
+
const proto = ReadableStream.prototype
|
|
10
|
+
|
|
11
|
+
// Start consuming the stream, emitting 'data'/'end'/'error'/'close' events
|
|
12
|
+
function _startReading(stream) {
|
|
13
|
+
if (stream._reading) return
|
|
14
|
+
stream._reading = true
|
|
15
|
+
stream._paused = false
|
|
16
|
+
const reader = stream.getReader()
|
|
17
|
+
const pump = () => reader.read().then(({ done, value }) => {
|
|
18
|
+
if (done) {
|
|
19
|
+
stream._reading = false
|
|
20
|
+
stream._emit('end')
|
|
21
|
+
stream._emit('close')
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
stream._emit('data', value)
|
|
25
|
+
if (!stream._paused) return pump()
|
|
26
|
+
stream._pump = pump
|
|
27
|
+
}).catch(err => {
|
|
28
|
+
stream._reading = false
|
|
29
|
+
stream._emit('error', err)
|
|
30
|
+
})
|
|
31
|
+
pump()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
proto._emit = function (event, ...args) {
|
|
35
|
+
this._listeners?.[event]?.slice().forEach(fn => fn(...args))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
proto.on = proto.addListener = function (event, fn) {
|
|
39
|
+
this._listeners ??= {}
|
|
40
|
+
; (this._listeners[event] ??= []).push(fn)
|
|
41
|
+
if (event === 'data') _startReading(this)
|
|
42
|
+
return this
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
proto.once = function (event, fn) {
|
|
46
|
+
const wrapped = (...args) => { this.off(event, wrapped); fn(...args) }
|
|
47
|
+
return this.on(event, wrapped)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
proto.off = proto.removeListener = function (event, fn) {
|
|
51
|
+
const list = this._listeners?.[event]
|
|
52
|
+
if (list) { const i = list.indexOf(fn); if (i >= 0) list.splice(i, 1) }
|
|
53
|
+
return this
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
proto.pipe = function (dest) {
|
|
57
|
+
this.on('data', chunk => dest.write?.(chunk))
|
|
58
|
+
this.once('end', () => dest.end?.())
|
|
59
|
+
this.once('error', err => dest.destroy?.(err))
|
|
60
|
+
return dest
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
proto.pause = function () {
|
|
64
|
+
this._paused = true
|
|
65
|
+
return this
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
proto.resume = function () {
|
|
69
|
+
this._paused = false
|
|
70
|
+
this._pump?.()
|
|
71
|
+
return this
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
proto.destroy = function (err) {
|
|
75
|
+
if (err) this._emit('error', err)
|
|
76
|
+
this._emit('close')
|
|
77
|
+
this.cancel(err).catch(() => { })
|
|
78
|
+
return this
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
proto.unpipe = function (dest) {
|
|
82
|
+
this._listeners = {}
|
|
83
|
+
return this
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Add Node.js-specific API to W3C WritableStream
|
|
88
|
+
{
|
|
89
|
+
const proto = WritableStream.prototype
|
|
90
|
+
|
|
91
|
+
proto._emit = function (event, ...args) {
|
|
92
|
+
this._listeners?.[event]?.slice().forEach(fn => fn(...args))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
proto.on = proto.addListener = function (event, fn) {
|
|
96
|
+
this._listeners ??= {}
|
|
97
|
+
; (this._listeners[event] ??= []).push(fn)
|
|
98
|
+
return this
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
proto.once = function (event, fn) {
|
|
102
|
+
const wrapped = (...args) => { this.off(event, wrapped); fn(...args) }
|
|
103
|
+
return this.on(event, wrapped)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
proto.off = proto.removeListener = function (event, fn) {
|
|
107
|
+
const list = this._listeners?.[event]
|
|
108
|
+
if (list) { const i = list.indexOf(fn); if (i >= 0) list.splice(i, 1) }
|
|
109
|
+
return this
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
proto._getWriter = function () {
|
|
113
|
+
if (!this._writer) this._writer = this.getWriter()
|
|
114
|
+
return this._writer
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
proto.write = function (chunk, encoding, callback) {
|
|
118
|
+
if (typeof encoding === 'function') { callback = encoding; encoding = undefined }
|
|
119
|
+
const writer = this._getWriter()
|
|
120
|
+
writer.ready.then(() => writer.write(chunk)).then(
|
|
121
|
+
() => { this._emit('drain'); callback?.() },
|
|
122
|
+
err => { this._emit('error', err); callback?.(err) }
|
|
123
|
+
)
|
|
124
|
+
return true
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
proto.end = function (chunk, encoding, callback) {
|
|
128
|
+
if (typeof chunk === 'function') { callback = chunk; chunk = null }
|
|
129
|
+
else if (typeof encoding === 'function') { callback = encoding; encoding = null }
|
|
130
|
+
const writer = this._getWriter()
|
|
131
|
+
const finish = () => writer.close().then(
|
|
132
|
+
() => { this._emit('finish'); this._emit('close'); callback?.() },
|
|
133
|
+
err => { this._emit('error', err); callback?.(err) }
|
|
134
|
+
)
|
|
135
|
+
if (chunk != null) {
|
|
136
|
+
writer.ready.then(() => writer.write(chunk)).then(finish, finish)
|
|
137
|
+
} else {
|
|
138
|
+
finish()
|
|
139
|
+
}
|
|
140
|
+
return this
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
proto.destroy = function (err) {
|
|
144
|
+
const writer = this._getWriter()
|
|
145
|
+
if (err) {
|
|
146
|
+
writer.abort(err).catch(() => { })
|
|
147
|
+
this._emit('error', err)
|
|
148
|
+
} else {
|
|
149
|
+
writer.close().catch(() => { })
|
|
150
|
+
}
|
|
151
|
+
this._emit('close')
|
|
152
|
+
return this
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
proto.cork = function () { this._corked = (this._corked || 0) + 1 }
|
|
156
|
+
proto.uncork = function () { if (this._corked > 0) this._corked-- }
|
|
157
|
+
|
|
158
|
+
proto.setDefaultEncoding = function (encoding) {
|
|
159
|
+
this._defaultEncoding = encoding
|
|
160
|
+
return this
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Add Node.js-specific API to W3C TransformStream
|
|
165
|
+
{
|
|
166
|
+
const proto = TransformStream.prototype
|
|
167
|
+
|
|
168
|
+
proto._emit = function (event, ...args) {
|
|
169
|
+
this._listeners?.[event]?.slice().forEach(fn => fn(...args))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
proto.on = proto.addListener = function (event, fn) {
|
|
173
|
+
this._listeners ??= {}
|
|
174
|
+
; (this._listeners[event] ??= []).push(fn)
|
|
175
|
+
if (event === 'data') this.readable.on('data', chunk => this._emit('data', chunk))
|
|
176
|
+
return this
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
proto.once = function (event, fn) {
|
|
180
|
+
const wrapped = (...args) => { this.off(event, wrapped); fn(...args) }
|
|
181
|
+
return this.on(event, wrapped)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
proto.off = proto.removeListener = function (event, fn) {
|
|
185
|
+
const list = this._listeners?.[event]
|
|
186
|
+
if (list) { const i = list.indexOf(fn); if (i >= 0) list.splice(i, 1) }
|
|
187
|
+
return this
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
proto.write = function (chunk, encoding, callback) {
|
|
191
|
+
return this.writable.write(chunk, encoding, callback)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
proto.end = function (chunk, encoding, callback) {
|
|
195
|
+
return this.writable.end(chunk, encoding, callback)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
proto.pipe = function (dest) {
|
|
199
|
+
return this.readable.pipe(dest)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
proto.pause = function () {
|
|
203
|
+
this.readable.pause()
|
|
204
|
+
return this
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
proto.resume = function () {
|
|
208
|
+
this.readable.resume()
|
|
209
|
+
return this
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
proto.destroy = function (err) {
|
|
213
|
+
this.readable.destroy(err)
|
|
214
|
+
this.writable.destroy(err)
|
|
215
|
+
return this
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -21,7 +21,7 @@ function getEsbuildLogLevel(mode) {
|
|
|
21
21
|
return "silent";
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
async function create_esbuild_context(task, devmode, onReady) {
|
|
25
25
|
const ws = task.target.workspace;
|
|
26
26
|
// Define modules mapping - using @jspm/core polyfills (same as Vite)
|
|
27
27
|
const jspmPolyfills = Path.resolve(PackageRootDir, "node_modules/@jspm/core/nodelibs/browser");
|
|
@@ -111,7 +111,7 @@ export async function create_esbuild_context(task, devmode) {
|
|
|
111
111
|
ESModuleResolverPlugin(modules_mapping, tsconfig),
|
|
112
112
|
...task.plugins,
|
|
113
113
|
StyleSheetPlugin(task),
|
|
114
|
-
StoragePlugin(task),
|
|
114
|
+
StoragePlugin(task, onReady),
|
|
115
115
|
],
|
|
116
116
|
loader: {
|
|
117
117
|
'.jpg': 'file',
|
|
@@ -255,7 +255,7 @@ function hasTailwindConfig(workspacePath) {
|
|
|
255
255
|
catch { }
|
|
256
256
|
return false;
|
|
257
257
|
}
|
|
258
|
-
export function StoragePlugin(task) {
|
|
258
|
+
export function StoragePlugin(task, onReady) {
|
|
259
259
|
return {
|
|
260
260
|
name: "dipatch-files",
|
|
261
261
|
setup: (build) => {
|
|
@@ -290,7 +290,11 @@ export function StoragePlugin(task) {
|
|
|
290
290
|
task.target.store();
|
|
291
291
|
const storeTime = (Date.now() - storeStart) / 1000;
|
|
292
292
|
const buildTime = (Date.now() - buildStartTime) / 1000;
|
|
293
|
-
task.log.info(`
|
|
293
|
+
task.log.info(`Store ES graph in ${result.outputFiles.length} file(s) (compile: ${buildTime.toFixed(2)}s, store: ${storeTime.toFixed(2)}s)`);
|
|
294
|
+
}
|
|
295
|
+
if (onReady) {
|
|
296
|
+
onReady();
|
|
297
|
+
onReady = null;
|
|
294
298
|
}
|
|
295
299
|
return null;
|
|
296
300
|
});
|
|
@@ -602,11 +606,14 @@ export class ESModulesTask extends BuildTask {
|
|
|
602
606
|
await prev_ctx.dispose();
|
|
603
607
|
}
|
|
604
608
|
const { target } = this;
|
|
605
|
-
this.context = await create_esbuild_context(this, target.devmode);
|
|
606
609
|
if (target.watch) {
|
|
607
|
-
|
|
610
|
+
return new Promise(async (resolve, reject) => {
|
|
611
|
+
this.context = await create_esbuild_context(this, target.devmode, resolve);
|
|
612
|
+
await this.context.watch();
|
|
613
|
+
});
|
|
608
614
|
}
|
|
609
615
|
else {
|
|
616
|
+
this.context = await create_esbuild_context(this, target.devmode);
|
|
610
617
|
await this.context.rebuild();
|
|
611
618
|
await this.context.dispose();
|
|
612
619
|
}
|
|
@@ -2,7 +2,8 @@ import Fs from 'fs';
|
|
|
2
2
|
import Os from 'os';
|
|
3
3
|
import Path from 'path';
|
|
4
4
|
import Ts from 'typescript';
|
|
5
|
-
import {
|
|
5
|
+
import { execFile } from 'child_process';
|
|
6
|
+
import { promisify } from 'util';
|
|
6
7
|
import { BuildTask } from "./task.js";
|
|
7
8
|
import { BuildTarget } from "../build-target.js";
|
|
8
9
|
import { Library } from "../../model/workspace.js";
|
|
@@ -93,7 +94,7 @@ class TypescriptProject {
|
|
|
93
94
|
this.dtsDir = Fs.mkdtempSync(Path.join(Os.tmpdir(), 'gear-dts-'));
|
|
94
95
|
}
|
|
95
96
|
/** Run tsgo to emit .d.ts files into dtsDir. Returns stderr output. */
|
|
96
|
-
emitWithTsgo() {
|
|
97
|
+
async emitWithTsgo() {
|
|
97
98
|
const tsgoPath = Path.resolve('node_modules/.bin/tsgo');
|
|
98
99
|
const args = [
|
|
99
100
|
'-p', Path.join(this.baseDir, 'tsconfig.json'),
|
|
@@ -103,17 +104,14 @@ class TypescriptProject {
|
|
|
103
104
|
'--outDir', this.dtsDir,
|
|
104
105
|
];
|
|
105
106
|
try {
|
|
106
|
-
|
|
107
|
+
await promisify(execFile)(tsgoPath, args, {
|
|
107
108
|
cwd: this.baseDir,
|
|
108
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
109
109
|
timeout: 120_000,
|
|
110
110
|
shell: true,
|
|
111
111
|
});
|
|
112
|
-
return '';
|
|
113
112
|
}
|
|
114
113
|
catch (e) {
|
|
115
114
|
// tsgo may exit non-zero on type errors but still emit .d.ts files
|
|
116
|
-
return e.stderr?.toString() || e.message || '';
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
/** Recursively collect all .d.ts files emitted by tsgo */
|
|
@@ -144,30 +142,11 @@ export function createTypescriptProject(baseDir, tsconfig, outDir) {
|
|
|
144
142
|
return new TypescriptProject(baseDir, tsconfig, outDir);
|
|
145
143
|
}
|
|
146
144
|
export function generateTypescriptDefinition(options) {
|
|
147
|
-
const project = options
|
|
145
|
+
const { project, prefix } = options;
|
|
148
146
|
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
147
|
const normalizedBaseDir = normalizeFileName(Path.resolve(baseDir)) + "/";
|
|
155
|
-
const normalizedDtsDir = normalizeFileName(Path.resolve(dtsDir)) + "/";
|
|
156
|
-
|
|
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
|
-
}
|
|
148
|
+
const normalizedDtsDir = normalizeFileName(Path.resolve(project.dtsDir)) + "/";
|
|
149
|
+
const resolveCache = new Map();
|
|
171
150
|
const outputParts = [];
|
|
172
151
|
if (options.externs) {
|
|
173
152
|
options.externs.forEach(function (path) {
|
|
@@ -179,8 +158,7 @@ export function generateTypescriptDefinition(options) {
|
|
|
179
158
|
outputParts.push(`/// <reference types="${type}" />` + eol);
|
|
180
159
|
});
|
|
181
160
|
}
|
|
182
|
-
//
|
|
183
|
-
const internalsMap = {};
|
|
161
|
+
// Process each emitted .d.ts file as internal: module
|
|
184
162
|
const dtsFiles = project.getEmittedDtsFiles();
|
|
185
163
|
for (const dtsPath of dtsFiles) {
|
|
186
164
|
const normalizedDts = normalizeFileName(Path.resolve(dtsPath));
|
|
@@ -188,83 +166,55 @@ export function generateTypescriptDefinition(options) {
|
|
|
188
166
|
continue;
|
|
189
167
|
const relativeDts = normalizedDts.slice(normalizedDtsDir.length);
|
|
190
168
|
const relativeSource = relativeDts.replace(/\.d\.ts$/, '');
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
internalsMap[strippedSource] = moduleId;
|
|
195
|
-
if (strippedSource.endsWith('/index')) {
|
|
196
|
-
internalsMap[strippedSource.slice(0, -6)] = moduleId;
|
|
197
|
-
}
|
|
169
|
+
const data = Fs.readFileSync(dtsPath, 'utf-8');
|
|
170
|
+
const declFile = Ts.createSourceFile(dtsPath, data, Ts.ScriptTarget.Latest, true);
|
|
171
|
+
writeDeclaration(declFile, relativeSource);
|
|
198
172
|
}
|
|
199
|
-
//
|
|
200
|
-
const publicReexports = [];
|
|
173
|
+
// Emit public re-export modules
|
|
201
174
|
if (options.exports) {
|
|
202
175
|
for (const entry of Object.values(options.exports)) {
|
|
203
|
-
const
|
|
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];
|
|
176
|
+
const internalId = resolveInternalModuleImport(entry.source);
|
|
215
177
|
if (internalId) {
|
|
216
|
-
|
|
178
|
+
outputParts.push(`declare module '${entry.id}' {${eol}`);
|
|
179
|
+
outputParts.push(`${indent}export * from '${internalId}';${eol}`);
|
|
180
|
+
outputParts.push(`}${eol}${eol}`);
|
|
217
181
|
}
|
|
218
182
|
}
|
|
219
183
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
outputParts.push(`declare module '${id}' {${eol}`);
|
|
246
|
-
outputParts.push(`${indent}export * from '${internalId}';${eol}`);
|
|
247
|
-
outputParts.push(`}${eol}${eol}`);
|
|
184
|
+
function resolveInternalModuleImport(moduleId, importDir = "") {
|
|
185
|
+
if (moduleId.charAt(0) === '.') {
|
|
186
|
+
return prefix + normalizeFileName(Path.join(importDir, moduleId));
|
|
187
|
+
}
|
|
188
|
+
if (resolveCache.has(moduleId))
|
|
189
|
+
return resolveCache.get(moduleId);
|
|
190
|
+
const containingFile = Path.resolve(baseDir, importDir, '__resolve.ts');
|
|
191
|
+
const result = Ts.resolveModuleName(moduleId, containingFile, project.compilerOptions, Ts.sys);
|
|
192
|
+
if (result.resolvedModule && !result.resolvedModule.isExternalLibraryImport) {
|
|
193
|
+
const resolved = normalizeFileName(result.resolvedModule.resolvedFileName);
|
|
194
|
+
if (resolved.startsWith(normalizedBaseDir)) {
|
|
195
|
+
const value = prefix + resolved.slice(normalizedBaseDir.length).replace(/\.(d\.ts|tsx?|jsx?)$/, '');
|
|
196
|
+
resolveCache.set(moduleId, value);
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
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;
|
|
248
209
|
}
|
|
249
210
|
function writeDeclaration(declarationFile, rawSourceModuleId) {
|
|
250
|
-
const moduleDeclId =
|
|
211
|
+
const moduleDeclId = resolveInternalModuleImport(rawSourceModuleId);
|
|
212
|
+
const moduleDir = Path.dirname(rawSourceModuleId);
|
|
251
213
|
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
214
|
const content = processTree(declarationFile, function (node) {
|
|
265
215
|
if (isNodeKindExternalModuleReference(node)) {
|
|
266
216
|
const expression = node.expression;
|
|
267
|
-
const resolved =
|
|
217
|
+
const resolved = resolveInternalModuleImport(expression.text, moduleDir) ?? expression.text;
|
|
268
218
|
return ` require('${resolved}')`;
|
|
269
219
|
}
|
|
270
220
|
else if (isNodeKindImportDeclaration(node) && !node.importClause) {
|
|
@@ -275,8 +225,8 @@ export function generateTypescriptDefinition(options) {
|
|
|
275
225
|
}
|
|
276
226
|
else if (isNodeKindStringLiteral(node) && node.parent &&
|
|
277
227
|
(isNodeKindExportDeclaration(node.parent) || isNodeKindImportDeclaration(node.parent) || isNodeKindImportType(node.parent?.parent))) {
|
|
278
|
-
const resolved =
|
|
279
|
-
if (resolved) {
|
|
228
|
+
const resolved = resolveInternalModuleImport(node.text, moduleDir);
|
|
229
|
+
if (resolved != null) {
|
|
280
230
|
return ` '${resolved}'`;
|
|
281
231
|
}
|
|
282
232
|
}
|
|
@@ -304,13 +254,10 @@ export class TypescriptDefinitionTask extends BuildTask {
|
|
|
304
254
|
const configText = file.read.text(Path.join(lib.path, "./tsconfig.json"))
|
|
305
255
|
|| file.read.text("./tsconfig.json");
|
|
306
256
|
const project = createTypescriptProject(lib.path, configText, storage.getBaseDirFS());
|
|
307
|
-
|
|
308
|
-
if (stderr) {
|
|
309
|
-
this.log.warn(stderr);
|
|
310
|
-
}
|
|
257
|
+
await project.emitWithTsgo();
|
|
311
258
|
const { dts } = generateTypescriptDefinition({
|
|
312
259
|
project,
|
|
313
|
-
prefix: lib.name,
|
|
260
|
+
prefix: lib.name + ":",
|
|
314
261
|
exclude: ["node_modules/**/*"],
|
|
315
262
|
exports: create_export_map(lib, lib.bundle),
|
|
316
263
|
});
|
|
@@ -7,6 +7,7 @@ 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";
|
|
10
|
+
import { read_lockfile } from "./lockfile.js";
|
|
10
11
|
const exclude_dirs = ["node_modules", ".git"];
|
|
11
12
|
function is_ignored_dir(ws, path) {
|
|
12
13
|
const normalized_path = make_normalized_path(path);
|
|
@@ -252,7 +253,7 @@ function show_constants(ws) {
|
|
|
252
253
|
}
|
|
253
254
|
}
|
|
254
255
|
export async function discover_workspace(ws) {
|
|
255
|
-
let
|
|
256
|
+
let lockfile = null;
|
|
256
257
|
for (let path = ws.path;;) {
|
|
257
258
|
const package_json = await readJsonFile(path + "/package.json");
|
|
258
259
|
if (package_json) {
|
|
@@ -267,30 +268,20 @@ export async function discover_workspace(ws) {
|
|
|
267
268
|
};
|
|
268
269
|
}
|
|
269
270
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
package_lock = await readJsonFile(package_lock_path);
|
|
271
|
+
if (!lockfile) {
|
|
272
|
+
lockfile = await read_lockfile(path);
|
|
273
273
|
}
|
|
274
274
|
const next_path = make_normalized_dirname(path);
|
|
275
275
|
if (next_path === path)
|
|
276
276
|
break;
|
|
277
277
|
path = next_path;
|
|
278
278
|
}
|
|
279
|
-
if (!
|
|
280
|
-
throw new Error(`
|
|
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
|
-
}
|
|
279
|
+
if (!lockfile) {
|
|
280
|
+
throw new Error(`Lock file not found for '${ws.name}'`);
|
|
291
281
|
}
|
|
282
|
+
ws.resolved_versions = lockfile.resolved_versions;
|
|
292
283
|
await discover_workspace_libraries(ws);
|
|
293
|
-
for (const location
|
|
284
|
+
for (const location of lockfile.installed_locations) {
|
|
294
285
|
await discover_library(ws, location, true);
|
|
295
286
|
}
|
|
296
287
|
for (const bun of ws.bundles) {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import Fs from "node:fs";
|
|
2
|
+
import Fsp from "node:fs/promises";
|
|
3
|
+
import YAML from "yaml";
|
|
4
|
+
import { readJsonFile } from "../storage.js";
|
|
5
|
+
export async function read_lockfile(dir) {
|
|
6
|
+
const npm_path = dir + "/package-lock.json";
|
|
7
|
+
if (Fs.existsSync(npm_path)) {
|
|
8
|
+
return parse_npm_lockfile(await readJsonFile(npm_path));
|
|
9
|
+
}
|
|
10
|
+
const pnpm_path = dir + "/pnpm-lock.yaml";
|
|
11
|
+
if (Fs.existsSync(pnpm_path)) {
|
|
12
|
+
return parse_pnpm_lockfile(YAML.parse(await Fsp.readFile(pnpm_path, "utf-8")));
|
|
13
|
+
}
|
|
14
|
+
const yarn_path = dir + "/yarn.lock";
|
|
15
|
+
if (Fs.existsSync(yarn_path)) {
|
|
16
|
+
return parse_yarn_lockfile(await Fsp.readFile(yarn_path, "utf-8"));
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function parse_npm_lockfile(lock) {
|
|
21
|
+
const resolved_versions = {};
|
|
22
|
+
const installed_locations = [];
|
|
23
|
+
for (const location in lock.packages) {
|
|
24
|
+
if (!location)
|
|
25
|
+
continue;
|
|
26
|
+
installed_locations.push(location);
|
|
27
|
+
if (location.startsWith("node_modules/")) {
|
|
28
|
+
let pkg = lock.packages[location];
|
|
29
|
+
if (pkg.link) {
|
|
30
|
+
pkg = lock.packages[pkg.resolved];
|
|
31
|
+
}
|
|
32
|
+
const name = location.replace(/^.*node_modules\//, "");
|
|
33
|
+
if (pkg?.version) {
|
|
34
|
+
resolved_versions[name] = pkg.version;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { resolved_versions, installed_locations };
|
|
39
|
+
}
|
|
40
|
+
function parse_pnpm_lockfile(lock) {
|
|
41
|
+
const resolved_versions = {};
|
|
42
|
+
const locations = new Set();
|
|
43
|
+
if (lock.packages) {
|
|
44
|
+
for (const key in lock.packages) {
|
|
45
|
+
const clean = key.startsWith("/") ? key.slice(1) : key;
|
|
46
|
+
const atIdx = clean.lastIndexOf("@");
|
|
47
|
+
if (atIdx > 0) {
|
|
48
|
+
const name = clean.slice(0, atIdx);
|
|
49
|
+
const version = clean.slice(atIdx + 1).split("(")[0];
|
|
50
|
+
if (name && version) {
|
|
51
|
+
resolved_versions[name] = version;
|
|
52
|
+
locations.add("node_modules/" + name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (lock.importers) {
|
|
58
|
+
for (const key in lock.importers) {
|
|
59
|
+
if (key !== ".")
|
|
60
|
+
locations.add(key);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { resolved_versions, installed_locations: [...locations] };
|
|
64
|
+
}
|
|
65
|
+
function parse_yarn_lockfile(text) {
|
|
66
|
+
const resolved_versions = {};
|
|
67
|
+
const locations = new Set();
|
|
68
|
+
if (text.includes("__metadata:")) {
|
|
69
|
+
const lock = YAML.parse(text);
|
|
70
|
+
for (const key in lock) {
|
|
71
|
+
if (key === "__metadata")
|
|
72
|
+
continue;
|
|
73
|
+
if (lock[key]?.version) {
|
|
74
|
+
const name = extract_package_name(key.split(",")[0].trim());
|
|
75
|
+
if (name) {
|
|
76
|
+
resolved_versions[name] = lock[key].version;
|
|
77
|
+
locations.add("node_modules/" + name);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
parse_yarn_classic(text, resolved_versions, locations);
|
|
84
|
+
}
|
|
85
|
+
return { resolved_versions, installed_locations: [...locations] };
|
|
86
|
+
}
|
|
87
|
+
function extract_package_name(entry) {
|
|
88
|
+
entry = entry.replace(/^"|"$/g, "");
|
|
89
|
+
// @scope/name@version or name@version
|
|
90
|
+
const at = entry.startsWith("@") ? entry.indexOf("@", 1) : entry.indexOf("@");
|
|
91
|
+
return at > 0 ? entry.slice(0, at) : null;
|
|
92
|
+
}
|
|
93
|
+
function parse_yarn_classic(text, resolved_versions, locations) {
|
|
94
|
+
let current_name = null;
|
|
95
|
+
for (const line of text.split("\n")) {
|
|
96
|
+
const trimmed = line.trim();
|
|
97
|
+
if (!line.startsWith(" ") && !line.startsWith("#") && trimmed.endsWith(":")) {
|
|
98
|
+
current_name = extract_package_name(trimmed.slice(0, -1).split(",")[0].trim());
|
|
99
|
+
}
|
|
100
|
+
else if (current_name && trimmed.startsWith("version ")) {
|
|
101
|
+
const version = trimmed.slice(8).replace(/^"|"$/g, "");
|
|
102
|
+
resolved_versions[current_name] = version;
|
|
103
|
+
locations.add("node_modules/" + current_name);
|
|
104
|
+
current_name = null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=lockfile.js.map
|