@jsenv/snapshot 2.7.5 → 2.8.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/package.json
CHANGED
|
@@ -203,23 +203,17 @@ export const createReplaceFilesystemWellKnownValues = ({
|
|
|
203
203
|
|
|
204
204
|
const replaceFileUrls = (string, { willBeWrittenOnFilesystem }) => {
|
|
205
205
|
for (const wellKownUrl of wellKownUrlArray) {
|
|
206
|
-
|
|
206
|
+
string = wellKownUrl.replace(string, {
|
|
207
207
|
willBeWrittenOnFilesystem,
|
|
208
208
|
});
|
|
209
|
-
if (replaceResult !== string) {
|
|
210
|
-
return replaceResult;
|
|
211
|
-
}
|
|
212
209
|
}
|
|
213
210
|
return string;
|
|
214
211
|
};
|
|
215
212
|
const replaceFilePaths = (string, { willBeWrittenOnFilesystem }) => {
|
|
216
213
|
for (const wellKownPath of wellKnownPathArray) {
|
|
217
|
-
|
|
214
|
+
string = wellKownPath.replace(string, {
|
|
218
215
|
willBeWrittenOnFilesystem,
|
|
219
216
|
});
|
|
220
|
-
if (replaceResult !== string) {
|
|
221
|
-
return replaceResult;
|
|
222
|
-
}
|
|
223
217
|
}
|
|
224
218
|
return string;
|
|
225
219
|
};
|
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
visitHtmlNodes,
|
|
13
13
|
} from "@jsenv/ast";
|
|
14
14
|
import { urlToExtension } from "@jsenv/urls";
|
|
15
|
+
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
|
|
15
16
|
import stripAnsi from "strip-ansi";
|
|
16
17
|
import { createReplaceFilesystemWellKnownValues } from "./filesystem_well_known_values.js";
|
|
17
18
|
|
|
18
19
|
export const replaceFluctuatingValues = (
|
|
19
|
-
|
|
20
|
+
value,
|
|
20
21
|
{
|
|
21
22
|
stringType,
|
|
22
23
|
rootDirectoryUrl,
|
|
@@ -28,103 +29,186 @@ export const replaceFluctuatingValues = (
|
|
|
28
29
|
}),
|
|
29
30
|
} = {},
|
|
30
31
|
) => {
|
|
31
|
-
if (fileUrl
|
|
32
|
-
const
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
32
|
+
if (fileUrl) {
|
|
33
|
+
const contentType = CONTENT_TYPE.fromUrlExtension(fileUrl);
|
|
34
|
+
if (Buffer.isBuffer(value) && CONTENT_TYPE.isTextual(contentType)) {
|
|
35
|
+
value = String(value);
|
|
36
|
+
}
|
|
37
|
+
if (stringType === undefined) {
|
|
38
|
+
const extension = urlToExtension(fileUrl);
|
|
39
|
+
if (extension === ".html") {
|
|
40
|
+
stringType = "html";
|
|
41
|
+
} else if (extension === ".svg") {
|
|
42
|
+
stringType = "svg";
|
|
43
|
+
} else if (extension === ".json" || CONTENT_TYPE.isJson(contentType)) {
|
|
44
|
+
stringType = "json";
|
|
45
|
+
}
|
|
37
46
|
}
|
|
38
47
|
}
|
|
39
|
-
const replaceDurations = (
|
|
48
|
+
const replaceDurations = (string) => {
|
|
40
49
|
// https://stackoverflow.com/a/59202307/24573072
|
|
41
|
-
|
|
50
|
+
string = string.replace(
|
|
42
51
|
/(?<!\d|\.)\d+(?:\.\d+)?(\s*)(seconds|second|s)\b/g,
|
|
43
52
|
(match, space, unit) => {
|
|
44
53
|
if (unit === "seconds") unit = "second";
|
|
45
54
|
return `<X>${space}${unit}`;
|
|
46
55
|
},
|
|
47
56
|
);
|
|
48
|
-
return
|
|
57
|
+
return string;
|
|
49
58
|
};
|
|
50
|
-
const replaceSizes = (
|
|
59
|
+
const replaceSizes = (string) => {
|
|
51
60
|
// the size of files might slighly differ from an OS to an other
|
|
52
61
|
// we round the floats to make them predictable
|
|
53
62
|
// (happens for HTML files where one char is added on linux)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
);
|
|
60
|
-
return
|
|
63
|
+
// string = string.replace(
|
|
64
|
+
// /(?<!\d|\.)(\d+(?:\.\d+)?)(\s*)(B|kB|MB)\b/g,
|
|
65
|
+
// (match, size, space, unit) => {
|
|
66
|
+
// return `${Math.round(parseFloat(size))}${space}${unit}`;
|
|
67
|
+
// },
|
|
68
|
+
// );
|
|
69
|
+
return string;
|
|
61
70
|
};
|
|
62
|
-
const replaceThings = (
|
|
71
|
+
const replaceThings = (string) => {
|
|
63
72
|
if (stringType === "filesystem") {
|
|
64
|
-
return replaceFilesystemWellKnownValues(
|
|
73
|
+
return replaceFilesystemWellKnownValues(string);
|
|
65
74
|
}
|
|
66
75
|
if (!preserveAnsi) {
|
|
67
|
-
|
|
76
|
+
string = stripAnsi(string);
|
|
68
77
|
}
|
|
69
|
-
|
|
78
|
+
string = replaceFilesystemWellKnownValues(string, {
|
|
70
79
|
willBeWrittenOnFilesystem: false,
|
|
71
80
|
});
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return
|
|
81
|
+
string = replaceHttpUrls(string);
|
|
82
|
+
string = replaceDurations(string);
|
|
83
|
+
string = replaceSizes(string);
|
|
84
|
+
return string;
|
|
76
85
|
};
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
if (value === null) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
if (typeof value === "string") {
|
|
90
|
+
if (stringType === "json") {
|
|
91
|
+
const jsValue = JSON.parse(value);
|
|
92
|
+
const replaced = replaceInObject(jsValue, { replace: replaceThings });
|
|
93
|
+
return JSON.stringify(replaced, null, " ");
|
|
94
|
+
}
|
|
95
|
+
if (stringType === "html" || stringType === "svg") {
|
|
96
|
+
// do parse html
|
|
97
|
+
const htmlAst =
|
|
98
|
+
stringType === "svg"
|
|
99
|
+
? parseSvgString(value)
|
|
100
|
+
: parseHtml({
|
|
101
|
+
html: value,
|
|
102
|
+
storeOriginalPositions: false,
|
|
103
|
+
});
|
|
104
|
+
// for each attribute value
|
|
105
|
+
// and each text node content
|
|
106
|
+
visitHtmlNodes(htmlAst, {
|
|
107
|
+
"*": (node) => {
|
|
108
|
+
const htmlNodeText = getHtmlNodeText(node);
|
|
109
|
+
if (htmlNodeText) {
|
|
110
|
+
setHtmlNodeText(node, replaceThings(htmlNodeText));
|
|
98
111
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
112
|
+
const attributes = getHtmlNodeAttributes(node);
|
|
113
|
+
if (attributes) {
|
|
114
|
+
for (const name of Object.keys(attributes)) {
|
|
115
|
+
attributes[name] = replaceThings(attributes[name]);
|
|
116
|
+
}
|
|
117
|
+
setHtmlNodeAttributes(node, attributes);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
return stringifyHtmlAst(htmlAst);
|
|
122
|
+
}
|
|
123
|
+
return replaceThings(value);
|
|
104
124
|
}
|
|
105
|
-
|
|
125
|
+
if (typeof value === "object") {
|
|
126
|
+
if (Buffer.isBuffer(value)) {
|
|
127
|
+
return value;
|
|
128
|
+
}
|
|
129
|
+
const jsValueReplaced = replaceInObject(value, { replace: replaceThings });
|
|
130
|
+
return JSON.stringify(jsValueReplaced, null, " ");
|
|
131
|
+
}
|
|
132
|
+
return value;
|
|
106
133
|
};
|
|
107
134
|
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (
|
|
114
|
-
|
|
135
|
+
const replaceInObject = (object, { replace }) => {
|
|
136
|
+
const deepCopy = (
|
|
137
|
+
value,
|
|
138
|
+
{ shouldReplaceStrings, shouldReplaceNumbers } = {},
|
|
139
|
+
) => {
|
|
140
|
+
if (value === null) {
|
|
141
|
+
return null;
|
|
115
142
|
}
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
143
|
+
if (Array.isArray(value)) {
|
|
144
|
+
const copy = [];
|
|
145
|
+
let i = 0;
|
|
146
|
+
while (i < value.length) {
|
|
147
|
+
copy[i] = deepCopy(value[i], {
|
|
148
|
+
shouldReplaceStrings,
|
|
149
|
+
shouldReplaceNumbers,
|
|
150
|
+
});
|
|
151
|
+
i++;
|
|
120
152
|
}
|
|
121
|
-
|
|
122
|
-
|
|
153
|
+
return copy;
|
|
154
|
+
}
|
|
155
|
+
if (typeof value === "object") {
|
|
156
|
+
const copy = {};
|
|
157
|
+
const keysToVisit = Object.keys(value);
|
|
158
|
+
for (const keyToVisit of keysToVisit) {
|
|
159
|
+
const nestedValue = value[keyToVisit];
|
|
160
|
+
copy[keyToVisit] = deepCopy(nestedValue, {
|
|
161
|
+
shouldReplaceStrings: shouldReplaceStrings || keyToVisit === "os",
|
|
162
|
+
shouldReplaceNumbers:
|
|
163
|
+
shouldReplaceNumbers ||
|
|
164
|
+
keyToVisit === "timings" ||
|
|
165
|
+
keyToVisit === "performance" ||
|
|
166
|
+
keyToVisit === "memoryUsage" ||
|
|
167
|
+
keyToVisit === "cpuUsage" ||
|
|
168
|
+
keyToVisit === "os",
|
|
169
|
+
});
|
|
123
170
|
}
|
|
124
|
-
|
|
125
|
-
return url;
|
|
126
|
-
} catch (e) {
|
|
127
|
-
return match;
|
|
171
|
+
return copy;
|
|
128
172
|
}
|
|
129
|
-
|
|
173
|
+
if (typeof value === "string") {
|
|
174
|
+
if (shouldReplaceStrings) {
|
|
175
|
+
return "<X>";
|
|
176
|
+
}
|
|
177
|
+
return replace(value);
|
|
178
|
+
}
|
|
179
|
+
if (typeof value === "number") {
|
|
180
|
+
if (shouldReplaceNumbers) {
|
|
181
|
+
return "<X>";
|
|
182
|
+
}
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
return value;
|
|
186
|
+
};
|
|
187
|
+
const copy = deepCopy(object);
|
|
188
|
+
return copy;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const replaceHttpUrls = (source) => {
|
|
192
|
+
return source;
|
|
193
|
+
// return source.replace(/(?:https?|ftp):\/\/\S+[\w/]/g, (match) => {
|
|
194
|
+
// const lastChar = match[match.length - 1];
|
|
195
|
+
// // hotfix because our url regex sucks a bit
|
|
196
|
+
// const endsWithSeparationChar = lastChar === ")" || lastChar === ":";
|
|
197
|
+
// if (endsWithSeparationChar) {
|
|
198
|
+
// match = match.slice(0, -1);
|
|
199
|
+
// }
|
|
200
|
+
// try {
|
|
201
|
+
// const urlObject = new URL(match);
|
|
202
|
+
// if (urlObject.hostname === "www.w3.org") {
|
|
203
|
+
// return match;
|
|
204
|
+
// }
|
|
205
|
+
// if (urlObject.port) {
|
|
206
|
+
// urlObject.port = 9999;
|
|
207
|
+
// }
|
|
208
|
+
// const url = urlObject.href;
|
|
209
|
+
// return url;
|
|
210
|
+
// } catch (e) {
|
|
211
|
+
// return match;
|
|
212
|
+
// }
|
|
213
|
+
// });
|
|
130
214
|
};
|
|
@@ -160,6 +160,16 @@ const renderOneSideEffect = (
|
|
|
160
160
|
lastSideEffectNumber,
|
|
161
161
|
});
|
|
162
162
|
if (text) {
|
|
163
|
+
if (
|
|
164
|
+
sideEffect.number === 1 &&
|
|
165
|
+
lastSideEffectNumber === 1 &&
|
|
166
|
+
(sideEffect.code === "return" ||
|
|
167
|
+
sideEffect.code === "throw" ||
|
|
168
|
+
sideEffect.code === "resolve" ||
|
|
169
|
+
sideEffect.code === "reject")
|
|
170
|
+
) {
|
|
171
|
+
label = null;
|
|
172
|
+
}
|
|
163
173
|
text = renderText(text, {
|
|
164
174
|
sideEffect,
|
|
165
175
|
sideEffectFileUrl,
|
|
@@ -167,11 +177,6 @@ const renderOneSideEffect = (
|
|
|
167
177
|
replace,
|
|
168
178
|
rootDirectoryUrl,
|
|
169
179
|
errorStackHidden,
|
|
170
|
-
onRenderError: () => {
|
|
171
|
-
if (sideEffect.number === 1 && lastSideEffectNumber === 1) {
|
|
172
|
-
label = null;
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
180
|
});
|
|
176
181
|
}
|
|
177
182
|
if (sideEffect.code === "source_code") {
|
|
@@ -208,7 +213,6 @@ const renderText = (
|
|
|
208
213
|
replace,
|
|
209
214
|
rootDirectoryUrl,
|
|
210
215
|
errorStackHidden,
|
|
211
|
-
onRenderError = () => {},
|
|
212
216
|
},
|
|
213
217
|
) => {
|
|
214
218
|
if (text && typeof text === "object") {
|
|
@@ -233,21 +237,20 @@ const renderText = (
|
|
|
233
237
|
return sourceMd;
|
|
234
238
|
}
|
|
235
239
|
if (text.type === "js_value") {
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
240
|
+
const jsValue = text.value;
|
|
241
|
+
if (jsValue === undefined) {
|
|
238
242
|
return renderMarkdownBlock("undefined", "js");
|
|
239
243
|
}
|
|
240
244
|
if (
|
|
241
|
-
|
|
242
|
-
(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
typeof
|
|
245
|
+
jsValue instanceof Error ||
|
|
246
|
+
(jsValue &&
|
|
247
|
+
jsValue.constructor &&
|
|
248
|
+
jsValue.constructor.name.includes("Error") &&
|
|
249
|
+
jsValue.stack &&
|
|
250
|
+
typeof jsValue.stack === "string")
|
|
247
251
|
) {
|
|
248
|
-
onRenderError();
|
|
249
252
|
// return renderMarkdownBlock(text.value.stack);
|
|
250
|
-
const exception = createException(
|
|
253
|
+
const exception = createException(jsValue, { rootDirectoryUrl });
|
|
251
254
|
const exceptionText = errorStackHidden
|
|
252
255
|
? `${exception.name}: ${exception.message}`
|
|
253
256
|
: exception.stack || exception.message || exception;
|
|
@@ -259,14 +262,7 @@ const renderText = (
|
|
|
259
262
|
replace,
|
|
260
263
|
});
|
|
261
264
|
}
|
|
262
|
-
|
|
263
|
-
return renderMarkdownBlock(
|
|
264
|
-
replace(
|
|
265
|
-
typeof value === "string" ? value : JSON.stringify(value, null, " "),
|
|
266
|
-
{ stringType: "json" },
|
|
267
|
-
),
|
|
268
|
-
"js",
|
|
269
|
-
);
|
|
265
|
+
return renderMarkdownBlock(replace(jsValue), "js");
|
|
270
266
|
}
|
|
271
267
|
if (text.type === "console") {
|
|
272
268
|
return renderConsole(text.value, {
|
|
@@ -279,7 +275,6 @@ const renderText = (
|
|
|
279
275
|
if (text.type === "file_content") {
|
|
280
276
|
return renderFileContent(text, {
|
|
281
277
|
sideEffect,
|
|
282
|
-
sideEffectFileUrl,
|
|
283
278
|
replace,
|
|
284
279
|
});
|
|
285
280
|
}
|
|
@@ -341,16 +336,18 @@ const renderPotentialAnsi = (
|
|
|
341
336
|
|
|
342
337
|
export const renderFileContent = (text, { sideEffect, replace }) => {
|
|
343
338
|
const { url, buffer, outDirectoryReason } = sideEffect.value;
|
|
339
|
+
const { value } = text;
|
|
340
|
+
let content = value;
|
|
344
341
|
if (outDirectoryReason) {
|
|
345
|
-
const {
|
|
346
|
-
writeFileSync(urlInsideOutDirectory, buffer);
|
|
342
|
+
const { outRelativeUrl, urlInsideOutDirectory } = text;
|
|
343
|
+
writeFileSync(urlInsideOutDirectory, replace(buffer, { fileUrl: url }));
|
|
347
344
|
let md = "";
|
|
348
345
|
if (
|
|
349
346
|
outDirectoryReason === "lot_of_chars" ||
|
|
350
347
|
outDirectoryReason === "lot_of_lines"
|
|
351
348
|
) {
|
|
352
349
|
md += "\n";
|
|
353
|
-
md += renderMarkdownBlock(escapeMarkdownBlockContent(replace(
|
|
350
|
+
md += renderMarkdownBlock(escapeMarkdownBlockContent(replace(content)));
|
|
354
351
|
const fileLink = renderLinkMarkdown(
|
|
355
352
|
{
|
|
356
353
|
text: outRelativeUrl,
|
|
@@ -371,13 +368,14 @@ export const renderFileContent = (text, { sideEffect, replace }) => {
|
|
|
371
368
|
);
|
|
372
369
|
return md;
|
|
373
370
|
}
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
const extension = urlToExtension(url).slice(1);
|
|
377
|
-
if (extension === "md") {
|
|
371
|
+
const extension = urlToExtension(url);
|
|
372
|
+
if (extension === ".md") {
|
|
378
373
|
content = escapeMarkdownBlockContent(content);
|
|
379
374
|
}
|
|
380
|
-
return renderMarkdownBlock(
|
|
375
|
+
return renderMarkdownBlock(
|
|
376
|
+
replace(content, { fileUrl: url }),
|
|
377
|
+
extension.slice(1),
|
|
378
|
+
);
|
|
381
379
|
};
|
|
382
380
|
|
|
383
381
|
const escapeMarkdownBlockContent = (content) => {
|