@git.zone/tsbundle 2.11.4 → 2.13.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/interfaces/index.d.ts +3 -0
- package/dist_ts/mod_custom/index.d.ts +10 -3
- package/dist_ts/mod_custom/index.js +278 -86
- package/dist_ts/mod_esbuild/index.child.d.ts +4 -8
- package/dist_ts/mod_esbuild/index.child.js +54 -44
- package/dist_ts/mod_esbuild/plugins.d.ts +5 -2
- package/dist_ts/mod_esbuild/plugins.js +5 -3
- package/dist_ts/mod_esbuild/workerplugin.d.ts +12 -0
- package/dist_ts/mod_esbuild/workerplugin.js +254 -0
- package/dist_ts/mod_output/artifactpublisher.d.ts +43 -0
- package/dist_ts/mod_output/artifactpublisher.js +925 -0
- package/dist_ts/mod_output/index.d.ts +1 -0
- package/dist_ts/mod_output/index.js +11 -3
- package/dist_ts/mod_presets/index.js +2 -1
- package/dist_ts/mod_rolldown/index.child.d.ts +4 -2
- package/dist_ts/mod_rolldown/index.child.js +48 -36
- package/dist_ts/mod_rspack/index.child.d.ts +4 -2
- package/dist_ts/mod_rspack/index.child.js +76 -115
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +4 -2
- package/dist_ts/tsbundle.class.tsbundle.js +98 -16
- package/package.json +7 -5
- package/readme.hints.md +20 -4
- package/readme.md +29 -6
- package/third-party-notices.md +29 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/interfaces/index.ts +3 -0
- package/ts/mod_custom/index.ts +348 -96
- package/ts/mod_esbuild/index.child.ts +81 -47
- package/ts/mod_esbuild/plugins.ts +9 -2
- package/ts/mod_esbuild/workerplugin.ts +328 -0
- package/ts/mod_output/artifactpublisher.ts +1185 -0
- package/ts/mod_output/index.ts +10 -2
- package/ts/mod_presets/index.ts +1 -0
- package/ts/mod_rolldown/index.child.ts +66 -42
- package/ts/mod_rspack/index.child.ts +98 -127
- package/ts/plugins.ts +3 -1
- package/ts/tsbundle.class.tsbundle.ts +102 -14
|
@@ -0,0 +1,925 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
const artifactOwner = '@git.zone/tsbundle';
|
|
3
|
+
const chunkManifestKind = 'chunk-namespace';
|
|
4
|
+
const chunkManifestSchemaVersion = 1;
|
|
5
|
+
const buildStageKind = 'build-stage';
|
|
6
|
+
const buildStageSchemaVersion = 1;
|
|
7
|
+
const lockKind = 'artifact-publication-lock';
|
|
8
|
+
const lockSchemaVersion = 1;
|
|
9
|
+
const lockWaitTimeoutMs = 60_000;
|
|
10
|
+
const lockLeaseTimeoutMs = 60 * 60 * 1000;
|
|
11
|
+
const ownershipHeartbeatIntervalMs = 30_000;
|
|
12
|
+
const staleStageThresholdMs = 24 * 60 * 60 * 1000;
|
|
13
|
+
const buildStageHeartbeats = new Map();
|
|
14
|
+
export const chunkManifestFile = '.tsbundle-artifacts.json';
|
|
15
|
+
const hasErrorCode = (errorArg) => (typeof errorArg === 'object' && errorArg !== null && 'code' in errorArg);
|
|
16
|
+
const createToken = () => plugins.crypto.randomBytes(16).toString('hex');
|
|
17
|
+
const isProcessAlive = (processIdArg) => {
|
|
18
|
+
try {
|
|
19
|
+
process.kill(processIdArg, 0);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return hasErrorCode(error) && error.code === 'EPERM';
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export const getProcessIdentity = (processIdArg) => {
|
|
27
|
+
if (process.platform !== 'linux') {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const processStat = plugins.fsSync.readFileSync(`/proc/${processIdArg}/stat`, 'utf8');
|
|
32
|
+
const commandEnd = processStat.lastIndexOf(')');
|
|
33
|
+
if (commandEnd === -1) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const fieldsAfterCommand = processStat.slice(commandEnd + 2).trim().split(/\s+/);
|
|
37
|
+
const processStartTicks = fieldsAfterCommand[19];
|
|
38
|
+
return processStartTicks ? `linux-proc-start:${processStartTicks}` : undefined;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const encodeProcessIdentity = (processIdentityArg) => (plugins.crypto.createHash('sha256').update(processIdentityArg).digest('base64url').slice(0, 16));
|
|
45
|
+
const getProcessIdentityToken = (processIdArg) => {
|
|
46
|
+
const processIdentity = getProcessIdentity(processIdArg);
|
|
47
|
+
return processIdentity
|
|
48
|
+
? encodeProcessIdentity(processIdentity)
|
|
49
|
+
: 'lease';
|
|
50
|
+
};
|
|
51
|
+
export const createProcessOwnership = () => ({
|
|
52
|
+
leaseManaged: true,
|
|
53
|
+
processId: process.pid,
|
|
54
|
+
processIdentity: getProcessIdentity(process.pid) || '',
|
|
55
|
+
});
|
|
56
|
+
export const isProcessOwnershipActive = (ownershipArg, markerPathArg, leaseTimeoutMsArg) => {
|
|
57
|
+
if (!isProcessAlive(ownershipArg.processId)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
if (ownershipArg.processIdentity) {
|
|
61
|
+
const currentIdentity = getProcessIdentity(ownershipArg.processId);
|
|
62
|
+
return currentIdentity === undefined || currentIdentity === ownershipArg.processIdentity;
|
|
63
|
+
}
|
|
64
|
+
if (!ownershipArg.leaseManaged) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
return Date.now() - plugins.fsSync.statSync(markerPathArg).mtimeMs < leaseTimeoutMsArg;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
export const startOwnershipHeartbeat = (markerPathArg) => {
|
|
75
|
+
const heartbeat = setInterval(() => {
|
|
76
|
+
try {
|
|
77
|
+
const now = new Date();
|
|
78
|
+
plugins.fsSync.utimesSync(markerPathArg, now, now);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (!hasErrorCode(error) || error.code !== 'ENOENT') {
|
|
82
|
+
console.warn(`tsbundle: unable to update ownership lease ${markerPathArg}: ${String(error)}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, ownershipHeartbeatIntervalMs);
|
|
86
|
+
heartbeat.unref();
|
|
87
|
+
return () => clearInterval(heartbeat);
|
|
88
|
+
};
|
|
89
|
+
const assertPathNotSymbolicLink = (pathArg, descriptionArg) => {
|
|
90
|
+
if (!plugins.fsSync.existsSync(pathArg)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const stat = plugins.fsSync.lstatSync(pathArg);
|
|
94
|
+
if (stat.isSymbolicLink()) {
|
|
95
|
+
throw new Error(`Refusing to use symbolic-link ${descriptionArg}: ${pathArg}`);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const assertRegularFile = (pathArg, descriptionArg) => {
|
|
99
|
+
const stat = plugins.fsSync.lstatSync(pathArg);
|
|
100
|
+
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
101
|
+
throw new Error(`Expected a regular ${descriptionArg}: ${pathArg}`);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const sameFile = (firstPathArg, secondPathArg) => {
|
|
105
|
+
const firstStat = plugins.fsSync.statSync(firstPathArg);
|
|
106
|
+
const secondStat = plugins.fsSync.statSync(secondPathArg);
|
|
107
|
+
return firstStat.dev === secondStat.dev && firstStat.ino === secondStat.ino;
|
|
108
|
+
};
|
|
109
|
+
const getLockPath = (targetPathArg) => `${targetPathArg}.tsbundle-lock`;
|
|
110
|
+
const getLockOwnerPath = (lockPathArg, ownerTokenArg) => (`${lockPathArg}.owner-${ownerTokenArg}`);
|
|
111
|
+
const parseLockMarker = (rawMarkerArg, targetPathArg) => {
|
|
112
|
+
const marker = JSON.parse(rawMarkerArg);
|
|
113
|
+
if (marker.owner !== artifactOwner
|
|
114
|
+
|| marker.kind !== lockKind
|
|
115
|
+
|| typeof marker.processId !== 'number'
|
|
116
|
+
|| !Number.isSafeInteger(marker.processId)
|
|
117
|
+
|| marker.processId <= 0
|
|
118
|
+
|| (marker.processIdentity !== undefined && typeof marker.processIdentity !== 'string')
|
|
119
|
+
|| (marker.leaseManaged !== undefined && typeof marker.leaseManaged !== 'boolean')
|
|
120
|
+
|| typeof marker.createdAt !== 'string'
|
|
121
|
+
|| typeof marker.ownerToken !== 'string'
|
|
122
|
+
|| !/^[a-f0-9]{32}$/.test(marker.ownerToken)
|
|
123
|
+
|| typeof marker.targetPath !== 'string'
|
|
124
|
+
|| plugins.path.resolve(marker.targetPath) !== plugins.path.resolve(targetPathArg)
|
|
125
|
+
|| marker.schemaVersion !== lockSchemaVersion) {
|
|
126
|
+
throw new Error(`Refusing to use invalid artifact publication lock for ${targetPathArg}`);
|
|
127
|
+
}
|
|
128
|
+
return marker;
|
|
129
|
+
};
|
|
130
|
+
const readLockMarker = (lockPathArg, targetPathArg) => {
|
|
131
|
+
try {
|
|
132
|
+
const stat = plugins.fsSync.lstatSync(lockPathArg);
|
|
133
|
+
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
134
|
+
throw new Error(`Refusing to use unsafe artifact publication lock: ${lockPathArg}`);
|
|
135
|
+
}
|
|
136
|
+
return parseLockMarker(plugins.fsSync.readFileSync(lockPathArg, 'utf8'), targetPathArg);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (hasErrorCode(error) && error.code === 'ENOENT') {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
const createLockOwner = (targetPathArg) => {
|
|
146
|
+
const lockPath = getLockPath(targetPathArg);
|
|
147
|
+
const marker = {
|
|
148
|
+
owner: artifactOwner,
|
|
149
|
+
kind: lockKind,
|
|
150
|
+
...createProcessOwnership(),
|
|
151
|
+
createdAt: new Date().toISOString(),
|
|
152
|
+
ownerToken: createToken(),
|
|
153
|
+
targetPath: plugins.path.resolve(targetPathArg),
|
|
154
|
+
schemaVersion: lockSchemaVersion,
|
|
155
|
+
};
|
|
156
|
+
const ownerPath = getLockOwnerPath(lockPath, marker.ownerToken);
|
|
157
|
+
try {
|
|
158
|
+
plugins.fsSync.writeFileSync(ownerPath, `${JSON.stringify(marker, null, 2)}\n`, {
|
|
159
|
+
flag: 'wx',
|
|
160
|
+
mode: 0o600,
|
|
161
|
+
});
|
|
162
|
+
return { lockPath, marker, ownerPath };
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
plugins.fsSync.rmSync(ownerPath, { force: true });
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const cleanupOrphanLockOwners = (targetPathArg) => {
|
|
170
|
+
const lockPath = getLockPath(targetPathArg);
|
|
171
|
+
const directory = plugins.path.dirname(lockPath);
|
|
172
|
+
const lockBasename = plugins.path.basename(lockPath);
|
|
173
|
+
const escapedLockBasename = lockBasename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
174
|
+
const ownerPattern = new RegExp(`^${escapedLockBasename}\\.owner-([a-f0-9]{32})(?:\\.reaping-(\\d+)-([A-Za-z0-9_-]{1,32})-(\\d+)-[a-f0-9]{32})?$`);
|
|
175
|
+
for (const entry of plugins.fsSync.readdirSync(directory, { withFileTypes: true })) {
|
|
176
|
+
const match = ownerPattern.exec(entry.name);
|
|
177
|
+
if (!match || !entry.isFile()) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const ownerPath = plugins.path.join(directory, entry.name);
|
|
181
|
+
const marker = parseLockMarker(plugins.fsSync.readFileSync(ownerPath, 'utf8'), targetPathArg);
|
|
182
|
+
if (isProcessOwnershipActive(marker, ownerPath, lockLeaseTimeoutMs)) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const baseOwnerPath = getLockOwnerPath(lockPath, match[1]);
|
|
186
|
+
const reaperOwnership = match[2]
|
|
187
|
+
? parseReaperOwnership(baseOwnerPath, ownerPath)
|
|
188
|
+
: undefined;
|
|
189
|
+
if (match[2] && !reaperOwnership) {
|
|
190
|
+
throw new Error(`Refusing to use invalid artifact lock reaping path: ${ownerPath}`);
|
|
191
|
+
}
|
|
192
|
+
if (reaperOwnership && isReaperOwnershipActive(reaperOwnership)) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (plugins.fsSync.existsSync(lockPath) && sameFile(lockPath, ownerPath)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
plugins.fsSync.rmSync(ownerPath, { force: true });
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const getReapingPath = (ownerPathArg) => (`${ownerPathArg}.reaping-${process.pid}-${getProcessIdentityToken(process.pid)}-${Date.now()}-${createToken()}`);
|
|
202
|
+
const parseReaperOwnership = (ownerPathArg, reapingPathArg) => {
|
|
203
|
+
const suffix = plugins.path.basename(reapingPathArg).slice(plugins.path.basename(ownerPathArg).length);
|
|
204
|
+
const match = /^\.reaping-(\d+)-([A-Za-z0-9_-]{1,32})-(\d+)-[a-f0-9]{32}$/.exec(suffix);
|
|
205
|
+
if (!match) {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
const processId = Number(match[1]);
|
|
209
|
+
const createdAt = Number(match[3]);
|
|
210
|
+
if (!Number.isSafeInteger(processId)
|
|
211
|
+
|| processId <= 0
|
|
212
|
+
|| !Number.isSafeInteger(createdAt)
|
|
213
|
+
|| createdAt <= 0) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
processId,
|
|
218
|
+
processIdentityToken: match[2],
|
|
219
|
+
createdAt,
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
const isReaperOwnershipActive = (ownershipArg) => {
|
|
223
|
+
if (!isProcessAlive(ownershipArg.processId)) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
if (ownershipArg.processIdentityToken !== 'lease') {
|
|
227
|
+
const currentIdentity = getProcessIdentity(ownershipArg.processId);
|
|
228
|
+
if (currentIdentity) {
|
|
229
|
+
return encodeProcessIdentity(currentIdentity) === ownershipArg.processIdentityToken;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return Date.now() - ownershipArg.createdAt < lockLeaseTimeoutMs;
|
|
233
|
+
};
|
|
234
|
+
const claimReapingOwner = (lockPathArg, ownerPathArg) => {
|
|
235
|
+
const reapingPath = getReapingPath(ownerPathArg);
|
|
236
|
+
try {
|
|
237
|
+
plugins.fsSync.renameSync(ownerPathArg, reapingPath);
|
|
238
|
+
return reapingPath;
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
if (!hasErrorCode(error) || error.code !== 'ENOENT') {
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const directory = plugins.path.dirname(ownerPathArg);
|
|
246
|
+
const prefix = `${plugins.path.basename(ownerPathArg)}.reaping-`;
|
|
247
|
+
let entries;
|
|
248
|
+
try {
|
|
249
|
+
entries = plugins.fsSync.readdirSync(directory).filter((entry) => entry.startsWith(prefix));
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (hasErrorCode(error) && error.code === 'ENOENT') {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
for (const entry of entries) {
|
|
258
|
+
const existingReapingPath = plugins.path.join(directory, entry);
|
|
259
|
+
const reaperOwnership = parseReaperOwnership(ownerPathArg, existingReapingPath);
|
|
260
|
+
if (!reaperOwnership) {
|
|
261
|
+
throw new Error(`Refusing to use invalid artifact lock reaping path: ${existingReapingPath}`);
|
|
262
|
+
}
|
|
263
|
+
if (isReaperOwnershipActive(reaperOwnership)) {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
try {
|
|
267
|
+
plugins.fsSync.renameSync(existingReapingPath, reapingPath);
|
|
268
|
+
return reapingPath;
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
if (hasErrorCode(error) && error.code === 'ENOENT') {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// The stale lock may already have been removed between inspection and claim.
|
|
278
|
+
if (!plugins.fsSync.existsSync(lockPathArg)) {
|
|
279
|
+
return undefined;
|
|
280
|
+
}
|
|
281
|
+
return undefined;
|
|
282
|
+
};
|
|
283
|
+
const tryReapStaleLock = (targetPathArg) => {
|
|
284
|
+
const lockPath = getLockPath(targetPathArg);
|
|
285
|
+
const marker = readLockMarker(lockPath, targetPathArg);
|
|
286
|
+
if (!marker || isProcessOwnershipActive(marker, lockPath, lockLeaseTimeoutMs)) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
const ownerPath = getLockOwnerPath(lockPath, marker.ownerToken);
|
|
290
|
+
const reapingPath = claimReapingOwner(lockPath, ownerPath);
|
|
291
|
+
if (!reapingPath) {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
if (plugins.fsSync.existsSync(lockPath) && sameFile(lockPath, reapingPath)) {
|
|
296
|
+
plugins.fsSync.unlinkSync(lockPath);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
finally {
|
|
300
|
+
plugins.fsSync.rmSync(reapingPath, { force: true });
|
|
301
|
+
}
|
|
302
|
+
return true;
|
|
303
|
+
};
|
|
304
|
+
const releaseLockOwner = (ownerArg) => {
|
|
305
|
+
let canRemoveOwner = false;
|
|
306
|
+
try {
|
|
307
|
+
if (!plugins.fsSync.existsSync(ownerArg.lockPath)) {
|
|
308
|
+
canRemoveOwner = true;
|
|
309
|
+
}
|
|
310
|
+
else if (plugins.fsSync.existsSync(ownerArg.ownerPath)
|
|
311
|
+
&& sameFile(ownerArg.lockPath, ownerArg.ownerPath)) {
|
|
312
|
+
plugins.fsSync.unlinkSync(ownerArg.lockPath);
|
|
313
|
+
canRemoveOwner = true;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
canRemoveOwner = true;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
console.warn(`tsbundle: unable to release artifact publication lock ${ownerArg.lockPath}: ${String(error)}`);
|
|
321
|
+
try {
|
|
322
|
+
const abandonedMarker = {
|
|
323
|
+
...ownerArg.marker,
|
|
324
|
+
leaseManaged: false,
|
|
325
|
+
processId: 2_147_483_647,
|
|
326
|
+
processIdentity: '',
|
|
327
|
+
};
|
|
328
|
+
plugins.fsSync.writeFileSync(ownerArg.ownerPath, `${JSON.stringify(abandonedMarker, null, 2)}\n`, { flag: 'w', mode: 0o600 });
|
|
329
|
+
}
|
|
330
|
+
catch (markerError) {
|
|
331
|
+
console.warn(`tsbundle: unable to mark artifact lock abandoned ${ownerArg.ownerPath}: ${String(markerError)}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (canRemoveOwner) {
|
|
335
|
+
try {
|
|
336
|
+
plugins.fsSync.rmSync(ownerArg.ownerPath, { force: true });
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
console.warn(`tsbundle: unable to remove artifact lock owner ${ownerArg.ownerPath}: ${String(error)}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
export const withArtifactPublicationLock = async (targetPathArg, callbackArg) => {
|
|
344
|
+
const resolvedTargetPath = plugins.path.resolve(targetPathArg);
|
|
345
|
+
plugins.fsSync.mkdirSync(plugins.path.dirname(resolvedTargetPath), { recursive: true });
|
|
346
|
+
cleanupOrphanLockOwners(resolvedTargetPath);
|
|
347
|
+
const owner = createLockOwner(resolvedTargetPath);
|
|
348
|
+
const deadline = Date.now() + lockWaitTimeoutMs;
|
|
349
|
+
let acquired = false;
|
|
350
|
+
let stopHeartbeat;
|
|
351
|
+
try {
|
|
352
|
+
while (!acquired) {
|
|
353
|
+
try {
|
|
354
|
+
plugins.fsSync.linkSync(owner.ownerPath, owner.lockPath);
|
|
355
|
+
acquired = true;
|
|
356
|
+
stopHeartbeat = startOwnershipHeartbeat(owner.ownerPath);
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
if (!hasErrorCode(error) || error.code !== 'EEXIST') {
|
|
360
|
+
const detail = hasErrorCode(error) ? ` (${error.code})` : '';
|
|
361
|
+
throw new Error(`Unable to acquire hard-link artifact publication lock${detail}: ${owner.lockPath}`);
|
|
362
|
+
}
|
|
363
|
+
tryReapStaleLock(resolvedTargetPath);
|
|
364
|
+
if (Date.now() >= deadline) {
|
|
365
|
+
throw new Error(`Timed out waiting for artifact publication lock: ${owner.lockPath}`);
|
|
366
|
+
}
|
|
367
|
+
await plugins.delay(25);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return await callbackArg();
|
|
371
|
+
}
|
|
372
|
+
finally {
|
|
373
|
+
stopHeartbeat?.();
|
|
374
|
+
if (acquired) {
|
|
375
|
+
releaseLockOwner(owner);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
plugins.fsSync.rmSync(owner.ownerPath, { force: true });
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
const getArtifactPublicationLockTargets = (targetPathArg, additionalTargetPathsArg = []) => {
|
|
383
|
+
const targetPath = plugins.path.resolve(targetPathArg);
|
|
384
|
+
return [...new Set([
|
|
385
|
+
targetPath,
|
|
386
|
+
plugins.path.join(plugins.path.dirname(targetPath), '.tsbundle-output-directory'),
|
|
387
|
+
...additionalTargetPathsArg.map((additionalPath) => plugins.path.resolve(additionalPath)),
|
|
388
|
+
])].sort((first, second) => first.localeCompare(second));
|
|
389
|
+
};
|
|
390
|
+
export const withArtifactPublicationLocks = async (targetPathArg, callbackArg, additionalTargetPathsArg = []) => {
|
|
391
|
+
const lockTargetPaths = getArtifactPublicationLockTargets(targetPathArg, additionalTargetPathsArg);
|
|
392
|
+
const acquireLock = async (indexArg) => {
|
|
393
|
+
if (indexArg === lockTargetPaths.length) {
|
|
394
|
+
return await callbackArg();
|
|
395
|
+
}
|
|
396
|
+
return await withArtifactPublicationLock(lockTargetPaths[indexArg], async () => await acquireLock(indexArg + 1));
|
|
397
|
+
};
|
|
398
|
+
return await acquireLock(0);
|
|
399
|
+
};
|
|
400
|
+
export const writeFileAtomically = (targetPathArg, contentArg, modeArg) => {
|
|
401
|
+
const targetPath = plugins.path.resolve(targetPathArg);
|
|
402
|
+
plugins.fsSync.mkdirSync(plugins.path.dirname(targetPath), { recursive: true });
|
|
403
|
+
assertPathNotSymbolicLink(targetPath, 'artifact target');
|
|
404
|
+
if (plugins.fsSync.existsSync(targetPath) && !plugins.fsSync.lstatSync(targetPath).isFile()) {
|
|
405
|
+
throw new Error(`Refusing to replace non-file artifact target: ${targetPath}`);
|
|
406
|
+
}
|
|
407
|
+
const temporaryPath = plugins.path.join(plugins.path.dirname(targetPath), `.${plugins.path.basename(targetPath)}.${process.pid}.${createToken()}.tsbundle-tmp`);
|
|
408
|
+
try {
|
|
409
|
+
plugins.fsSync.writeFileSync(temporaryPath, contentArg, {
|
|
410
|
+
flag: 'wx',
|
|
411
|
+
mode: modeArg,
|
|
412
|
+
});
|
|
413
|
+
plugins.fsSync.renameSync(temporaryPath, targetPath);
|
|
414
|
+
}
|
|
415
|
+
finally {
|
|
416
|
+
plugins.fsSync.rmSync(temporaryPath, { force: true });
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
export const getChunkNamespace = (logicalOutputNameArg) => (plugins.crypto
|
|
420
|
+
.createHash('sha256')
|
|
421
|
+
.update(logicalOutputNameArg)
|
|
422
|
+
.digest('base64url')
|
|
423
|
+
.slice(0, 24));
|
|
424
|
+
const getChunkNamespaceDirectory = (directoryArg, namespaceArg) => (plugins.path.join(directoryArg, 'chunks', namespaceArg));
|
|
425
|
+
const getChunkManifestPath = (namespaceDirectoryArg) => (plugins.path.join(namespaceDirectoryArg, chunkManifestFile));
|
|
426
|
+
const parseChunkManifest = (rawManifestArg) => {
|
|
427
|
+
try {
|
|
428
|
+
const manifest = JSON.parse(rawManifestArg);
|
|
429
|
+
if (manifest.owner === artifactOwner
|
|
430
|
+
&& manifest.kind === chunkManifestKind
|
|
431
|
+
&& typeof manifest.logicalOutputName === 'string'
|
|
432
|
+
&& typeof manifest.namespace === 'string'
|
|
433
|
+
&& manifest.schemaVersion === chunkManifestSchemaVersion) {
|
|
434
|
+
return manifest;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
catch {
|
|
438
|
+
return undefined;
|
|
439
|
+
}
|
|
440
|
+
return undefined;
|
|
441
|
+
};
|
|
442
|
+
const readChunkManifest = (namespaceDirectoryArg) => {
|
|
443
|
+
const manifestPath = getChunkManifestPath(namespaceDirectoryArg);
|
|
444
|
+
try {
|
|
445
|
+
assertRegularFile(manifestPath, 'chunk ownership manifest');
|
|
446
|
+
return parseChunkManifest(plugins.fsSync.readFileSync(manifestPath, 'utf8'));
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
if (hasErrorCode(error) && error.code === 'ENOENT') {
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
452
|
+
throw error;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
const assertOwnedChunkNamespace = (namespaceDirectoryArg, logicalOutputNameArg, namespaceArg) => {
|
|
456
|
+
const manifest = readChunkManifest(namespaceDirectoryArg);
|
|
457
|
+
if (!manifest
|
|
458
|
+
|| manifest.logicalOutputName !== logicalOutputNameArg
|
|
459
|
+
|| manifest.namespace !== namespaceArg) {
|
|
460
|
+
throw new Error(`Refusing to modify unowned chunk namespace: ${namespaceDirectoryArg}`);
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
const assertSafeArtifactTree = (directoryArg) => {
|
|
464
|
+
if (!plugins.fsSync.existsSync(directoryArg)) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
const stat = plugins.fsSync.lstatSync(directoryArg);
|
|
468
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
469
|
+
throw new Error(`Refusing to use unsafe generated artifact directory: ${directoryArg}`);
|
|
470
|
+
}
|
|
471
|
+
for (const entry of plugins.fsSync.readdirSync(directoryArg, { withFileTypes: true })) {
|
|
472
|
+
const entryPath = plugins.path.join(directoryArg, entry.name);
|
|
473
|
+
const entryStat = plugins.fsSync.lstatSync(entryPath);
|
|
474
|
+
if (entryStat.isSymbolicLink()) {
|
|
475
|
+
throw new Error(`Refusing to use symbolic-link generated artifact: ${entryPath}`);
|
|
476
|
+
}
|
|
477
|
+
if (entryStat.isDirectory()) {
|
|
478
|
+
assertSafeArtifactTree(entryPath);
|
|
479
|
+
}
|
|
480
|
+
else if (!entryStat.isFile()) {
|
|
481
|
+
throw new Error(`Refusing to use non-file generated artifact: ${entryPath}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
const listArtifactFiles = (directoryArg) => {
|
|
486
|
+
if (!plugins.fsSync.existsSync(directoryArg)) {
|
|
487
|
+
return [];
|
|
488
|
+
}
|
|
489
|
+
assertSafeArtifactTree(directoryArg);
|
|
490
|
+
const files = [];
|
|
491
|
+
const collect = (currentDirectoryArg) => {
|
|
492
|
+
for (const entry of plugins.fsSync.readdirSync(currentDirectoryArg, { withFileTypes: true })) {
|
|
493
|
+
const entryPath = plugins.path.join(currentDirectoryArg, entry.name);
|
|
494
|
+
if (entry.isDirectory()) {
|
|
495
|
+
collect(entryPath);
|
|
496
|
+
}
|
|
497
|
+
else if (entry.isFile() && entry.name !== chunkManifestFile) {
|
|
498
|
+
files.push(entryPath);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
collect(directoryArg);
|
|
503
|
+
return files.sort((first, second) => first.localeCompare(second));
|
|
504
|
+
};
|
|
505
|
+
const rebaseSourceMap = (sourceMapContentArg, sourceDirectoryArg, targetDirectoryArg, targetFileNameArg) => {
|
|
506
|
+
const sourceMap = JSON.parse(sourceMapContentArg.toString('utf8'));
|
|
507
|
+
if (Array.isArray(sourceMap.sources)) {
|
|
508
|
+
const sourceRoot = sourceMap.sourceRoot || '';
|
|
509
|
+
sourceMap.sources = sourceMap.sources.map((source) => {
|
|
510
|
+
if (/^(?:[a-z]+:|\/)/i.test(source)) {
|
|
511
|
+
return source;
|
|
512
|
+
}
|
|
513
|
+
const absoluteSource = plugins.path.resolve(sourceDirectoryArg, sourceRoot, source);
|
|
514
|
+
return plugins.path.relative(targetDirectoryArg, absoluteSource).split(plugins.path.sep).join('/');
|
|
515
|
+
});
|
|
516
|
+
if (sourceMap.sourceRoot) {
|
|
517
|
+
sourceMap.sourceRoot = '';
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if (targetFileNameArg) {
|
|
521
|
+
sourceMap.file = targetFileNameArg;
|
|
522
|
+
}
|
|
523
|
+
return Buffer.from(JSON.stringify(sourceMap));
|
|
524
|
+
};
|
|
525
|
+
const prepareChunkArtifacts = (sourceNamespaceDirectoryArg, targetNamespaceDirectoryArg) => listArtifactFiles(sourceNamespaceDirectoryArg).map((sourcePath) => {
|
|
526
|
+
const relativePath = plugins.path.relative(sourceNamespaceDirectoryArg, sourcePath);
|
|
527
|
+
const targetPath = plugins.path.join(targetNamespaceDirectoryArg, relativePath);
|
|
528
|
+
const sourceStat = plugins.fsSync.statSync(sourcePath);
|
|
529
|
+
const sourceContent = plugins.fsSync.readFileSync(sourcePath);
|
|
530
|
+
return {
|
|
531
|
+
content: sourcePath.endsWith('.map')
|
|
532
|
+
? rebaseSourceMap(sourceContent, sourceNamespaceDirectoryArg, targetNamespaceDirectoryArg)
|
|
533
|
+
: sourceContent,
|
|
534
|
+
mode: sourceStat.mode,
|
|
535
|
+
relativePath,
|
|
536
|
+
targetPath,
|
|
537
|
+
};
|
|
538
|
+
});
|
|
539
|
+
const snapshotFile = (pathArg) => {
|
|
540
|
+
if (!plugins.fsSync.existsSync(pathArg)) {
|
|
541
|
+
return { existed: false, path: pathArg };
|
|
542
|
+
}
|
|
543
|
+
assertRegularFile(pathArg, 'destination artifact');
|
|
544
|
+
const stat = plugins.fsSync.statSync(pathArg);
|
|
545
|
+
return {
|
|
546
|
+
content: plugins.fsSync.readFileSync(pathArg),
|
|
547
|
+
existed: true,
|
|
548
|
+
mode: stat.mode,
|
|
549
|
+
path: pathArg,
|
|
550
|
+
};
|
|
551
|
+
};
|
|
552
|
+
const restoreSnapshot = (snapshotArg) => {
|
|
553
|
+
if (snapshotArg.existed) {
|
|
554
|
+
writeFileAtomically(snapshotArg.path, snapshotArg.content, snapshotArg.mode);
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
assertPathNotSymbolicLink(snapshotArg.path, 'rollback target');
|
|
558
|
+
plugins.fsSync.rmSync(snapshotArg.path, { force: true });
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
const removeEmptyDirectories = (startDirectoryArg, stopDirectoryArg) => {
|
|
562
|
+
let currentDirectory = plugins.path.resolve(startDirectoryArg);
|
|
563
|
+
const stopDirectory = plugins.path.resolve(stopDirectoryArg);
|
|
564
|
+
while (currentDirectory !== stopDirectory && currentDirectory.startsWith(`${stopDirectory}${plugins.path.sep}`)) {
|
|
565
|
+
try {
|
|
566
|
+
plugins.fsSync.rmdirSync(currentDirectory);
|
|
567
|
+
}
|
|
568
|
+
catch (error) {
|
|
569
|
+
if (hasErrorCode(error) && ['ENOENT', 'ENOTEMPTY', 'EEXIST'].includes(error.code || '')) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
currentDirectory = plugins.path.dirname(currentDirectory);
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
const prepareAdditionalArtifacts = (artifactsArg, targetPathArg, targetMapPathArg, targetChunksDirectoryArg, lockTargetPathsArg) => {
|
|
578
|
+
const outputDirectory = plugins.path.dirname(targetPathArg);
|
|
579
|
+
const seenTargets = new Set();
|
|
580
|
+
return artifactsArg.map((artifact) => {
|
|
581
|
+
const sourcePath = plugins.path.resolve(artifact.sourcePath);
|
|
582
|
+
const targetPath = plugins.path.resolve(artifact.targetPath);
|
|
583
|
+
assertRegularFile(sourcePath, 'included source file');
|
|
584
|
+
if (plugins.path.dirname(targetPath) !== outputDirectory) {
|
|
585
|
+
throw new Error(`Included artifact must target the bundle output directory: ${targetPath}`);
|
|
586
|
+
}
|
|
587
|
+
if (targetPath === targetPathArg
|
|
588
|
+
|| targetPath === targetMapPathArg
|
|
589
|
+
|| lockTargetPathsArg.some((lockTargetPath) => (targetPath === plugins.path.resolve(lockTargetPath)
|
|
590
|
+
|| targetPath === plugins.path.resolve(getLockPath(lockTargetPath))))
|
|
591
|
+
|| targetPath === targetChunksDirectoryArg
|
|
592
|
+
|| targetPath.startsWith(`${targetChunksDirectoryArg}${plugins.path.sep}`)
|
|
593
|
+
|| plugins.path.basename(targetPath).includes('.tsbundle-')) {
|
|
594
|
+
throw new Error(`Included artifact collides with a reserved bundle path: ${targetPath}`);
|
|
595
|
+
}
|
|
596
|
+
if (seenTargets.has(targetPath)) {
|
|
597
|
+
throw new Error(`Multiple included artifacts target the same output path: ${targetPath}`);
|
|
598
|
+
}
|
|
599
|
+
seenTargets.add(targetPath);
|
|
600
|
+
const sourceStat = plugins.fsSync.statSync(sourcePath);
|
|
601
|
+
return {
|
|
602
|
+
content: plugins.fsSync.readFileSync(sourcePath),
|
|
603
|
+
mode: sourceStat.mode,
|
|
604
|
+
targetPath,
|
|
605
|
+
};
|
|
606
|
+
});
|
|
607
|
+
};
|
|
608
|
+
const ensureChunkNamespace = (namespaceDirectoryArg, logicalOutputNameArg, namespaceArg) => {
|
|
609
|
+
if (plugins.fsSync.existsSync(namespaceDirectoryArg)) {
|
|
610
|
+
assertSafeArtifactTree(namespaceDirectoryArg);
|
|
611
|
+
assertOwnedChunkNamespace(namespaceDirectoryArg, logicalOutputNameArg, namespaceArg);
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
plugins.fsSync.mkdirSync(namespaceDirectoryArg, { recursive: true });
|
|
615
|
+
try {
|
|
616
|
+
const manifest = {
|
|
617
|
+
owner: artifactOwner,
|
|
618
|
+
kind: chunkManifestKind,
|
|
619
|
+
logicalOutputName: logicalOutputNameArg,
|
|
620
|
+
namespace: namespaceArg,
|
|
621
|
+
schemaVersion: chunkManifestSchemaVersion,
|
|
622
|
+
};
|
|
623
|
+
writeFileAtomically(getChunkManifestPath(namespaceDirectoryArg), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
624
|
+
}
|
|
625
|
+
catch (error) {
|
|
626
|
+
plugins.fsSync.rmSync(namespaceDirectoryArg, { recursive: true, force: true });
|
|
627
|
+
throw error;
|
|
628
|
+
}
|
|
629
|
+
return true;
|
|
630
|
+
};
|
|
631
|
+
const reconcileChunkNamespace = (namespaceDirectoryArg, chunksDirectoryArg, desiredRelativePathsArg, logicalOutputNameArg, namespaceArg) => {
|
|
632
|
+
if (!plugins.fsSync.existsSync(namespaceDirectoryArg)) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
assertSafeArtifactTree(namespaceDirectoryArg);
|
|
636
|
+
assertOwnedChunkNamespace(namespaceDirectoryArg, logicalOutputNameArg, namespaceArg);
|
|
637
|
+
if (desiredRelativePathsArg.size === 0) {
|
|
638
|
+
plugins.fsSync.rmSync(namespaceDirectoryArg, { recursive: true, force: true });
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
for (const artifactPath of listArtifactFiles(namespaceDirectoryArg)) {
|
|
642
|
+
const relativePath = plugins.path.relative(namespaceDirectoryArg, artifactPath);
|
|
643
|
+
if (!desiredRelativePathsArg.has(relativePath)) {
|
|
644
|
+
plugins.fsSync.rmSync(artifactPath, { force: true });
|
|
645
|
+
removeEmptyDirectories(plugins.path.dirname(artifactPath), namespaceDirectoryArg);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
try {
|
|
650
|
+
plugins.fsSync.rmdirSync(chunksDirectoryArg);
|
|
651
|
+
}
|
|
652
|
+
catch (error) {
|
|
653
|
+
if (!hasErrorCode(error) || !['ENOENT', 'ENOTEMPTY', 'EEXIST'].includes(error.code || '')) {
|
|
654
|
+
throw error;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
export const publishGeneratedArtifacts = async (optionsArg) => {
|
|
659
|
+
const sourceDirectory = plugins.path.resolve(optionsArg.sourceDirectory);
|
|
660
|
+
const sourceMainPath = plugins.path.resolve(optionsArg.sourceMainPath);
|
|
661
|
+
const targetPath = plugins.path.resolve(optionsArg.targetPath);
|
|
662
|
+
const targetDirectory = plugins.path.dirname(targetPath);
|
|
663
|
+
const targetMapPath = `${targetPath}.map`;
|
|
664
|
+
const additionalLockTargets = optionsArg.lockTargetPath
|
|
665
|
+
? [optionsArg.lockTargetPath]
|
|
666
|
+
: [];
|
|
667
|
+
const lockTargetPaths = getArtifactPublicationLockTargets(targetPath, additionalLockTargets);
|
|
668
|
+
const sourceNamespaceDirectory = getChunkNamespaceDirectory(sourceDirectory, optionsArg.chunkNamespace);
|
|
669
|
+
const targetChunksDirectory = plugins.path.join(targetDirectory, 'chunks');
|
|
670
|
+
const targetNamespaceDirectory = getChunkNamespaceDirectory(targetDirectory, optionsArg.chunkNamespace);
|
|
671
|
+
const publishUnderLocks = async () => {
|
|
672
|
+
assertRegularFile(sourceMainPath, 'generated main bundle');
|
|
673
|
+
assertPathNotSymbolicLink(targetPath, 'bundle target');
|
|
674
|
+
assertPathNotSymbolicLink(targetMapPath, 'bundle source map target');
|
|
675
|
+
assertPathNotSymbolicLink(targetChunksDirectory, 'chunk directory');
|
|
676
|
+
if (plugins.fsSync.existsSync(targetPath)) {
|
|
677
|
+
assertRegularFile(targetPath, 'bundle target');
|
|
678
|
+
}
|
|
679
|
+
if (plugins.fsSync.existsSync(targetNamespaceDirectory)) {
|
|
680
|
+
assertSafeArtifactTree(targetNamespaceDirectory);
|
|
681
|
+
assertOwnedChunkNamespace(targetNamespaceDirectory, optionsArg.logicalOutputName, optionsArg.chunkNamespace);
|
|
682
|
+
}
|
|
683
|
+
const sourceMainStat = plugins.fsSync.statSync(sourceMainPath);
|
|
684
|
+
let mainContent = plugins.fsSync.readFileSync(sourceMainPath, 'utf8');
|
|
685
|
+
const sourceMainName = plugins.path.basename(sourceMainPath);
|
|
686
|
+
const targetMainName = plugins.path.basename(targetPath);
|
|
687
|
+
const sourceMapPattern = new RegExp(`//# sourceMappingURL=${sourceMainName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\.map`, 'g');
|
|
688
|
+
mainContent = mainContent.replace(sourceMapPattern, `//# sourceMappingURL=${targetMainName}.map`);
|
|
689
|
+
const sourceMapPath = `${sourceMainPath}.map`;
|
|
690
|
+
let preparedMainMap;
|
|
691
|
+
let sourceMapMode;
|
|
692
|
+
if (optionsArg.sourceMapsEnabled) {
|
|
693
|
+
assertRegularFile(sourceMapPath, 'generated source map');
|
|
694
|
+
preparedMainMap = rebaseSourceMap(plugins.fsSync.readFileSync(sourceMapPath), sourceDirectory, targetDirectory, targetMainName);
|
|
695
|
+
sourceMapMode = plugins.fsSync.statSync(sourceMapPath).mode;
|
|
696
|
+
}
|
|
697
|
+
const preparedChunks = prepareChunkArtifacts(sourceNamespaceDirectory, targetNamespaceDirectory);
|
|
698
|
+
const desiredChunkPaths = new Set(preparedChunks.map((artifact) => artifact.relativePath));
|
|
699
|
+
for (const artifact of preparedChunks) {
|
|
700
|
+
if (plugins.fsSync.existsSync(artifact.targetPath)) {
|
|
701
|
+
assertRegularFile(artifact.targetPath, 'generated chunk target');
|
|
702
|
+
if (!plugins.fsSync.readFileSync(artifact.targetPath).equals(artifact.content)) {
|
|
703
|
+
throw new Error(`Generated chunk name collision with different content: ${artifact.targetPath}`);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
const preparedAdditionalArtifacts = prepareAdditionalArtifacts(optionsArg.additionalArtifacts || [], targetPath, targetMapPath, targetChunksDirectory, lockTargetPaths);
|
|
708
|
+
const additionalSnapshots = preparedAdditionalArtifacts.map((artifact) => snapshotFile(artifact.targetPath));
|
|
709
|
+
const mapSnapshot = snapshotFile(targetMapPath);
|
|
710
|
+
const newlyCreatedChunkPaths = [];
|
|
711
|
+
let namespaceCreated = false;
|
|
712
|
+
let mainCommitted = false;
|
|
713
|
+
try {
|
|
714
|
+
if (preparedChunks.length > 0) {
|
|
715
|
+
namespaceCreated = ensureChunkNamespace(targetNamespaceDirectory, optionsArg.logicalOutputName, optionsArg.chunkNamespace);
|
|
716
|
+
for (const artifact of preparedChunks) {
|
|
717
|
+
if (plugins.fsSync.existsSync(artifact.targetPath)) {
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
writeFileAtomically(artifact.targetPath, artifact.content, artifact.mode);
|
|
721
|
+
newlyCreatedChunkPaths.push(artifact.targetPath);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
for (const artifact of preparedAdditionalArtifacts) {
|
|
725
|
+
writeFileAtomically(artifact.targetPath, artifact.content, artifact.mode);
|
|
726
|
+
}
|
|
727
|
+
if (preparedMainMap) {
|
|
728
|
+
writeFileAtomically(targetMapPath, preparedMainMap, sourceMapMode);
|
|
729
|
+
}
|
|
730
|
+
writeFileAtomically(targetPath, mainContent, sourceMainStat.mode);
|
|
731
|
+
mainCommitted = true;
|
|
732
|
+
}
|
|
733
|
+
catch (error) {
|
|
734
|
+
const rollbackErrors = [];
|
|
735
|
+
for (const snapshot of [...additionalSnapshots].reverse()) {
|
|
736
|
+
try {
|
|
737
|
+
restoreSnapshot(snapshot);
|
|
738
|
+
}
|
|
739
|
+
catch (rollbackError) {
|
|
740
|
+
rollbackErrors.push(rollbackError);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
try {
|
|
744
|
+
restoreSnapshot(mapSnapshot);
|
|
745
|
+
}
|
|
746
|
+
catch (rollbackError) {
|
|
747
|
+
rollbackErrors.push(rollbackError);
|
|
748
|
+
}
|
|
749
|
+
try {
|
|
750
|
+
if (namespaceCreated) {
|
|
751
|
+
plugins.fsSync.rmSync(targetNamespaceDirectory, { recursive: true, force: true });
|
|
752
|
+
try {
|
|
753
|
+
plugins.fsSync.rmdirSync(targetChunksDirectory);
|
|
754
|
+
}
|
|
755
|
+
catch (cleanupError) {
|
|
756
|
+
if (!hasErrorCode(cleanupError)
|
|
757
|
+
|| !['ENOENT', 'ENOTEMPTY', 'EEXIST'].includes(cleanupError.code || '')) {
|
|
758
|
+
throw cleanupError;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
for (const chunkPath of [...newlyCreatedChunkPaths].reverse()) {
|
|
764
|
+
plugins.fsSync.rmSync(chunkPath, { force: true });
|
|
765
|
+
removeEmptyDirectories(plugins.path.dirname(chunkPath), targetNamespaceDirectory);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
catch (rollbackError) {
|
|
770
|
+
rollbackErrors.push(rollbackError);
|
|
771
|
+
}
|
|
772
|
+
if (rollbackErrors.length > 0) {
|
|
773
|
+
throw new AggregateError([error, ...rollbackErrors], 'Artifact publication failed and rollback was incomplete.');
|
|
774
|
+
}
|
|
775
|
+
throw error;
|
|
776
|
+
}
|
|
777
|
+
if (mainCommitted) {
|
|
778
|
+
try {
|
|
779
|
+
if (!optionsArg.sourceMapsEnabled) {
|
|
780
|
+
assertPathNotSymbolicLink(targetMapPath, 'stale source map target');
|
|
781
|
+
plugins.fsSync.rmSync(targetMapPath, { force: true });
|
|
782
|
+
}
|
|
783
|
+
reconcileChunkNamespace(targetNamespaceDirectory, targetChunksDirectory, desiredChunkPaths, optionsArg.logicalOutputName, optionsArg.chunkNamespace);
|
|
784
|
+
}
|
|
785
|
+
catch (error) {
|
|
786
|
+
console.warn(`tsbundle: output committed but stale artifact cleanup was incomplete: ${String(error)}`);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
await withArtifactPublicationLocks(targetPath, publishUnderLocks, additionalLockTargets);
|
|
791
|
+
};
|
|
792
|
+
const assertBuildStageDirectory = (stageDirectoryArg, outputDirectoryArg) => {
|
|
793
|
+
const stageDirectory = plugins.path.resolve(stageDirectoryArg);
|
|
794
|
+
const outputDirectory = plugins.path.resolve(outputDirectoryArg);
|
|
795
|
+
if (plugins.path.dirname(stageDirectory) !== outputDirectory
|
|
796
|
+
|| !plugins.path.basename(stageDirectory).startsWith('.tsbundle-stage-')) {
|
|
797
|
+
throw new Error(`Refusing to use unexpected build stage: ${stageDirectoryArg}`);
|
|
798
|
+
}
|
|
799
|
+
const stat = plugins.fsSync.lstatSync(stageDirectory);
|
|
800
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
801
|
+
throw new Error(`Refusing to use unsafe build stage: ${stageDirectoryArg}`);
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
const getBuildStageMarkerPath = (stageDirectoryArg) => (plugins.path.join(stageDirectoryArg, '.tsbundle-stage.json'));
|
|
805
|
+
const parseBuildStageMarker = (rawMarkerArg) => {
|
|
806
|
+
try {
|
|
807
|
+
const marker = JSON.parse(rawMarkerArg);
|
|
808
|
+
if (marker.owner === artifactOwner
|
|
809
|
+
&& marker.kind === buildStageKind
|
|
810
|
+
&& typeof marker.processId === 'number'
|
|
811
|
+
&& Number.isSafeInteger(marker.processId)
|
|
812
|
+
&& marker.processId > 0
|
|
813
|
+
&& (marker.processIdentity === undefined || typeof marker.processIdentity === 'string')
|
|
814
|
+
&& (marker.leaseManaged === undefined || typeof marker.leaseManaged === 'boolean')
|
|
815
|
+
&& typeof marker.createdAt === 'string'
|
|
816
|
+
&& typeof marker.invocationId === 'string'
|
|
817
|
+
&& /^[A-Za-z0-9._-]{1,128}$/.test(marker.invocationId)
|
|
818
|
+
&& marker.schemaVersion === buildStageSchemaVersion) {
|
|
819
|
+
return marker;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
catch {
|
|
823
|
+
return undefined;
|
|
824
|
+
}
|
|
825
|
+
return undefined;
|
|
826
|
+
};
|
|
827
|
+
const readBuildStageMarker = (stageDirectoryArg) => {
|
|
828
|
+
try {
|
|
829
|
+
const markerPath = getBuildStageMarkerPath(stageDirectoryArg);
|
|
830
|
+
assertRegularFile(markerPath, 'build stage marker');
|
|
831
|
+
return parseBuildStageMarker(plugins.fsSync.readFileSync(markerPath, 'utf8'));
|
|
832
|
+
}
|
|
833
|
+
catch (error) {
|
|
834
|
+
if (hasErrorCode(error) && error.code === 'ENOENT') {
|
|
835
|
+
return undefined;
|
|
836
|
+
}
|
|
837
|
+
throw error;
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
const buildStageMarkersMatch = (firstMarkerArg, secondMarkerArg) => (firstMarkerArg.owner === secondMarkerArg.owner
|
|
841
|
+
&& firstMarkerArg.kind === secondMarkerArg.kind
|
|
842
|
+
&& firstMarkerArg.processId === secondMarkerArg.processId
|
|
843
|
+
&& firstMarkerArg.processIdentity === secondMarkerArg.processIdentity
|
|
844
|
+
&& firstMarkerArg.leaseManaged === secondMarkerArg.leaseManaged
|
|
845
|
+
&& firstMarkerArg.createdAt === secondMarkerArg.createdAt
|
|
846
|
+
&& firstMarkerArg.invocationId === secondMarkerArg.invocationId
|
|
847
|
+
&& firstMarkerArg.schemaVersion === secondMarkerArg.schemaVersion);
|
|
848
|
+
export const cleanupStaleBuildStages = (outputDirectoryArg) => {
|
|
849
|
+
const outputDirectory = plugins.path.resolve(outputDirectoryArg);
|
|
850
|
+
if (!plugins.fsSync.existsSync(outputDirectory)) {
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
for (const entry of plugins.fsSync.readdirSync(outputDirectory, { withFileTypes: true })) {
|
|
854
|
+
if (!entry.isDirectory() || !entry.name.startsWith('.tsbundle-stage-')) {
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
const stageDirectory = plugins.path.join(outputDirectory, entry.name);
|
|
858
|
+
let marker;
|
|
859
|
+
try {
|
|
860
|
+
assertBuildStageDirectory(stageDirectory, outputDirectory);
|
|
861
|
+
marker = readBuildStageMarker(stageDirectory);
|
|
862
|
+
}
|
|
863
|
+
catch (error) {
|
|
864
|
+
if (hasErrorCode(error) && error.code === 'ENOENT') {
|
|
865
|
+
continue;
|
|
866
|
+
}
|
|
867
|
+
throw error;
|
|
868
|
+
}
|
|
869
|
+
if (!marker) {
|
|
870
|
+
continue;
|
|
871
|
+
}
|
|
872
|
+
const createdAt = Date.parse(marker.createdAt);
|
|
873
|
+
if (!Number.isFinite(createdAt)
|
|
874
|
+
|| Date.now() - createdAt < staleStageThresholdMs
|
|
875
|
+
|| isProcessOwnershipActive(marker, getBuildStageMarkerPath(stageDirectory), staleStageThresholdMs)) {
|
|
876
|
+
continue;
|
|
877
|
+
}
|
|
878
|
+
const currentMarker = readBuildStageMarker(stageDirectory);
|
|
879
|
+
if (currentMarker && buildStageMarkersMatch(marker, currentMarker)) {
|
|
880
|
+
plugins.fsSync.rmSync(stageDirectory, { recursive: true, force: true });
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
export const createBuildStage = (outputDirectoryArg) => {
|
|
885
|
+
const outputDirectory = plugins.path.resolve(outputDirectoryArg);
|
|
886
|
+
plugins.fsSync.mkdirSync(outputDirectory, { recursive: true });
|
|
887
|
+
assertPathNotSymbolicLink(outputDirectory, 'build output directory');
|
|
888
|
+
cleanupStaleBuildStages(outputDirectory);
|
|
889
|
+
const stageDirectory = plugins.fsSync.mkdtempSync(plugins.path.join(outputDirectory, '.tsbundle-stage-'));
|
|
890
|
+
try {
|
|
891
|
+
assertBuildStageDirectory(stageDirectory, outputDirectory);
|
|
892
|
+
const marker = {
|
|
893
|
+
owner: artifactOwner,
|
|
894
|
+
kind: buildStageKind,
|
|
895
|
+
...createProcessOwnership(),
|
|
896
|
+
createdAt: new Date().toISOString(),
|
|
897
|
+
invocationId: `${process.pid}-${Date.now()}-${createToken()}`,
|
|
898
|
+
schemaVersion: buildStageSchemaVersion,
|
|
899
|
+
};
|
|
900
|
+
plugins.fsSync.writeFileSync(getBuildStageMarkerPath(stageDirectory), `${JSON.stringify(marker, null, 2)}\n`, { flag: 'wx', mode: 0o600 });
|
|
901
|
+
buildStageHeartbeats.set(stageDirectory, startOwnershipHeartbeat(getBuildStageMarkerPath(stageDirectory)));
|
|
902
|
+
return { marker, stageDirectory };
|
|
903
|
+
}
|
|
904
|
+
catch (error) {
|
|
905
|
+
plugins.fsSync.rmSync(stageDirectory, { recursive: true, force: true });
|
|
906
|
+
throw error;
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
export const cleanupBuildStage = (stageDirectoryArg, outputDirectoryArg, expectedMarkerArg) => {
|
|
910
|
+
buildStageHeartbeats.get(stageDirectoryArg)?.();
|
|
911
|
+
buildStageHeartbeats.delete(stageDirectoryArg);
|
|
912
|
+
try {
|
|
913
|
+
assertBuildStageDirectory(stageDirectoryArg, outputDirectoryArg);
|
|
914
|
+
const currentMarker = readBuildStageMarker(stageDirectoryArg);
|
|
915
|
+
if (currentMarker && buildStageMarkersMatch(currentMarker, expectedMarkerArg)) {
|
|
916
|
+
plugins.fsSync.rmSync(stageDirectoryArg, { recursive: true, force: true });
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
catch (error) {
|
|
920
|
+
if (!hasErrorCode(error) || error.code !== 'ENOENT') {
|
|
921
|
+
throw error;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJ0aWZhY3RwdWJsaXNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2Rfb3V0cHV0L2FydGlmYWN0cHVibGlzaGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE1BQU0sYUFBYSxHQUFHLG9CQUFvQixDQUFDO0FBQzNDLE1BQU0saUJBQWlCLEdBQUcsaUJBQWlCLENBQUM7QUFDNUMsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLENBQUM7QUFDckMsTUFBTSxjQUFjLEdBQUcsYUFBYSxDQUFDO0FBQ3JDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLE1BQU0sUUFBUSxHQUFHLDJCQUEyQixDQUFDO0FBQzdDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDO0FBQ2pDLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDMUMsTUFBTSw0QkFBNEIsR0FBRyxNQUFNLENBQUM7QUFDNUMsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDbEQsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBc0IsQ0FBQztBQUUzRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRywwQkFBMEIsQ0FBQztBQTJFNUQsTUFBTSxZQUFZLEdBQUcsQ0FBQyxRQUFpQixFQUFxQyxFQUFFLENBQUMsQ0FDN0UsT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLFFBQVEsS0FBSyxJQUFJLElBQUksTUFBTSxJQUFJLFFBQVEsQ0FDeEUsQ0FBQztBQUVGLE1BQU0sV0FBVyxHQUFHLEdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMs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
|