@codedrifters/configulator 0.0.273 → 0.0.274
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/lib/index.d.mts +246 -1
- package/lib/index.d.ts +247 -2
- package/lib/index.js +525 -42
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +521 -44
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -9026,6 +9026,126 @@ var checkLinksProcedure = {
|
|
|
9026
9026
|
description: "Link integrity checker that wraps `astro check` (internal links) and `lychee` (external URLs) and normalizes their output into a single JSON-array stream of { url, docPath, line, kind, reason } records. Detection is data: the helper exits 0 when a tool ran successfully regardless of how many broken links it reported. Non-zero exits are reserved for tool-level failures.",
|
|
9027
9027
|
content: renderCheckLinksProcedure()
|
|
9028
9028
|
};
|
|
9029
|
+
function renderCheckDocSamplesProcedure() {
|
|
9030
|
+
const nodeScript = [
|
|
9031
|
+
"(async () => {",
|
|
9032
|
+
" const { compileFencedSamples } = await import('@codedrifters/configulator');",
|
|
9033
|
+
" const docsRoot = process.argv[1];",
|
|
9034
|
+
" const failures = compileFencedSamples({ docsRoot });",
|
|
9035
|
+
" process.stdout.write(JSON.stringify(failures));",
|
|
9036
|
+
"})().catch((err) => {",
|
|
9037
|
+
" console.error('check-doc-samples.sh: ' + (err && err.stack ? err.stack : err));",
|
|
9038
|
+
" process.exit(3);",
|
|
9039
|
+
"});"
|
|
9040
|
+
].join("\n");
|
|
9041
|
+
return [
|
|
9042
|
+
"#!/usr/bin/env bash",
|
|
9043
|
+
"# check-doc-samples.sh \u2014 Compile fenced TS/TSX samples in the Starlight docs.",
|
|
9044
|
+
"#",
|
|
9045
|
+
"# Usage:",
|
|
9046
|
+
"# .claude/procedures/check-doc-samples.sh <docs-root>",
|
|
9047
|
+
"#",
|
|
9048
|
+
"# Where:",
|
|
9049
|
+
"# <docs-root> \u2014 path to the markdown content tree",
|
|
9050
|
+
"# (e.g. `docs/src/content/docs`). Walked recursively",
|
|
9051
|
+
"# for `*.md` files.",
|
|
9052
|
+
"#",
|
|
9053
|
+
"# Wraps the `compileFencedSamples` API exported from",
|
|
9054
|
+
"# `@codedrifters/configulator`. For every fenced ` ```ts `,",
|
|
9055
|
+
"# ` ```typescript `, ` ```tsx `, or ` ```typescriptreact ` block in",
|
|
9056
|
+
"# the docs, the helper writes the sample to an in-memory file,",
|
|
9057
|
+
"# runs the TypeScript compiler against it (in-process, via the TS",
|
|
9058
|
+
"# compiler API), and reports any compilation diagnostics.",
|
|
9059
|
+
"#",
|
|
9060
|
+
"# Skipped samples (fence meta `skip` / `no-check`, or first line",
|
|
9061
|
+
"# `// @no-check`) are passed through unchecked.",
|
|
9062
|
+
"#",
|
|
9063
|
+
"# Output (stdout, single JSON array):",
|
|
9064
|
+
"#",
|
|
9065
|
+
"# [",
|
|
9066
|
+
"# {",
|
|
9067
|
+
'# "docPath": "<path relative to <docs-root>>",',
|
|
9068
|
+
'# "line": <1-indexed line number of the opening fence>,',
|
|
9069
|
+
'# "fenceIndex": <0-indexed fenced-block position within the doc>,',
|
|
9070
|
+
'# "lang": "ts" | "typescript" | "tsx" | "typescriptreact",',
|
|
9071
|
+
'# "diagnostics": [ "<TS<code>: <message>>", ... ]',
|
|
9072
|
+
"# },",
|
|
9073
|
+
"# ...",
|
|
9074
|
+
"# ]",
|
|
9075
|
+
"#",
|
|
9076
|
+
"# An empty array (`[]`) is emitted when every sample compiled.",
|
|
9077
|
+
"# Detection is **data**, not failure: this helper exits 0 when the",
|
|
9078
|
+
"# compilation phase ran successfully, regardless of how many",
|
|
9079
|
+
"# samples failed to compile. The downstream docs-sync scan phase",
|
|
9080
|
+
"# (#520) is responsible for treating failures as one of the two",
|
|
9081
|
+
"# hard-block cases per the parent epic.",
|
|
9082
|
+
"#",
|
|
9083
|
+
"# Exit codes:",
|
|
9084
|
+
"# 0 \u2014 compilation phase ran; failures (zero or more) are on",
|
|
9085
|
+
"# stdout as a JSON array.",
|
|
9086
|
+
"# 1 \u2014 usage error (missing args, unreadable docs root).",
|
|
9087
|
+
"# 2 \u2014 a required binary is not on PATH (`node` / `pnpm`).",
|
|
9088
|
+
"# 3 \u2014 the compilation phase threw an unhandled exception.",
|
|
9089
|
+
"# Stderr carries the diagnostic.",
|
|
9090
|
+
"#",
|
|
9091
|
+
"# Dependencies: expects `node` and `pnpm` on PATH and the workspace",
|
|
9092
|
+
"# `@codedrifters/configulator` package to be installed (the helper",
|
|
9093
|
+
"# resolves the API through `pnpm exec node` from the repo root).",
|
|
9094
|
+
"",
|
|
9095
|
+
"set -uo pipefail",
|
|
9096
|
+
"",
|
|
9097
|
+
"err() {",
|
|
9098
|
+
' printf "check-doc-samples.sh: %s\\n" "$*" >&2',
|
|
9099
|
+
"}",
|
|
9100
|
+
"",
|
|
9101
|
+
'if [ "$#" -lt 1 ]; then',
|
|
9102
|
+
' err "usage: check-doc-samples.sh <docs-root>"',
|
|
9103
|
+
" exit 1",
|
|
9104
|
+
"fi",
|
|
9105
|
+
"",
|
|
9106
|
+
'docs_root="$1"',
|
|
9107
|
+
"",
|
|
9108
|
+
'if [ ! -d "$docs_root" ]; then',
|
|
9109
|
+
' err "docs root not found: $docs_root"',
|
|
9110
|
+
" exit 1",
|
|
9111
|
+
"fi",
|
|
9112
|
+
"",
|
|
9113
|
+
"if ! command -v node >/dev/null 2>&1; then",
|
|
9114
|
+
' err "node is required but not on PATH"',
|
|
9115
|
+
" exit 2",
|
|
9116
|
+
"fi",
|
|
9117
|
+
"",
|
|
9118
|
+
"if ! command -v pnpm >/dev/null 2>&1; then",
|
|
9119
|
+
' err "pnpm is required but not on PATH"',
|
|
9120
|
+
" exit 2",
|
|
9121
|
+
"fi",
|
|
9122
|
+
"",
|
|
9123
|
+
"# Resolve docs_root to an absolute path so the inline node script",
|
|
9124
|
+
"# is independent of the cwd `pnpm exec` chooses.",
|
|
9125
|
+
'docs_root_abs="$(cd "$docs_root" && pwd)"',
|
|
9126
|
+
"",
|
|
9127
|
+
"# Run the inline node script through `pnpm exec` so module",
|
|
9128
|
+
"# resolution finds `@codedrifters/configulator` via the workspace",
|
|
9129
|
+
"# even when the helper is invoked from a sub-package directory.",
|
|
9130
|
+
"# The `--input-type=module` flag lets us use top-level `await` and",
|
|
9131
|
+
"# `import()` cleanly. Diagnostics from the script flow to stderr;",
|
|
9132
|
+
"# stdout carries only the JSON array.",
|
|
9133
|
+
'pnpm exec node --input-type=module -e "' + nodeScript.replace(/"/g, '\\"') + '" "$docs_root_abs"',
|
|
9134
|
+
"status=$?",
|
|
9135
|
+
"",
|
|
9136
|
+
'if [ "$status" -ne 0 ]; then',
|
|
9137
|
+
' err "compileFencedSamples exited with status $status"',
|
|
9138
|
+
" exit 3",
|
|
9139
|
+
"fi",
|
|
9140
|
+
"",
|
|
9141
|
+
"exit 0"
|
|
9142
|
+
].join("\n");
|
|
9143
|
+
}
|
|
9144
|
+
var checkDocSamplesProcedure = {
|
|
9145
|
+
name: "check-doc-samples.sh",
|
|
9146
|
+
description: "Fenced-sample compilation checker that wraps the `compileFencedSamples` API and emits a JSON-array stream of { docPath, line, fenceIndex, lang, diagnostics } failure records. Skipped samples (meta `skip`/`no-check`, or first-line `// @no-check`) are passed through unchecked. Detection is data: the helper exits 0 whenever compilation ran successfully regardless of failure count.",
|
|
9147
|
+
content: renderCheckDocSamplesProcedure()
|
|
9148
|
+
};
|
|
9029
9149
|
function buildDocsSyncBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
9030
9150
|
return {
|
|
9031
9151
|
name: "docs-sync",
|
|
@@ -9075,7 +9195,11 @@ function buildDocsSyncBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
9075
9195
|
],
|
|
9076
9196
|
skills: [buildDocsSyncPrSkill(), buildDocsSyncAuditSkill()],
|
|
9077
9197
|
subAgents: [buildDocsSyncSubAgent(paths)],
|
|
9078
|
-
procedures: [
|
|
9198
|
+
procedures: [
|
|
9199
|
+
extractApiProcedure,
|
|
9200
|
+
checkLinksProcedure,
|
|
9201
|
+
checkDocSamplesProcedure
|
|
9202
|
+
],
|
|
9079
9203
|
labels: [
|
|
9080
9204
|
{
|
|
9081
9205
|
name: "type:docs-sync",
|
|
@@ -26819,8 +26943,8 @@ var FALLBACKS = {
|
|
|
26819
26943
|
monorepoLayoutSeedBlock: ""
|
|
26820
26944
|
};
|
|
26821
26945
|
var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
|
|
26822
|
-
function getNestedValue(obj,
|
|
26823
|
-
const parts =
|
|
26946
|
+
function getNestedValue(obj, path6) {
|
|
26947
|
+
const parts = path6.split(".");
|
|
26824
26948
|
let current = obj;
|
|
26825
26949
|
for (const part of parts) {
|
|
26826
26950
|
if (current == null || typeof current !== "object") {
|
|
@@ -27046,20 +27170,20 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27046
27170
|
obj.excludedCommands = [...sandbox.excludedCommands];
|
|
27047
27171
|
}
|
|
27048
27172
|
if (sandbox.filesystem) {
|
|
27049
|
-
const
|
|
27173
|
+
const fs3 = {};
|
|
27050
27174
|
if (sandbox.filesystem.allowRead?.length) {
|
|
27051
|
-
|
|
27175
|
+
fs3.allowRead = [...sandbox.filesystem.allowRead];
|
|
27052
27176
|
}
|
|
27053
27177
|
if (sandbox.filesystem.denyRead?.length) {
|
|
27054
|
-
|
|
27178
|
+
fs3.denyRead = [...sandbox.filesystem.denyRead];
|
|
27055
27179
|
}
|
|
27056
27180
|
if (sandbox.filesystem.allowWrite?.length) {
|
|
27057
|
-
|
|
27181
|
+
fs3.allowWrite = [...sandbox.filesystem.allowWrite];
|
|
27058
27182
|
}
|
|
27059
27183
|
if (sandbox.filesystem.denyWrite?.length) {
|
|
27060
|
-
|
|
27184
|
+
fs3.denyWrite = [...sandbox.filesystem.denyWrite];
|
|
27061
27185
|
}
|
|
27062
|
-
if (Object.keys(
|
|
27186
|
+
if (Object.keys(fs3).length > 0) obj.filesystem = fs3;
|
|
27063
27187
|
}
|
|
27064
27188
|
if (sandbox.network) {
|
|
27065
27189
|
const net = {};
|
|
@@ -28921,10 +29045,357 @@ function stripYamlFrontmatter(source) {
|
|
|
28921
29045
|
return lines.join("\n");
|
|
28922
29046
|
}
|
|
28923
29047
|
|
|
28924
|
-
// src/docs-sync/
|
|
29048
|
+
// src/docs-sync/sample-compilation/compilation.ts
|
|
29049
|
+
import * as path4 from "path";
|
|
29050
|
+
import * as ts from "typescript";
|
|
29051
|
+
|
|
29052
|
+
// src/docs-sync/sample-compilation/extraction.ts
|
|
29053
|
+
import * as fs2 from "fs";
|
|
28925
29054
|
import * as path3 from "path";
|
|
29055
|
+
import { fromMarkdown as fromMarkdown2 } from "mdast-util-from-markdown";
|
|
29056
|
+
var SampleLang = {
|
|
29057
|
+
Ts: "ts",
|
|
29058
|
+
Typescript: "typescript",
|
|
29059
|
+
Tsx: "tsx",
|
|
29060
|
+
Typescriptreact: "typescriptreact"
|
|
29061
|
+
};
|
|
29062
|
+
var DEFAULT_DOCS_ROOT2 = "docs/src/content/docs";
|
|
29063
|
+
var PLAIN_LANGS = /* @__PURE__ */ new Set([SampleLang.Ts, SampleLang.Typescript]);
|
|
29064
|
+
var JSX_LANGS = /* @__PURE__ */ new Set([
|
|
29065
|
+
SampleLang.Tsx,
|
|
29066
|
+
SampleLang.Typescriptreact
|
|
29067
|
+
]);
|
|
29068
|
+
function extractFencedSamples(options = {}) {
|
|
29069
|
+
const docsRoot = path3.resolve(options.docsRoot ?? DEFAULT_DOCS_ROOT2);
|
|
29070
|
+
const includeTsx = options.includeTsx ?? true;
|
|
29071
|
+
if (!fs2.existsSync(docsRoot)) {
|
|
29072
|
+
return [];
|
|
29073
|
+
}
|
|
29074
|
+
const records = [];
|
|
29075
|
+
for (const absolutePath of walkMarkdownFiles2(docsRoot)) {
|
|
29076
|
+
const docPath = toPosix2(path3.relative(docsRoot, absolutePath));
|
|
29077
|
+
const source = fs2.readFileSync(absolutePath, "utf-8");
|
|
29078
|
+
const tree = fromMarkdown2(stripYamlFrontmatter2(source));
|
|
29079
|
+
let fenceIndex = 0;
|
|
29080
|
+
collectFencedCode(tree, (node) => {
|
|
29081
|
+
const lang = normalizeLang(node.lang);
|
|
29082
|
+
if (lang === void 0) {
|
|
29083
|
+
return;
|
|
29084
|
+
}
|
|
29085
|
+
if (!includeTsx && JSX_LANGS.has(lang)) {
|
|
29086
|
+
return;
|
|
29087
|
+
}
|
|
29088
|
+
if (!PLAIN_LANGS.has(lang) && !JSX_LANGS.has(lang)) {
|
|
29089
|
+
return;
|
|
29090
|
+
}
|
|
29091
|
+
const start = node.position?.start;
|
|
29092
|
+
if (!start) {
|
|
29093
|
+
return;
|
|
29094
|
+
}
|
|
29095
|
+
const skip = detectSkip(node);
|
|
29096
|
+
records.push({
|
|
29097
|
+
docPath,
|
|
29098
|
+
line: start.line,
|
|
29099
|
+
fenceIndex,
|
|
29100
|
+
lang,
|
|
29101
|
+
code: node.value ?? "",
|
|
29102
|
+
skipped: skip.skipped,
|
|
29103
|
+
skipReason: skip.reason
|
|
29104
|
+
});
|
|
29105
|
+
fenceIndex += 1;
|
|
29106
|
+
});
|
|
29107
|
+
}
|
|
29108
|
+
records.sort((a, b) => {
|
|
29109
|
+
if (a.docPath !== b.docPath) {
|
|
29110
|
+
return a.docPath.localeCompare(b.docPath);
|
|
29111
|
+
}
|
|
29112
|
+
if (a.line !== b.line) {
|
|
29113
|
+
return a.line - b.line;
|
|
29114
|
+
}
|
|
29115
|
+
return a.fenceIndex - b.fenceIndex;
|
|
29116
|
+
});
|
|
29117
|
+
return records;
|
|
29118
|
+
}
|
|
29119
|
+
function walkMarkdownFiles2(root) {
|
|
29120
|
+
const out = [];
|
|
29121
|
+
const stack = [root];
|
|
29122
|
+
while (stack.length > 0) {
|
|
29123
|
+
const dir = stack.pop();
|
|
29124
|
+
let entries;
|
|
29125
|
+
try {
|
|
29126
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
29127
|
+
} catch {
|
|
29128
|
+
continue;
|
|
29129
|
+
}
|
|
29130
|
+
for (const entry of entries) {
|
|
29131
|
+
const full = path3.join(dir, entry.name);
|
|
29132
|
+
if (entry.isDirectory()) {
|
|
29133
|
+
stack.push(full);
|
|
29134
|
+
} else if (entry.isFile() && full.toLowerCase().endsWith(".md")) {
|
|
29135
|
+
out.push(full);
|
|
29136
|
+
}
|
|
29137
|
+
}
|
|
29138
|
+
}
|
|
29139
|
+
out.sort();
|
|
29140
|
+
return out;
|
|
29141
|
+
}
|
|
29142
|
+
function collectFencedCode(tree, visit) {
|
|
29143
|
+
walk(tree);
|
|
29144
|
+
function walk(node) {
|
|
29145
|
+
if (node.type === "code") {
|
|
29146
|
+
visit(node);
|
|
29147
|
+
return;
|
|
29148
|
+
}
|
|
29149
|
+
if (node.type === "html") {
|
|
29150
|
+
return;
|
|
29151
|
+
}
|
|
29152
|
+
const parent = node;
|
|
29153
|
+
if (Array.isArray(parent.children)) {
|
|
29154
|
+
for (const child of parent.children) {
|
|
29155
|
+
walk(child);
|
|
29156
|
+
}
|
|
29157
|
+
}
|
|
29158
|
+
}
|
|
29159
|
+
}
|
|
29160
|
+
function normalizeLang(raw) {
|
|
29161
|
+
if (!raw) {
|
|
29162
|
+
return void 0;
|
|
29163
|
+
}
|
|
29164
|
+
const lower = raw.toLowerCase();
|
|
29165
|
+
switch (lower) {
|
|
29166
|
+
case "ts":
|
|
29167
|
+
return SampleLang.Ts;
|
|
29168
|
+
case "typescript":
|
|
29169
|
+
return SampleLang.Typescript;
|
|
29170
|
+
case "tsx":
|
|
29171
|
+
return SampleLang.Tsx;
|
|
29172
|
+
case "typescriptreact":
|
|
29173
|
+
return SampleLang.Typescriptreact;
|
|
29174
|
+
default:
|
|
29175
|
+
return void 0;
|
|
29176
|
+
}
|
|
29177
|
+
}
|
|
29178
|
+
var META_SKIP_PATTERN = /\b(skip|no-check)\b/i;
|
|
29179
|
+
var PRAGMA_NO_CHECK_PATTERN = /^\s*\/\/\s*@no-check\b/i;
|
|
29180
|
+
function detectSkip(node) {
|
|
29181
|
+
const meta = node.meta ?? "";
|
|
29182
|
+
const metaMatch = META_SKIP_PATTERN.exec(meta);
|
|
29183
|
+
if (metaMatch) {
|
|
29184
|
+
return { skipped: true, reason: `meta:${metaMatch[1].toLowerCase()}` };
|
|
29185
|
+
}
|
|
29186
|
+
const code = node.value ?? "";
|
|
29187
|
+
const firstLine = firstNonBlankLine(code);
|
|
29188
|
+
if (firstLine !== void 0 && PRAGMA_NO_CHECK_PATTERN.test(firstLine)) {
|
|
29189
|
+
return { skipped: true, reason: "pragma:@no-check" };
|
|
29190
|
+
}
|
|
29191
|
+
return { skipped: false, reason: "" };
|
|
29192
|
+
}
|
|
29193
|
+
function firstNonBlankLine(source) {
|
|
29194
|
+
for (const line of source.split("\n")) {
|
|
29195
|
+
if (line.trim().length > 0) {
|
|
29196
|
+
return line;
|
|
29197
|
+
}
|
|
29198
|
+
}
|
|
29199
|
+
return void 0;
|
|
29200
|
+
}
|
|
29201
|
+
function toPosix2(p) {
|
|
29202
|
+
return p.split(path3.sep).join("/");
|
|
29203
|
+
}
|
|
29204
|
+
function stripYamlFrontmatter2(source) {
|
|
29205
|
+
if (!source.startsWith("---")) {
|
|
29206
|
+
return source;
|
|
29207
|
+
}
|
|
29208
|
+
const lines = source.split("\n");
|
|
29209
|
+
if (lines[0] !== "---") {
|
|
29210
|
+
return source;
|
|
29211
|
+
}
|
|
29212
|
+
let endIndex = -1;
|
|
29213
|
+
for (let i = 1; i < lines.length; i++) {
|
|
29214
|
+
if (lines[i] === "---") {
|
|
29215
|
+
endIndex = i;
|
|
29216
|
+
break;
|
|
29217
|
+
}
|
|
29218
|
+
}
|
|
29219
|
+
if (endIndex < 0) {
|
|
29220
|
+
return source;
|
|
29221
|
+
}
|
|
29222
|
+
for (let i = 0; i <= endIndex; i++) {
|
|
29223
|
+
lines[i] = "";
|
|
29224
|
+
}
|
|
29225
|
+
return lines.join("\n");
|
|
29226
|
+
}
|
|
29227
|
+
|
|
29228
|
+
// src/docs-sync/sample-compilation/compilation.ts
|
|
29229
|
+
var DEFAULT_SAMPLE_COMPILER_OPTIONS = {
|
|
29230
|
+
target: ts.ScriptTarget.ES2022,
|
|
29231
|
+
module: ts.ModuleKind.ESNext,
|
|
29232
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
29233
|
+
lib: ["lib.es2022.d.ts", "lib.dom.d.ts"],
|
|
29234
|
+
strict: true,
|
|
29235
|
+
noUnusedLocals: false,
|
|
29236
|
+
noUnusedParameters: false,
|
|
29237
|
+
skipLibCheck: true,
|
|
29238
|
+
esModuleInterop: true,
|
|
29239
|
+
resolveJsonModule: true,
|
|
29240
|
+
isolatedModules: true,
|
|
29241
|
+
jsx: ts.JsxEmit.Preserve,
|
|
29242
|
+
noEmit: true,
|
|
29243
|
+
allowSyntheticDefaultImports: true
|
|
29244
|
+
};
|
|
29245
|
+
var REPO_RELATIVE_MODULE_PATTERN = /^['"](?:\.\.?\/|\/)/;
|
|
29246
|
+
function compileFencedSamples(options = {}) {
|
|
29247
|
+
const samples = extractFencedSamples(options);
|
|
29248
|
+
const tolerateRepoRelative = options.tolerateRepoRelativeMissingModule ?? true;
|
|
29249
|
+
const failures = [];
|
|
29250
|
+
for (const sample of samples) {
|
|
29251
|
+
if (sample.skipped) {
|
|
29252
|
+
continue;
|
|
29253
|
+
}
|
|
29254
|
+
const diagnostics = compileSingleSample(
|
|
29255
|
+
sample,
|
|
29256
|
+
options.compilerOptions,
|
|
29257
|
+
tolerateRepoRelative
|
|
29258
|
+
);
|
|
29259
|
+
if (diagnostics.length > 0) {
|
|
29260
|
+
failures.push({
|
|
29261
|
+
docPath: sample.docPath,
|
|
29262
|
+
line: sample.line,
|
|
29263
|
+
fenceIndex: sample.fenceIndex,
|
|
29264
|
+
lang: sample.lang,
|
|
29265
|
+
diagnostics
|
|
29266
|
+
});
|
|
29267
|
+
}
|
|
29268
|
+
}
|
|
29269
|
+
return failures;
|
|
29270
|
+
}
|
|
29271
|
+
function compileSingleSample(sample, overrides, tolerateRepoRelative) {
|
|
29272
|
+
const filename = sampleFilename(sample);
|
|
29273
|
+
const compilerOptions = mergeCompilerOptions(overrides);
|
|
29274
|
+
const host = createSingleFileHost(filename, sample.code, compilerOptions);
|
|
29275
|
+
const program = ts.createProgram({
|
|
29276
|
+
rootNames: [filename],
|
|
29277
|
+
options: compilerOptions,
|
|
29278
|
+
host
|
|
29279
|
+
});
|
|
29280
|
+
const sourceFile = program.getSourceFile(filename);
|
|
29281
|
+
const collected = [];
|
|
29282
|
+
if (sourceFile) {
|
|
29283
|
+
collected.push(...program.getSyntacticDiagnostics(sourceFile));
|
|
29284
|
+
collected.push(...program.getSemanticDiagnostics(sourceFile));
|
|
29285
|
+
} else {
|
|
29286
|
+
collected.push(...program.getSyntacticDiagnostics());
|
|
29287
|
+
collected.push(...program.getSemanticDiagnostics());
|
|
29288
|
+
}
|
|
29289
|
+
const diagnostics = [];
|
|
29290
|
+
for (const d of collected) {
|
|
29291
|
+
if (tolerateRepoRelative && isRepoRelativeMissingModule(d, sample.code)) {
|
|
29292
|
+
continue;
|
|
29293
|
+
}
|
|
29294
|
+
diagnostics.push(formatDiagnostic(d));
|
|
29295
|
+
}
|
|
29296
|
+
return diagnostics;
|
|
29297
|
+
}
|
|
29298
|
+
function sampleFilename(sample) {
|
|
29299
|
+
const safeDoc = sample.docPath.replace(/[^a-zA-Z0-9]+/g, "_");
|
|
29300
|
+
const ext = sample.lang === SampleLang.Tsx || sample.lang === SampleLang.Typescriptreact ? "tsx" : "ts";
|
|
29301
|
+
return path4.posix.join("/", `${safeDoc}__${sample.fenceIndex}.${ext}`);
|
|
29302
|
+
}
|
|
29303
|
+
function mergeCompilerOptions(overrides) {
|
|
29304
|
+
if (!overrides) {
|
|
29305
|
+
return { ...DEFAULT_SAMPLE_COMPILER_OPTIONS };
|
|
29306
|
+
}
|
|
29307
|
+
const merged = { ...DEFAULT_SAMPLE_COMPILER_OPTIONS };
|
|
29308
|
+
for (const key of Object.keys(overrides)) {
|
|
29309
|
+
const value = overrides[key];
|
|
29310
|
+
if (value === void 0) {
|
|
29311
|
+
delete merged[key];
|
|
29312
|
+
} else {
|
|
29313
|
+
merged[key] = value;
|
|
29314
|
+
}
|
|
29315
|
+
}
|
|
29316
|
+
return merged;
|
|
29317
|
+
}
|
|
29318
|
+
function createSingleFileHost(filename, source, compilerOptions) {
|
|
29319
|
+
const baseHost = ts.createCompilerHost(compilerOptions, true);
|
|
29320
|
+
return {
|
|
29321
|
+
...baseHost,
|
|
29322
|
+
getSourceFile(name, languageVersionOrOptions, onError, shouldCreate) {
|
|
29323
|
+
if (name === filename) {
|
|
29324
|
+
return ts.createSourceFile(
|
|
29325
|
+
name,
|
|
29326
|
+
source,
|
|
29327
|
+
languageVersionOrOptions,
|
|
29328
|
+
true
|
|
29329
|
+
);
|
|
29330
|
+
}
|
|
29331
|
+
return baseHost.getSourceFile(
|
|
29332
|
+
name,
|
|
29333
|
+
languageVersionOrOptions,
|
|
29334
|
+
onError,
|
|
29335
|
+
shouldCreate
|
|
29336
|
+
);
|
|
29337
|
+
},
|
|
29338
|
+
fileExists(name) {
|
|
29339
|
+
if (name === filename) {
|
|
29340
|
+
return true;
|
|
29341
|
+
}
|
|
29342
|
+
return baseHost.fileExists(name);
|
|
29343
|
+
},
|
|
29344
|
+
readFile(name) {
|
|
29345
|
+
if (name === filename) {
|
|
29346
|
+
return source;
|
|
29347
|
+
}
|
|
29348
|
+
return baseHost.readFile(name);
|
|
29349
|
+
},
|
|
29350
|
+
writeFile() {
|
|
29351
|
+
},
|
|
29352
|
+
getCanonicalFileName(name) {
|
|
29353
|
+
return baseHost.getCanonicalFileName(name);
|
|
29354
|
+
},
|
|
29355
|
+
useCaseSensitiveFileNames() {
|
|
29356
|
+
return baseHost.useCaseSensitiveFileNames();
|
|
29357
|
+
},
|
|
29358
|
+
getNewLine() {
|
|
29359
|
+
return baseHost.getNewLine();
|
|
29360
|
+
},
|
|
29361
|
+
getDefaultLibFileName(o) {
|
|
29362
|
+
return baseHost.getDefaultLibFileName(o);
|
|
29363
|
+
},
|
|
29364
|
+
getCurrentDirectory() {
|
|
29365
|
+
return baseHost.getCurrentDirectory();
|
|
29366
|
+
}
|
|
29367
|
+
};
|
|
29368
|
+
}
|
|
29369
|
+
function isRepoRelativeMissingModule(d, code) {
|
|
29370
|
+
if (d.code !== 2307) {
|
|
29371
|
+
return false;
|
|
29372
|
+
}
|
|
29373
|
+
const text = ts.flattenDiagnosticMessageText(d.messageText, "\n");
|
|
29374
|
+
const match = /'([^']+)'/.exec(text);
|
|
29375
|
+
if (!match) {
|
|
29376
|
+
return false;
|
|
29377
|
+
}
|
|
29378
|
+
const specifier = match[1];
|
|
29379
|
+
if (!specifier) {
|
|
29380
|
+
return false;
|
|
29381
|
+
}
|
|
29382
|
+
const inSourceSingle = `'${specifier}'`;
|
|
29383
|
+
const inSourceDouble = `"${specifier}"`;
|
|
29384
|
+
if (!code.includes(inSourceSingle) && !code.includes(inSourceDouble)) {
|
|
29385
|
+
return false;
|
|
29386
|
+
}
|
|
29387
|
+
return REPO_RELATIVE_MODULE_PATTERN.test(`'${specifier}'`);
|
|
29388
|
+
}
|
|
29389
|
+
function formatDiagnostic(d) {
|
|
29390
|
+
const text = ts.flattenDiagnosticMessageText(d.messageText, " ");
|
|
29391
|
+
const code = d.code === void 0 ? "" : `TS${d.code}: `;
|
|
29392
|
+
return `${code}${text}`.trim();
|
|
29393
|
+
}
|
|
29394
|
+
|
|
29395
|
+
// src/docs-sync/tsdoc-coverage/coverage.ts
|
|
29396
|
+
import * as path5 from "path";
|
|
28926
29397
|
import { TSDocParser } from "@microsoft/tsdoc";
|
|
28927
|
-
import * as
|
|
29398
|
+
import * as ts2 from "typescript";
|
|
28928
29399
|
var TsDocCoverageKind = {
|
|
28929
29400
|
Class: "Class",
|
|
28930
29401
|
Interface: "Interface",
|
|
@@ -28940,8 +29411,8 @@ var DEFAULT_THIN_SUMMARY_WORD_THRESHOLD = 4;
|
|
|
28940
29411
|
var DEFAULT_ENTRY_POINT = "src/index.ts";
|
|
28941
29412
|
function analyzeTsDocCoverage(options) {
|
|
28942
29413
|
const resolvedOptions = typeof options === "string" ? { packageRoot: options } : options;
|
|
28943
|
-
const packageRoot =
|
|
28944
|
-
const entryPoint =
|
|
29414
|
+
const packageRoot = path5.resolve(resolvedOptions.packageRoot);
|
|
29415
|
+
const entryPoint = path5.resolve(
|
|
28945
29416
|
packageRoot,
|
|
28946
29417
|
resolvedOptions.entryPoint ?? DEFAULT_ENTRY_POINT
|
|
28947
29418
|
);
|
|
@@ -28950,7 +29421,7 @@ function analyzeTsDocCoverage(options) {
|
|
|
28950
29421
|
packageRoot,
|
|
28951
29422
|
resolvedOptions.tsconfigPath
|
|
28952
29423
|
);
|
|
28953
|
-
const program =
|
|
29424
|
+
const program = ts2.createProgram({
|
|
28954
29425
|
rootNames: [entryPoint],
|
|
28955
29426
|
options: compilerOptions
|
|
28956
29427
|
});
|
|
@@ -29004,24 +29475,24 @@ function analyzeTsDocCoverage(options) {
|
|
|
29004
29475
|
}
|
|
29005
29476
|
function resolveCompilerOptions(packageRoot, tsconfigPath) {
|
|
29006
29477
|
if (tsconfigPath) {
|
|
29007
|
-
const absoluteTsconfig =
|
|
29008
|
-
const configFile =
|
|
29478
|
+
const absoluteTsconfig = path5.resolve(packageRoot, tsconfigPath);
|
|
29479
|
+
const configFile = ts2.readConfigFile(absoluteTsconfig, ts2.sys.readFile);
|
|
29009
29480
|
if (configFile.error) {
|
|
29010
29481
|
throw new Error(
|
|
29011
|
-
`analyzeTsDocCoverage: failed to read tsconfig at ${absoluteTsconfig}: ${
|
|
29482
|
+
`analyzeTsDocCoverage: failed to read tsconfig at ${absoluteTsconfig}: ${ts2.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
|
|
29012
29483
|
);
|
|
29013
29484
|
}
|
|
29014
|
-
const parsed =
|
|
29485
|
+
const parsed = ts2.parseJsonConfigFileContent(
|
|
29015
29486
|
configFile.config,
|
|
29016
|
-
|
|
29017
|
-
|
|
29487
|
+
ts2.sys,
|
|
29488
|
+
path5.dirname(absoluteTsconfig)
|
|
29018
29489
|
);
|
|
29019
29490
|
return { ...parsed.options, noEmit: true };
|
|
29020
29491
|
}
|
|
29021
29492
|
return {
|
|
29022
|
-
target:
|
|
29023
|
-
module:
|
|
29024
|
-
moduleResolution:
|
|
29493
|
+
target: ts2.ScriptTarget.ESNext,
|
|
29494
|
+
module: ts2.ModuleKind.NodeNext,
|
|
29495
|
+
moduleResolution: ts2.ModuleResolutionKind.NodeNext,
|
|
29025
29496
|
allowJs: false,
|
|
29026
29497
|
declaration: false,
|
|
29027
29498
|
noEmit: true,
|
|
@@ -29046,7 +29517,7 @@ function resolveAlias(symbol, checker) {
|
|
|
29046
29517
|
return current;
|
|
29047
29518
|
}
|
|
29048
29519
|
function isAlias(symbol) {
|
|
29049
|
-
return (symbol.flags &
|
|
29520
|
+
return (symbol.flags & ts2.SymbolFlags.Alias) !== 0;
|
|
29050
29521
|
}
|
|
29051
29522
|
function pickPrimaryDeclaration(symbol) {
|
|
29052
29523
|
const declarations = symbol.getDeclarations();
|
|
@@ -29054,53 +29525,53 @@ function pickPrimaryDeclaration(symbol) {
|
|
|
29054
29525
|
return void 0;
|
|
29055
29526
|
}
|
|
29056
29527
|
const concrete = declarations.find(
|
|
29057
|
-
(d) => !
|
|
29528
|
+
(d) => !ts2.isExportSpecifier(d) && !ts2.isExportAssignment(d) && !ts2.isExportDeclaration(d)
|
|
29058
29529
|
);
|
|
29059
29530
|
return concrete ?? declarations[0];
|
|
29060
29531
|
}
|
|
29061
29532
|
function classifyDeclaration(declaration) {
|
|
29062
|
-
if (
|
|
29533
|
+
if (ts2.isClassDeclaration(declaration)) {
|
|
29063
29534
|
return TsDocCoverageKind.Class;
|
|
29064
29535
|
}
|
|
29065
|
-
if (
|
|
29536
|
+
if (ts2.isInterfaceDeclaration(declaration)) {
|
|
29066
29537
|
return TsDocCoverageKind.Interface;
|
|
29067
29538
|
}
|
|
29068
|
-
if (
|
|
29539
|
+
if (ts2.isTypeAliasDeclaration(declaration)) {
|
|
29069
29540
|
return TsDocCoverageKind.TypeAlias;
|
|
29070
29541
|
}
|
|
29071
|
-
if (
|
|
29542
|
+
if (ts2.isEnumDeclaration(declaration)) {
|
|
29072
29543
|
return TsDocCoverageKind.Enum;
|
|
29073
29544
|
}
|
|
29074
|
-
if (
|
|
29545
|
+
if (ts2.isFunctionDeclaration(declaration) || ts2.isMethodDeclaration(declaration)) {
|
|
29075
29546
|
return TsDocCoverageKind.Function;
|
|
29076
29547
|
}
|
|
29077
|
-
if (
|
|
29548
|
+
if (ts2.isVariableDeclaration(declaration) || ts2.isVariableStatement(declaration)) {
|
|
29078
29549
|
return TsDocCoverageKind.Variable;
|
|
29079
29550
|
}
|
|
29080
|
-
if (
|
|
29551
|
+
if (ts2.isModuleDeclaration(declaration)) {
|
|
29081
29552
|
return TsDocCoverageKind.Module;
|
|
29082
29553
|
}
|
|
29083
|
-
if (
|
|
29554
|
+
if (ts2.isExportAssignment(declaration)) {
|
|
29084
29555
|
return TsDocCoverageKind.Default;
|
|
29085
29556
|
}
|
|
29086
29557
|
return TsDocCoverageKind.Other;
|
|
29087
29558
|
}
|
|
29088
29559
|
function resolveLocation(declaration) {
|
|
29089
|
-
const target =
|
|
29560
|
+
const target = ts2.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
|
|
29090
29561
|
const source = target.getSourceFile();
|
|
29091
29562
|
const { line } = source.getLineAndCharacterOfPosition(target.getStart());
|
|
29092
29563
|
return { file: source.fileName, line: line + 1 };
|
|
29093
29564
|
}
|
|
29094
29565
|
function parseTsDocFor(declaration, parser) {
|
|
29095
|
-
const target =
|
|
29566
|
+
const target = ts2.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
|
|
29096
29567
|
const sourceText = target.getSourceFile().getFullText();
|
|
29097
|
-
const ranges =
|
|
29568
|
+
const ranges = ts2.getLeadingCommentRanges(sourceText, target.getFullStart());
|
|
29098
29569
|
if (!ranges || ranges.length === 0) {
|
|
29099
29570
|
return void 0;
|
|
29100
29571
|
}
|
|
29101
29572
|
for (let i = ranges.length - 1; i >= 0; i--) {
|
|
29102
29573
|
const range = ranges[i];
|
|
29103
|
-
if (range.kind !==
|
|
29574
|
+
if (range.kind !== ts2.SyntaxKind.MultiLineCommentTrivia) {
|
|
29104
29575
|
continue;
|
|
29105
29576
|
}
|
|
29106
29577
|
const text = sourceText.slice(range.pos, range.end);
|
|
@@ -29323,14 +29794,14 @@ var LAYOUT_ROOT_BY_PROJECT_TYPE = {
|
|
|
29323
29794
|
};
|
|
29324
29795
|
function validateMonorepoLayout(root) {
|
|
29325
29796
|
const violations = [];
|
|
29326
|
-
const rootOutdir =
|
|
29797
|
+
const rootOutdir = toPosix3(root.outdir);
|
|
29327
29798
|
for (const sub of root.subprojects) {
|
|
29328
29799
|
const className = sub.constructor.name;
|
|
29329
29800
|
const expectedRoot = expectedRootFor(sub, className);
|
|
29330
29801
|
if (expectedRoot === void 0) {
|
|
29331
29802
|
continue;
|
|
29332
29803
|
}
|
|
29333
|
-
const relOutdir = relativeOutdir(rootOutdir,
|
|
29804
|
+
const relOutdir = relativeOutdir(rootOutdir, toPosix3(sub.outdir));
|
|
29334
29805
|
if (!outdirMatchesRoot(relOutdir, expectedRoot)) {
|
|
29335
29806
|
violations.push({
|
|
29336
29807
|
projectName: sub.name,
|
|
@@ -29389,7 +29860,7 @@ function outdirMatchesRoot(relOutdir, expectedRoot) {
|
|
|
29389
29860
|
}
|
|
29390
29861
|
return segments.length >= 2;
|
|
29391
29862
|
}
|
|
29392
|
-
function
|
|
29863
|
+
function toPosix3(p) {
|
|
29393
29864
|
return p.replace(/\\/g, "/");
|
|
29394
29865
|
}
|
|
29395
29866
|
function relativeOutdir(rootOutdir, subOutdir) {
|
|
@@ -29478,8 +29949,8 @@ var ResetTask = class _ResetTask extends Component14 {
|
|
|
29478
29949
|
const resetTask = this.project.tasks.addTask(this.taskName, {
|
|
29479
29950
|
description: "Delete build artifacts specified by pathsToRemove option, or artifactsDirectory if pathsToRemove is empty"
|
|
29480
29951
|
});
|
|
29481
|
-
this.pathsToRemove.forEach((
|
|
29482
|
-
resetTask.exec(`[ -e "${
|
|
29952
|
+
this.pathsToRemove.forEach((path6) => {
|
|
29953
|
+
resetTask.exec(`[ -e "${path6}" ] && rm -rf ${path6} || true`);
|
|
29483
29954
|
});
|
|
29484
29955
|
const rootHasTurbo = TurboRepo.of(this.project.root) !== void 0;
|
|
29485
29956
|
const isSubproject = this.project !== this.project.root;
|
|
@@ -31387,7 +31858,7 @@ export const collections = {
|
|
|
31387
31858
|
`;
|
|
31388
31859
|
|
|
31389
31860
|
// src/typescript/typescript-config.ts
|
|
31390
|
-
import { relative as
|
|
31861
|
+
import { relative as relative6 } from "path";
|
|
31391
31862
|
import { Component as Component19 } from "projen";
|
|
31392
31863
|
import { ensureRelativePathStartsWithDot } from "projen/lib/util/path";
|
|
31393
31864
|
var TypeScriptConfig = class extends Component19 {
|
|
@@ -31406,7 +31877,7 @@ var TypeScriptConfig = class extends Component19 {
|
|
|
31406
31877
|
...tsPaths,
|
|
31407
31878
|
[dep.name]: [
|
|
31408
31879
|
ensureRelativePathStartsWithDot(
|
|
31409
|
-
|
|
31880
|
+
relative6(project.outdir, subproject.outdir)
|
|
31410
31881
|
)
|
|
31411
31882
|
]
|
|
31412
31883
|
};
|
|
@@ -31464,6 +31935,7 @@ export {
|
|
|
31464
31935
|
DEFAULT_PROGRESS_FILES_STATE_DIR,
|
|
31465
31936
|
DEFAULT_REQUIRE_LINKED_ISSUE,
|
|
31466
31937
|
DEFAULT_REQUIRE_PRODUCT_CONTEXT,
|
|
31938
|
+
DEFAULT_SAMPLE_COMPILER_OPTIONS,
|
|
31467
31939
|
DEFAULT_SCHEDULED_TASKS_ROOT,
|
|
31468
31940
|
DEFAULT_SCHEDULED_TASK_ENTRIES,
|
|
31469
31941
|
DEFAULT_SHARED_EDITING_CONFLICT_STRATEGY,
|
|
@@ -31509,6 +31981,7 @@ export {
|
|
|
31509
31981
|
SCOPE_CLASS_VALUES,
|
|
31510
31982
|
SHARED_EDITING_CONFLICT_STRATEGY_VALUES,
|
|
31511
31983
|
STARLIGHT_ROLE,
|
|
31984
|
+
SampleLang,
|
|
31512
31985
|
StarlightProject,
|
|
31513
31986
|
TestRunner,
|
|
31514
31987
|
TsDocCoverageKind,
|
|
@@ -31551,14 +32024,17 @@ export {
|
|
|
31551
32024
|
buildStandardsResearchBundle,
|
|
31552
32025
|
buildUnblockDependentsProcedure,
|
|
31553
32026
|
businessModelsBundle,
|
|
32027
|
+
checkDocSamplesProcedure,
|
|
31554
32028
|
checkLinksProcedure,
|
|
31555
32029
|
classifyIssueScope,
|
|
31556
32030
|
classifyRun,
|
|
31557
32031
|
companyProfileBundle,
|
|
32032
|
+
compileFencedSamples,
|
|
31558
32033
|
customerProfileBundle,
|
|
31559
32034
|
docsSyncBundle,
|
|
31560
32035
|
extractApiProcedure,
|
|
31561
32036
|
extractDocReferences,
|
|
32037
|
+
extractFencedSamples,
|
|
31562
32038
|
formatLayoutViolation,
|
|
31563
32039
|
formatStarlightSingletonViolation,
|
|
31564
32040
|
getLatestEligibleVersion,
|
|
@@ -31575,6 +32051,7 @@ export {
|
|
|
31575
32051
|
regulatoryResearchBundle,
|
|
31576
32052
|
renderAgentTierCaseStatement,
|
|
31577
32053
|
renderAgentTierSection,
|
|
32054
|
+
renderCheckDocSamplesProcedure,
|
|
31578
32055
|
renderCheckLinksProcedure,
|
|
31579
32056
|
renderCustomDocSectionBlock,
|
|
31580
32057
|
renderCustomDocSections,
|