pkgprn 0.5.0 → 0.5.2
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/{src/extract-references.js → extract-references.js} +4 -23
- package/index.d.ts.map +14 -14
- package/{src/index.js → index.js} +3 -20
- package/package.json +4 -4
- package/{src/prune.js → prune.js} +38 -214
- package/strip-comments.js +496 -0
- package/src/strip-comments.js +0 -731
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { decode, encode } from '@jridgewell/sourcemap-codec';
|
|
2
|
+
|
|
3
|
+
const jsExtensions = ['.js', '.mjs', '.cjs'];
|
|
4
|
+
|
|
5
|
+
export function isStrippableFile(file) {
|
|
6
|
+
return jsExtensions.some(ext => file.endsWith(ext));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const regexPrecedingKeywords = new Set([
|
|
10
|
+
'return',
|
|
11
|
+
'throw',
|
|
12
|
+
'typeof',
|
|
13
|
+
'void',
|
|
14
|
+
'delete',
|
|
15
|
+
'new',
|
|
16
|
+
'in',
|
|
17
|
+
'instanceof',
|
|
18
|
+
'case',
|
|
19
|
+
'yield',
|
|
20
|
+
'await',
|
|
21
|
+
'of',
|
|
22
|
+
'export',
|
|
23
|
+
'import',
|
|
24
|
+
'default',
|
|
25
|
+
'extends',
|
|
26
|
+
'else',
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
function classifyBlockComment(source, start, end) {
|
|
30
|
+
|
|
31
|
+
if (source[start + 2] === '!') {
|
|
32
|
+
return 'license';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const body = source.slice(start + 2, end - 2);
|
|
36
|
+
if (body.includes('@license') || body.includes('@preserve')) {
|
|
37
|
+
return 'license';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (source[start + 2] === '*' && end - start > 4) {
|
|
41
|
+
return 'jsdoc';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return 'regular';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function scanComments(source) {
|
|
48
|
+
|
|
49
|
+
const comments = [];
|
|
50
|
+
const len = source.length;
|
|
51
|
+
let i = 0;
|
|
52
|
+
|
|
53
|
+
const templateStack = [];
|
|
54
|
+
|
|
55
|
+
let exprEnd = false;
|
|
56
|
+
|
|
57
|
+
if (len >= 2 && source[0] === '#' && source[1] === '!') {
|
|
58
|
+
|
|
59
|
+
while (i < len && source[i] !== '\n') i++;
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
while (i < len) {
|
|
64
|
+
const ch = source.charCodeAt(i);
|
|
65
|
+
|
|
66
|
+
if (ch <= 0x20 || ch === 0xfeff || ch === 0xa0) {
|
|
67
|
+
i++;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (ch === 0x2f && i + 1 < len && source.charCodeAt(i + 1) === 0x2f ) {
|
|
72
|
+
const start = i;
|
|
73
|
+
i += 2;
|
|
74
|
+
while (i < len && source.charCodeAt(i) !== 0x0a ) i++;
|
|
75
|
+
comments.push({ start, end: i, type: 'regular' });
|
|
76
|
+
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (ch === 0x2f && i + 1 < len && source.charCodeAt(i + 1) === 0x2a ) {
|
|
81
|
+
const start = i;
|
|
82
|
+
i += 2;
|
|
83
|
+
while (i < len && !((source.charCodeAt(i) === 0x2a && i + 1 < len && source.charCodeAt(i + 1) === 0x2f) )) {
|
|
84
|
+
i++;
|
|
85
|
+
}
|
|
86
|
+
if (i < len) i += 2;
|
|
87
|
+
comments.push({ start, end: i, type: classifyBlockComment(source, start, i) });
|
|
88
|
+
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (ch === 0x2f && !exprEnd) {
|
|
93
|
+
i = skipRegex(source, i, len);
|
|
94
|
+
exprEnd = true;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (ch === 0x27 ) {
|
|
99
|
+
i = skipSingleString(source, i, len);
|
|
100
|
+
exprEnd = true;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (ch === 0x22 ) {
|
|
105
|
+
i = skipDoubleString(source, i, len);
|
|
106
|
+
exprEnd = true;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (ch === 0x60 ) {
|
|
111
|
+
i = scanTemplateTail(source, i + 1, len, templateStack, comments);
|
|
112
|
+
exprEnd = true;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (ch === 0x7d ) {
|
|
117
|
+
if (templateStack.length > 0) {
|
|
118
|
+
const depth = templateStack[templateStack.length - 1];
|
|
119
|
+
if (depth === 0) {
|
|
120
|
+
|
|
121
|
+
templateStack.pop();
|
|
122
|
+
i = scanTemplateTail(source, i + 1, len, templateStack, comments);
|
|
123
|
+
exprEnd = true;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
templateStack[templateStack.length - 1] = depth - 1;
|
|
127
|
+
}
|
|
128
|
+
i++;
|
|
129
|
+
|
|
130
|
+
exprEnd = false;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (ch === 0x7b ) {
|
|
135
|
+
if (templateStack.length > 0) {
|
|
136
|
+
templateStack[templateStack.length - 1]++;
|
|
137
|
+
}
|
|
138
|
+
i++;
|
|
139
|
+
exprEnd = false;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (isIdentStart(ch) || isDigit(ch)) {
|
|
144
|
+
const wordStart = i;
|
|
145
|
+
i++;
|
|
146
|
+
while (i < len && isIdentPart(source.charCodeAt(i))) i++;
|
|
147
|
+
const word = source.slice(wordStart, i);
|
|
148
|
+
exprEnd = !regexPrecedingKeywords.has(word);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if ((ch === 0x2b || ch === 0x2d) && i + 1 < len && source.charCodeAt(i + 1) === ch) {
|
|
153
|
+
i += 2;
|
|
154
|
+
exprEnd = true;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (ch === 0x29 || ch === 0x5d ) {
|
|
159
|
+
i++;
|
|
160
|
+
exprEnd = true;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
i++;
|
|
165
|
+
exprEnd = false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return comments;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function isDigit(ch) {
|
|
172
|
+
return ch >= 0x30 && ch <= 0x39;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function isIdentStart(ch) {
|
|
176
|
+
return (
|
|
177
|
+
(ch >= 0x41 && ch <= 0x5a) ||
|
|
178
|
+
(ch >= 0x61 && ch <= 0x7a) ||
|
|
179
|
+
ch === 0x5f ||
|
|
180
|
+
ch === 0x24 ||
|
|
181
|
+
ch === 0x5c ||
|
|
182
|
+
ch > 0x7f
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function isIdentPart(ch) {
|
|
187
|
+
return isIdentStart(ch) || isDigit(ch);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function skipSingleString(s, i, len) {
|
|
191
|
+
i++;
|
|
192
|
+
while (i < len) {
|
|
193
|
+
const ch = s.charCodeAt(i);
|
|
194
|
+
if (ch === 0x27 ) {
|
|
195
|
+
i++;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
if (ch === 0x5c ) {
|
|
199
|
+
i += 2;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (ch === 0x0a || ch === 0x0d ) break;
|
|
203
|
+
i++;
|
|
204
|
+
}
|
|
205
|
+
return i;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function skipDoubleString(s, i, len) {
|
|
209
|
+
i++;
|
|
210
|
+
while (i < len) {
|
|
211
|
+
const ch = s.charCodeAt(i);
|
|
212
|
+
if (ch === 0x22 ) {
|
|
213
|
+
i++;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
if (ch === 0x5c ) {
|
|
217
|
+
i += 2;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (ch === 0x0a || ch === 0x0d) break;
|
|
221
|
+
i++;
|
|
222
|
+
}
|
|
223
|
+
return i;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function skipRegex(s, i, len) {
|
|
227
|
+
i++;
|
|
228
|
+
while (i < len) {
|
|
229
|
+
const ch = s.charCodeAt(i);
|
|
230
|
+
if (ch === 0x5c ) {
|
|
231
|
+
i += 2;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (ch === 0x5b ) {
|
|
235
|
+
|
|
236
|
+
i++;
|
|
237
|
+
while (i < len) {
|
|
238
|
+
const cc = s.charCodeAt(i);
|
|
239
|
+
if (cc === 0x5c ) {
|
|
240
|
+
i += 2;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (cc === 0x5d ) {
|
|
244
|
+
i++;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
if (cc === 0x0a || cc === 0x0d) break;
|
|
248
|
+
i++;
|
|
249
|
+
}
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (ch === 0x2f ) {
|
|
253
|
+
i++;
|
|
254
|
+
|
|
255
|
+
while (i < len && isRegexFlag(s.charCodeAt(i))) i++;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
if (ch === 0x0a || ch === 0x0d) break;
|
|
259
|
+
i++;
|
|
260
|
+
}
|
|
261
|
+
return i;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function isRegexFlag(ch) {
|
|
265
|
+
return ch >= 0x61 && ch <= 0x7a;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function scanTemplateTail(s, i, len, templateStack, comments) {
|
|
269
|
+
void comments;
|
|
270
|
+
while (i < len) {
|
|
271
|
+
const ch = s.charCodeAt(i);
|
|
272
|
+
if (ch === 0x5c ) {
|
|
273
|
+
i += 2;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (ch === 0x60 ) {
|
|
277
|
+
i++;
|
|
278
|
+
return i;
|
|
279
|
+
}
|
|
280
|
+
if (ch === 0x24 && i + 1 < len && s.charCodeAt(i + 1) === 0x7b ) {
|
|
281
|
+
i += 2;
|
|
282
|
+
templateStack.push(0);
|
|
283
|
+
return i;
|
|
284
|
+
}
|
|
285
|
+
i++;
|
|
286
|
+
}
|
|
287
|
+
return i;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function parseCommentTypes(value) {
|
|
291
|
+
if (value === true || value === 'all') {
|
|
292
|
+
return new Set( (['jsdoc', 'license', 'regular']));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const valid = (['jsdoc', 'license', 'regular']);
|
|
296
|
+
const parts = String(value)
|
|
297
|
+
.split(',')
|
|
298
|
+
.map(s => s.trim())
|
|
299
|
+
.filter(Boolean);
|
|
300
|
+
|
|
301
|
+
const result = new Set();
|
|
302
|
+
|
|
303
|
+
for (const part of parts) {
|
|
304
|
+
if (part === 'all') {
|
|
305
|
+
return new Set(valid);
|
|
306
|
+
}
|
|
307
|
+
if (!valid.includes( (part))) {
|
|
308
|
+
throw new Error(`unknown comment type "${part}" (expected: ${valid.join(', ')}, all)`);
|
|
309
|
+
}
|
|
310
|
+
result.add( (part));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (result.size === 0) {
|
|
314
|
+
return new Set(valid);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export function stripComments(source, typesToStrip) {
|
|
321
|
+
return stripCommentsWithLineMap(source, typesToStrip).result;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export function stripCommentsWithLineMap(source, typesToStrip) {
|
|
325
|
+
const comments = scanComments(source);
|
|
326
|
+
|
|
327
|
+
if (comments.length === 0) return { result: source, lineMap: null };
|
|
328
|
+
|
|
329
|
+
const toRemove = comments.filter(c => typesToStrip.has(c.type));
|
|
330
|
+
|
|
331
|
+
if (toRemove.length === 0) return { result: source, lineMap: null };
|
|
332
|
+
|
|
333
|
+
const parts = [];
|
|
334
|
+
let pos = 0;
|
|
335
|
+
|
|
336
|
+
for (const { start, end } of toRemove) {
|
|
337
|
+
if (start > pos) {
|
|
338
|
+
parts.push(source.slice(pos, start));
|
|
339
|
+
}
|
|
340
|
+
pos = end;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (pos < source.length) {
|
|
344
|
+
parts.push(source.slice(pos));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
let intermediate = parts.join('');
|
|
348
|
+
|
|
349
|
+
const origLines = source.split('\n');
|
|
350
|
+
const origLineCount = origLines.length;
|
|
351
|
+
|
|
352
|
+
function translateOffset(offset) {
|
|
353
|
+
let removed = 0;
|
|
354
|
+
for (const { start, end } of toRemove) {
|
|
355
|
+
if (offset < start) break;
|
|
356
|
+
if (offset < end) return -1;
|
|
357
|
+
removed += end - start;
|
|
358
|
+
}
|
|
359
|
+
return offset - removed;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const intermediateText = intermediate;
|
|
363
|
+
const intermediateLineStarts = buildLineStarts(intermediateText);
|
|
364
|
+
|
|
365
|
+
const origToIntermediate = new Int32Array(origLineCount).fill(-1);
|
|
366
|
+
let origOffset = 0;
|
|
367
|
+
for (let oi = 0; oi < origLineCount; oi++) {
|
|
368
|
+
const lineLen = origLines[oi].length;
|
|
369
|
+
|
|
370
|
+
let survived = false;
|
|
371
|
+
for (let ci = 0; ci < lineLen; ci++) {
|
|
372
|
+
const ch = source.charCodeAt(origOffset + ci);
|
|
373
|
+
|
|
374
|
+
if (ch === 0x20 || ch === 0x09 || ch === 0x0d) continue;
|
|
375
|
+
const mapped = translateOffset(origOffset + ci);
|
|
376
|
+
if (mapped !== -1) {
|
|
377
|
+
survived = true;
|
|
378
|
+
|
|
379
|
+
origToIntermediate[oi] = offsetToLine(intermediateLineStarts, mapped);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (!survived) {
|
|
384
|
+
origToIntermediate[oi] = -1;
|
|
385
|
+
}
|
|
386
|
+
origOffset += lineLen + 1;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
intermediate = intermediate.replace(/[ \t]+$/gm, '');
|
|
390
|
+
|
|
391
|
+
intermediate = intermediate.replace(/\n{3,}/g, '\n\n');
|
|
392
|
+
|
|
393
|
+
if (intermediate.startsWith('#!')) {
|
|
394
|
+
const hashbangEnd = intermediate.indexOf('\n');
|
|
395
|
+
if (hashbangEnd !== -1) {
|
|
396
|
+
const before = intermediate.slice(0, hashbangEnd + 1);
|
|
397
|
+
const after = intermediate.slice(hashbangEnd + 1).replace(/^\n+/, '');
|
|
398
|
+
intermediate = before + after;
|
|
399
|
+
}
|
|
400
|
+
} else {
|
|
401
|
+
intermediate = intermediate.replace(/^\n+/, '');
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (source.endsWith('\n') && intermediate.length > 0) {
|
|
405
|
+
intermediate = intermediate.replace(/\n*$/, '\n');
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const result = intermediate;
|
|
409
|
+
|
|
410
|
+
const finalLines = result.split('\n');
|
|
411
|
+
const intLines = intermediateText.split('\n');
|
|
412
|
+
|
|
413
|
+
const intLinesTrimmed = intLines.map(l => l.replace(/[ \t]+$/, ''));
|
|
414
|
+
|
|
415
|
+
const intermediateToFinal = new Int32Array(intLines.length).fill(-1);
|
|
416
|
+
let fi = 0;
|
|
417
|
+
for (let ii = 0; ii < intLinesTrimmed.length && fi < finalLines.length; ii++) {
|
|
418
|
+
if (intLinesTrimmed[ii] === finalLines[fi]) {
|
|
419
|
+
intermediateToFinal[ii] = fi;
|
|
420
|
+
fi++;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const lineMap = new Int32Array(origLineCount).fill(-1);
|
|
426
|
+
for (let oi = 0; oi < origLineCount; oi++) {
|
|
427
|
+
const il = origToIntermediate[oi];
|
|
428
|
+
if (il >= 0 && il < intermediateToFinal.length) {
|
|
429
|
+
lineMap[oi] = intermediateToFinal[il];
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return { result, lineMap };
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function buildLineStarts(text) {
|
|
437
|
+
|
|
438
|
+
const starts = [0];
|
|
439
|
+
for (let i = 0; i < text.length; i++) {
|
|
440
|
+
if (text.charCodeAt(i) === 0x0a) {
|
|
441
|
+
starts.push(i + 1);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return starts;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function offsetToLine(lineStarts, offset) {
|
|
448
|
+
|
|
449
|
+
let lo = 0;
|
|
450
|
+
let hi = lineStarts.length - 1;
|
|
451
|
+
while (lo < hi) {
|
|
452
|
+
const mid = (lo + hi + 1) >>> 1;
|
|
453
|
+
if (lineStarts[mid] <= offset) {
|
|
454
|
+
lo = mid;
|
|
455
|
+
} else {
|
|
456
|
+
hi = mid - 1;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return lo;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
export function adjustSourcemapLineMappings(map, sourceIndex, lineMap) {
|
|
463
|
+
if (map.version !== 3 || typeof map.mappings !== 'string') return;
|
|
464
|
+
|
|
465
|
+
const decoded = decode(map.mappings);
|
|
466
|
+
|
|
467
|
+
for (const line of decoded) {
|
|
468
|
+
|
|
469
|
+
for (let si = line.length - 1; si >= 0; si--) {
|
|
470
|
+
const seg = line[si];
|
|
471
|
+
|
|
472
|
+
if (seg.length < 4) continue;
|
|
473
|
+
const seg4 = (seg);
|
|
474
|
+
|
|
475
|
+
if (seg4[1] !== sourceIndex) continue;
|
|
476
|
+
|
|
477
|
+
const origLine = seg4[2];
|
|
478
|
+
if (origLine < 0 || origLine >= lineMap.length) {
|
|
479
|
+
|
|
480
|
+
line.splice(si, 1);
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const newLine = lineMap[origLine];
|
|
485
|
+
if (newLine === -1) {
|
|
486
|
+
|
|
487
|
+
line.splice(si, 1);
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
seg4[2] = newLine;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
map.mappings = encode(decoded);
|
|
496
|
+
}
|