@markup-carve/carve-lsp 0.1.1 → 0.1.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.
Files changed (63) hide show
  1. package/README.md +55 -0
  2. package/dist/analyze.d.ts +17 -1
  3. package/dist/analyze.js +53 -1
  4. package/dist/analyze.js.map +1 -1
  5. package/dist/analyze.test.js +84 -0
  6. package/dist/analyze.test.js.map +1 -1
  7. package/dist/definition.js +22 -2
  8. package/dist/definition.js.map +1 -1
  9. package/dist/hover.js +23 -8
  10. package/dist/hover.js.map +1 -1
  11. package/dist/include-directive.d.ts +61 -0
  12. package/dist/include-directive.js +158 -0
  13. package/dist/include-directive.js.map +1 -0
  14. package/dist/include-directive.test.d.ts +1 -0
  15. package/dist/include-directive.test.js +83 -0
  16. package/dist/include-directive.test.js.map +1 -0
  17. package/dist/include-path.d.ts +63 -0
  18. package/dist/include-path.js +135 -0
  19. package/dist/include-path.js.map +1 -0
  20. package/dist/include-path.test.d.ts +1 -0
  21. package/dist/include-path.test.js +189 -0
  22. package/dist/include-path.test.js.map +1 -0
  23. package/dist/include-security-conformance.test.d.ts +1 -0
  24. package/dist/include-security-conformance.test.js +100 -0
  25. package/dist/include-security-conformance.test.js.map +1 -0
  26. package/dist/include-settings.d.ts +50 -0
  27. package/dist/include-settings.js +135 -0
  28. package/dist/include-settings.js.map +1 -0
  29. package/dist/include-settings.test.d.ts +1 -0
  30. package/dist/include-settings.test.js +191 -0
  31. package/dist/include-settings.test.js.map +1 -0
  32. package/dist/includes.d.ts +78 -0
  33. package/dist/includes.js +158 -0
  34. package/dist/includes.js.map +1 -0
  35. package/dist/includes.test.d.ts +1 -0
  36. package/dist/includes.test.js +202 -0
  37. package/dist/includes.test.js.map +1 -0
  38. package/dist/inline-text.d.ts +24 -0
  39. package/dist/inline-text.js +34 -0
  40. package/dist/inline-text.js.map +1 -0
  41. package/dist/inline-text.test.d.ts +1 -0
  42. package/dist/inline-text.test.js +32 -0
  43. package/dist/inline-text.test.js.map +1 -0
  44. package/dist/position-encoding.test.d.ts +1 -0
  45. package/dist/position-encoding.test.js +143 -0
  46. package/dist/position-encoding.test.js.map +1 -0
  47. package/dist/position.d.ts +82 -0
  48. package/dist/position.js +137 -0
  49. package/dist/position.js.map +1 -0
  50. package/dist/position.test.d.ts +1 -0
  51. package/dist/position.test.js +61 -0
  52. package/dist/position.test.js.map +1 -0
  53. package/dist/references.js +3 -0
  54. package/dist/references.js.map +1 -1
  55. package/dist/semantic.d.ts +14 -0
  56. package/dist/semantic.js +98 -13
  57. package/dist/semantic.js.map +1 -1
  58. package/dist/semantic.test.d.ts +1 -0
  59. package/dist/semantic.test.js +93 -0
  60. package/dist/semantic.test.js.map +1 -0
  61. package/dist/server.js +50 -23
  62. package/dist/server.js.map +1 -1
  63. package/package.json +2 -2
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Recognition of processor-level `{{ … }}` include directives (PART 6 grammar,
3
+ * PART 9 §19 rule I1).
4
+ *
5
+ * Kept separate from {@link ./includes.js} so consumers that only need to
6
+ * RECOGNIZE a directive do not pull in the expander's file-system imports.
7
+ *
8
+ * The regular expressions and `parseDirective` mirror `src/include-directive.ts`
9
+ * in the carve-js engine deliberately: one rule, one spelling. What is added
10
+ * here is source-level scanning. The engine recognizes directives on
11
+ * reassembled inline runs of a parsed AST; this server has no include-aware
12
+ * engine to parse with (the pinned `@markup-carve/carve` predates the pass), so
13
+ * it scans the raw document text and shields verbatim regions itself.
14
+ */
15
+ export const DIRECTIVE_SCAN_RE = /\{\{\s+(?:"((?:\\.|[^"\\])*)"|\u201c([^\u201d]*)\u201d|([^#@}\s"\u201c]+))((?:\s+#[A-Za-z_][\w-]*)?)(.*?)\s+\}\}/g;
16
+ export const DIRECTIVE_FULL_RE = /^\{\{\s+(?:"((?:\\.|[^"\\])*)"|\u201c([^\u201d]*)\u201d|([^#@}\s"\u201c]+))((?:\s+#[A-Za-z_][\w-]*)?)(.*?)\s+\}\}$/;
17
+ const OPTION_RE = /^@([A-Za-z_][\w-]*):([^#@}\s]+)$/;
18
+ function unescapeQuotedPath(value) {
19
+ return value.replace(/\\(["\\])/g, '$1');
20
+ }
21
+ /**
22
+ * Parse one candidate directive token. Returns null when the token is not a
23
+ * well-formed directive per I1 (a bad shape, or an unrecognized or malformed
24
+ * option), in which case it stays ordinary text and `onInvalidOption` fires so
25
+ * the caller can raise `include-unknown-option`.
26
+ */
27
+ export function parseDirective(raw, onInvalidOption) {
28
+ const m = DIRECTIVE_FULL_RE.exec(raw);
29
+ if (!m)
30
+ return null;
31
+ const includePath = m[1] !== undefined ? unescapeQuotedPath(m[1]) : (m[2] ?? m[3]);
32
+ if (includePath === '')
33
+ return null;
34
+ const sectionPart = m[4]?.trim();
35
+ const section = sectionPart ? sectionPart.slice(1) : undefined;
36
+ let lines;
37
+ let shift = 0;
38
+ const rest = m[5]?.trim();
39
+ if (rest) {
40
+ for (const part of rest.split(/\s+/)) {
41
+ const opt = OPTION_RE.exec(part);
42
+ const invalid = () => {
43
+ // I1: an unrecognized (or malformed) option makes the directive
44
+ // unresolvable - warning plus literal text, never a silent drop.
45
+ if (part.startsWith('@'))
46
+ onInvalidOption?.(part);
47
+ return null;
48
+ };
49
+ if (!opt)
50
+ return invalid();
51
+ const [, key, value] = opt;
52
+ if (key === 'lines') {
53
+ const lm = /^([1-9]\d*)-([1-9]\d*)$/.exec(value);
54
+ if (!lm)
55
+ return invalid();
56
+ lines = { start: Number(lm[1]), end: Number(lm[2]) };
57
+ if (lines.end < lines.start)
58
+ return invalid();
59
+ }
60
+ else if (key === 'shift') {
61
+ // I8: a signed integer or the literal "auto", never both forms.
62
+ if (value === 'auto')
63
+ shift = 'auto';
64
+ else if (!/^[+-]?\d+$/.test(value))
65
+ return invalid();
66
+ else
67
+ shift = Number(value);
68
+ }
69
+ else {
70
+ return invalid();
71
+ }
72
+ }
73
+ }
74
+ const directive = { raw, path: includePath, shift };
75
+ if (section !== undefined)
76
+ directive.section = section;
77
+ if (lines !== undefined)
78
+ directive.lines = lines;
79
+ return directive;
80
+ }
81
+ /**
82
+ * Regions of `source` whose content is verbatim and therefore shielded from
83
+ * include recognition (I9): fenced blocks of every flavour, raw blocks
84
+ * (```` ```=html ````) included, and inline code spans.
85
+ *
86
+ * Approximate by design, and deliberately so: it is a line-and-backtick scan
87
+ * rather than a parse, because the pinned engine cannot tell us where a
88
+ * directive sits relative to a fence. It errs toward shielding - an ambiguous
89
+ * region is treated as verbatim and the directive stays literal, which is the
90
+ * safe direction for a file-read capability.
91
+ */
92
+ export function verbatimSpans(source) {
93
+ const spans = [];
94
+ let offset = 0;
95
+ let fence = null;
96
+ for (const line of source.split('\n')) {
97
+ const lineStart = offset;
98
+ const lineEnd = offset + line.length;
99
+ offset = lineEnd + 1;
100
+ if (fence) {
101
+ const close = /^ {0,3}(`{3,}|~{3,})[ \t]*$/.exec(line);
102
+ if (close && close[1][0] === fence.char && close[1].length >= fence.length) {
103
+ spans.push({ start: fence.start, end: lineEnd });
104
+ fence = null;
105
+ }
106
+ continue;
107
+ }
108
+ const open = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
109
+ // A backtick fence's info string may not itself contain a backtick; a
110
+ // tilde fence's may. Same rule the engines apply.
111
+ if (open && !(open[1][0] === '`' && open[2].includes('`'))) {
112
+ fence = { char: open[1][0], length: open[1].length, start: lineStart };
113
+ continue;
114
+ }
115
+ // Inline code spans, matched run-for-run within the line.
116
+ const runs = /`+/g;
117
+ let openRun = null;
118
+ for (let m = runs.exec(line); m; m = runs.exec(line)) {
119
+ if (!openRun) {
120
+ openRun = { index: m.index, length: m[0].length };
121
+ continue;
122
+ }
123
+ if (m[0].length === openRun.length) {
124
+ spans.push({ start: lineStart + openRun.index, end: lineStart + m.index + m[0].length });
125
+ openRun = null;
126
+ }
127
+ }
128
+ }
129
+ // An unterminated fence shields everything to the end of the document.
130
+ if (fence)
131
+ spans.push({ start: fence.start, end: source.length });
132
+ return spans;
133
+ }
134
+ /**
135
+ * Locate the well-formed directives in `source`, in source order, skipping any
136
+ * that begin inside a verbatim region (I9).
137
+ *
138
+ * `onInvalidOption` fires for a token of directive shape whose options do not
139
+ * parse, so the caller can raise `include-unknown-option` on it.
140
+ */
141
+ export function findDirectives(source, onInvalidOption) {
142
+ const shielded = verbatimSpans(source);
143
+ const inVerbatim = (index) => shielded.some((span) => index >= span.start && index < span.end);
144
+ const re = new RegExp(DIRECTIVE_SCAN_RE.source, 'g');
145
+ const found = [];
146
+ for (let m = re.exec(source); m; m = re.exec(source)) {
147
+ const start = m.index;
148
+ const end = start + m[0].length;
149
+ if (inVerbatim(start))
150
+ continue;
151
+ const parsed = parseDirective(m[0], (part) => onInvalidOption?.(part, start, end));
152
+ if (!parsed)
153
+ continue;
154
+ found.push({ ...parsed, start, end });
155
+ }
156
+ return found;
157
+ }
158
+ //# sourceMappingURL=include-directive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"include-directive.js","sourceRoot":"","sources":["../src/include-directive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,83 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { findDirectives, parseDirective, verbatimSpans } from './include-directive.js';
4
+ // Expectations here follow the cross-engine include-conformance vectors named
5
+ // in each test (markup-carve/carve tests/include-conformance/vectors). Those
6
+ // vectors currently live only on the unmerged spec branch for
7
+ // markup-carve/carve#291, so they are cited rather than vendored.
8
+ test('a bare directive is recognized with its path', () => {
9
+ const [d] = findDirectives('{{ child.crv }}');
10
+ assert.ok(d);
11
+ assert.equal(d.path, 'child.crv');
12
+ assert.equal(d.start, 0);
13
+ assert.equal(d.end, 15);
14
+ });
15
+ test('a quoted path carrying a space is recognized (i01-quoted-path-roundtrip)', () => {
16
+ const [d] = findDirectives('{{ "my chapter.crv" }}');
17
+ assert.ok(d);
18
+ assert.equal(d.path, 'my chapter.crv');
19
+ });
20
+ test('a section selector is separated from the path', () => {
21
+ const [d] = findDirectives('{{ c.crv #Intro }}');
22
+ assert.ok(d);
23
+ assert.equal(d.path, 'c.crv');
24
+ assert.equal(d.section, 'Intro');
25
+ });
26
+ test('empty and pathless brace pairs stay literal (i01-*-literal)', () => {
27
+ // Each of these is ordinary text under the PART 6 production: the path token
28
+ // is mandatory and may not begin with `#` or `@`.
29
+ for (const source of ['{{}}', '{{ }}', '{{ #sec }}', '{{ @shift:1 }}']) {
30
+ assert.deepEqual(findDirectives(source), [], source);
31
+ }
32
+ });
33
+ test('an unknown option makes the directive literal and reports the option (i01-unknown-option-literal)', () => {
34
+ const seen = [];
35
+ const found = findDirectives('{{ child @nope:1 }}', (part) => seen.push(part));
36
+ assert.deepEqual(found, []);
37
+ assert.deepEqual(seen, ['@nope:1']);
38
+ });
39
+ test('a malformed shift value is an unknown option (i01-shift-malformed-value)', () => {
40
+ const seen = [];
41
+ assert.deepEqual(findDirectives('{{ child @shift:x }}', (part) => seen.push(part)), []);
42
+ assert.deepEqual(seen, ['@shift:x']);
43
+ });
44
+ test('several directives in one run are all found (i09a-multi-directive-one-run)', () => {
45
+ const found = findDirectives('start {{ a.crv }} mid {{ b.crv }} end');
46
+ assert.deepEqual(found.map((d) => d.path), ['a.crv', 'b.crv']);
47
+ });
48
+ test('adjacent directives are both found', () => {
49
+ const found = findDirectives('{{ a.crv }}{{ d.crv }}');
50
+ assert.deepEqual(found.map((d) => d.path), ['a.crv', 'd.crv']);
51
+ });
52
+ // ---------------------------------------------------------------------------
53
+ // Verbatim shielding (I9)
54
+ // ---------------------------------------------------------------------------
55
+ test('a directive inside a fence or a code span is shielded (i09-verbatim-fence-and-code-span)', () => {
56
+ const source = '```txt\n{{ child }}\n```\n\nUse `{{ child }}`.';
57
+ assert.deepEqual(findDirectives(source), []);
58
+ });
59
+ test('a raw block shields its directive (i09-verbatim-raw-block)', () => {
60
+ assert.deepEqual(findDirectives('```=html\n{{ child }}\n```'), []);
61
+ });
62
+ test('a fence shields only itself; a directive after it still resolves (i09-fence-info-shields-plain-expands)', () => {
63
+ const source = '```js\n{{ child }}\n```\n\n{{ child }}';
64
+ const found = findDirectives(source);
65
+ assert.equal(found.length, 1);
66
+ // The surviving one is the directive AFTER the closing fence.
67
+ assert.equal(found[0].start, source.lastIndexOf('{{ child }}'));
68
+ });
69
+ test('a tilde fence shields too', () => {
70
+ assert.deepEqual(findDirectives('~~~\n{{ child }}\n~~~'), []);
71
+ });
72
+ test('an unterminated fence shields to the end of the document', () => {
73
+ assert.deepEqual(findDirectives('```\n{{ child }}\n'), []);
74
+ });
75
+ test('verbatimSpans covers the whole fence including its markers', () => {
76
+ const source = '```\nx\n```\n';
77
+ assert.deepEqual(verbatimSpans(source), [{ start: 0, end: 9 }]);
78
+ });
79
+ test('parseDirective rejects a token that is not a directive', () => {
80
+ assert.equal(parseDirective('{{ oops'), null);
81
+ assert.equal(parseDirective('{{ }}'), null);
82
+ });
83
+ //# sourceMappingURL=include-directive.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"include-directive.test.js","sourceRoot":"","sources":["../src/include-directive.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Why a resolver refused a target. Reported on {@link IncludeWarning.detail},
3
+ * never folded into the diagnostic message: §19 I7 requires a
4
+ * processor-generated message naming the failure class, and the
5
+ * include-conformance goldens (`i10-fs-*`) spell every containment denial as
6
+ * the single rule `include-unresolved` so that a denial cannot be used to probe
7
+ * host layout. The class is kept available for tooling and tests.
8
+ */
9
+ export type IncludeDenial = 'remote-not-allowed' | 'absolute-denied' | 'outside-root' | 'not-found' | 'not-a-file';
10
+ export interface IncludeContext {
11
+ /** Identity of the including document, supplied by the host when known. */
12
+ sourcePath?: string;
13
+ /**
14
+ * Include chain, root first: the canonical id of each ancestor. Used for
15
+ * relative resolution (a nested include resolves against its actual parent
16
+ * directory) and for the cycle guard.
17
+ */
18
+ stack: string[];
19
+ /** Zero-based include depth of the directive being resolved. */
20
+ depth: number;
21
+ }
22
+ export type IncludeResolved = {
23
+ ok: true;
24
+ id: string;
25
+ source: string;
26
+ bytes: number;
27
+ } | {
28
+ ok: false;
29
+ id: string;
30
+ denial: IncludeDenial;
31
+ };
32
+ export type IncludeResolver = (includePath: string, ctx: IncludeContext) => IncludeResolved;
33
+ export interface FileSystemResolverOptions {
34
+ /** Allow absolute include paths, still subject to root containment. Default false. */
35
+ allowAbsolute?: boolean;
36
+ /**
37
+ * Hosts a remote include may name. Empty (the default) means no remote
38
+ * include is permitted at all.
39
+ *
40
+ * Note that this server never fetches over the network under any setting:
41
+ * an allowlisted host is still refused, because there is no fetcher. The
42
+ * option exists so that "allowlist explicitly configured" is a real,
43
+ * inspectable condition rather than an implicit one, and so a host that
44
+ * later gains a fetcher has the gate already in place.
45
+ */
46
+ allowedRemoteHosts?: string[];
47
+ }
48
+ /**
49
+ * Filesystem resolver with canonical root containment, for a workspace the
50
+ * client reports as trusted.
51
+ *
52
+ * Canonicalize-then-contain: the candidate is resolved to its real path
53
+ * (symlinks followed) and only then compared against the real root.
54
+ *
55
+ * Deliberately NOT a lexical ban on `..`, which is both too strict and too
56
+ * weak. Too strict: `../shared/glossary.crv` from `chapters/ch1.crv` is a
57
+ * normal book layout whose canonical target is inside the root, and the
58
+ * conformance vector `i10-fs-dotdot-inside-root-allowed` requires it to
59
+ * resolve. Too weak: a symlink inside the root pointing out of it, or an
60
+ * absolute path, escapes without containing `..` at all
61
+ * (`i10-fs-symlink-dir-escape-denied`). Canonical containment subsumes both.
62
+ */
63
+ export declare function fileSystemResolver(includeRoot: string, opts?: FileSystemResolverOptions): IncludeResolver;
@@ -0,0 +1,135 @@
1
+ /**
2
+ * The single place an include path becomes a file read.
3
+ *
4
+ * PART 9 §19 puts four MUSTs on this function, and they are here rather than
5
+ * spread over the callers on purpose: a guard applied on one path and missed on
6
+ * another is the defect this repository's siblings keep hitting. Nothing else
7
+ * in this package joins, canonicalizes or opens an include target.
8
+ *
9
+ * - MUST resolve include paths only to files under the configured project root
10
+ * AFTER symlink resolution (rejecting `..`-traversal and absolute paths that
11
+ * escape the root)
12
+ * - MUST NOT fetch remote URLs unless an allowlist is explicitly configured
13
+ *
14
+ * The remaining two MUSTs (recursion depth, total expanded byte size) are
15
+ * properties of the include GRAPH rather than of one path, so they live in
16
+ * {@link ./includes.js} where the walk is.
17
+ */
18
+ import { closeSync, fstatSync, openSync, readSync, realpathSync } from 'node:fs';
19
+ import path from 'node:path';
20
+ /** A scheme with an authority (`https://…`), or a protocol-relative `//host/…`. */
21
+ const REMOTE_RE = /^(?:[A-Za-z][A-Za-z0-9+.-]*:)?\/\//;
22
+ function remoteHost(spec) {
23
+ const withScheme = spec.startsWith('//') ? `https:${spec}` : spec;
24
+ try {
25
+ return new URL(withScheme).hostname;
26
+ }
27
+ catch {
28
+ return '';
29
+ }
30
+ }
31
+ /**
32
+ * Filesystem resolver with canonical root containment, for a workspace the
33
+ * client reports as trusted.
34
+ *
35
+ * Canonicalize-then-contain: the candidate is resolved to its real path
36
+ * (symlinks followed) and only then compared against the real root.
37
+ *
38
+ * Deliberately NOT a lexical ban on `..`, which is both too strict and too
39
+ * weak. Too strict: `../shared/glossary.crv` from `chapters/ch1.crv` is a
40
+ * normal book layout whose canonical target is inside the root, and the
41
+ * conformance vector `i10-fs-dotdot-inside-root-allowed` requires it to
42
+ * resolve. Too weak: a symlink inside the root pointing out of it, or an
43
+ * absolute path, escapes without containing `..` at all
44
+ * (`i10-fs-symlink-dir-escape-denied`). Canonical containment subsumes both.
45
+ */
46
+ export function fileSystemResolver(includeRoot, opts = {}) {
47
+ const rootReal = realpathSync(includeRoot);
48
+ const allowedRemoteHosts = opts.allowedRemoteHosts ?? [];
49
+ const contains = (candidate) => {
50
+ const rel = path.relative(rootReal, candidate);
51
+ if (rel === '')
52
+ return true;
53
+ if (!rel || path.isAbsolute(rel))
54
+ return false;
55
+ // Segment-wise, so a directory legitimately named "..foo" is not read as
56
+ // an escape the way a startsWith('..') prefix test would.
57
+ return rel.split(path.sep)[0] !== '..';
58
+ };
59
+ return (includePath, ctx) => {
60
+ // GUARD 1 (§19: MUST NOT fetch remote URLs unless an allowlist is
61
+ // explicitly configured). Checked before any path join, so a URL can never
62
+ // be mistaken for a relative path and read off disk as `<root>/https:/…`.
63
+ if (REMOTE_RE.test(includePath)) {
64
+ const host = remoteHost(includePath);
65
+ if (!allowedRemoteHosts.includes(host)) {
66
+ return { ok: false, id: includePath, denial: 'remote-not-allowed' };
67
+ }
68
+ // Allowlisted, and still refused: this server has no fetcher. Reported
69
+ // as a denial rather than silently, so the author sees why.
70
+ return { ok: false, id: includePath, denial: 'remote-not-allowed' };
71
+ }
72
+ // GUARD 2 (§19: absolute paths). Denied outright by default; when the host
73
+ // opts in, an absolute path still has to survive GUARD 3.
74
+ if (!opts.allowAbsolute && path.isAbsolute(includePath)) {
75
+ return { ok: false, id: includePath, denial: 'absolute-denied' };
76
+ }
77
+ // The stack carries the canonical path of each ancestor, so a nested
78
+ // relative include resolves against its actual parent directory, not the
79
+ // root.
80
+ const parent = ctx.stack[ctx.stack.length - 1];
81
+ const base = parent ? path.dirname(path.resolve(rootReal, parent)) : rootReal;
82
+ const joined = path.isAbsolute(includePath)
83
+ ? includePath
84
+ : path.resolve(base, includePath);
85
+ let real;
86
+ try {
87
+ // Symlink resolution happens HERE, before containment, which is what
88
+ // makes a symlinked escape visible to GUARD 3 at all.
89
+ real = realpathSync(joined);
90
+ }
91
+ catch {
92
+ return { ok: false, id: includePath, denial: 'not-found' };
93
+ }
94
+ // GUARD 3 (§19: only files under the configured project root AFTER symlink
95
+ // resolution). Catches `..` that leaves the root, a symlink that points out
96
+ // of it, and an absolute path outside it.
97
+ if (!contains(real)) {
98
+ return { ok: false, id: includePath, denial: 'outside-root' };
99
+ }
100
+ let fd;
101
+ try {
102
+ fd = openSync(real, 'r');
103
+ }
104
+ catch {
105
+ return { ok: false, id: includePath, denial: 'not-found' };
106
+ }
107
+ try {
108
+ const stat = fstatSync(fd);
109
+ // Regular files only. A FIFO or a character device would block the read
110
+ // or stream without end, and neither is a document.
111
+ if (!stat.isFile())
112
+ return { ok: false, id: real, denial: 'not-a-file' };
113
+ const buffer = Buffer.allocUnsafe(stat.size);
114
+ let read = 0;
115
+ while (read < stat.size) {
116
+ const n = readSync(fd, buffer, read, stat.size - read, read);
117
+ if (n <= 0)
118
+ break;
119
+ read += n;
120
+ }
121
+ return {
122
+ ok: true,
123
+ id: real,
124
+ source: buffer.subarray(0, read).toString('utf8'),
125
+ // Encoded bytes, not JavaScript characters, so the budget counts what
126
+ // the include-bomb actually costs.
127
+ bytes: read,
128
+ };
129
+ }
130
+ finally {
131
+ closeSync(fd);
132
+ }
133
+ };
134
+ }
135
+ //# sourceMappingURL=include-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"include-path.js","sourceRoot":"","sources":["../src/include-path.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};