@bendyline/squisq 2.3.3 → 2.4.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/{Doc-BrgZC7SE.d.ts → Doc-DLpyOAXJ.d.ts} +87 -2
- package/dist/{ImageEditDoc-rum0Xb9P.d.ts → ImageEditDoc-Cu30xb9b.d.ts} +1 -1
- package/dist/{chunk-2ZWIXGAC.js → chunk-2S74DPJH.js} +4 -0
- package/dist/{chunk-RS5AP3J4.js → chunk-AE3IUKMM.js} +1 -1
- package/dist/{chunk-QWCFK5FN.js → chunk-CUYHFOFL.js} +5 -1
- package/dist/{chunk-G3JOS25T.js → chunk-D4LPP3P5.js} +43 -14
- package/dist/{chunk-GQNH7PLN.js → chunk-F2IEPSMA.js} +1320 -8
- package/dist/{chunk-IZLKI3IL.js → chunk-KPBZZVGY.js} +29 -5
- package/dist/{chunk-BCCXTMN5.js → chunk-O7JILDEF.js} +7 -0
- package/dist/{chunk-SPTY4C6F.js → chunk-REDUXXDJ.js} +1 -1
- package/dist/{chunk-ABP4LAJS.js → chunk-ZHLNKB2I.js} +1 -1
- package/dist/chunk-ZYO3DBTA.js +983 -0
- package/dist/doc/index.d.ts +103 -6
- package/dist/doc/index.js +8 -6
- package/dist/generate/index.d.ts +1 -1
- package/dist/imageEdit/index.d.ts +3 -3
- package/dist/index.d.ts +6 -6
- package/dist/index.js +29 -11
- package/dist/jsonForm/index.d.ts +1 -1
- package/dist/jsonForm/index.js +2 -2
- package/dist/markdown/index.d.ts +118 -1
- package/dist/markdown/index.js +21 -5
- package/dist/{materializePageSection-CrZWYnXM.d.ts → materializePageSection-CgNs5Qmw.d.ts} +2 -2
- package/dist/narration/index.d.ts +1 -1
- package/dist/narration/index.js +4 -4
- package/dist/recommend/index.js +2 -2
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/index.js +2 -2
- package/dist/{themeLibrary-DJt89gyP.d.ts → themeLibrary-RWsNtlOu.d.ts} +1 -1
- package/dist/transform/index.d.ts +2 -2
- package/dist/transform/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-UA5DTYAY.js +0 -400
package/dist/chunk-UA5DTYAY.js
DELETED
|
@@ -1,400 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assertMarkdownDocumentWithinLimits,
|
|
3
|
-
toMdast
|
|
4
|
-
} from "./chunk-G3JOS25T.js";
|
|
5
|
-
import {
|
|
6
|
-
formatFrontmatterYaml
|
|
7
|
-
} from "./chunk-BCCXTMN5.js";
|
|
8
|
-
|
|
9
|
-
// src/markdown/stringify.ts
|
|
10
|
-
import { unified } from "unified";
|
|
11
|
-
import remarkStringify from "remark-stringify";
|
|
12
|
-
import remarkGfm from "remark-gfm";
|
|
13
|
-
import remarkMath from "remark-math";
|
|
14
|
-
import remarkDirective from "remark-directive";
|
|
15
|
-
var defaultProcessor;
|
|
16
|
-
var DQ_RUN = `"(?:[^"\\\\]|\\\\.)*"`;
|
|
17
|
-
var SQ_RUN = `'(?:[^'\\\\]|\\\\.)*'`;
|
|
18
|
-
var ESCAPED_TEMPLATE_SPAN_RE = new RegExp(
|
|
19
|
-
`\\{\\\\\\[((?:${DQ_RUN}|${SQ_RUN}|\\\\.|[^\\]\\\\])*)\\]\\}`,
|
|
20
|
-
"g"
|
|
21
|
-
);
|
|
22
|
-
var HEADING_LINE_RE = /^#{1,6} .*$/gm;
|
|
23
|
-
var TRAILING_ESCAPED_PANDOC_SPAN_RE = new RegExp(
|
|
24
|
-
`\\{(?!\\\\?\\[)((?:${DQ_RUN}|${SQ_RUN}|\\\\.|[^}\\\\])*)\\}(?=\\s*(?:\\{\\[.*)?$)`
|
|
25
|
-
);
|
|
26
|
-
var UNESCAPE_PUNCT_RE = /\\([\\[\]:#.,+=/?;@%$(){}'"-])/g;
|
|
27
|
-
function unescapeMarkdownPunct(text) {
|
|
28
|
-
return text.replace(UNESCAPE_PUNCT_RE, "$1");
|
|
29
|
-
}
|
|
30
|
-
var PREFERRED_MASK_SENTINEL = "\0";
|
|
31
|
-
function pickMaskSentinel(text) {
|
|
32
|
-
const present = new Set(text);
|
|
33
|
-
if (!present.has(PREFERRED_MASK_SENTINEL)) return PREFERRED_MASK_SENTINEL;
|
|
34
|
-
for (let cp = 57344; cp <= 63743; cp++) {
|
|
35
|
-
const ch = String.fromCodePoint(cp);
|
|
36
|
-
if (!present.has(ch)) return ch;
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
var FENCE_OPEN_RE = /^([ \t]*)(`{3,}|~{3,})(.*)$/;
|
|
41
|
-
function findFencedRanges(text) {
|
|
42
|
-
const ranges = [];
|
|
43
|
-
let offset = 0;
|
|
44
|
-
let open = null;
|
|
45
|
-
for (const line of text.split("\n")) {
|
|
46
|
-
const lineEnd = offset + line.length;
|
|
47
|
-
if (open) {
|
|
48
|
-
const close = /^([ \t]*)(`{3,}|~{3,})[ \t]*$/.exec(line);
|
|
49
|
-
if (close && close[2][0] === open.marker && close[2].length >= open.length && close[1].length <= open.indent + 3) {
|
|
50
|
-
ranges.push([open.start, lineEnd]);
|
|
51
|
-
open = null;
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
const match = FENCE_OPEN_RE.exec(line);
|
|
55
|
-
if (match && !(match[2][0] === "`" && match[3].includes("`"))) {
|
|
56
|
-
open = {
|
|
57
|
-
marker: match[2][0],
|
|
58
|
-
length: match[2].length,
|
|
59
|
-
indent: match[1].length,
|
|
60
|
-
start: offset
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
offset = lineEnd + 1;
|
|
65
|
-
}
|
|
66
|
-
if (open) ranges.push([open.start, text.length]);
|
|
67
|
-
return ranges;
|
|
68
|
-
}
|
|
69
|
-
function isEscapedAt(text, i) {
|
|
70
|
-
let slashes = 0;
|
|
71
|
-
for (let k = i - 1; k >= 0 && text[k] === "\\"; k--) slashes++;
|
|
72
|
-
return slashes % 2 === 1;
|
|
73
|
-
}
|
|
74
|
-
function findInlineCodeRanges(text, from, to) {
|
|
75
|
-
const ranges = [];
|
|
76
|
-
let i = from;
|
|
77
|
-
while (i < to) {
|
|
78
|
-
if (text[i] !== "`" || isEscapedAt(text, i)) {
|
|
79
|
-
i++;
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
let openEnd = i;
|
|
83
|
-
while (openEnd < to && text[openEnd] === "`") openEnd++;
|
|
84
|
-
const runLength = openEnd - i;
|
|
85
|
-
let j = openEnd;
|
|
86
|
-
let closed = -1;
|
|
87
|
-
while (j < to) {
|
|
88
|
-
if (text[j] !== "`") {
|
|
89
|
-
j++;
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
let runEnd = j;
|
|
93
|
-
while (runEnd < to && text[runEnd] === "`") runEnd++;
|
|
94
|
-
if (runEnd - j === runLength) {
|
|
95
|
-
closed = runEnd;
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
j = runEnd;
|
|
99
|
-
}
|
|
100
|
-
if (closed === -1) {
|
|
101
|
-
i = openEnd;
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
ranges.push([i, closed]);
|
|
105
|
-
i = closed;
|
|
106
|
-
}
|
|
107
|
-
return ranges;
|
|
108
|
-
}
|
|
109
|
-
function transformOutsideCode(text, transform) {
|
|
110
|
-
const fenced = findFencedRanges(text);
|
|
111
|
-
const ranges = [];
|
|
112
|
-
let cursor = 0;
|
|
113
|
-
for (const [start, end] of fenced) {
|
|
114
|
-
ranges.push(...findInlineCodeRanges(text, cursor, start));
|
|
115
|
-
ranges.push([start, end]);
|
|
116
|
-
cursor = end;
|
|
117
|
-
}
|
|
118
|
-
ranges.push(...findInlineCodeRanges(text, cursor, text.length));
|
|
119
|
-
if (ranges.length === 0) return transform(text);
|
|
120
|
-
const sentinel = pickMaskSentinel(text);
|
|
121
|
-
if (sentinel === null) return text;
|
|
122
|
-
const protectedText = [];
|
|
123
|
-
let masked = "";
|
|
124
|
-
let last = 0;
|
|
125
|
-
for (const [start, end] of ranges) {
|
|
126
|
-
masked += text.slice(last, start);
|
|
127
|
-
masked += `${sentinel}${protectedText.length}${sentinel}`;
|
|
128
|
-
protectedText.push(text.slice(start, end));
|
|
129
|
-
last = end;
|
|
130
|
-
}
|
|
131
|
-
masked += text.slice(last);
|
|
132
|
-
return transform(masked).replace(
|
|
133
|
-
new RegExp(`${sentinel}(\\d+)${sentinel}`, "g"),
|
|
134
|
-
(_m, index) => protectedText[Number(index)]
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
function stringifyMarkdown(doc, options) {
|
|
138
|
-
options?.signal?.throwIfAborted();
|
|
139
|
-
assertMarkdownDocumentWithinLimits(doc, options?.limits, options?.signal);
|
|
140
|
-
const mdastTree = toMdast(doc);
|
|
141
|
-
const useDefaults = !options || options.gfm !== false && options.math !== false && options.directive !== false && !options.bullet && !options.bulletOrdered && !options.emphasis && !options.strong && !options.rule && !options.fence && options.setext == null;
|
|
142
|
-
let processor;
|
|
143
|
-
if (useDefaults) {
|
|
144
|
-
if (!defaultProcessor) {
|
|
145
|
-
defaultProcessor = unified().use(remarkGfm).use(remarkMath).use(remarkDirective).use(remarkStringify, {
|
|
146
|
-
bullet: "-",
|
|
147
|
-
bulletOrdered: ".",
|
|
148
|
-
emphasis: "*",
|
|
149
|
-
strong: "*",
|
|
150
|
-
rule: "-",
|
|
151
|
-
fence: "`",
|
|
152
|
-
setext: false
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
processor = defaultProcessor;
|
|
156
|
-
} else {
|
|
157
|
-
processor = unified();
|
|
158
|
-
if (options?.gfm !== false) {
|
|
159
|
-
processor = processor.use(remarkGfm);
|
|
160
|
-
}
|
|
161
|
-
if (options?.math !== false) {
|
|
162
|
-
processor = processor.use(remarkMath);
|
|
163
|
-
}
|
|
164
|
-
if (options?.directive !== false) {
|
|
165
|
-
processor = processor.use(remarkDirective);
|
|
166
|
-
}
|
|
167
|
-
processor = processor.use(remarkStringify, {
|
|
168
|
-
bullet: options?.bullet ?? "-",
|
|
169
|
-
bulletOrdered: options?.bulletOrdered ?? ".",
|
|
170
|
-
emphasis: options?.emphasis ?? "*",
|
|
171
|
-
strong: options?.strong ?? "*",
|
|
172
|
-
rule: options?.rule ?? "-",
|
|
173
|
-
fence: options?.fence ?? "`",
|
|
174
|
-
setext: options?.setext ?? false
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
const result = processor.stringify(mdastTree);
|
|
178
|
-
const cleaned = transformOutsideCode(result, (text) => {
|
|
179
|
-
let out = text.replace(
|
|
180
|
-
ESCAPED_TEMPLATE_SPAN_RE,
|
|
181
|
-
(_m, inner) => `{[${unescapeMarkdownPunct(inner)}]}`
|
|
182
|
-
);
|
|
183
|
-
out = out.replace(
|
|
184
|
-
HEADING_LINE_RE,
|
|
185
|
-
(line) => line.replace(
|
|
186
|
-
TRAILING_ESCAPED_PANDOC_SPAN_RE,
|
|
187
|
-
(_m, inner) => `{${unescapeMarkdownPunct(inner)}}`
|
|
188
|
-
)
|
|
189
|
-
);
|
|
190
|
-
return out.replace(/\{(?!\\?\[)[^}]*\}/g, (match) => match.replace(/\\:/g, ":"));
|
|
191
|
-
});
|
|
192
|
-
if (doc.frontmatter && Object.keys(doc.frontmatter).length > 0) {
|
|
193
|
-
const yaml = formatFrontmatterYaml(doc.frontmatter);
|
|
194
|
-
if (yaml) return `---
|
|
195
|
-
${yaml}
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
${cleaned}`;
|
|
199
|
-
}
|
|
200
|
-
return cleaned;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// src/markdown/resourcePolicy.ts
|
|
204
|
-
var DEFAULT_RESOURCE_MAX_BYTES = 64 * 1024 * 1024;
|
|
205
|
-
var DEFAULT_RESOURCE_TIMEOUT_MS = 15e3;
|
|
206
|
-
var DEFAULT_INTERACTIVE_RESOURCE_POLICY = Object.freeze({
|
|
207
|
-
allowRemote: true,
|
|
208
|
-
allowRelative: true,
|
|
209
|
-
allowBlob: true,
|
|
210
|
-
allowData: true,
|
|
211
|
-
allowedHosts: Object.freeze([]),
|
|
212
|
-
maxBytes: DEFAULT_RESOURCE_MAX_BYTES,
|
|
213
|
-
timeoutMs: DEFAULT_RESOURCE_TIMEOUT_MS
|
|
214
|
-
});
|
|
215
|
-
var LOCAL_ONLY_RESOURCE_POLICY = Object.freeze({
|
|
216
|
-
allowRemote: false,
|
|
217
|
-
allowRelative: true,
|
|
218
|
-
allowBlob: true,
|
|
219
|
-
allowData: true,
|
|
220
|
-
allowedHosts: Object.freeze([]),
|
|
221
|
-
maxBytes: DEFAULT_RESOURCE_MAX_BYTES,
|
|
222
|
-
timeoutMs: DEFAULT_RESOURCE_TIMEOUT_MS
|
|
223
|
-
});
|
|
224
|
-
var ResourcePolicyError = class extends Error {
|
|
225
|
-
constructor(code, message) {
|
|
226
|
-
super(message);
|
|
227
|
-
this.name = "ResourcePolicyError";
|
|
228
|
-
this.code = code;
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
function isResourceUrlAllowed(input, policy = DEFAULT_INTERACTIVE_RESOURCE_POLICY) {
|
|
232
|
-
if (typeof input !== "string") return false;
|
|
233
|
-
const value = input.trim();
|
|
234
|
-
if (!value || hasUrlControlCharacters(value)) return false;
|
|
235
|
-
const resolved = resolvePolicy(policy);
|
|
236
|
-
if (value.startsWith("\\\\")) return false;
|
|
237
|
-
if (value.startsWith("//")) {
|
|
238
|
-
if (!resolved.allowRemote) return false;
|
|
239
|
-
return hostAllowed(parseUrl(`https:${value}`), resolved.allowedHosts);
|
|
240
|
-
}
|
|
241
|
-
const schemeMatch = /^([a-z][a-z0-9+.-]*):/i.exec(value);
|
|
242
|
-
if (!schemeMatch) return resolved.allowRelative;
|
|
243
|
-
const scheme = schemeMatch[1].toLowerCase();
|
|
244
|
-
if (scheme === "blob") return resolved.allowBlob;
|
|
245
|
-
if (scheme === "data") return resolved.allowData && isSafeMediaDataUrl(value);
|
|
246
|
-
if (scheme !== "http" && scheme !== "https") return false;
|
|
247
|
-
if (!resolved.allowRemote) return false;
|
|
248
|
-
return hostAllowed(parseUrl(value), resolved.allowedHosts);
|
|
249
|
-
}
|
|
250
|
-
async function fetchResourceBytes(input, options = {}) {
|
|
251
|
-
const policy = resolvePolicy(options.policy);
|
|
252
|
-
if (!isResourceUrlAllowed(input, policy)) {
|
|
253
|
-
throw new ResourcePolicyError(
|
|
254
|
-
"RESOURCE_BLOCKED",
|
|
255
|
-
`Resource URL is blocked by policy: ${input}`
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
259
|
-
if (typeof fetchImpl !== "function") {
|
|
260
|
-
throw new Error("fetchResourceBytes requires a fetch implementation");
|
|
261
|
-
}
|
|
262
|
-
const controller = new AbortController();
|
|
263
|
-
let timedOut = false;
|
|
264
|
-
const onAbort = () => controller.abort(options.signal?.reason);
|
|
265
|
-
if (options.signal?.aborted) onAbort();
|
|
266
|
-
else options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
267
|
-
const timeout = setTimeout(() => {
|
|
268
|
-
timedOut = true;
|
|
269
|
-
controller.abort();
|
|
270
|
-
}, policy.timeoutMs);
|
|
271
|
-
try {
|
|
272
|
-
const response = await fetchImpl(input, {
|
|
273
|
-
signal: controller.signal,
|
|
274
|
-
credentials: "omit",
|
|
275
|
-
redirect: "follow",
|
|
276
|
-
referrerPolicy: "no-referrer"
|
|
277
|
-
});
|
|
278
|
-
if (!response.ok) throw new Error(`Resource request failed with HTTP ${response.status}`);
|
|
279
|
-
const finalUrl = response.url || input;
|
|
280
|
-
if (!isResourceUrlAllowed(finalUrl, policy)) {
|
|
281
|
-
throw new ResourcePolicyError(
|
|
282
|
-
"RESOURCE_BLOCKED",
|
|
283
|
-
`Resource redirect destination is blocked by policy: ${finalUrl}`
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
const contentType = response.headers?.get?.("content-type")?.split(";", 1)[0].trim() ?? "";
|
|
287
|
-
if (contentType && options.contentTypePrefixes?.length && !options.contentTypePrefixes.some((prefix) => contentType.toLowerCase().startsWith(prefix))) {
|
|
288
|
-
throw new ResourcePolicyError(
|
|
289
|
-
"RESOURCE_BLOCKED",
|
|
290
|
-
`Resource Content-Type is not allowed: ${contentType || "(missing)"}`
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
const declaredLength = Number(response.headers?.get?.("content-length"));
|
|
294
|
-
if (Number.isFinite(declaredLength) && declaredLength > policy.maxBytes) {
|
|
295
|
-
throw tooLarge(policy.maxBytes);
|
|
296
|
-
}
|
|
297
|
-
const bytes = await readResponseBounded(response, policy.maxBytes, controller.signal);
|
|
298
|
-
return { bytes, contentType, finalUrl };
|
|
299
|
-
} catch (error) {
|
|
300
|
-
if (timedOut) {
|
|
301
|
-
throw new ResourcePolicyError(
|
|
302
|
-
"RESOURCE_TIMEOUT",
|
|
303
|
-
`Resource request exceeded ${policy.timeoutMs} ms`
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
throw error;
|
|
307
|
-
} finally {
|
|
308
|
-
clearTimeout(timeout);
|
|
309
|
-
options.signal?.removeEventListener("abort", onAbort);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
function resolvePolicy(policy) {
|
|
313
|
-
return {
|
|
314
|
-
...DEFAULT_INTERACTIVE_RESOURCE_POLICY,
|
|
315
|
-
...policy,
|
|
316
|
-
allowedHosts: policy?.allowedHosts ?? DEFAULT_INTERACTIVE_RESOURCE_POLICY.allowedHosts
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
function parseUrl(value) {
|
|
320
|
-
try {
|
|
321
|
-
return new URL(value);
|
|
322
|
-
} catch {
|
|
323
|
-
return null;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
function hostAllowed(url, allowedHosts) {
|
|
327
|
-
if (!url || url.username || url.password) return false;
|
|
328
|
-
if (allowedHosts.length === 0) return true;
|
|
329
|
-
const host = url.hostname.toLowerCase().replace(/\.$/, "");
|
|
330
|
-
return allowedHosts.some((entry) => {
|
|
331
|
-
const allowed = entry.trim().toLowerCase().replace(/\.$/, "");
|
|
332
|
-
if (allowed.startsWith("*.")) {
|
|
333
|
-
const suffix = allowed.slice(2);
|
|
334
|
-
return host !== suffix && host.endsWith(`.${suffix}`);
|
|
335
|
-
}
|
|
336
|
-
return host === allowed;
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
function isSafeMediaDataUrl(value) {
|
|
340
|
-
return /^data:(?:image\/(?!svg\+xml)[a-z0-9.+-]+|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+);/i.test(
|
|
341
|
-
value
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
function hasUrlControlCharacters(value) {
|
|
345
|
-
for (const char of value) {
|
|
346
|
-
const code = char.charCodeAt(0);
|
|
347
|
-
if (code < 32 || code === 127) return true;
|
|
348
|
-
}
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
async function readResponseBounded(response, maxBytes, signal) {
|
|
352
|
-
if (!response.body) {
|
|
353
|
-
const buffer = response.arrayBuffer ? await response.arrayBuffer() : await (await response.blob()).arrayBuffer();
|
|
354
|
-
const bytes = new Uint8Array(buffer);
|
|
355
|
-
if (bytes.byteLength > maxBytes) throw tooLarge(maxBytes);
|
|
356
|
-
return bytes;
|
|
357
|
-
}
|
|
358
|
-
const reader = response.body.getReader();
|
|
359
|
-
const chunks = [];
|
|
360
|
-
let total = 0;
|
|
361
|
-
try {
|
|
362
|
-
while (true) {
|
|
363
|
-
signal.throwIfAborted();
|
|
364
|
-
const { done, value } = await reader.read();
|
|
365
|
-
if (done) break;
|
|
366
|
-
total += value.byteLength;
|
|
367
|
-
if (total > maxBytes) {
|
|
368
|
-
await reader.cancel();
|
|
369
|
-
throw tooLarge(maxBytes);
|
|
370
|
-
}
|
|
371
|
-
chunks.push(value);
|
|
372
|
-
}
|
|
373
|
-
} finally {
|
|
374
|
-
reader.releaseLock();
|
|
375
|
-
}
|
|
376
|
-
const out = new Uint8Array(total);
|
|
377
|
-
let offset = 0;
|
|
378
|
-
for (const chunk of chunks) {
|
|
379
|
-
out.set(chunk, offset);
|
|
380
|
-
offset += chunk.byteLength;
|
|
381
|
-
}
|
|
382
|
-
return out;
|
|
383
|
-
}
|
|
384
|
-
function tooLarge(maxBytes) {
|
|
385
|
-
return new ResourcePolicyError(
|
|
386
|
-
"RESOURCE_TOO_LARGE",
|
|
387
|
-
`Resource exceeds the ${maxBytes}-byte policy limit`
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
export {
|
|
392
|
-
stringifyMarkdown,
|
|
393
|
-
DEFAULT_RESOURCE_MAX_BYTES,
|
|
394
|
-
DEFAULT_RESOURCE_TIMEOUT_MS,
|
|
395
|
-
DEFAULT_INTERACTIVE_RESOURCE_POLICY,
|
|
396
|
-
LOCAL_ONLY_RESOURCE_POLICY,
|
|
397
|
-
ResourcePolicyError,
|
|
398
|
-
isResourceUrlAllowed,
|
|
399
|
-
fetchResourceBytes
|
|
400
|
-
};
|