@ng-doc/builder 22.0.0 → 22.1.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/engine/builders/helpers/get-playground-metadata.js +7 -1
- package/engine/builders/helpers/get-playground-metadata.js.map +1 -1
- package/engine/builders/page/demo-assets.builder.js +2 -0
- package/engine/builders/page/demo-assets.builder.js.map +1 -1
- package/engine/builders/shared/content.builder.js +2 -0
- package/engine/builders/shared/content.builder.js.map +1 -1
- package/engine/builders/shared/page-wrapper.builder.js +2 -0
- package/engine/builders/shared/page-wrapper.builder.js.map +1 -1
- package/generator/bootstrap/bin.js +27 -3
- package/generator/bootstrap/cli.js +27 -3
- package/generator/bootstrap/index.js +17 -3
- package/generator/build-metafile.json +529 -221
- package/generator/build-provenance.json +6 -4
- package/generator/compiler/index.d.ts +20 -0
- package/generator/compiler/index.js +1875 -625
- package/generator/compiler/plan.d.ts +24 -0
- package/generator/content/code-snippet.d.ts +20 -0
- package/generator/content/content-compiler.d.ts +5 -1
- package/generator/content/format-cache.d.ts +108 -0
- package/generator/content/highlight-cache.d.ts +12 -36
- package/generator/content/html-pipeline.d.ts +10 -1
- package/generator/content/html-pool.d.ts +8 -2
- package/generator/content/html-worker.js +622 -39
- package/generator/contracts.d.ts +39 -0
- package/generator/discovery/index.d.ts +2 -0
- package/generator/kernel/flags.d.ts +2 -0
- package/generator/outputs/index.d.ts +13 -0
- package/generator/semantic/angular.d.ts +21 -1
- package/generator/semantic/formatting.d.ts +27 -0
- package/generator/semantic/fragments.d.ts +11 -2
- package/generator/templates/api/class-declaration.html.nunj +5 -3
- package/generator/templates/demo-app.ts.nunj +37 -0
- package/generator/templates/demo-routes.ts.nunj +23 -0
- package/generator/templates/index.ts.nunj +5 -0
- package/generator/templates/page-wrapper.ts.nunj +6 -1
- package/generator/templates/page.ts.nunj +9 -2
- package/generator/templates/routes.ts.nunj +7 -3
- package/generator/templates/symbol/members.html.nunj +6 -4
- package/generator/templates/symbol/page.html.nunj +1 -1
- package/generator/vite/application-builder.js +6 -1
- package/generator/vite/application.d.ts +14 -0
- package/generator/vite/demo-application.d.ts +34 -0
- package/generator/vite/dev-server-builder.js +6 -1
- package/generator/vite/host-updates.d.ts +69 -2
- package/generator/vite/index.js +490 -130
- package/generator/vite/lifecycle.d.ts +1 -0
- package/generator/vite/prerender-entry.js +72 -2
- package/generator/vite/prerender-runtime.d.ts +13 -0
- package/generator/vite/prerender.d.ts +2 -0
- package/helpers/format-cache.d.ts +34 -0
- package/helpers/format-cache.js +26 -0
- package/helpers/format-cache.js.map +1 -0
- package/helpers/format-code.js +9 -2
- package/helpers/format-code.js.map +1 -1
- package/helpers/to-template-string.d.ts +5 -1
- package/helpers/to-template-string.js +7 -2
- package/helpers/to-template-string.js.map +1 -1
- package/interfaces/code-block-options.d.ts +5 -0
- package/interfaces/configuration.d.ts +84 -1
- package/package.json +5 -4
- package/parsers/parse-code-block-params.d.ts +10 -1
- package/parsers/parse-code-block-params.js +29 -3
- package/parsers/parse-code-block-params.js.map +1 -1
- package/schematics/collection.json +1 -1
- package/schematics/migrate-to-vite/analyze.js +46 -3
- package/schematics/migrate-to-vite/analyze.js.map +1 -1
- package/schematics/migrate-to-vite/setup/workspace.d.ts +5 -0
- package/schematics/migrate-to-vite/setup/workspace.js +20 -0
- package/schematics/migrate-to-vite/setup/workspace.js.map +1 -1
- package/schematics/migrate-to-vite/testing/fixtures.d.ts +12 -0
- package/schematics/migrate-to-vite/testing/fixtures.js +27 -0
- package/schematics/migrate-to-vite/testing/fixtures.js.map +1 -1
- package/schematics/vite-setup/index.d.ts +9 -5
- package/schematics/vite-setup/index.js +11 -5
- package/schematics/vite-setup/index.js.map +1 -1
- package/schematics/vite-setup/schema.json +1 -1
- package/templates/api/class-declaration.html.nunj +5 -3
- package/templates/demo-app.ts.nunj +37 -0
- package/templates/demo-routes.ts.nunj +23 -0
- package/templates/index.ts.nunj +5 -0
- package/templates/page-wrapper.ts.nunj +6 -1
- package/templates/page.ts.nunj +9 -2
- package/templates/routes.ts.nunj +7 -3
- package/templates/symbol/members.html.nunj +6 -4
- package/templates/symbol/page.html.nunj +1 -1
|
@@ -886,6 +886,329 @@ var init_helpers2 = __esm({
|
|
|
886
886
|
}
|
|
887
887
|
});
|
|
888
888
|
|
|
889
|
+
// libs/utils/html/plugins/keyword-positions.ts
|
|
890
|
+
function scanInlineCode(text) {
|
|
891
|
+
if (WHOLE_KEYWORD.test(text)) {
|
|
892
|
+
return { whole: true, position: () => REFERENCE };
|
|
893
|
+
}
|
|
894
|
+
if (HTML_START.test(text) || !(CODE_PUNCTUATION.test(text) || DECLARATION_START.test(text))) {
|
|
895
|
+
return void 0;
|
|
896
|
+
}
|
|
897
|
+
const scan = scanTypeScript(text);
|
|
898
|
+
return isProse(text, scan.masked) ? void 0 : scan;
|
|
899
|
+
}
|
|
900
|
+
function scanCodeBlock(text, mode) {
|
|
901
|
+
return mode === "html" ? scanHtml(text) : scanTypeScript(text);
|
|
902
|
+
}
|
|
903
|
+
function scanTypeScript(text) {
|
|
904
|
+
const masked = maskTypeScript(text);
|
|
905
|
+
const locals = localBindings(text, masked);
|
|
906
|
+
return {
|
|
907
|
+
whole: false,
|
|
908
|
+
masked,
|
|
909
|
+
position(start, end, key) {
|
|
910
|
+
if (masked[start] === TEMPLATE) {
|
|
911
|
+
const before = text[start - 1] ?? "";
|
|
912
|
+
const element = key.includes("-") && (before === "<" || before === "/" && text[start - 2] === "<");
|
|
913
|
+
const controlFlow = CONTROL_FLOW.test(key) && !WORD_CHARACTER.test(before);
|
|
914
|
+
return element || controlFlow ? REFERENCE : NOT_A_REFERENCE;
|
|
915
|
+
}
|
|
916
|
+
if (masked[start] !== CODE) {
|
|
917
|
+
return NOT_A_REFERENCE;
|
|
918
|
+
}
|
|
919
|
+
const previous = previousSignificant(text, start, masked);
|
|
920
|
+
const next = nextSignificant(text, end, masked);
|
|
921
|
+
const nextCharacter = text[next] ?? "";
|
|
922
|
+
if (SYNTAX_WORDS.has(key) || RESERVED_WORDS.has(key) && nextCharacter !== "(") {
|
|
923
|
+
return NOT_A_REFERENCE;
|
|
924
|
+
}
|
|
925
|
+
if (text[previous] === "." && text[previous - 1] !== ".") {
|
|
926
|
+
const ownerEnd = text[previous - 1] === "?" ? previous - 1 : previous;
|
|
927
|
+
const owner = text.slice(0, ownerEnd).match(IDENTIFIER_BEFORE)?.[0];
|
|
928
|
+
const word = text.slice(start, end);
|
|
929
|
+
return owner && !/[.#]/.test(word) ? { link: true, keyword: `${owner}.${key.toLowerCase()}` } : NOT_A_REFERENCE;
|
|
930
|
+
}
|
|
931
|
+
if (isDeclaredName(text, masked, previous, next)) {
|
|
932
|
+
return NOT_A_REFERENCE;
|
|
933
|
+
}
|
|
934
|
+
return locals.has(key) ? NOT_A_REFERENCE : REFERENCE;
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
function isDeclaredName(text, masked, previous, next) {
|
|
939
|
+
const after = text[next];
|
|
940
|
+
const afterNext = text[nextSignificant(text, next + 1, masked)];
|
|
941
|
+
if (after === ":" && text[next + 1] !== ":") {
|
|
942
|
+
const ternary = text[previous] === "?" && text[previous + 1] !== ".";
|
|
943
|
+
return !ternary && previousWord(text, previous) !== "case";
|
|
944
|
+
}
|
|
945
|
+
if ((after === "?" || after === "!") && afterNext === ":") {
|
|
946
|
+
return true;
|
|
947
|
+
}
|
|
948
|
+
if (after === "?" && (afterNext === ")" || afterNext === ",")) {
|
|
949
|
+
return true;
|
|
950
|
+
}
|
|
951
|
+
if (after === "=" && text[next + 1] !== "=" && text[next + 1] !== ">") {
|
|
952
|
+
return !TYPE_CONTEXT.includes(text[previous] ?? "") && !TYPE_WORDS.includes(previousWord(text, previous));
|
|
953
|
+
}
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
956
|
+
function scanHtml(text) {
|
|
957
|
+
const masked = maskHtml(text);
|
|
958
|
+
return {
|
|
959
|
+
whole: false,
|
|
960
|
+
position: (start) => masked[start] === CODE ? REFERENCE : NOT_A_REFERENCE
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
function maskTypeScript(text) {
|
|
964
|
+
const masked = new Uint8Array(text.length);
|
|
965
|
+
const templates = [];
|
|
966
|
+
let depth = 0;
|
|
967
|
+
let index = 0;
|
|
968
|
+
const string2 = (quote) => {
|
|
969
|
+
const start = index++;
|
|
970
|
+
while (index < text.length && text[index] !== quote && text[index] !== "\n") {
|
|
971
|
+
index += text[index] === "\\" ? 2 : 1;
|
|
972
|
+
}
|
|
973
|
+
masked.fill(STRING, start, Math.min(++index, text.length));
|
|
974
|
+
};
|
|
975
|
+
const template = () => {
|
|
976
|
+
const start = index++;
|
|
977
|
+
while (index < text.length && text[index] !== "`") {
|
|
978
|
+
if (text[index] === "\\") {
|
|
979
|
+
index += 2;
|
|
980
|
+
} else if (text[index] === "$" && text[index + 1] === "{") {
|
|
981
|
+
masked.fill(TEMPLATE, start, index);
|
|
982
|
+
templates.push(depth);
|
|
983
|
+
index += 2;
|
|
984
|
+
return;
|
|
985
|
+
} else {
|
|
986
|
+
index++;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
masked.fill(TEMPLATE, start, Math.min(++index, text.length));
|
|
990
|
+
};
|
|
991
|
+
while (index < text.length) {
|
|
992
|
+
const character = text[index];
|
|
993
|
+
if (character === "/" && text[index + 1] === "/") {
|
|
994
|
+
const end = text.indexOf("\n", index);
|
|
995
|
+
const stop = end < 0 ? text.length : end;
|
|
996
|
+
masked.fill(COMMENT, index, stop);
|
|
997
|
+
index = stop;
|
|
998
|
+
} else if (character === "/" && text[index + 1] === "*") {
|
|
999
|
+
const end = text.indexOf("*/", index + 2);
|
|
1000
|
+
const stop = end < 0 ? text.length : end + 2;
|
|
1001
|
+
masked.fill(COMMENT, index, stop);
|
|
1002
|
+
index = stop;
|
|
1003
|
+
} else if (character === "'" || character === '"') {
|
|
1004
|
+
string2(character);
|
|
1005
|
+
} else if (character === "`") {
|
|
1006
|
+
template();
|
|
1007
|
+
} else if (character === "{") {
|
|
1008
|
+
depth++;
|
|
1009
|
+
index++;
|
|
1010
|
+
} else if (character === "}") {
|
|
1011
|
+
if (templates.length && templates[templates.length - 1] === depth) {
|
|
1012
|
+
templates.pop();
|
|
1013
|
+
template();
|
|
1014
|
+
} else {
|
|
1015
|
+
depth--;
|
|
1016
|
+
index++;
|
|
1017
|
+
}
|
|
1018
|
+
} else {
|
|
1019
|
+
index++;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return masked;
|
|
1023
|
+
}
|
|
1024
|
+
function maskHtml(text) {
|
|
1025
|
+
const masked = new Uint8Array(text.length);
|
|
1026
|
+
let index = 0;
|
|
1027
|
+
while (index < text.length) {
|
|
1028
|
+
if (text.startsWith("<!--", index)) {
|
|
1029
|
+
const end = text.indexOf("-->", index + 4);
|
|
1030
|
+
const stop = end < 0 ? text.length : end + 3;
|
|
1031
|
+
masked.fill(COMMENT, index, stop);
|
|
1032
|
+
index = stop;
|
|
1033
|
+
} else if (text[index] === "<" && /[A-Za-z/]/.test(text[index + 1] ?? "")) {
|
|
1034
|
+
index = maskTag(text, index + 1, masked);
|
|
1035
|
+
} else {
|
|
1036
|
+
index++;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return masked;
|
|
1040
|
+
}
|
|
1041
|
+
function maskTag(text, index, masked) {
|
|
1042
|
+
while (index < text.length && text[index] !== ">") {
|
|
1043
|
+
if (text[index] !== "=") {
|
|
1044
|
+
index++;
|
|
1045
|
+
continue;
|
|
1046
|
+
}
|
|
1047
|
+
index++;
|
|
1048
|
+
while (text[index] === " " || text[index] === " " || text[index] === "\n") index++;
|
|
1049
|
+
const quote = text[index];
|
|
1050
|
+
const start = index;
|
|
1051
|
+
if (quote === '"' || quote === "'") {
|
|
1052
|
+
const end = text.indexOf(quote, index + 1);
|
|
1053
|
+
index = end < 0 ? text.length : end + 1;
|
|
1054
|
+
} else {
|
|
1055
|
+
while (index < text.length && !/[\s>]/.test(text[index] ?? "")) index++;
|
|
1056
|
+
}
|
|
1057
|
+
masked.fill(STRING, start, index);
|
|
1058
|
+
}
|
|
1059
|
+
return index + 1;
|
|
1060
|
+
}
|
|
1061
|
+
function localBindings(text, masked) {
|
|
1062
|
+
const names = /* @__PURE__ */ new Set();
|
|
1063
|
+
for (const match of text.matchAll(/\b(?:const|let|var)\s+([\p{L}_$][\p{L}\w$]*)/gu)) {
|
|
1064
|
+
if (!masked[match.index]) names.add(match[1] ?? "");
|
|
1065
|
+
}
|
|
1066
|
+
for (const match of text.matchAll(
|
|
1067
|
+
/\bimport\s+(?:type\s+)?([^;]*?)\s+from\s+(['"])\.{1,2}\/[^'"]*\2/gu
|
|
1068
|
+
)) {
|
|
1069
|
+
if (masked[match.index]) continue;
|
|
1070
|
+
for (const name of (match[1] ?? "").matchAll(
|
|
1071
|
+
/([\p{L}_$][\p{L}\w$]*)(?:\s+as\s+([\p{L}_$][\p{L}\w$]*))?/gu
|
|
1072
|
+
)) {
|
|
1073
|
+
const local = name[2] ?? name[1] ?? "";
|
|
1074
|
+
if (local !== "type" && local !== "as") names.add(local);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
return names;
|
|
1078
|
+
}
|
|
1079
|
+
function isProse(text, masked) {
|
|
1080
|
+
for (const match of text.matchAll(/[\p{L}_$][\p{L}\w$]*(?: [\p{L}_$][\p{L}\w$]*){2,}/gu)) {
|
|
1081
|
+
const words2 = match[0].split(" ");
|
|
1082
|
+
const plain = words2.filter((word) => !SYNTAX_WORDS.has(word) && !RESERVED_WORDS.has(word));
|
|
1083
|
+
if (!masked[match.index] && plain.length >= 3) {
|
|
1084
|
+
return true;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return false;
|
|
1088
|
+
}
|
|
1089
|
+
function previousSignificant(text, index, masked) {
|
|
1090
|
+
let position = index - 1;
|
|
1091
|
+
while (position >= 0 && insignificant(text, position, masked)) position--;
|
|
1092
|
+
return position;
|
|
1093
|
+
}
|
|
1094
|
+
function nextSignificant(text, index, masked) {
|
|
1095
|
+
let position = index;
|
|
1096
|
+
while (position < text.length && insignificant(text, position, masked)) position++;
|
|
1097
|
+
return position;
|
|
1098
|
+
}
|
|
1099
|
+
function insignificant(text, index, masked) {
|
|
1100
|
+
return masked[index] === COMMENT || /\s/.test(text[index] ?? "");
|
|
1101
|
+
}
|
|
1102
|
+
function previousWord(text, index) {
|
|
1103
|
+
let start = index;
|
|
1104
|
+
while (start >= 0 && WORD_CHARACTER.test(text[start] ?? "")) start--;
|
|
1105
|
+
return text.slice(start + 1, index + 1);
|
|
1106
|
+
}
|
|
1107
|
+
var WORD_CHARACTER, IDENTIFIER_BEFORE, WHOLE_KEYWORD, CODE_PUNCTUATION, DECLARATION_START, HTML_START, SYNTAX_WORDS, RESERVED_WORDS, TYPE_CONTEXT, TYPE_WORDS, CODE, STRING, COMMENT, TEMPLATE, CONTROL_FLOW, NOT_A_REFERENCE, REFERENCE;
|
|
1108
|
+
var init_keyword_positions = __esm({
|
|
1109
|
+
"libs/utils/html/plugins/keyword-positions.ts"() {
|
|
1110
|
+
"use strict";
|
|
1111
|
+
WORD_CHARACTER = /[*\p{L}\w$@-]/u;
|
|
1112
|
+
IDENTIFIER_BEFORE = /[\p{L}\w$@-]+$/u;
|
|
1113
|
+
WHOLE_KEYWORD = /^\s*[*\p{L}\w$@-]+(?:[.#][\p{L}\w-]+)?(?:\?[\w=&]+)?\s*$/u;
|
|
1114
|
+
CODE_PUNCTUATION = /[(){}[\]<>|:=@]/;
|
|
1115
|
+
DECLARATION_START = /^\s*(?:export|import|class|interface|type|const|let|var|function|enum|abstract|declare)\s/;
|
|
1116
|
+
HTML_START = /^\s*<\/?[A-Za-z]/;
|
|
1117
|
+
SYNTAX_WORDS = /* @__PURE__ */ new Set([
|
|
1118
|
+
"await",
|
|
1119
|
+
"break",
|
|
1120
|
+
"case",
|
|
1121
|
+
"catch",
|
|
1122
|
+
"continue",
|
|
1123
|
+
"debugger",
|
|
1124
|
+
"delete",
|
|
1125
|
+
"do",
|
|
1126
|
+
"else",
|
|
1127
|
+
"false",
|
|
1128
|
+
"finally",
|
|
1129
|
+
"for",
|
|
1130
|
+
"function",
|
|
1131
|
+
"if",
|
|
1132
|
+
"instanceof",
|
|
1133
|
+
"new",
|
|
1134
|
+
"null",
|
|
1135
|
+
"return",
|
|
1136
|
+
"super",
|
|
1137
|
+
"switch",
|
|
1138
|
+
"this",
|
|
1139
|
+
"throw",
|
|
1140
|
+
"true",
|
|
1141
|
+
"try",
|
|
1142
|
+
"typeof",
|
|
1143
|
+
"void",
|
|
1144
|
+
"while",
|
|
1145
|
+
"with",
|
|
1146
|
+
"yield"
|
|
1147
|
+
]);
|
|
1148
|
+
RESERVED_WORDS = /* @__PURE__ */ new Set([
|
|
1149
|
+
"abstract",
|
|
1150
|
+
"accessor",
|
|
1151
|
+
"any",
|
|
1152
|
+
"as",
|
|
1153
|
+
"asserts",
|
|
1154
|
+
"async",
|
|
1155
|
+
"bigint",
|
|
1156
|
+
"boolean",
|
|
1157
|
+
"class",
|
|
1158
|
+
"const",
|
|
1159
|
+
"constructor",
|
|
1160
|
+
"declare",
|
|
1161
|
+
"default",
|
|
1162
|
+
"enum",
|
|
1163
|
+
"export",
|
|
1164
|
+
"extends",
|
|
1165
|
+
"from",
|
|
1166
|
+
"get",
|
|
1167
|
+
"implements",
|
|
1168
|
+
"import",
|
|
1169
|
+
"in",
|
|
1170
|
+
"infer",
|
|
1171
|
+
"interface",
|
|
1172
|
+
"is",
|
|
1173
|
+
"keyof",
|
|
1174
|
+
"let",
|
|
1175
|
+
"module",
|
|
1176
|
+
"namespace",
|
|
1177
|
+
"never",
|
|
1178
|
+
"number",
|
|
1179
|
+
"object",
|
|
1180
|
+
"of",
|
|
1181
|
+
"out",
|
|
1182
|
+
"override",
|
|
1183
|
+
"package",
|
|
1184
|
+
"private",
|
|
1185
|
+
"protected",
|
|
1186
|
+
"public",
|
|
1187
|
+
"readonly",
|
|
1188
|
+
"require",
|
|
1189
|
+
"satisfies",
|
|
1190
|
+
"set",
|
|
1191
|
+
"static",
|
|
1192
|
+
"string",
|
|
1193
|
+
"symbol",
|
|
1194
|
+
"type",
|
|
1195
|
+
"undefined",
|
|
1196
|
+
"unique",
|
|
1197
|
+
"unknown",
|
|
1198
|
+
"var"
|
|
1199
|
+
]);
|
|
1200
|
+
TYPE_CONTEXT = [":", "|", "&", "<"];
|
|
1201
|
+
TYPE_WORDS = ["type", "extends", "keyof", "typeof"];
|
|
1202
|
+
CODE = 0;
|
|
1203
|
+
STRING = 1;
|
|
1204
|
+
COMMENT = 2;
|
|
1205
|
+
TEMPLATE = 3;
|
|
1206
|
+
CONTROL_FLOW = /^@[a-z]+$/;
|
|
1207
|
+
NOT_A_REFERENCE = Object.freeze({ link: false });
|
|
1208
|
+
REFERENCE = Object.freeze({ link: true });
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
|
|
889
1212
|
// libs/utils/html/plugins/keywords.plugin.ts
|
|
890
1213
|
import { isElement as isElement5 } from "hast-util-is-element";
|
|
891
1214
|
import { toString } from "hast-util-to-string";
|
|
@@ -897,23 +1220,50 @@ function keywordsPlugin(config) {
|
|
|
897
1220
|
}
|
|
898
1221
|
const isInlineCode = !isElement5(ancestors[ancestors.length - 1], "pre");
|
|
899
1222
|
const lang = asArray(node.properties?.["className"] ?? []).find((className) => className.startsWith("language-"))?.replace("language-", "") ?? "";
|
|
900
|
-
if (isInlineCode
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
Array.prototype.splice.apply(parent.children, [index, 1].concat(nodes));
|
|
909
|
-
return [SKIP, index + nodes.length];
|
|
910
|
-
});
|
|
1223
|
+
if (!isInlineCode && !LANGUAGES.includes(lang)) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
const offsets = textOffsets(node);
|
|
1227
|
+
const text = Array.from(offsets.keys()).map((textNode) => textNode.value).join("");
|
|
1228
|
+
const scan = isInlineCode ? scanInlineCode(text) : scanCodeBlock(text, HTML_LANGUAGES.includes(lang) ? "html" : "typescript");
|
|
1229
|
+
if (!scan) {
|
|
1230
|
+
return;
|
|
911
1231
|
}
|
|
1232
|
+
visitParents(node, "text", (node2, ancestors2) => {
|
|
1233
|
+
if (hasLinkAncestor(ancestors2)) {
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
const parent = ancestors2[ancestors2.length - 1];
|
|
1237
|
+
const index = parent.children.indexOf(node2);
|
|
1238
|
+
const nodes = getNodes(
|
|
1239
|
+
node2,
|
|
1240
|
+
parent,
|
|
1241
|
+
isInlineCode,
|
|
1242
|
+
config,
|
|
1243
|
+
lang,
|
|
1244
|
+
scan,
|
|
1245
|
+
offsets.get(node2) ?? 0
|
|
1246
|
+
);
|
|
1247
|
+
Array.prototype.splice.apply(parent.children, [index, 1].concat(nodes));
|
|
1248
|
+
return [SKIP, index + nodes.length];
|
|
1249
|
+
});
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
function textOffsets(node) {
|
|
1253
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
1254
|
+
let offset = 0;
|
|
1255
|
+
visitParents(node, "text", (text) => {
|
|
1256
|
+
offsets.set(text, offset);
|
|
1257
|
+
offset += text.value.length;
|
|
912
1258
|
});
|
|
1259
|
+
return offsets;
|
|
913
1260
|
}
|
|
914
|
-
function getNodes(node, parent, isInlineCode, config, language) {
|
|
1261
|
+
function getNodes(node, parent, isInlineCode, config, language, scan, offset) {
|
|
915
1262
|
const { addUsedKeyword, getKeyword } = config;
|
|
1263
|
+
let start = offset;
|
|
916
1264
|
return toString(node).split(SPLIT_REGEXP).map((word) => {
|
|
1265
|
+
const wordStart = start;
|
|
1266
|
+
start += word.length;
|
|
917
1267
|
const match = word.match(MATCH_KEYWORD_REGEXP);
|
|
918
1268
|
if (!match) {
|
|
919
1269
|
return { type: "text", value: word };
|
|
@@ -924,8 +1274,13 @@ function getNodes(node, parent, isInlineCode, config, language) {
|
|
|
924
1274
|
anchor = "",
|
|
925
1275
|
queryParams = ""
|
|
926
1276
|
} = match.groups;
|
|
927
|
-
const
|
|
928
|
-
|
|
1277
|
+
const position = scan.position(wordStart, wordStart + word.length, key);
|
|
1278
|
+
if (!position.link) {
|
|
1279
|
+
return { type: "text", value: word };
|
|
1280
|
+
}
|
|
1281
|
+
const isMember = position.keyword !== void 0;
|
|
1282
|
+
const usedKeyword = position.keyword ?? `${key}${delimiter}${anchor?.toLowerCase()}`;
|
|
1283
|
+
const rootKeyword2 = isMember ? void 0 : getKeyword?.(key);
|
|
929
1284
|
const keyword = getKeyword?.(usedKeyword);
|
|
930
1285
|
const isGuideKeyword = key.startsWith("*");
|
|
931
1286
|
const isLanguageAllowed = !keyword?.languages && ALWAYS_ALLOWED_LANGUAGES.includes(language) || !!keyword?.languages?.includes(language);
|
|
@@ -938,7 +1293,7 @@ function getNodes(node, parent, isInlineCode, config, language) {
|
|
|
938
1293
|
addUsedKeyword?.(usedKeyword);
|
|
939
1294
|
const notFoundGuideKeyword = isGuideKeyword && !keyword;
|
|
940
1295
|
const notFoundApiAnchorKeyword = !!rootKeyword2 && !!anchor && !keyword;
|
|
941
|
-
if (getKeyword &&
|
|
1296
|
+
if (getKeyword && scan.whole && (notFoundGuideKeyword || notFoundApiAnchorKeyword)) {
|
|
942
1297
|
throw new Error(`Route with keyword "${word}" is missing.`);
|
|
943
1298
|
}
|
|
944
1299
|
if (parent.properties) {
|
|
@@ -954,7 +1309,7 @@ function getNodes(node, parent, isInlineCode, config, language) {
|
|
|
954
1309
|
}
|
|
955
1310
|
}
|
|
956
1311
|
return keyword ? createLinkNode(
|
|
957
|
-
isInlineCode ? keyword.title : word,
|
|
1312
|
+
isInlineCode && !isMember ? keyword.title : word,
|
|
958
1313
|
keyword.path,
|
|
959
1314
|
keyword.type,
|
|
960
1315
|
keyword.description
|
|
@@ -974,14 +1329,16 @@ function createLinkNode(text, href, type, description) {
|
|
|
974
1329
|
children: [{ type: "text", value: text }]
|
|
975
1330
|
};
|
|
976
1331
|
}
|
|
977
|
-
var ALWAYS_ALLOWED_LANGUAGES, LANGUAGES, SPLIT_REGEXP, MATCH_KEYWORD_REGEXP;
|
|
1332
|
+
var ALWAYS_ALLOWED_LANGUAGES, HTML_LANGUAGES, LANGUAGES, SPLIT_REGEXP, MATCH_KEYWORD_REGEXP;
|
|
978
1333
|
var init_keywords_plugin = __esm({
|
|
979
1334
|
"libs/utils/html/plugins/keywords.plugin.ts"() {
|
|
980
1335
|
"use strict";
|
|
981
1336
|
init_core();
|
|
982
1337
|
init_helpers2();
|
|
1338
|
+
init_keyword_positions();
|
|
983
1339
|
ALWAYS_ALLOWED_LANGUAGES = ["typescript", "ts", "angular-ts"];
|
|
984
|
-
|
|
1340
|
+
HTML_LANGUAGES = [...KEYWORD_ALLOWED_LANGUAGES];
|
|
1341
|
+
LANGUAGES = [...ALWAYS_ALLOWED_LANGUAGES, ...HTML_LANGUAGES];
|
|
985
1342
|
SPLIT_REGEXP = /([*\p{L}\w$@-]+(?:[.#][\p{L}\w-]+)?(?:\?[\w=&]+)?)/u;
|
|
986
1343
|
MATCH_KEYWORD_REGEXP = /(?<key>[*\p{L}\w$@-]+)((?<delimiter>[.#])(?<anchor>[\p{L}\w-]+))?(?<queryParams>\?[\w=&]+)?/u;
|
|
987
1344
|
}
|
|
@@ -1039,13 +1396,14 @@ var init_add_heading_anchors_plugin = __esm({
|
|
|
1039
1396
|
});
|
|
1040
1397
|
|
|
1041
1398
|
// libs/utils/html/plugins/cached-shiki.plugin.ts
|
|
1042
|
-
import rehypeShiki from "@shikijs/rehype";
|
|
1043
1399
|
import { toString as toString2 } from "hast-util-to-string";
|
|
1044
1400
|
import { visit as visit2 } from "unist-util-visit";
|
|
1045
1401
|
function cachedShikiPlugin(settings2) {
|
|
1046
|
-
const { cache, themes, identity, defaultLanguage } = settings2;
|
|
1402
|
+
const { cache, themes, languages, identity, defaultLanguage } = settings2;
|
|
1047
1403
|
const id = `${themes.light}
|
|
1048
|
-
${themes.dark}
|
|
1404
|
+
${themes.dark}
|
|
1405
|
+
${languages ?? ""}
|
|
1406
|
+
${settings2.grammars ?? "all"}`;
|
|
1049
1407
|
return async (tree2) => {
|
|
1050
1408
|
const blocks = [];
|
|
1051
1409
|
visit2(tree2, "element", (node, index, parent) => {
|
|
@@ -1062,11 +1420,18 @@ ${themes.dark}`;
|
|
|
1062
1420
|
blocks.push({
|
|
1063
1421
|
node,
|
|
1064
1422
|
parent,
|
|
1065
|
-
key: cache.key({
|
|
1423
|
+
key: cache.key({
|
|
1424
|
+
options: identity,
|
|
1425
|
+
themes,
|
|
1426
|
+
...languages === void 0 ? {} : { languages },
|
|
1427
|
+
lang,
|
|
1428
|
+
meta,
|
|
1429
|
+
code
|
|
1430
|
+
})
|
|
1066
1431
|
});
|
|
1067
1432
|
});
|
|
1068
1433
|
let highlighter;
|
|
1069
|
-
const load = async () => highlighter ??= await highlighterFor(id, settings2.
|
|
1434
|
+
const load = async () => highlighter ??= await highlighterFor(id, settings2.transformer);
|
|
1070
1435
|
if (cache.loads?.(themes) !== true) await load();
|
|
1071
1436
|
const values = [];
|
|
1072
1437
|
for (const block of blocks) {
|
|
@@ -1087,13 +1452,11 @@ ${themes.dark}`;
|
|
|
1087
1452
|
});
|
|
1088
1453
|
};
|
|
1089
1454
|
}
|
|
1090
|
-
function highlighterFor(id,
|
|
1455
|
+
function highlighterFor(id, transformer) {
|
|
1091
1456
|
const known3 = highlighters.get(id);
|
|
1092
1457
|
if (known3) return known3;
|
|
1093
1458
|
const created = (async () => {
|
|
1094
|
-
const transform =
|
|
1095
|
-
options()
|
|
1096
|
-
);
|
|
1459
|
+
const transform = transformer();
|
|
1097
1460
|
await transform({ type: "root", children: [] });
|
|
1098
1461
|
return transform;
|
|
1099
1462
|
})();
|
|
@@ -1111,11 +1474,18 @@ async function highlight(transform, node) {
|
|
|
1111
1474
|
function fragment(value) {
|
|
1112
1475
|
try {
|
|
1113
1476
|
const parsed = JSON.parse(value);
|
|
1114
|
-
return Array.isArray(parsed) && parsed.length > 0 && parsed.every(
|
|
1477
|
+
return Array.isArray(parsed) && parsed.length > 0 && parsed.every(isReplacement) ? parsed : void 0;
|
|
1115
1478
|
} catch {
|
|
1116
1479
|
return void 0;
|
|
1117
1480
|
}
|
|
1118
1481
|
}
|
|
1482
|
+
function isReplacement(value) {
|
|
1483
|
+
if (isNode(value)) return value.type === "element";
|
|
1484
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1485
|
+
const node = value;
|
|
1486
|
+
const children = node["children"];
|
|
1487
|
+
return node["type"] === "root" && Array.isArray(children) && children.length > 0 && children.every((child) => isNode(child) && child.type === "element");
|
|
1488
|
+
}
|
|
1119
1489
|
function isNode(value) {
|
|
1120
1490
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1121
1491
|
const node = value;
|
|
@@ -1308,11 +1678,158 @@ var init_table_wrapper = __esm({
|
|
|
1308
1678
|
}
|
|
1309
1679
|
});
|
|
1310
1680
|
|
|
1681
|
+
// libs/utils/html/shiki-grammars.ts
|
|
1682
|
+
import {
|
|
1683
|
+
bundledLanguages,
|
|
1684
|
+
createHighlighter
|
|
1685
|
+
} from "shiki";
|
|
1686
|
+
import { visit as visit7 } from "unist-util-visit";
|
|
1687
|
+
function shikiGrammars() {
|
|
1688
|
+
grammars ??= ShikiGrammars.create().catch((error) => {
|
|
1689
|
+
grammars = void 0;
|
|
1690
|
+
throw error;
|
|
1691
|
+
});
|
|
1692
|
+
return grammars;
|
|
1693
|
+
}
|
|
1694
|
+
function createGrammarlessHighlighter(themes) {
|
|
1695
|
+
return createHighlighter({ themes, langs: [] });
|
|
1696
|
+
}
|
|
1697
|
+
function blockLanguages(tree2, defaultLanguage) {
|
|
1698
|
+
const languages = /* @__PURE__ */ new Set();
|
|
1699
|
+
visit7(tree2, "element", (node) => {
|
|
1700
|
+
if (node.tagName !== "pre") return;
|
|
1701
|
+
const head = node.children[0];
|
|
1702
|
+
if (!head || head.type !== "element" || head.tagName !== "code" || !head.properties) return;
|
|
1703
|
+
const classes = head.properties["className"];
|
|
1704
|
+
const languageClass = Array.isArray(classes) ? classes.find((item) => typeof item === "string" && item.startsWith(languagePrefix2)) : void 0;
|
|
1705
|
+
languages.add(
|
|
1706
|
+
typeof languageClass === "string" ? languageClass.slice(languagePrefix2.length) : defaultLanguage
|
|
1707
|
+
);
|
|
1708
|
+
});
|
|
1709
|
+
return languages;
|
|
1710
|
+
}
|
|
1711
|
+
function includedScopes(registration) {
|
|
1712
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
1713
|
+
const walk = (value) => {
|
|
1714
|
+
if (Array.isArray(value)) value.forEach(walk);
|
|
1715
|
+
else if (value && typeof value === "object")
|
|
1716
|
+
for (const [key, item] of Object.entries(value)) {
|
|
1717
|
+
if (key === "include" && typeof item === "string") {
|
|
1718
|
+
if (!item.startsWith("#") && !item.startsWith("$")) scopes.add(item.split("#")[0]);
|
|
1719
|
+
} else walk(item);
|
|
1720
|
+
}
|
|
1721
|
+
};
|
|
1722
|
+
walk(registration);
|
|
1723
|
+
return scopes;
|
|
1724
|
+
}
|
|
1725
|
+
function prefixes(scope) {
|
|
1726
|
+
const parts = scope.split(".");
|
|
1727
|
+
return parts.map((_, index) => parts.slice(0, index + 1).join("."));
|
|
1728
|
+
}
|
|
1729
|
+
var ShikiGrammars, grammars, languagePrefix2;
|
|
1730
|
+
var init_shiki_grammars = __esm({
|
|
1731
|
+
"libs/utils/html/shiki-grammars.ts"() {
|
|
1732
|
+
"use strict";
|
|
1733
|
+
ShikiGrammars = class _ShikiGrammars {
|
|
1734
|
+
constructor(registrations) {
|
|
1735
|
+
this.byName = /* @__PURE__ */ new Map();
|
|
1736
|
+
this.byScope = /* @__PURE__ */ new Map();
|
|
1737
|
+
this.injectors = /* @__PURE__ */ new Map();
|
|
1738
|
+
this.order = /* @__PURE__ */ new Map();
|
|
1739
|
+
this.closures = /* @__PURE__ */ new Map();
|
|
1740
|
+
this.loaded = /* @__PURE__ */ new WeakMap();
|
|
1741
|
+
const mention = (name) => {
|
|
1742
|
+
if (!this.order.has(name)) this.order.set(name, this.order.size);
|
|
1743
|
+
};
|
|
1744
|
+
for (const registration of registrations) {
|
|
1745
|
+
mention(registration.name);
|
|
1746
|
+
for (const embedded of registration.embeddedLangs ?? []) mention(embedded);
|
|
1747
|
+
if (this.byScope.has(registration.scopeName)) continue;
|
|
1748
|
+
this.byScope.set(registration.scopeName, registration);
|
|
1749
|
+
this.byName.set(registration.name, registration);
|
|
1750
|
+
for (const alias of registration.aliases ?? []) this.byName.set(alias, registration);
|
|
1751
|
+
for (const target of registration.injectTo ?? []) {
|
|
1752
|
+
const list = this.injectors.get(target) ?? [];
|
|
1753
|
+
list.push(registration);
|
|
1754
|
+
this.injectors.set(target, list);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* The bundled grammars, in the order `@shikijs/rehype` registers them: every bundled language
|
|
1760
|
+
* name, each with the registrations of its module.
|
|
1761
|
+
*/
|
|
1762
|
+
static async create() {
|
|
1763
|
+
const modules = await Promise.all(
|
|
1764
|
+
Object.keys(bundledLanguages).map(
|
|
1765
|
+
(name) => bundledLanguages[name]()
|
|
1766
|
+
)
|
|
1767
|
+
);
|
|
1768
|
+
return new _ShikiGrammars(modules.flatMap((module) => module.default));
|
|
1769
|
+
}
|
|
1770
|
+
/**
|
|
1771
|
+
* The grammars that a block of `language` can reach, in registration order; empty for a
|
|
1772
|
+
* language that no bundled grammar names (it falls back to plain text, as before).
|
|
1773
|
+
* @param language
|
|
1774
|
+
*/
|
|
1775
|
+
closure(language) {
|
|
1776
|
+
const known3 = this.closures.get(language);
|
|
1777
|
+
if (known3) return known3;
|
|
1778
|
+
const set = /* @__PURE__ */ new Set();
|
|
1779
|
+
const queue = [this.byName.get(language)];
|
|
1780
|
+
while (queue.length) {
|
|
1781
|
+
const registration = queue.pop();
|
|
1782
|
+
if (!registration || set.has(registration)) continue;
|
|
1783
|
+
set.add(registration);
|
|
1784
|
+
for (const name of [
|
|
1785
|
+
...registration.embeddedLangs ?? [],
|
|
1786
|
+
...registration.embeddedLangsLazy ?? []
|
|
1787
|
+
])
|
|
1788
|
+
queue.push(this.byName.get(name));
|
|
1789
|
+
for (const scope of includedScopes(registration)) queue.push(this.byScope.get(scope));
|
|
1790
|
+
for (const prefix of prefixes(registration.scopeName))
|
|
1791
|
+
queue.push(...this.injectors.get(prefix) ?? []);
|
|
1792
|
+
for (const target of registration.injectTo ?? [])
|
|
1793
|
+
queue.push(...this.injectors.get(target) ?? []);
|
|
1794
|
+
}
|
|
1795
|
+
const closure = [...set].sort(
|
|
1796
|
+
(left, right) => this.order.get(left.name) - this.order.get(right.name)
|
|
1797
|
+
);
|
|
1798
|
+
this.closures.set(language, closure);
|
|
1799
|
+
return closure;
|
|
1800
|
+
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Loads the closures of `languages` that `highlighter` does not hold yet.
|
|
1803
|
+
* @param highlighter
|
|
1804
|
+
* @param languages
|
|
1805
|
+
*/
|
|
1806
|
+
load(highlighter, languages) {
|
|
1807
|
+
let loaded = this.loaded.get(highlighter);
|
|
1808
|
+
if (!loaded) this.loaded.set(highlighter, loaded = /* @__PURE__ */ new Set());
|
|
1809
|
+
const missing = /* @__PURE__ */ new Set();
|
|
1810
|
+
for (const language of languages)
|
|
1811
|
+
for (const registration of this.closure(language))
|
|
1812
|
+
if (!loaded.has(registration.name)) missing.add(registration);
|
|
1813
|
+
if (!missing.size) return;
|
|
1814
|
+
const batch = [...missing].sort(
|
|
1815
|
+
(left, right) => this.order.get(left.name) - this.order.get(right.name)
|
|
1816
|
+
);
|
|
1817
|
+
highlighter.loadLanguageSync(batch);
|
|
1818
|
+
for (const registration of batch) loaded.add(registration.name);
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
languagePrefix2 = "language-";
|
|
1822
|
+
}
|
|
1823
|
+
});
|
|
1824
|
+
|
|
1311
1825
|
// libs/utils/html/process-html.ts
|
|
1312
|
-
import
|
|
1826
|
+
import rehypeShiki from "@shikijs/rehype";
|
|
1827
|
+
import rehypeShikiFromHighlighter from "@shikijs/rehype/core";
|
|
1828
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
1313
1829
|
import rehypeMinifyWhitespace2 from "rehype-minify-whitespace";
|
|
1314
1830
|
import rehypeParse3 from "rehype-parse";
|
|
1315
1831
|
import rehypeStringify3 from "rehype-stringify";
|
|
1832
|
+
import { bundledLanguages as bundledLanguages2, createHighlighter as createHighlighter2 } from "shiki";
|
|
1316
1833
|
import { unified as unified3 } from "unified";
|
|
1317
1834
|
async function processHtml(html, config) {
|
|
1318
1835
|
const anchors = /* @__PURE__ */ new Set();
|
|
@@ -1320,6 +1837,8 @@ async function processHtml(html, config) {
|
|
|
1320
1837
|
light: config.lightTheme ?? "github-light",
|
|
1321
1838
|
dark: config.darkTheme ?? "ayu-dark"
|
|
1322
1839
|
};
|
|
1840
|
+
const langs = config.langs?.length ? config.langs : void 0;
|
|
1841
|
+
const used = !langs && config.grammars === "used";
|
|
1323
1842
|
try {
|
|
1324
1843
|
const content = await unified3().use(rehypeParse3, { fragment: true }).use(rehypeStringify3).use(mermaidPlugin).use(
|
|
1325
1844
|
config.highlight ? [
|
|
@@ -1328,12 +1847,16 @@ async function processHtml(html, config) {
|
|
|
1328
1847
|
{
|
|
1329
1848
|
cache: config.highlight,
|
|
1330
1849
|
themes,
|
|
1850
|
+
...langs ? { languages: languagesId(langs) } : {},
|
|
1851
|
+
...used ? { grammars: "used" } : {},
|
|
1331
1852
|
identity: HIGHLIGHT_IDENTITY,
|
|
1332
1853
|
defaultLanguage: DEFAULT_LANGUAGE,
|
|
1333
|
-
|
|
1854
|
+
transformer: () => langs ? withLanguages(themes, langs) : used ? withUsedGrammars(themes) : rehypeShiki(
|
|
1855
|
+
shikiOptions(themes)
|
|
1856
|
+
)
|
|
1334
1857
|
}
|
|
1335
1858
|
]
|
|
1336
|
-
] : [[
|
|
1859
|
+
] : langs ? [[() => withLanguages(themes, langs)]] : used ? [[() => withUsedGrammars(themes)]] : [[rehypeShiki, shikiOptions(themes)]]
|
|
1337
1860
|
).use(highlightCodeLines).use(table_wrapper_default).use(sluggerPlugin, anchors.add.bind(anchors), config.headings).use(rehypeMinifyWhitespace2).use(addHeadingAnchors, config.route).use(markElementsPlugin).process(html).then((file) => file.toString());
|
|
1338
1861
|
return { content, anchors: Array.from(anchors) };
|
|
1339
1862
|
} catch (error) {
|
|
@@ -1359,7 +1882,59 @@ function shikiOptions(themes) {
|
|
|
1359
1882
|
function shikiTheme(name) {
|
|
1360
1883
|
return name === NG_DOC_SYNTAX_THEME_NAME ? ngDocSyntaxTheme() : name;
|
|
1361
1884
|
}
|
|
1362
|
-
|
|
1885
|
+
function languagesId(langs) {
|
|
1886
|
+
let id = languageIds.get(langs);
|
|
1887
|
+
if (id === void 0) {
|
|
1888
|
+
id = createHash2("sha256").update(JSON.stringify(langs)).digest("hex");
|
|
1889
|
+
languageIds.set(langs, id);
|
|
1890
|
+
}
|
|
1891
|
+
return id;
|
|
1892
|
+
}
|
|
1893
|
+
function withLanguages(themes, langs) {
|
|
1894
|
+
const id = `${themes.light}
|
|
1895
|
+
${themes.dark}
|
|
1896
|
+
${languagesId(langs)}`;
|
|
1897
|
+
return async (tree2) => {
|
|
1898
|
+
let highlighter = languageHighlighters.get(id);
|
|
1899
|
+
if (!highlighter) {
|
|
1900
|
+
highlighter = createHighlighter2({
|
|
1901
|
+
themes: [shikiTheme(themes.light), shikiTheme(themes.dark)],
|
|
1902
|
+
// Later registrations of a name replace earlier ones, so the given languages win.
|
|
1903
|
+
langs: [...Object.keys(bundledLanguages2), ...langs]
|
|
1904
|
+
});
|
|
1905
|
+
languageHighlighters.set(id, highlighter);
|
|
1906
|
+
const created = highlighter;
|
|
1907
|
+
created.catch(() => {
|
|
1908
|
+
if (languageHighlighters.get(id) === created) languageHighlighters.delete(id);
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
const transform = rehypeShikiFromHighlighter(await highlighter, shikiOptions(themes));
|
|
1912
|
+
await transform(tree2);
|
|
1913
|
+
};
|
|
1914
|
+
}
|
|
1915
|
+
function withUsedGrammars(themes) {
|
|
1916
|
+
const id = `${themes.light}
|
|
1917
|
+
${themes.dark}`;
|
|
1918
|
+
return async (tree2) => {
|
|
1919
|
+
let highlighter = usedHighlighters.get(id);
|
|
1920
|
+
if (!highlighter) {
|
|
1921
|
+
highlighter = createGrammarlessHighlighter([
|
|
1922
|
+
shikiTheme(themes.light),
|
|
1923
|
+
shikiTheme(themes.dark)
|
|
1924
|
+
]);
|
|
1925
|
+
usedHighlighters.set(id, highlighter);
|
|
1926
|
+
const created = highlighter;
|
|
1927
|
+
created.catch(() => {
|
|
1928
|
+
if (usedHighlighters.get(id) === created) usedHighlighters.delete(id);
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1931
|
+
const [grammars2, ready] = await Promise.all([shikiGrammars(), highlighter]);
|
|
1932
|
+
grammars2.load(ready, blockLanguages(tree2, DEFAULT_LANGUAGE));
|
|
1933
|
+
const transform = rehypeShikiFromHighlighter(ready, shikiOptions(themes));
|
|
1934
|
+
await transform(tree2);
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
var DEFAULT_LANGUAGE, HIGHLIGHT_IDENTITY, languageHighlighters, languageIds, usedHighlighters;
|
|
1363
1938
|
var init_process_html = __esm({
|
|
1364
1939
|
"libs/utils/html/process-html.ts"() {
|
|
1365
1940
|
"use strict";
|
|
@@ -1371,24 +1946,28 @@ var init_process_html = __esm({
|
|
|
1371
1946
|
init_mermaid_plugin();
|
|
1372
1947
|
init_slugger_plugin();
|
|
1373
1948
|
init_table_wrapper();
|
|
1949
|
+
init_shiki_grammars();
|
|
1374
1950
|
DEFAULT_LANGUAGE = "ts";
|
|
1375
1951
|
HIGHLIGHT_IDENTITY = {
|
|
1376
|
-
format:
|
|
1952
|
+
format: 2,
|
|
1377
1953
|
defaultLanguage: DEFAULT_LANGUAGE,
|
|
1378
1954
|
fallbackLanguage: "text",
|
|
1379
1955
|
addLanguageClass: true,
|
|
1380
1956
|
parseMetaString: "json-without-backslashes",
|
|
1381
1957
|
tokenizeTimeLimit: 0
|
|
1382
1958
|
};
|
|
1959
|
+
languageHighlighters = /* @__PURE__ */ new Map();
|
|
1960
|
+
languageIds = /* @__PURE__ */ new WeakMap();
|
|
1961
|
+
usedHighlighters = /* @__PURE__ */ new Map();
|
|
1383
1962
|
}
|
|
1384
1963
|
});
|
|
1385
1964
|
|
|
1386
1965
|
// libs/utils/html/plugins/remove-not-indexable-content.plugin.ts
|
|
1387
1966
|
import { filter } from "unist-util-filter";
|
|
1388
|
-
import { visit as
|
|
1967
|
+
import { visit as visit8 } from "unist-util-visit";
|
|
1389
1968
|
function removeNotIndexableContentPlugin() {
|
|
1390
1969
|
return (tree2) => {
|
|
1391
|
-
|
|
1970
|
+
visit8(tree2, "element", (node) => {
|
|
1392
1971
|
if (isHeading(node) && isHiddenSpan(node.children[0])) {
|
|
1393
1972
|
node.children = node.children.slice(1);
|
|
1394
1973
|
}
|
|
@@ -1469,8 +2048,7 @@ var init_utils = __esm({
|
|
|
1469
2048
|
}
|
|
1470
2049
|
});
|
|
1471
2050
|
|
|
1472
|
-
// libs/builder/generator/content/
|
|
1473
|
-
init_core();
|
|
2051
|
+
// libs/builder/generator/content/format-cache.ts
|
|
1474
2052
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
1475
2053
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
1476
2054
|
import { mkdir as mkdir3, rename as rename3, rm as rm3, writeFile as writeFile3 } from "node:fs/promises";
|
|
@@ -1525,24 +2103,24 @@ function sha256Hex(value) {
|
|
|
1525
2103
|
function canonicalJson(value) {
|
|
1526
2104
|
return canonical(value, /* @__PURE__ */ new Set()) ?? "null";
|
|
1527
2105
|
}
|
|
1528
|
-
function canonical(value,
|
|
2106
|
+
function canonical(value, path18) {
|
|
1529
2107
|
if (value !== null && typeof value === "object" && typeof value.toJSON === "function")
|
|
1530
2108
|
value = value.toJSON();
|
|
1531
2109
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
1532
|
-
if (
|
|
1533
|
-
|
|
2110
|
+
if (path18.has(value)) throw new TypeError("Converting circular structure to canonical JSON");
|
|
2111
|
+
path18.add(value);
|
|
1534
2112
|
let text;
|
|
1535
2113
|
if (Array.isArray(value)) {
|
|
1536
|
-
text = `[${Array.from(value, (item) => canonical(item,
|
|
2114
|
+
text = `[${Array.from(value, (item) => canonical(item, path18) ?? "null").join(",")}]`;
|
|
1537
2115
|
} else {
|
|
1538
2116
|
const fields = [];
|
|
1539
2117
|
for (const key of Object.keys(value).sort(compareCodeUnits)) {
|
|
1540
|
-
const item = canonical(value[key],
|
|
2118
|
+
const item = canonical(value[key], path18);
|
|
1541
2119
|
if (item !== void 0) fields.push(`${JSON.stringify(key)}:${item}`);
|
|
1542
2120
|
}
|
|
1543
2121
|
text = `{${fields.join(",")}}`;
|
|
1544
2122
|
}
|
|
1545
|
-
|
|
2123
|
+
path18.delete(value);
|
|
1546
2124
|
return text;
|
|
1547
2125
|
}
|
|
1548
2126
|
function canonicalJsonStrict(value) {
|
|
@@ -1649,16 +2227,16 @@ var ObservationRecorder = class {
|
|
|
1649
2227
|
* file does not exist; a read error propagates.
|
|
1650
2228
|
*/
|
|
1651
2229
|
readFile(file) {
|
|
1652
|
-
const
|
|
1653
|
-
let bytes = this.bytes?.get(
|
|
2230
|
+
const path18 = this.normalize(file);
|
|
2231
|
+
let bytes = this.bytes?.get(path18);
|
|
1654
2232
|
const exists = bytes !== void 0 || existsSync(file);
|
|
1655
|
-
this.add({ kind: "existence", path:
|
|
2233
|
+
this.add({ kind: "existence", path: path18, exists });
|
|
1656
2234
|
if (!exists) return void 0;
|
|
1657
2235
|
if (!bytes) {
|
|
1658
2236
|
bytes = readFileSync(file);
|
|
1659
|
-
this.bytes?.set(
|
|
2237
|
+
this.bytes?.set(path18, bytes);
|
|
1660
2238
|
}
|
|
1661
|
-
this.add({ kind: "content", path:
|
|
2239
|
+
this.add({ kind: "content", path: path18, digest: bytesDigest(bytes) });
|
|
1662
2240
|
return bytes;
|
|
1663
2241
|
}
|
|
1664
2242
|
/** {@link readFile} decoded as UTF-8; a missing file throws like `readFileSync`. */
|
|
@@ -1673,12 +2251,12 @@ var ObservationRecorder = class {
|
|
|
1673
2251
|
return this.ordered.map(cloneDependency);
|
|
1674
2252
|
}
|
|
1675
2253
|
};
|
|
1676
|
-
function readText(
|
|
1677
|
-
const bytes = readFileSync(
|
|
2254
|
+
function readText(path18) {
|
|
2255
|
+
const bytes = readFileSync(path18);
|
|
1678
2256
|
return { text: bytes.toString("utf8"), digest: bytesDigest(bytes) };
|
|
1679
2257
|
}
|
|
1680
|
-
async function readTextFile(
|
|
1681
|
-
const bytes = await readFile(
|
|
2258
|
+
async function readTextFile(path18) {
|
|
2259
|
+
const bytes = await readFile(path18);
|
|
1682
2260
|
return { text: bytes.toString("utf8"), digest: bytesDigest(bytes) };
|
|
1683
2261
|
}
|
|
1684
2262
|
function cloneDependency(dependency) {
|
|
@@ -2134,9 +2712,9 @@ var ObservationStamps = class {
|
|
|
2134
2712
|
result.changed = { path: dependency.path, kind: "content" };
|
|
2135
2713
|
return result;
|
|
2136
2714
|
}
|
|
2137
|
-
const
|
|
2715
|
+
const current2 = stampOf(dependency.path);
|
|
2138
2716
|
const recorded = this.stamps.get(dependency.path);
|
|
2139
|
-
if (
|
|
2717
|
+
if (current2 && recorded && sameStamp(current2, recorded)) {
|
|
2140
2718
|
result.stamped += 1;
|
|
2141
2719
|
continue;
|
|
2142
2720
|
}
|
|
@@ -2144,7 +2722,7 @@ var ObservationStamps = class {
|
|
|
2144
2722
|
this.stamps.delete(dependency.path);
|
|
2145
2723
|
let digest3;
|
|
2146
2724
|
try {
|
|
2147
|
-
digest3 =
|
|
2725
|
+
digest3 = current2 ? this.digestOf(dependency.path) : void 0;
|
|
2148
2726
|
} catch {
|
|
2149
2727
|
digest3 = void 0;
|
|
2150
2728
|
}
|
|
@@ -2153,7 +2731,7 @@ var ObservationStamps = class {
|
|
|
2153
2731
|
return result;
|
|
2154
2732
|
}
|
|
2155
2733
|
const after = stampOf(dependency.path);
|
|
2156
|
-
if (
|
|
2734
|
+
if (current2 && after && sameStamp(current2, after) && stampSettledBefore(after, startedNs)) {
|
|
2157
2735
|
this.stamps.set(dependency.path, after);
|
|
2158
2736
|
}
|
|
2159
2737
|
}
|
|
@@ -2298,8 +2876,8 @@ var DirectoryListings = class _DirectoryListings {
|
|
|
2298
2876
|
result.changed = listing.path;
|
|
2299
2877
|
return result;
|
|
2300
2878
|
}
|
|
2301
|
-
const
|
|
2302
|
-
if (
|
|
2879
|
+
const current2 = directoryStamp(listing.path);
|
|
2880
|
+
if (current2 && listing.stamp && sameStamp(current2, listing.stamp)) {
|
|
2303
2881
|
result.stamped += 1;
|
|
2304
2882
|
continue;
|
|
2305
2883
|
}
|
|
@@ -2310,7 +2888,7 @@ var DirectoryListings = class _DirectoryListings {
|
|
|
2310
2888
|
return result;
|
|
2311
2889
|
}
|
|
2312
2890
|
const after = directoryStamp(listing.path);
|
|
2313
|
-
if (
|
|
2891
|
+
if (current2 && after && sameStamp(current2, after) && stampSettledBefore(after, startedNs)) {
|
|
2314
2892
|
listing.stamp = after;
|
|
2315
2893
|
}
|
|
2316
2894
|
}
|
|
@@ -2612,9 +3190,9 @@ var ReasonCollector = class {
|
|
|
2612
3190
|
}
|
|
2613
3191
|
add(ownerId, reason, detail) {
|
|
2614
3192
|
const key = `${ownerId}\0${reason}`;
|
|
2615
|
-
const
|
|
2616
|
-
|
|
2617
|
-
this.reasons.set(key,
|
|
3193
|
+
const current2 = this.reasons.get(key) ?? { ownerId, reason, details: /* @__PURE__ */ new Set() };
|
|
3194
|
+
current2.details.add(detail);
|
|
3195
|
+
this.reasons.set(key, current2);
|
|
2618
3196
|
}
|
|
2619
3197
|
values() {
|
|
2620
3198
|
return [...this.reasons.values()].map(({ ownerId, reason, details }) => ({
|
|
@@ -3002,9 +3580,11 @@ function isRoute(value) {
|
|
|
3002
3580
|
"metadata",
|
|
3003
3581
|
"category",
|
|
3004
3582
|
"modulePath",
|
|
3005
|
-
"apiListSegment"
|
|
3583
|
+
"apiListSegment",
|
|
3584
|
+
"demoModulePath",
|
|
3585
|
+
"demoNames"
|
|
3006
3586
|
]
|
|
3007
|
-
) && [value.id, value.path, value.title].every(string) && (value.parentId === void 0 || string(value.parentId)) && (value.order === void 0 || finite(value.order)) && (value.hidden === void 0 || typeof value.hidden === "boolean") && (value.icon === void 0 || string(value.icon)) && (value.modulePath === void 0 || string(value.modulePath)) && (value.apiListSegment === void 0 || string(value.apiListSegment)) && (value.metadata === void 0 || isRecord(value.metadata) && exact(value.metadata, ["description", "tags"]) && string(value.metadata.description) && isRecord(value.metadata.tags) && Object.values(value.metadata.tags).every(stringArray)) && (value.category === void 0 || isRecord(value.category) && exact(value.category, ["runtimeImport"], ["expandable", "expanded"]) && isRecord(value.category.runtimeImport) && exact(value.category.runtimeImport, ["source", "exportName"]) && string(value.category.runtimeImport.source) && string(value.category.runtimeImport.exportName) && (value.category.expandable === void 0 || typeof value.category.expandable === "boolean") && (value.category.expanded === void 0 || typeof value.category.expanded === "boolean"));
|
|
3587
|
+
) && [value.id, value.path, value.title].every(string) && (value.parentId === void 0 || string(value.parentId)) && (value.order === void 0 || finite(value.order)) && (value.hidden === void 0 || typeof value.hidden === "boolean") && (value.icon === void 0 || string(value.icon)) && (value.modulePath === void 0 || string(value.modulePath)) && (value.apiListSegment === void 0 || string(value.apiListSegment)) && (value.demoModulePath === void 0 || string(value.demoModulePath)) && (value.demoNames === void 0 || stringArray(value.demoNames)) && (value.metadata === void 0 || isRecord(value.metadata) && exact(value.metadata, ["description", "tags"]) && string(value.metadata.description) && isRecord(value.metadata.tags) && Object.values(value.metadata.tags).every(stringArray)) && (value.category === void 0 || isRecord(value.category) && exact(value.category, ["runtimeImport"], ["expandable", "expanded"]) && isRecord(value.category.runtimeImport) && exact(value.category.runtimeImport, ["source", "exportName"]) && string(value.category.runtimeImport.source) && string(value.category.runtimeImport.exportName) && (value.category.expandable === void 0 || typeof value.category.expandable === "boolean") && (value.category.expanded === void 0 || typeof value.category.expanded === "boolean"));
|
|
3008
3588
|
}
|
|
3009
3589
|
function isApiList(value) {
|
|
3010
3590
|
return isRecord(value) && exact(
|
|
@@ -3100,18 +3680,18 @@ function validDescriptorPlan(artifact) {
|
|
|
3100
3680
|
const closures = new Map(descriptors.map((descriptor) => [descriptor.id, descriptor.closureIds]));
|
|
3101
3681
|
const visiting = /* @__PURE__ */ new Set();
|
|
3102
3682
|
const visited2 = /* @__PURE__ */ new Set();
|
|
3103
|
-
const
|
|
3683
|
+
const visit9 = (id) => {
|
|
3104
3684
|
if (visiting.has(id)) return false;
|
|
3105
3685
|
if (visited2.has(id)) return true;
|
|
3106
3686
|
visiting.add(id);
|
|
3107
3687
|
const valid = (closures.get(id) ?? []).every(
|
|
3108
|
-
(dependency) => ids.has(dependency) &&
|
|
3688
|
+
(dependency) => ids.has(dependency) && visit9(dependency)
|
|
3109
3689
|
);
|
|
3110
3690
|
visiting.delete(id);
|
|
3111
3691
|
visited2.add(id);
|
|
3112
3692
|
return valid;
|
|
3113
3693
|
};
|
|
3114
|
-
return [...ids].every(
|
|
3694
|
+
return [...ids].every(visit9);
|
|
3115
3695
|
}
|
|
3116
3696
|
function absoluteNormalizedPath(value) {
|
|
3117
3697
|
if (!string(value) || value.includes("\0") || value.includes("\\")) return false;
|
|
@@ -3358,7 +3938,9 @@ var TRACKED_PROGRAM_REUSE_FLAG = "NGDOC_TRACKED_PROGRAM_REUSE";
|
|
|
3358
3938
|
var FAST_START_FLAG = "NGDOC_FAST_START";
|
|
3359
3939
|
var PARALLEL_WRITES_FLAG = "NGDOC_PARALLEL_WRITES";
|
|
3360
3940
|
var HIGHLIGHT_CACHE_FLAG = "NGDOC_HIGHLIGHT_CACHE";
|
|
3941
|
+
var FORMAT_CACHE_FLAG = "NGDOC_FORMAT_CACHE";
|
|
3361
3942
|
var PARALLEL_RENDER_FLAG = "NGDOC_PARALLEL_RENDER";
|
|
3943
|
+
var USED_GRAMMARS_FLAG = "NGDOC_USED_GRAMMARS";
|
|
3362
3944
|
var FLAGS = Object.freeze(
|
|
3363
3945
|
[
|
|
3364
3946
|
{
|
|
@@ -3436,6 +4018,16 @@ var FLAGS = Object.freeze(
|
|
|
3436
4018
|
description: "Code blocks are highlighted with one Shiki highlighter per runtime and cached by their text, language, meta, themes and Shiki version; development keeps the cache beside the artifact cache.",
|
|
3437
4019
|
verify: true
|
|
3438
4020
|
},
|
|
4021
|
+
{
|
|
4022
|
+
name: FORMAT_CACHE_FLAG,
|
|
4023
|
+
description: "The Prettier configuration is resolved once per generation, and formatted signatures and snippets are cached by their code, parser, configuration and Prettier version; development keeps the cache beside the artifact cache.",
|
|
4024
|
+
verify: true
|
|
4025
|
+
},
|
|
4026
|
+
{
|
|
4027
|
+
name: USED_GRAMMARS_FLAG,
|
|
4028
|
+
description: "Code blocks are highlighted by a highlighter that loads only the Shiki grammars their languages reach, instead of every bundled grammar; the HTML is the same.",
|
|
4029
|
+
verify: false
|
|
4030
|
+
},
|
|
3439
4031
|
{
|
|
3440
4032
|
name: PARALLEL_RENDER_FLAG,
|
|
3441
4033
|
description: "A large generation runs the HTML processing of its pages (highlighting, anchors, keyword links, search records) on up to four worker threads, while the main thread prepares the next pages in order.",
|
|
@@ -3481,6 +4073,10 @@ var RUNTIME_PACKAGES = [
|
|
|
3481
4073
|
["@shikijs/rehype"],
|
|
3482
4074
|
["shiki", "@shikijs/rehype"],
|
|
3483
4075
|
["@shikijs/core", "shiki"],
|
|
4076
|
+
["@shikijs/langs", "shiki"],
|
|
4077
|
+
["@shikijs/themes", "shiki"],
|
|
4078
|
+
["@shikijs/engine-oniguruma", "shiki"],
|
|
4079
|
+
["@shikijs/vscode-textmate", "@shikijs/core"],
|
|
3484
4080
|
["marked"],
|
|
3485
4081
|
["gray-matter"],
|
|
3486
4082
|
["nunjucks"],
|
|
@@ -3519,10 +4115,10 @@ function packageVersions(list, from) {
|
|
|
3519
4115
|
return versions;
|
|
3520
4116
|
}
|
|
3521
4117
|
function packageDirectory(name, directory) {
|
|
3522
|
-
for (let
|
|
3523
|
-
const candidate = path4.join(
|
|
4118
|
+
for (let current2 = directory; ; current2 = path4.dirname(current2)) {
|
|
4119
|
+
const candidate = path4.join(current2, "node_modules", name);
|
|
3524
4120
|
if (existsSync3(path4.join(candidate, "package.json"))) return candidate;
|
|
3525
|
-
if (path4.dirname(
|
|
4121
|
+
if (path4.dirname(current2) === current2) return void 0;
|
|
3526
4122
|
}
|
|
3527
4123
|
}
|
|
3528
4124
|
function packageVersion(directory) {
|
|
@@ -3535,15 +4131,28 @@ function packageVersion(directory) {
|
|
|
3535
4131
|
}
|
|
3536
4132
|
}
|
|
3537
4133
|
|
|
3538
|
-
// libs/builder/generator/content/
|
|
3539
|
-
var
|
|
4134
|
+
// libs/builder/generator/content/format-cache.ts
|
|
4135
|
+
var FORMAT_CACHE_MISMATCH = "CONTENT_FORMAT_CACHE_MISMATCH";
|
|
3540
4136
|
var PACK_VERSION = 1;
|
|
3541
|
-
var
|
|
4137
|
+
var SYNTAX_ERROR = "!";
|
|
4138
|
+
function encode(format) {
|
|
4139
|
+
try {
|
|
4140
|
+
return `=${format()}`;
|
|
4141
|
+
} catch (error) {
|
|
4142
|
+
if (error instanceof Error && error.name === "SyntaxError" && "loc" in error)
|
|
4143
|
+
return SYNTAX_ERROR;
|
|
4144
|
+
throw error;
|
|
4145
|
+
}
|
|
4146
|
+
}
|
|
4147
|
+
function decode(entry) {
|
|
4148
|
+
if (entry === SYNTAX_ERROR)
|
|
4149
|
+
throw new SyntaxError("Prettier rejected this code before (format cache).");
|
|
4150
|
+
return entry.slice(1);
|
|
4151
|
+
}
|
|
4152
|
+
var PRETTIER_PACKAGES = ["prettier", "@prettier/sync"];
|
|
4153
|
+
var FORMAT_CACHE_LIMIT = 16 * 1024 * 1024;
|
|
3542
4154
|
var memory = /* @__PURE__ */ new Map();
|
|
3543
4155
|
var memoryBytes = 0;
|
|
3544
|
-
var journal = [];
|
|
3545
|
-
var epoch = 0;
|
|
3546
|
-
var proven = /* @__PURE__ */ new Set();
|
|
3547
4156
|
var packs = /* @__PURE__ */ new Map();
|
|
3548
4157
|
var sizeOf = (key, value) => key.length + value.length;
|
|
3549
4158
|
function remember(key, value) {
|
|
@@ -3551,11 +4160,213 @@ function remember(key, value) {
|
|
|
3551
4160
|
if (previous !== void 0) memoryBytes -= sizeOf(key, previous);
|
|
3552
4161
|
memory.set(key, value);
|
|
3553
4162
|
memoryBytes += sizeOf(key, value);
|
|
4163
|
+
}
|
|
4164
|
+
function formatCacheSwitch(options) {
|
|
4165
|
+
if (options.formatCache === false) return "off";
|
|
4166
|
+
const value = readFlag(FORMAT_CACHE_FLAG).value;
|
|
4167
|
+
return value === "off" ? "off" : options.formatCache === "verify" ? "verify" : value;
|
|
4168
|
+
}
|
|
4169
|
+
function createFormatSession(options, request, configuration) {
|
|
4170
|
+
const mode = formatCacheSwitch(options);
|
|
4171
|
+
if (mode === "off" || options.incrementalReuse === false) return void 0;
|
|
4172
|
+
const pack = request.mode === "development" && configuration.cacheEnabled ? path5.join(configuration.cacheRoot, `${digestOf(options.projectId)}.format.json`) : void 0;
|
|
4173
|
+
return new FormatSession(mode === "verify", pack);
|
|
4174
|
+
}
|
|
4175
|
+
var FormatSession = class {
|
|
4176
|
+
constructor(verify, pack) {
|
|
4177
|
+
this.verify = verify;
|
|
4178
|
+
this.pack = pack;
|
|
4179
|
+
/** The keys this generation hit or formatted. */
|
|
4180
|
+
this.used = /* @__PURE__ */ new Set();
|
|
4181
|
+
/** The resolved configuration per directory (`''` for the process's working directory). */
|
|
4182
|
+
this.configs = /* @__PURE__ */ new Map();
|
|
4183
|
+
/** Each resolved configuration's identity in the keys; undefined: not cacheable. */
|
|
4184
|
+
this.identities = /* @__PURE__ */ new Map();
|
|
4185
|
+
this.loaded = false;
|
|
4186
|
+
/** An entry was replaced (a `verify` repair): the pack must be written. */
|
|
4187
|
+
this.replaced = false;
|
|
4188
|
+
this.mismatchCount = 0;
|
|
4189
|
+
const engine = runtimePackages();
|
|
4190
|
+
this.context = digestOf({
|
|
4191
|
+
version: PACK_VERSION,
|
|
4192
|
+
engine: Object.fromEntries(PRETTIER_PACKAGES.map((name) => [name, engine[name] ?? null]))
|
|
4193
|
+
});
|
|
4194
|
+
if (memoryBytes > FORMAT_CACHE_LIMIT) {
|
|
4195
|
+
memory.clear();
|
|
4196
|
+
memoryBytes = 0;
|
|
4197
|
+
packs.clear();
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
/** How many `verify` hits and configurations differed from the cached ones. */
|
|
4201
|
+
get mismatches() {
|
|
4202
|
+
return this.mismatchCount;
|
|
4203
|
+
}
|
|
4204
|
+
config(configDirectory, resolve10) {
|
|
4205
|
+
const directory = configDirectory ?? "";
|
|
4206
|
+
if (this.configs.has(directory)) {
|
|
4207
|
+
const known3 = this.configs.get(directory);
|
|
4208
|
+
if (!this.verify) return known3;
|
|
4209
|
+
const fresh = resolve10();
|
|
4210
|
+
if (canonicalJsonStrict(fresh) === canonicalJsonStrict(known3)) return known3;
|
|
4211
|
+
this.mismatchCount += 1;
|
|
4212
|
+
return this.remember(directory, configDirectory, fresh);
|
|
4213
|
+
}
|
|
4214
|
+
return this.remember(directory, configDirectory, resolve10());
|
|
4215
|
+
}
|
|
4216
|
+
format(input, format) {
|
|
4217
|
+
const identity = this.identities.get(input.config);
|
|
4218
|
+
if (identity === void 0) return format();
|
|
4219
|
+
this.load();
|
|
4220
|
+
const key = digestOf({
|
|
4221
|
+
context: this.context,
|
|
4222
|
+
parser: input.parser,
|
|
4223
|
+
config: identity,
|
|
4224
|
+
code: input.code
|
|
4225
|
+
});
|
|
4226
|
+
const known3 = memory.get(key);
|
|
4227
|
+
const usable = known3 !== void 0 && (known3 === SYNTAX_ERROR || known3.startsWith("="));
|
|
4228
|
+
if (usable && !this.verify) {
|
|
4229
|
+
this.used.add(key);
|
|
4230
|
+
return decode(known3);
|
|
4231
|
+
}
|
|
4232
|
+
const value = encode(format);
|
|
4233
|
+
if (known3 !== void 0 && known3 !== value) {
|
|
4234
|
+
if (usable) this.mismatchCount += 1;
|
|
4235
|
+
this.replaced = true;
|
|
4236
|
+
}
|
|
4237
|
+
if (known3 !== value) remember(key, value);
|
|
4238
|
+
this.used.add(key);
|
|
4239
|
+
return decode(value);
|
|
4240
|
+
}
|
|
4241
|
+
/**
|
|
4242
|
+
* Writes the pack after the artifact cache: the entries this generation hit or formatted, plus
|
|
4243
|
+
* those the pack held before unless the generation rendered every content (`complete`), or the
|
|
4244
|
+
* result would exceed {@link FORMAT_CACHE_LIMIT}. Best effort.
|
|
4245
|
+
* @param complete
|
|
4246
|
+
*/
|
|
4247
|
+
async save(complete) {
|
|
4248
|
+
if (!this.pack) return;
|
|
4249
|
+
if (!this.loaded) return;
|
|
4250
|
+
const file = this.pack;
|
|
4251
|
+
const last = packs.get(file);
|
|
4252
|
+
const previous = !complete && last?.context === this.context ? last.keys : [];
|
|
4253
|
+
let selected = new Set([...previous, ...this.used].filter((key) => memory.has(key)));
|
|
4254
|
+
const size = (keys2) => {
|
|
4255
|
+
let total = 0;
|
|
4256
|
+
for (const key of keys2) total += sizeOf(key, memory.get(key));
|
|
4257
|
+
return total;
|
|
4258
|
+
};
|
|
4259
|
+
if (size(selected) > FORMAT_CACHE_LIMIT)
|
|
4260
|
+
selected = new Set([...this.used].filter((key) => memory.has(key)));
|
|
4261
|
+
const keys = [...selected].sort(compareCodeUnits);
|
|
4262
|
+
if (!this.replaced && last?.context === this.context && last.keys.length === keys.length && last.keys.every((key, index) => key === keys[index]) && last.content === currentContent2(file))
|
|
4263
|
+
return;
|
|
4264
|
+
const content = {
|
|
4265
|
+
version: PACK_VERSION,
|
|
4266
|
+
context: this.context,
|
|
4267
|
+
entries: Object.fromEntries(keys.map((key) => [key, memory.get(key)]))
|
|
4268
|
+
};
|
|
4269
|
+
const text = JSON.stringify(content);
|
|
4270
|
+
const temporary = `${file}.${randomUUID3()}.tmp`;
|
|
4271
|
+
try {
|
|
4272
|
+
await mkdir3(path5.dirname(file), { recursive: true });
|
|
4273
|
+
await sweepTemporaries(file);
|
|
4274
|
+
await writeFile3(temporary, text, { flag: "wx" });
|
|
4275
|
+
await retryingRename(rename3)(temporary, file);
|
|
4276
|
+
packs.set(file, { context: this.context, keys, content: contentDigest(text) });
|
|
4277
|
+
this.replaced = false;
|
|
4278
|
+
} catch {
|
|
4279
|
+
packs.delete(file);
|
|
4280
|
+
} finally {
|
|
4281
|
+
await rm3(temporary, { force: true }).catch(() => void 0);
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
remember(directory, configDirectory, config) {
|
|
4285
|
+
const frozen = config && Object.isFrozen(config) ? config : config && Object.freeze(config);
|
|
4286
|
+
this.configs.set(directory, frozen);
|
|
4287
|
+
if (!this.identities.has(frozen))
|
|
4288
|
+
this.identities.set(frozen, identityOf(frozen, configDirectory));
|
|
4289
|
+
return frozen;
|
|
4290
|
+
}
|
|
4291
|
+
/** Reads the pack once per runtime and context; an unusable pack is not read. */
|
|
4292
|
+
load() {
|
|
4293
|
+
if (this.loaded) return;
|
|
4294
|
+
this.loaded = true;
|
|
4295
|
+
if (!this.pack || packs.get(this.pack)?.context === this.context) return;
|
|
4296
|
+
try {
|
|
4297
|
+
const bytes = readFileSync5(this.pack);
|
|
4298
|
+
const value = JSON.parse(bytes.toString("utf8"));
|
|
4299
|
+
if (!isPackFile(value) || value.context !== this.context) return;
|
|
4300
|
+
const keys = Object.keys(value.entries).sort(compareCodeUnits);
|
|
4301
|
+
for (const key of keys) if (!memory.has(key)) remember(key, value.entries[key]);
|
|
4302
|
+
packs.set(this.pack, { context: this.context, keys, content: bytesDigest(bytes) });
|
|
4303
|
+
} catch {
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
};
|
|
4307
|
+
function identityOf(config, configDirectory) {
|
|
4308
|
+
const json = canonicalJsonStrict(config);
|
|
4309
|
+
if (json === void 0) return void 0;
|
|
4310
|
+
const plugins = Array.isArray(config?.plugins) ? config.plugins : [];
|
|
4311
|
+
const versions = {};
|
|
4312
|
+
for (const plugin of plugins) {
|
|
4313
|
+
if (typeof plugin !== "string" || plugin.startsWith(".") || path5.isAbsolute(plugin))
|
|
4314
|
+
return void 0;
|
|
4315
|
+
const version = packageVersions([[plugin]], configDirectory ?? process.cwd())[plugin];
|
|
4316
|
+
if (!version) return void 0;
|
|
4317
|
+
versions[plugin] = version;
|
|
4318
|
+
}
|
|
4319
|
+
return digestOf({ config: json, plugins: versions });
|
|
4320
|
+
}
|
|
4321
|
+
function currentContent2(file) {
|
|
4322
|
+
try {
|
|
4323
|
+
return bytesDigest(readFileSync5(file));
|
|
4324
|
+
} catch {
|
|
4325
|
+
return void 0;
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
function isPackFile(value) {
|
|
4329
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
4330
|
+
const file = value;
|
|
4331
|
+
const entries = file["entries"];
|
|
4332
|
+
return file["version"] === PACK_VERSION && typeof file["context"] === "string" && !!entries && typeof entries === "object" && !Array.isArray(entries) && Object.values(entries).every((entry) => typeof entry === "string");
|
|
4333
|
+
}
|
|
4334
|
+
|
|
4335
|
+
// libs/builder/generator/content/highlight-cache.ts
|
|
4336
|
+
init_core();
|
|
4337
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
4338
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
4339
|
+
import { mkdir as mkdir4, rename as rename4, rm as rm4, writeFile as writeFile4 } from "node:fs/promises";
|
|
4340
|
+
import path6 from "node:path";
|
|
4341
|
+
var SHIKI_PACKAGES = [
|
|
4342
|
+
"shiki",
|
|
4343
|
+
"@shikijs/core",
|
|
4344
|
+
"@shikijs/langs",
|
|
4345
|
+
"@shikijs/themes",
|
|
4346
|
+
"@shikijs/engine-oniguruma",
|
|
4347
|
+
"@shikijs/vscode-textmate",
|
|
4348
|
+
"@shikijs/rehype"
|
|
4349
|
+
];
|
|
4350
|
+
var HIGHLIGHT_CACHE_MISMATCH = "CONTENT_HIGHLIGHT_CACHE_MISMATCH";
|
|
4351
|
+
var PACK_VERSION2 = 1;
|
|
4352
|
+
var HIGHLIGHT_CACHE_LIMIT = 64 * 1024 * 1024;
|
|
4353
|
+
var memory2 = /* @__PURE__ */ new Map();
|
|
4354
|
+
var memoryBytes2 = 0;
|
|
4355
|
+
var journal = [];
|
|
4356
|
+
var epoch = 0;
|
|
4357
|
+
var proven = /* @__PURE__ */ new Set();
|
|
4358
|
+
var packs2 = /* @__PURE__ */ new Map();
|
|
4359
|
+
var sizeOf2 = (key, value) => key.length + value.length;
|
|
4360
|
+
function remember2(key, value) {
|
|
4361
|
+
const previous = memory2.get(key);
|
|
4362
|
+
if (previous !== void 0) memoryBytes2 -= sizeOf2(key, previous);
|
|
4363
|
+
memory2.set(key, value);
|
|
4364
|
+
memoryBytes2 += sizeOf2(key, value);
|
|
3554
4365
|
journal.push([key, value]);
|
|
3555
4366
|
}
|
|
3556
4367
|
function forget() {
|
|
3557
|
-
|
|
3558
|
-
|
|
4368
|
+
memory2.clear();
|
|
4369
|
+
memoryBytes2 = 0;
|
|
3559
4370
|
journal.length = 0;
|
|
3560
4371
|
epoch += 1;
|
|
3561
4372
|
}
|
|
@@ -3567,14 +4378,22 @@ function highlightCacheSwitch(options) {
|
|
|
3567
4378
|
const value = readFlag(HIGHLIGHT_CACHE_FLAG).value;
|
|
3568
4379
|
return value === "off" ? "off" : options.highlightCache === "verify" ? "verify" : value;
|
|
3569
4380
|
}
|
|
4381
|
+
function grammarsSwitch(options) {
|
|
4382
|
+
return options.usedGrammars === false || readFlag(USED_GRAMMARS_FLAG).value === "off" ? "all" : "used";
|
|
4383
|
+
}
|
|
3570
4384
|
function createHighlightSession(options, request, configuration) {
|
|
3571
4385
|
const mode = highlightCacheSwitch(options);
|
|
3572
4386
|
if (mode === "off" || options.incrementalReuse === false) return void 0;
|
|
3573
|
-
const pack = request.mode === "development" && configuration.cacheEnabled ?
|
|
3574
|
-
return new HighlightSession(
|
|
4387
|
+
const pack = request.mode === "development" && configuration.cacheEnabled ? path6.join(configuration.cacheRoot, `${digestOf(options.projectId)}.highlight.json`) : void 0;
|
|
4388
|
+
return new HighlightSession(
|
|
4389
|
+
configuration.themes,
|
|
4390
|
+
mode === "verify",
|
|
4391
|
+
pack,
|
|
4392
|
+
configuration.shikiLangs
|
|
4393
|
+
);
|
|
3575
4394
|
}
|
|
3576
4395
|
var HighlightSession = class {
|
|
3577
|
-
constructor(themes, verify, pack) {
|
|
4396
|
+
constructor(themes, verify, pack, langs) {
|
|
3578
4397
|
this.themes = themes;
|
|
3579
4398
|
this.verify = verify;
|
|
3580
4399
|
this.pack = pack;
|
|
@@ -3585,17 +4404,15 @@ var HighlightSession = class {
|
|
|
3585
4404
|
this.replaced = false;
|
|
3586
4405
|
const engine = runtimePackages();
|
|
3587
4406
|
this.context = digestOf({
|
|
3588
|
-
version:
|
|
3589
|
-
engine:
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
},
|
|
3594
|
-
themes: { light: themeIdentity(themes.light), dark: themeIdentity(themes.dark) }
|
|
4407
|
+
version: PACK_VERSION2,
|
|
4408
|
+
engine: Object.fromEntries(SHIKI_PACKAGES.map((name) => [name, engine[name] ?? null])),
|
|
4409
|
+
themes: { light: themeIdentity(themes.light), dark: themeIdentity(themes.dark) },
|
|
4410
|
+
// The configured languages: a block highlights with them, and they must load.
|
|
4411
|
+
...langs?.length ? { langs: digestOf(langs) } : {}
|
|
3595
4412
|
});
|
|
3596
|
-
if (
|
|
4413
|
+
if (memoryBytes2 > HIGHLIGHT_CACHE_LIMIT) {
|
|
3597
4414
|
forget();
|
|
3598
|
-
|
|
4415
|
+
packs2.clear();
|
|
3599
4416
|
}
|
|
3600
4417
|
}
|
|
3601
4418
|
/** The cache of one `processHtml` call. */
|
|
@@ -3606,13 +4423,13 @@ var HighlightSession = class {
|
|
|
3606
4423
|
return {
|
|
3607
4424
|
key: (block) => digestOf({ context, block }),
|
|
3608
4425
|
get: (key) => {
|
|
3609
|
-
const value =
|
|
4426
|
+
const value = memory2.get(key);
|
|
3610
4427
|
if (value !== void 0) used.add(key);
|
|
3611
4428
|
return value;
|
|
3612
4429
|
},
|
|
3613
4430
|
set: (key, value) => {
|
|
3614
|
-
if (
|
|
3615
|
-
|
|
4431
|
+
if (memory2.has(key)) this.replaced = true;
|
|
4432
|
+
remember2(key, value);
|
|
3616
4433
|
used.add(key);
|
|
3617
4434
|
proven.add(context);
|
|
3618
4435
|
},
|
|
@@ -3633,7 +4450,7 @@ var HighlightSession = class {
|
|
|
3633
4450
|
}
|
|
3634
4451
|
/** The entry this runtime holds for `key`, without counting it as used. */
|
|
3635
4452
|
peek(key) {
|
|
3636
|
-
return
|
|
4453
|
+
return memory2.get(key);
|
|
3637
4454
|
}
|
|
3638
4455
|
/**
|
|
3639
4456
|
* Takes in what one document's highlighting recorded out of plan order (a render thread, or the
|
|
@@ -3647,32 +4464,32 @@ var HighlightSession = class {
|
|
|
3647
4464
|
const fresh = new Map(record.fresh);
|
|
3648
4465
|
let mismatches = 0;
|
|
3649
4466
|
for (const key of record.mismatched) {
|
|
3650
|
-
const known3 =
|
|
4467
|
+
const known3 = memory2.get(key);
|
|
3651
4468
|
if (known3 !== void 0 && known3 !== fresh.get(key)) mismatches += 1;
|
|
3652
4469
|
}
|
|
3653
4470
|
for (const [key, value] of record.fresh) {
|
|
3654
|
-
const known3 =
|
|
4471
|
+
const known3 = memory2.get(key);
|
|
3655
4472
|
if (known3 === value) continue;
|
|
3656
4473
|
if (known3 !== void 0) this.replaced = true;
|
|
3657
|
-
|
|
4474
|
+
remember2(key, value);
|
|
3658
4475
|
proven.add(this.context);
|
|
3659
4476
|
}
|
|
3660
|
-
for (const key of record.used) if (
|
|
4477
|
+
for (const key of record.used) if (memory2.has(key)) this.used.add(key);
|
|
3661
4478
|
return mismatches;
|
|
3662
4479
|
}
|
|
3663
4480
|
/** Reads the pack once per runtime and context; an unusable pack is not read. */
|
|
3664
4481
|
load() {
|
|
3665
4482
|
if (this.loaded || !this.pack) return;
|
|
3666
4483
|
this.loaded = true;
|
|
3667
|
-
if (
|
|
4484
|
+
if (packs2.get(this.pack)?.context === this.context) return;
|
|
3668
4485
|
try {
|
|
3669
|
-
const bytes =
|
|
4486
|
+
const bytes = readFileSync6(this.pack);
|
|
3670
4487
|
const value = JSON.parse(bytes.toString("utf8"));
|
|
3671
|
-
if (!
|
|
4488
|
+
if (!isPackFile2(value) || value.context !== this.context) return;
|
|
3672
4489
|
const keys = Object.keys(value.entries).sort(compareCodeUnits);
|
|
3673
|
-
for (const key of keys) if (!
|
|
4490
|
+
for (const key of keys) if (!memory2.has(key)) remember2(key, value.entries[key]);
|
|
3674
4491
|
if (keys.length) proven.add(this.context);
|
|
3675
|
-
|
|
4492
|
+
packs2.set(this.pack, { context: this.context, keys, content: bytesDigest(bytes) });
|
|
3676
4493
|
} catch {
|
|
3677
4494
|
}
|
|
3678
4495
|
}
|
|
@@ -3685,55 +4502,55 @@ var HighlightSession = class {
|
|
|
3685
4502
|
async save(complete) {
|
|
3686
4503
|
if (!this.pack) return;
|
|
3687
4504
|
const file = this.pack;
|
|
3688
|
-
const last =
|
|
4505
|
+
const last = packs2.get(file);
|
|
3689
4506
|
const previous = !complete && last?.context === this.context ? last.keys : [];
|
|
3690
|
-
let selected = new Set([...previous, ...this.used].filter((key) =>
|
|
4507
|
+
let selected = new Set([...previous, ...this.used].filter((key) => memory2.has(key)));
|
|
3691
4508
|
const size = (keys2) => {
|
|
3692
4509
|
let total = 0;
|
|
3693
|
-
for (const key of keys2) total +=
|
|
4510
|
+
for (const key of keys2) total += sizeOf2(key, memory2.get(key));
|
|
3694
4511
|
return total;
|
|
3695
4512
|
};
|
|
3696
4513
|
if (size(selected) > HIGHLIGHT_CACHE_LIMIT)
|
|
3697
|
-
selected = new Set([...this.used].filter((key) =>
|
|
4514
|
+
selected = new Set([...this.used].filter((key) => memory2.has(key)));
|
|
3698
4515
|
const keys = [...selected].sort(compareCodeUnits);
|
|
3699
|
-
if (!this.replaced && last?.context === this.context && last.keys.length === keys.length && last.keys.every((key, index) => key === keys[index]) && last.content ===
|
|
4516
|
+
if (!this.replaced && last?.context === this.context && last.keys.length === keys.length && last.keys.every((key, index) => key === keys[index]) && last.content === currentContent3(file))
|
|
3700
4517
|
return;
|
|
3701
4518
|
const content = {
|
|
3702
|
-
version:
|
|
4519
|
+
version: PACK_VERSION2,
|
|
3703
4520
|
context: this.context,
|
|
3704
|
-
entries: Object.fromEntries(keys.map((key) => [key,
|
|
4521
|
+
entries: Object.fromEntries(keys.map((key) => [key, memory2.get(key)]))
|
|
3705
4522
|
};
|
|
3706
4523
|
const text = JSON.stringify(content);
|
|
3707
|
-
const temporary = `${file}.${
|
|
4524
|
+
const temporary = `${file}.${randomUUID4()}.tmp`;
|
|
3708
4525
|
try {
|
|
3709
|
-
await
|
|
4526
|
+
await mkdir4(path6.dirname(file), { recursive: true });
|
|
3710
4527
|
await sweepTemporaries(file);
|
|
3711
|
-
await
|
|
3712
|
-
await retryingRename(
|
|
3713
|
-
|
|
4528
|
+
await writeFile4(temporary, text, { flag: "wx" });
|
|
4529
|
+
await retryingRename(rename4)(temporary, file);
|
|
4530
|
+
packs2.set(file, { context: this.context, keys, content: contentDigest(text) });
|
|
3714
4531
|
this.replaced = false;
|
|
3715
4532
|
} catch {
|
|
3716
|
-
|
|
4533
|
+
packs2.delete(file);
|
|
3717
4534
|
} finally {
|
|
3718
|
-
await
|
|
4535
|
+
await rm4(temporary, { force: true }).catch(() => void 0);
|
|
3719
4536
|
}
|
|
3720
4537
|
}
|
|
3721
4538
|
};
|
|
3722
4539
|
function themeIdentity(name) {
|
|
3723
4540
|
return name === NG_DOC_SYNTAX_THEME_NAME ? { ngDoc: digestOf(ngDocSyntaxTheme()) } : name;
|
|
3724
4541
|
}
|
|
3725
|
-
function
|
|
4542
|
+
function currentContent3(file) {
|
|
3726
4543
|
try {
|
|
3727
|
-
return bytesDigest(
|
|
4544
|
+
return bytesDigest(readFileSync6(file));
|
|
3728
4545
|
} catch {
|
|
3729
4546
|
return void 0;
|
|
3730
4547
|
}
|
|
3731
4548
|
}
|
|
3732
|
-
function
|
|
4549
|
+
function isPackFile2(value) {
|
|
3733
4550
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
3734
4551
|
const file = value;
|
|
3735
4552
|
const entries = file["entries"];
|
|
3736
|
-
return file["version"] ===
|
|
4553
|
+
return file["version"] === PACK_VERSION2 && typeof file["context"] === "string" && !!entries && typeof entries === "object" && !Array.isArray(entries) && Object.values(entries).every((entry) => typeof entry === "string");
|
|
3737
4554
|
}
|
|
3738
4555
|
|
|
3739
4556
|
// libs/builder/generator/content/html-pool.ts
|
|
@@ -3743,7 +4560,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
3743
4560
|
import { Worker } from "node:worker_threads";
|
|
3744
4561
|
|
|
3745
4562
|
// libs/builder/generator/worker/protocol.ts
|
|
3746
|
-
function
|
|
4563
|
+
function encode2(value) {
|
|
3747
4564
|
const result = JSON.stringify(
|
|
3748
4565
|
value,
|
|
3749
4566
|
function(key, item) {
|
|
@@ -3756,7 +4573,7 @@ function encode(value) {
|
|
|
3756
4573
|
if (result === void 0) throw new Error("Worker transport requires a JSON value");
|
|
3757
4574
|
return result;
|
|
3758
4575
|
}
|
|
3759
|
-
function
|
|
4576
|
+
function decode2(value) {
|
|
3760
4577
|
if (typeof value !== "string") throw new Error("Worker message must be JSON text");
|
|
3761
4578
|
const parsed = JSON.parse(value);
|
|
3762
4579
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -3769,7 +4586,7 @@ function decode(value) {
|
|
|
3769
4586
|
import matter from "gray-matter";
|
|
3770
4587
|
import { Marked } from "marked";
|
|
3771
4588
|
import { existsSync as existsSync4 } from "node:fs";
|
|
3772
|
-
import
|
|
4589
|
+
import path8 from "node:path";
|
|
3773
4590
|
|
|
3774
4591
|
// libs/builder/helpers/keyword-heading-title.ts
|
|
3775
4592
|
var LEADING_EMOJI = new RegExp("^(?:\\p{Regional_Indicator}{2}|(?:\\p{Emoji_Presentation}|\\p{Extended_Pictographic}\uFE0F)(?:\\p{Emoji_Modifier}|\uFE0F|\u200D\\p{Extended_Pictographic}\uFE0F?)*)\\s*", "u");
|
|
@@ -3818,7 +4635,16 @@ function param(key, newKeyName) {
|
|
|
3818
4635
|
|
|
3819
4636
|
// libs/builder/parsers/parse-code-block-params.ts
|
|
3820
4637
|
var CODE_BLOCK_LANGUAGE = /[\p{L}\p{N}+#-]+/u;
|
|
3821
|
-
|
|
4638
|
+
var SNIPPET_ID = /[a-zA-Z0-9-]+/;
|
|
4639
|
+
var LINE_RANGE = /^L(\d+)(?:(-)(?:L(\d+))?)?$/;
|
|
4640
|
+
function fileFragment(fragment2) {
|
|
4641
|
+
const range = LINE_RANGE.exec(fragment2);
|
|
4642
|
+
if (!range) return { snippet: fragment2 };
|
|
4643
|
+
const fileLineStart = Number(range[1]) - 1;
|
|
4644
|
+
if (!range[2]) return { fileLineStart, fileLineEnd: fileLineStart + 1 };
|
|
4645
|
+
return { fileLineStart, fileLineEnd: range[3] === void 0 ? void 0 : Number(range[3]) };
|
|
4646
|
+
}
|
|
4647
|
+
function parseCodeBlockParams(options, parserOptions = {}) {
|
|
3822
4648
|
const parser2 = P4.createLanguage({
|
|
3823
4649
|
language: () => P4.regexp(CODE_BLOCK_LANGUAGE).skip(P4.optWhitespace).map((language) => ({ language })),
|
|
3824
4650
|
// File Parsers
|
|
@@ -3829,7 +4655,7 @@ function parseCodeBlockParams(options) {
|
|
|
3829
4655
|
(fileLineStart, fileLineEnd) => ({ fileLineStart, fileLineEnd })
|
|
3830
4656
|
),
|
|
3831
4657
|
fileLineStart: (p) => P4.string("#").then(p["fileLineNumber"]).map((num) => num - 1).map((fileLineStart) => ({ fileLineStart, fileLineEnd: fileLineStart + 1 })),
|
|
3832
|
-
lineParams: (p) => p["fileLineRange"].or(p["fileLineStart"]).fallback({}),
|
|
4658
|
+
lineParams: (p) => (parserOptions.snippets ? P4.string("#").then(P4.regexp(SNIPPET_ID)).map(fileFragment) : p["fileLineRange"].or(p["fileLineStart"])).fallback({}),
|
|
3833
4659
|
highlightedLinesRange: () => P4.seqMap(
|
|
3834
4660
|
number.skip(P4.string("-")),
|
|
3835
4661
|
number,
|
|
@@ -3845,7 +4671,11 @@ function parseCodeBlockParams(options) {
|
|
|
3845
4671
|
active: () => P4.string("active").map(() => ({ active: true })),
|
|
3846
4672
|
file: (p) => P4.seq(
|
|
3847
4673
|
p["filePath"],
|
|
3848
|
-
p["lineParams"].map(({ fileLineStart, fileLineEnd }) => ({
|
|
4674
|
+
p["lineParams"].map(({ fileLineStart, fileLineEnd, snippet: snippet2 }) => ({
|
|
4675
|
+
fileLineStart,
|
|
4676
|
+
fileLineEnd,
|
|
4677
|
+
...snippet2 === void 0 ? {} : { snippet: snippet2 }
|
|
4678
|
+
}))
|
|
3849
4679
|
).map(([file, lineParams]) => ({ ...file, ...lineParams })),
|
|
3850
4680
|
highlightedLines: (p) => p["highlightedLinesRange"].or(number).sepBy(P4.string(",").then(P4.optWhitespace)).wrap(P4.string("{"), P4.string("}")).map((a) => Array.from(new Set(a.flat()))).map((highlightedLines) => ({ highlightedLines })),
|
|
3851
4681
|
// Combined Parsers
|
|
@@ -3960,11 +4790,62 @@ function footprintOf(result) {
|
|
|
3960
4790
|
}
|
|
3961
4791
|
|
|
3962
4792
|
// libs/builder/generator/kernel/paths.ts
|
|
3963
|
-
import
|
|
3964
|
-
function hostPath(file, rules =
|
|
4793
|
+
import path7 from "node:path";
|
|
4794
|
+
function hostPath(file, rules = path7) {
|
|
3965
4795
|
return rules.resolve(file).replace(/\\/g, "/");
|
|
3966
4796
|
}
|
|
3967
4797
|
|
|
4798
|
+
// libs/builder/parsers/parse-snippet.ts
|
|
4799
|
+
import P5 from "parsimmon";
|
|
4800
|
+
function parseSnippet(string2) {
|
|
4801
|
+
const parser2 = P5.createLanguage({
|
|
4802
|
+
keyword: () => P5.string("snippet"),
|
|
4803
|
+
id: () => P5.string("#").then(P5.regexp(/[a-zA-Z0-9-]+/)).fallback(null).map((id) => ({ id })),
|
|
4804
|
+
lang: () => P5.string(":").then(P5.regexp(/[a-zA-Z0-9-]+/)).fallback(void 0).map((lang) => ({ lang })),
|
|
4805
|
+
icon: () => param("icon"),
|
|
4806
|
+
title: () => paramValue().map((title) => ({ title })),
|
|
4807
|
+
opened: () => P5.string("opened").result(true).fallback(void 0).map((opened) => ({ opened })),
|
|
4808
|
+
snippet: ({ keyword, id, lang, icon, title, opened }) => keyword.then(
|
|
4809
|
+
P5.seq(
|
|
4810
|
+
id,
|
|
4811
|
+
lang,
|
|
4812
|
+
P5.whitespace.then(title.or(icon).or(opened).sepBy(P5.whitespace)).fallback([])
|
|
4813
|
+
).map(([id2, lang2, rest]) => ({ ...id2, ...lang2, ...Object.assign({}, ...rest) }))
|
|
4814
|
+
),
|
|
4815
|
+
snippetFromFile: ({ lang, icon, title, opened }) => P5.seq(
|
|
4816
|
+
param("snippet-from-file", "fromFile"),
|
|
4817
|
+
lang,
|
|
4818
|
+
P5.whitespace.then(title.or(icon).or(opened).sepBy(P5.whitespace)).fallback([])
|
|
4819
|
+
).map(([id, lang2, rest]) => ({ ...id, ...lang2, ...Object.assign({}, ...rest) })),
|
|
4820
|
+
anySnippet: ({ snippet: snippet2, snippetFromFile }) => snippetFromFile.or(snippet2)
|
|
4821
|
+
});
|
|
4822
|
+
const result = parser2.anySnippet.parse(string2);
|
|
4823
|
+
return result.status ? result.value : void 0;
|
|
4824
|
+
}
|
|
4825
|
+
|
|
4826
|
+
// libs/builder/generator/content/code-snippet.ts
|
|
4827
|
+
var MARKER = /^.*((\/\/|<!--|\/\*)\s*)(snippet.*?(?=(-->|\*\/)?))\s*(-->|\*\/)?$/;
|
|
4828
|
+
function snippetRegion(text, id) {
|
|
4829
|
+
const lines = text.split("\n").map((line) => line.replace(/\r$/, ""));
|
|
4830
|
+
const markers = lines.map((line) => {
|
|
4831
|
+
const match = MARKER.exec(line);
|
|
4832
|
+
return match ? parseSnippet(match[3].trim())?.id ?? null : void 0;
|
|
4833
|
+
});
|
|
4834
|
+
const start = markers.indexOf(id);
|
|
4835
|
+
if (start < 0) return { status: "unknown" };
|
|
4836
|
+
const end = markers.indexOf(id, start + 1);
|
|
4837
|
+
if (end < 0) return { status: "unclosed" };
|
|
4838
|
+
const region = removeLinesFromCode(
|
|
4839
|
+
lines.slice(start + 1, end).filter((_, index) => markers[start + 1 + index] === void 0).join("\n")
|
|
4840
|
+
).split("\n");
|
|
4841
|
+
while (region.length && !region[0].trim()) region.shift();
|
|
4842
|
+
while (region.length && !region[region.length - 1].trim()) region.pop();
|
|
4843
|
+
const indent = Math.min(
|
|
4844
|
+
...region.filter((line) => line.trim()).map((line) => line.length - line.trimStart().length)
|
|
4845
|
+
);
|
|
4846
|
+
return { status: "found", code: region.map((line) => line.slice(indent)).join("\n") };
|
|
4847
|
+
}
|
|
4848
|
+
|
|
3968
4849
|
// libs/builder/generator/content/html-pipeline.ts
|
|
3969
4850
|
import { parseFile } from "@orama/plugin-parsedoc";
|
|
3970
4851
|
var htmlUtilities = () => Promise.resolve().then(() => (init_utils(), utils_exports));
|
|
@@ -3972,13 +4853,13 @@ var notAborted = () => false;
|
|
|
3972
4853
|
async function renderDocuments(task, highlight2, aborted = notAborted) {
|
|
3973
4854
|
const results = [];
|
|
3974
4855
|
for (const document of task.documents) {
|
|
3975
|
-
const result = await renderDocument(document, task
|
|
4856
|
+
const result = await renderDocument(document, task, highlight2, aborted);
|
|
3976
4857
|
results.push(result);
|
|
3977
4858
|
if (!("html" in result)) break;
|
|
3978
4859
|
}
|
|
3979
4860
|
return results;
|
|
3980
4861
|
}
|
|
3981
|
-
async function renderDocument(document, themes, highlight2, aborted) {
|
|
4862
|
+
async function renderDocument(document, { themes, langs, grammars: grammars2 }, highlight2, aborted) {
|
|
3982
4863
|
if (aborted()) return { aborted: true, mismatches: 0 };
|
|
3983
4864
|
const utilities = await htmlUtilities();
|
|
3984
4865
|
if (aborted()) return { aborted: true, mismatches: 0 };
|
|
@@ -3988,6 +4869,8 @@ async function renderDocument(document, themes, highlight2, aborted) {
|
|
|
3988
4869
|
...document.route === void 0 ? {} : { route: document.route },
|
|
3989
4870
|
lightTheme: themes.light,
|
|
3990
4871
|
darkTheme: themes.dark,
|
|
4872
|
+
...langs ? { langs } : {},
|
|
4873
|
+
grammars: grammars2 ?? "used",
|
|
3991
4874
|
...call ? { highlight: call } : {}
|
|
3992
4875
|
});
|
|
3993
4876
|
const mismatches = call?.mismatches.length ?? 0;
|
|
@@ -4106,6 +4989,7 @@ function recordingHighlight(settings2, themes, store) {
|
|
|
4106
4989
|
}
|
|
4107
4990
|
};
|
|
4108
4991
|
}
|
|
4992
|
+
var WARM_DOCUMENT = ["ts", "angular-ts", "angular-html"].map((language) => `<pre><code class="language-${language}">warm</code></pre>`).join("");
|
|
4109
4993
|
|
|
4110
4994
|
// libs/builder/generator/content/content-compiler.ts
|
|
4111
4995
|
var PARALLEL_RENDER_MISMATCH = "CONTENT_PARALLEL_MISMATCH";
|
|
@@ -4120,10 +5004,11 @@ var GeneratorContentCompiler = class {
|
|
|
4120
5004
|
* is highlighted (`./highlight-cache`).
|
|
4121
5005
|
* @param back - Where the HTML pipeline runs; without it, in this thread, at once.
|
|
4122
5006
|
*/
|
|
4123
|
-
constructor(services, highlight2, back) {
|
|
5007
|
+
constructor(services, highlight2, back, grammars2 = "used") {
|
|
4124
5008
|
this.services = services;
|
|
4125
5009
|
this.highlight = highlight2;
|
|
4126
5010
|
this.back = back;
|
|
5011
|
+
this.grammars = grammars2;
|
|
4127
5012
|
}
|
|
4128
5013
|
/**
|
|
4129
5014
|
* Whether this call records its footprint. The semantic service's effective recorder state
|
|
@@ -4222,8 +5107,8 @@ var GeneratorContentCompiler = class {
|
|
|
4222
5107
|
);
|
|
4223
5108
|
return { dependencies, diagnostics };
|
|
4224
5109
|
}
|
|
4225
|
-
const
|
|
4226
|
-
if (!
|
|
5110
|
+
const current2 = await this.descriptorFields(request, dependencies, diagnostics, signal);
|
|
5111
|
+
if (!current2) {
|
|
4227
5112
|
if (!diagnostics.some((item) => item.code === "CONTENT_ABORTED")) {
|
|
4228
5113
|
diagnostics.push(
|
|
4229
5114
|
this.diag(
|
|
@@ -4235,7 +5120,7 @@ var GeneratorContentCompiler = class {
|
|
|
4235
5120
|
}
|
|
4236
5121
|
return { dependencies, diagnostics };
|
|
4237
5122
|
}
|
|
4238
|
-
if (!this.matchesDescriptor(request, descriptor,
|
|
5123
|
+
if (!this.matchesDescriptor(request, descriptor, current2)) {
|
|
4239
5124
|
diagnostics.push(
|
|
4240
5125
|
this.diag(
|
|
4241
5126
|
"CONTENT_DESCRIPTOR_STALE",
|
|
@@ -4365,11 +5250,11 @@ var GeneratorContentCompiler = class {
|
|
|
4365
5250
|
return `Descriptor closure for "${request.id}" is invalid.`;
|
|
4366
5251
|
return void 0;
|
|
4367
5252
|
}
|
|
4368
|
-
matchesDescriptor(request, descriptor,
|
|
5253
|
+
matchesDescriptor(request, descriptor, current2) {
|
|
4369
5254
|
return /^[a-f0-9]{64}$/.test(descriptor.requestDigest) && expectedContentId(request, descriptor.ownerId) === request.id && Number.isSafeInteger(descriptor.ordinal) && descriptor.ordinal >= 0 && sameValue2(
|
|
4370
5255
|
descriptor.closureIds,
|
|
4371
5256
|
request.kind === "header" ? [] : [`${descriptor.ownerId}:header`]
|
|
4372
|
-
) && sameValue2(omitDescriptorPublication(descriptor),
|
|
5257
|
+
) && sameValue2(omitDescriptorPublication(descriptor), current2);
|
|
4373
5258
|
}
|
|
4374
5259
|
matchesCompiledDependencies(descriptor, dependencies) {
|
|
4375
5260
|
return descriptor.dependencies.every((expected) => {
|
|
@@ -4405,7 +5290,7 @@ var GeneratorContentCompiler = class {
|
|
|
4405
5290
|
entryId: request.entry.id,
|
|
4406
5291
|
source: { path: request.markdown },
|
|
4407
5292
|
text: parsed.content,
|
|
4408
|
-
scope:
|
|
5293
|
+
scope: path8.dirname(request.markdown),
|
|
4409
5294
|
kind: "guide",
|
|
4410
5295
|
values: {
|
|
4411
5296
|
title: request.entry.title,
|
|
@@ -4423,7 +5308,7 @@ var GeneratorContentCompiler = class {
|
|
|
4423
5308
|
const processed = await this.process(
|
|
4424
5309
|
this.markdownToHtml(
|
|
4425
5310
|
rendered.value,
|
|
4426
|
-
|
|
5311
|
+
path8.dirname(request.markdown),
|
|
4427
5312
|
dependencies,
|
|
4428
5313
|
diagnostics
|
|
4429
5314
|
),
|
|
@@ -4704,7 +5589,13 @@ var GeneratorContentCompiler = class {
|
|
|
4704
5589
|
* `compileStaged` that the front is done: everything after the pipeline is pure.
|
|
4705
5590
|
*/
|
|
4706
5591
|
render(documents, signal, staged) {
|
|
4707
|
-
const
|
|
5592
|
+
const { themes, shikiLangs } = this.services.configuration;
|
|
5593
|
+
const task = {
|
|
5594
|
+
documents,
|
|
5595
|
+
themes,
|
|
5596
|
+
...shikiLangs ? { langs: shikiLangs } : {},
|
|
5597
|
+
...this.grammars === "all" ? { grammars: "all" } : {}
|
|
5598
|
+
};
|
|
4708
5599
|
const rendered = this.back ? this.back.render(task, signal) : renderDocuments(
|
|
4709
5600
|
task,
|
|
4710
5601
|
() => this.highlight?.call(),
|
|
@@ -4954,16 +5845,27 @@ var GeneratorContentCompiler = class {
|
|
|
4954
5845
|
markdownToHtml(markdown, context, dependencies, diagnostics) {
|
|
4955
5846
|
const renderer = {
|
|
4956
5847
|
code: (code, language) => {
|
|
4957
|
-
const options = parseCodeBlockParams(language?.trim() || "typescript");
|
|
5848
|
+
const options = parseCodeBlockParams(language?.trim() || "typescript", { snippets: true });
|
|
4958
5849
|
if (options.file) {
|
|
4959
|
-
const source = hostPath(
|
|
5850
|
+
const source = hostPath(path8.resolve(context, options.file));
|
|
4960
5851
|
const fullSource = this.readPhysicalFile(
|
|
4961
5852
|
source,
|
|
4962
5853
|
dependencies,
|
|
4963
5854
|
diagnostics,
|
|
4964
5855
|
"CONTENT_SNIPPET_READ"
|
|
4965
5856
|
);
|
|
4966
|
-
if (fullSource !== void 0) {
|
|
5857
|
+
if (fullSource !== void 0 && options.snippet !== void 0) {
|
|
5858
|
+
const region = snippetRegion(fullSource, options.snippet);
|
|
5859
|
+
if (region.status === "found") code = region.code;
|
|
5860
|
+
else
|
|
5861
|
+
diagnostics.push(
|
|
5862
|
+
this.diag(
|
|
5863
|
+
"CONTENT_SNIPPET_UNKNOWN",
|
|
5864
|
+
region.status === "unknown" ? `Snippet "${options.snippet}" is not in ${options.file}: no "snippet#${options.snippet}" marker.` : `Snippet "${options.snippet}" in ${options.file} has no closing "snippet#${options.snippet}" marker.`,
|
|
5865
|
+
source
|
|
5866
|
+
)
|
|
5867
|
+
);
|
|
5868
|
+
} else if (fullSource !== void 0) {
|
|
4967
5869
|
try {
|
|
4968
5870
|
const sourceCode = fullSource.split("\n").slice(options.fileLineStart, options.fileLineEnd).join("\n").trim();
|
|
4969
5871
|
code = removeLinesFromCode(sourceCode);
|
|
@@ -5152,7 +6054,7 @@ var HtmlThread = class {
|
|
|
5152
6054
|
receive(message2) {
|
|
5153
6055
|
let reply;
|
|
5154
6056
|
try {
|
|
5155
|
-
reply =
|
|
6057
|
+
reply = decode2(message2);
|
|
5156
6058
|
} catch (error) {
|
|
5157
6059
|
this.fail(error);
|
|
5158
6060
|
return;
|
|
@@ -5202,7 +6104,7 @@ var HtmlPool = class {
|
|
|
5202
6104
|
while (this.threads.length < this.size) {
|
|
5203
6105
|
const thread = new HtmlThread(this.entry, () => this.changed());
|
|
5204
6106
|
this.threads.push(thread);
|
|
5205
|
-
if (warm) thread.post(
|
|
6107
|
+
if (warm) thread.post(encode2({ type: "warm", ...warm }));
|
|
5206
6108
|
}
|
|
5207
6109
|
this.changed();
|
|
5208
6110
|
}
|
|
@@ -5358,7 +6260,7 @@ var RenderBack = class {
|
|
|
5358
6260
|
signal,
|
|
5359
6261
|
(thread, id) => [
|
|
5360
6262
|
...this.highlightSync(thread, settings2),
|
|
5361
|
-
|
|
6263
|
+
encode2({
|
|
5362
6264
|
type: "render",
|
|
5363
6265
|
id,
|
|
5364
6266
|
task,
|
|
@@ -5392,9 +6294,9 @@ var RenderBack = class {
|
|
|
5392
6294
|
pool,
|
|
5393
6295
|
signal,
|
|
5394
6296
|
(thread, id) => {
|
|
5395
|
-
const messages = [
|
|
6297
|
+
const messages = [encode2({ type: "link", id, task, keywords: set })];
|
|
5396
6298
|
if (thread.keywords !== keywords) {
|
|
5397
|
-
messages.unshift(
|
|
6299
|
+
messages.unshift(encode2({ type: "keywords", id: set, keywords }));
|
|
5398
6300
|
thread.keywords = keywords;
|
|
5399
6301
|
}
|
|
5400
6302
|
return messages;
|
|
@@ -5508,7 +6410,7 @@ var RenderBack = class {
|
|
|
5508
6410
|
const from = reset ? 0 : thread.highlight.cursor;
|
|
5509
6411
|
thread.highlight = { epoch: epoch2, cursor: entries.length };
|
|
5510
6412
|
return [
|
|
5511
|
-
|
|
6413
|
+
encode2({
|
|
5512
6414
|
type: "highlight",
|
|
5513
6415
|
reset,
|
|
5514
6416
|
context: settings2.context,
|
|
@@ -5605,7 +6507,7 @@ import fg2 from "fast-glob";
|
|
|
5605
6507
|
import matter2 from "gray-matter";
|
|
5606
6508
|
import { existsSync as existsSync6, realpathSync as realpathSync2 } from "node:fs";
|
|
5607
6509
|
import { createRequire } from "node:module";
|
|
5608
|
-
import
|
|
6510
|
+
import path9 from "node:path";
|
|
5609
6511
|
import { types as nodeTypes } from "node:util";
|
|
5610
6512
|
import vm from "node:vm";
|
|
5611
6513
|
import nunjucks from "nunjucks";
|
|
@@ -5936,7 +6838,7 @@ var TrackingLoader = class extends nunjucks.Loader {
|
|
|
5936
6838
|
* error escapes later as an uncaught exception. Thrown from the loader, it fails this render
|
|
5937
6839
|
* synchronously, and each including template prefixes its own path to the message.
|
|
5938
6840
|
*/
|
|
5939
|
-
compile(
|
|
6841
|
+
compile(path18, text) {
|
|
5940
6842
|
const environment = this.environment();
|
|
5941
6843
|
try {
|
|
5942
6844
|
return {
|
|
@@ -5947,13 +6849,13 @@ var TrackingLoader = class extends nunjucks.Loader {
|
|
|
5947
6849
|
text,
|
|
5948
6850
|
environment.asyncFilters,
|
|
5949
6851
|
environment.extensionsList,
|
|
5950
|
-
|
|
6852
|
+
path18,
|
|
5951
6853
|
environment.opts
|
|
5952
6854
|
)
|
|
5953
6855
|
)()
|
|
5954
6856
|
};
|
|
5955
6857
|
} catch (error) {
|
|
5956
|
-
throw nunjucksLib._prettifyError(
|
|
6858
|
+
throw nunjucksLib._prettifyError(path18, environment.opts.dev, error);
|
|
5957
6859
|
}
|
|
5958
6860
|
}
|
|
5959
6861
|
};
|
|
@@ -6083,8 +6985,8 @@ function locateConfig(request, workspaceRoot, dependencies) {
|
|
|
6083
6985
|
dependencies.observeFile(explicit);
|
|
6084
6986
|
return existsSync6(explicit) ? explicit : void 0;
|
|
6085
6987
|
}
|
|
6086
|
-
let directory =
|
|
6087
|
-
const root =
|
|
6988
|
+
let directory = path9.dirname(normalizeAbsolute(request.defaults.docsRoot, workspaceRoot));
|
|
6989
|
+
const root = path9.parse(directory).root;
|
|
6088
6990
|
while (true) {
|
|
6089
6991
|
for (const name of [
|
|
6090
6992
|
"ng-doc.config.ts",
|
|
@@ -6092,12 +6994,12 @@ function locateConfig(request, workspaceRoot, dependencies) {
|
|
|
6092
6994
|
"ng-doc.config.mjs",
|
|
6093
6995
|
"ng-doc.config.cjs"
|
|
6094
6996
|
]) {
|
|
6095
|
-
const candidate =
|
|
6997
|
+
const candidate = path9.join(directory, name);
|
|
6096
6998
|
if (dependencies.observeFile(candidate)) return normalizePath2(candidate);
|
|
6097
6999
|
}
|
|
6098
7000
|
if (directory === workspaceRoot || directory === root || !isWithin(workspaceRoot, directory))
|
|
6099
7001
|
break;
|
|
6100
|
-
directory =
|
|
7002
|
+
directory = path9.dirname(directory);
|
|
6101
7003
|
}
|
|
6102
7004
|
return void 0;
|
|
6103
7005
|
}
|
|
@@ -6158,7 +7060,10 @@ async function evaluateModules(workspaceRoot, tsConfig, configFile, descriptions
|
|
|
6158
7060
|
treeShaking: true,
|
|
6159
7061
|
tsconfig: normalizeAbsolute(tsConfig, workspaceRoot),
|
|
6160
7062
|
logLevel: "silent",
|
|
6161
|
-
plugins: [
|
|
7063
|
+
plugins: [
|
|
7064
|
+
...configFile ? [browserModuleImports(configFile, dependencies)] : [],
|
|
7065
|
+
descriptionSanitizer(modules, dependencies, probes)
|
|
7066
|
+
]
|
|
6162
7067
|
});
|
|
6163
7068
|
throwIfAborted(signal);
|
|
6164
7069
|
const inputs = result.metafile?.inputs ?? {};
|
|
@@ -6218,6 +7123,35 @@ async function evaluateModules(workspaceRoot, tsConfig, configFile, descriptions
|
|
|
6218
7123
|
throw error;
|
|
6219
7124
|
}
|
|
6220
7125
|
}
|
|
7126
|
+
var BROWSER_MODULE = "ng-doc-browser-module:";
|
|
7127
|
+
function browserModuleImports(configFile, dependencies) {
|
|
7128
|
+
const config = normalizePath2(path9.resolve(configFile));
|
|
7129
|
+
return {
|
|
7130
|
+
name: "ng-doc-browser-module-imports",
|
|
7131
|
+
setup(build2) {
|
|
7132
|
+
build2.onResolve({ filter: /.*/ }, async (args) => {
|
|
7133
|
+
if (args.kind !== "dynamic-import" || args.pluginData?.ngDocBrowserModule || !path9.isAbsolute(args.importer) || normalizePath2(path9.resolve(args.importer)) !== config) {
|
|
7134
|
+
return void 0;
|
|
7135
|
+
}
|
|
7136
|
+
if (path9.isAbsolute(args.path) || /^\.{1,2}\//.test(args.path)) {
|
|
7137
|
+
observeResolutionCandidates(path9.resolve(args.resolveDir, args.path), dependencies);
|
|
7138
|
+
}
|
|
7139
|
+
const resolved = await build2.resolve(args.path, {
|
|
7140
|
+
kind: "dynamic-import",
|
|
7141
|
+
importer: args.importer,
|
|
7142
|
+
resolveDir: args.resolveDir,
|
|
7143
|
+
pluginData: { ngDocBrowserModule: true }
|
|
7144
|
+
});
|
|
7145
|
+
if (resolved.errors.length || !resolved.path || resolved.external) {
|
|
7146
|
+
return { path: args.path, external: true };
|
|
7147
|
+
}
|
|
7148
|
+
const file = normalizeAbsolute(resolved.path);
|
|
7149
|
+
dependencies.add({ kind: "existence", path: file, exists: true });
|
|
7150
|
+
return { path: `${BROWSER_MODULE}${encodeURIComponent(file)}`, external: true };
|
|
7151
|
+
});
|
|
7152
|
+
}
|
|
7153
|
+
};
|
|
7154
|
+
}
|
|
6221
7155
|
function descriptionSanitizer(modules, dependencies, probes) {
|
|
6222
7156
|
const kinds = new Map(modules.map((item) => [normalizePath2(item.source), item.kind]));
|
|
6223
7157
|
const importers = /* @__PURE__ */ new Map();
|
|
@@ -6225,10 +7159,10 @@ function descriptionSanitizer(modules, dependencies, probes) {
|
|
|
6225
7159
|
name: "ng-doc-description-sanitizer",
|
|
6226
7160
|
setup(build2) {
|
|
6227
7161
|
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
6228
|
-
if (!
|
|
6229
|
-
const target =
|
|
7162
|
+
if (!path9.isAbsolute(args.path) && !/^\.{1,2}\//.test(args.path)) return void 0;
|
|
7163
|
+
const target = path9.resolve(args.resolveDir, args.path);
|
|
6230
7164
|
const candidates = observeResolutionCandidates(target, dependencies);
|
|
6231
|
-
if (
|
|
7165
|
+
if (path9.isAbsolute(args.importer)) {
|
|
6232
7166
|
let importer = importers.get(args.importer);
|
|
6233
7167
|
if (importer === void 0) {
|
|
6234
7168
|
importer = normalizeAbsolute(args.importer);
|
|
@@ -6248,7 +7182,7 @@ function descriptionSanitizer(modules, dependencies, probes) {
|
|
|
6248
7182
|
kinds.get(normalizePath2(args.path)) ?? kindFor(args.path)
|
|
6249
7183
|
),
|
|
6250
7184
|
loader: "ts",
|
|
6251
|
-
resolveDir:
|
|
7185
|
+
resolveDir: path9.dirname(args.path)
|
|
6252
7186
|
};
|
|
6253
7187
|
});
|
|
6254
7188
|
build2.onLoad({ filter: /\.(?:[cm]?[jt]s|[jt]sx|json)$/, namespace: "file" }, (args) => {
|
|
@@ -6257,8 +7191,8 @@ function descriptionSanitizer(modules, dependencies, probes) {
|
|
|
6257
7191
|
if (!contents) return void 0;
|
|
6258
7192
|
return {
|
|
6259
7193
|
contents,
|
|
6260
|
-
loader: BUNDLE_LOADERS[
|
|
6261
|
-
resolveDir:
|
|
7194
|
+
loader: BUNDLE_LOADERS[path9.extname(args.path).toLowerCase()] ?? "js",
|
|
7195
|
+
resolveDir: path9.dirname(args.path)
|
|
6262
7196
|
};
|
|
6263
7197
|
});
|
|
6264
7198
|
}
|
|
@@ -6289,7 +7223,7 @@ function sanitizeDescription(source, kind) {
|
|
|
6289
7223
|
(declaration) => ts.isIdentifier(declaration.name) && declaration.name.text === exportName
|
|
6290
7224
|
)?.initializer : void 0;
|
|
6291
7225
|
const transformer = (context) => {
|
|
6292
|
-
const
|
|
7226
|
+
const visit9 = (node) => {
|
|
6293
7227
|
if (node === root && ts.isObjectLiteralExpression(node)) {
|
|
6294
7228
|
const properties = node.properties.flatMap((property) => {
|
|
6295
7229
|
const name = propertyName(property);
|
|
@@ -6337,9 +7271,9 @@ function sanitizeDescription(source, kind) {
|
|
|
6337
7271
|
});
|
|
6338
7272
|
return context.factory.updateObjectLiteralExpression(node, properties);
|
|
6339
7273
|
}
|
|
6340
|
-
return ts.visitEachChild(node,
|
|
7274
|
+
return ts.visitEachChild(node, visit9, context);
|
|
6341
7275
|
};
|
|
6342
|
-
return (node) => ts.visitNode(node,
|
|
7276
|
+
return (node) => ts.visitNode(node, visit9);
|
|
6343
7277
|
};
|
|
6344
7278
|
const transformed = ts.transform(sourceFile, [transformer]);
|
|
6345
7279
|
try {
|
|
@@ -6381,7 +7315,7 @@ var EvaluationScope = class {
|
|
|
6381
7315
|
this.timers = /* @__PURE__ */ new Set();
|
|
6382
7316
|
this.disposed = false;
|
|
6383
7317
|
this.networkAbort = new AbortController();
|
|
6384
|
-
const filename =
|
|
7318
|
+
const filename = path9.join(workspaceRoot, ".ng-doc-discovery-evaluator.cjs");
|
|
6385
7319
|
const module = { exports: {} };
|
|
6386
7320
|
const nativeRequire = createRequire(filename);
|
|
6387
7321
|
const schedule = (callback, delay, ...args) => {
|
|
@@ -6464,7 +7398,7 @@ var EvaluationScope = class {
|
|
|
6464
7398
|
evaluate(code, timeoutMs) {
|
|
6465
7399
|
this.assertActive();
|
|
6466
7400
|
new vm.Script(code, {
|
|
6467
|
-
filename:
|
|
7401
|
+
filename: path9.join(this.workspaceRoot, ".ng-doc-discovery-evaluator.cjs")
|
|
6468
7402
|
}).runInContext(this.context, { timeout: timeoutMs });
|
|
6469
7403
|
return this.context.module.exports;
|
|
6470
7404
|
}
|
|
@@ -6497,6 +7431,7 @@ async function normalizeConfiguration(request, workspaceRoot, configFile, raw, d
|
|
|
6497
7431
|
const globalKeywords = normalizeKeywords(
|
|
6498
7432
|
validGlobalKeywords(raw.keywords?.keywords ?? {}, configFile ?? workspaceRoot, diagnostics)
|
|
6499
7433
|
);
|
|
7434
|
+
const shikiLangs = shikiLanguages(raw.shiki?.langs, configFile ?? workspaceRoot, diagnostics);
|
|
6500
7435
|
const remoteKeywords = [];
|
|
6501
7436
|
const executables = [];
|
|
6502
7437
|
const loaders = raw.keywords?.loaders ?? [];
|
|
@@ -6543,12 +7478,16 @@ async function normalizeConfiguration(request, workspaceRoot, configFile, raw, d
|
|
|
6543
7478
|
);
|
|
6544
7479
|
const headerTemplate = raw.guide?.headerTemplate ? normalizeAbsolute(raw.guide.headerTemplate, workspaceRoot) : void 0;
|
|
6545
7480
|
if (headerTemplate) dependencies.observeFile(headerTemplate);
|
|
7481
|
+
const demoApplication = demoApplicationSettings(raw, configFile ?? workspaceRoot, diagnostics);
|
|
7482
|
+
if (diagnostics.some((item) => item.severity === "error")) {
|
|
7483
|
+
return { globalKeywords, remoteKeywords, diagnostics };
|
|
7484
|
+
}
|
|
6546
7485
|
const withoutDigest = {
|
|
6547
7486
|
projectId: request.projectId,
|
|
6548
7487
|
workspaceRoot,
|
|
6549
7488
|
docsRoots,
|
|
6550
7489
|
tsConfig: normalizeAbsolute(raw.tsConfig ?? request.defaults.tsConfig, workspaceRoot),
|
|
6551
|
-
outputRoot: raw.outDir === void 0 ? normalizeAbsolute(request.defaults.outputRoot, workspaceRoot) : normalizeAbsolute(
|
|
7490
|
+
outputRoot: raw.outDir === void 0 ? normalizeAbsolute(request.defaults.outputRoot, workspaceRoot) : normalizeAbsolute(path9.join(workspaceRoot, raw.outDir, "ng-doc", request.projectId)),
|
|
6552
7491
|
cacheRoot: normalizeAbsolute(request.defaults.cacheRoot, workspaceRoot),
|
|
6553
7492
|
routePrefix: normalizeRoute(raw.routePrefix ?? ""),
|
|
6554
7493
|
guideDirectory: "guides",
|
|
@@ -6557,10 +7496,13 @@ async function normalizeConfiguration(request, workspaceRoot, configFile, raw, d
|
|
|
6557
7496
|
inlineStyleLanguage: options.inlineStyleLanguage,
|
|
6558
7497
|
anchorHeadings: raw.guide?.anchorHeadings ?? options.defaultAnchorHeadings,
|
|
6559
7498
|
headerTemplate,
|
|
7499
|
+
...raw.api?.protectedMembers === false ? { apiProtectedMembers: false } : {},
|
|
7500
|
+
...demoApplication ? { demoApplication } : {},
|
|
6560
7501
|
themes: {
|
|
6561
7502
|
light: raw.shiki?.themes?.light ?? options.defaultThemes.light,
|
|
6562
7503
|
dark: raw.shiki?.themes?.dark ?? options.defaultThemes.dark
|
|
6563
7504
|
},
|
|
7505
|
+
...shikiLangs.length ? { shikiLangs } : {},
|
|
6564
7506
|
repo: raw.repoConfig ? {
|
|
6565
7507
|
url: raw.repoConfig.url,
|
|
6566
7508
|
platform: raw.repoConfig.platform ?? "github",
|
|
@@ -6581,12 +7523,87 @@ async function normalizeConfiguration(request, workspaceRoot, configFile, raw, d
|
|
|
6581
7523
|
};
|
|
6582
7524
|
return { configuration, globalKeywords, remoteKeywords, diagnostics };
|
|
6583
7525
|
}
|
|
7526
|
+
var DEFAULT_DEMO_PATH = "demo-preview";
|
|
7527
|
+
var DEMO_PATH_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
7528
|
+
function demoApplicationSettings(raw, source, diagnostics) {
|
|
7529
|
+
const invalid = (code, message2) => {
|
|
7530
|
+
diagnostics.push({
|
|
7531
|
+
code,
|
|
7532
|
+
severity: "error",
|
|
7533
|
+
stage: "evaluation",
|
|
7534
|
+
message: message2,
|
|
7535
|
+
source: { path: source }
|
|
7536
|
+
});
|
|
7537
|
+
return void 0;
|
|
7538
|
+
};
|
|
7539
|
+
const { isolatedDemos, demoApplication, demoProviders } = raw;
|
|
7540
|
+
if (isolatedDemos !== void 0 && typeof isolatedDemos !== "boolean") {
|
|
7541
|
+
return invalid("DISCOVERY_DEMO_APPLICATION_INVALID", "isolatedDemos must be a boolean.");
|
|
7542
|
+
}
|
|
7543
|
+
const configured = demoApplication !== null && typeof demoApplication === "object";
|
|
7544
|
+
if (demoApplication !== void 0 && typeof demoApplication !== "boolean" && !configured) {
|
|
7545
|
+
return invalid(
|
|
7546
|
+
"DISCOVERY_DEMO_APPLICATION_INVALID",
|
|
7547
|
+
"demoApplication must be a boolean or an object."
|
|
7548
|
+
);
|
|
7549
|
+
}
|
|
7550
|
+
let demoPath;
|
|
7551
|
+
if (configured && demoApplication.path !== void 0) {
|
|
7552
|
+
const value = demoApplication.path;
|
|
7553
|
+
const segments = typeof value === "string" ? value.split("/").filter(Boolean) : [];
|
|
7554
|
+
if (!segments.length || segments.some((segment) => !DEMO_PATH_SEGMENT.test(segment))) {
|
|
7555
|
+
return invalid(
|
|
7556
|
+
"DISCOVERY_DEMO_PATH_INVALID",
|
|
7557
|
+
`demoApplication.path must be one or more URL segments of letters, digits, '-', '_' and '.', each starting with a letter or a digit; got ${JSON.stringify(value)}.`
|
|
7558
|
+
);
|
|
7559
|
+
}
|
|
7560
|
+
demoPath = segments.join("/");
|
|
7561
|
+
}
|
|
7562
|
+
const providers = demoProviders === void 0 ? void 0 : demoProvidersModule(demoProviders, invalid);
|
|
7563
|
+
if (demoProviders !== void 0 && !providers) return void 0;
|
|
7564
|
+
if (demoApplication === false && isolatedDemos === true) {
|
|
7565
|
+
diagnostics.push({
|
|
7566
|
+
code: "DISCOVERY_DEMO_APPLICATION_OFF",
|
|
7567
|
+
severity: "warning",
|
|
7568
|
+
stage: "evaluation",
|
|
7569
|
+
message: "isolatedDemos has no effect while demoApplication is false: demos render in the page.",
|
|
7570
|
+
source: { path: source }
|
|
7571
|
+
});
|
|
7572
|
+
}
|
|
7573
|
+
const pages = demoApplication === false ? "none" : isolatedDemos === true || demoApplication === true || configured ? "all" : void 0;
|
|
7574
|
+
const settings2 = {
|
|
7575
|
+
...pages ? { pages } : {},
|
|
7576
|
+
...isolatedDemos === true && pages !== "none" ? { isolated: true } : {},
|
|
7577
|
+
...demoPath && demoPath !== DEFAULT_DEMO_PATH ? { path: demoPath } : {},
|
|
7578
|
+
...providers ? { providers } : {}
|
|
7579
|
+
};
|
|
7580
|
+
return Object.keys(settings2).length ? settings2 : void 0;
|
|
7581
|
+
}
|
|
7582
|
+
function demoProvidersModule(value, invalid) {
|
|
7583
|
+
const usage = "write it as `demoProviders: () => import('./demo.providers')` in ng-doc.config.ts";
|
|
7584
|
+
if (typeof value !== "function") {
|
|
7585
|
+
return invalid(
|
|
7586
|
+
"DISCOVERY_DEMO_PROVIDERS_INVALID",
|
|
7587
|
+
`demoProviders must be a function: ${usage}.`
|
|
7588
|
+
);
|
|
7589
|
+
}
|
|
7590
|
+
const compact = Function.prototype.toString.call(value).replace(/\s+/g, "");
|
|
7591
|
+
const marker = `(["'\`])${BROWSER_MODULE}([^"'\`]+)\\1`;
|
|
7592
|
+
const match = new RegExp(`^(?:async)?\\(\\)=>\\(?import\\(${marker}\\)\\)?$`).exec(compact) ?? new RegExp(`^(?:async)?\\(\\)=>\\{returnimport\\(${marker}\\);?\\}$`).exec(compact);
|
|
7593
|
+
if (!match) {
|
|
7594
|
+
return invalid(
|
|
7595
|
+
"DISCOVERY_DEMO_PROVIDERS_IMPORT",
|
|
7596
|
+
compact.includes(BROWSER_MODULE) ? `demoProviders must only import its module: ${usage}.` : `demoProviders must import a file by a literal path that resolves from ng-doc.config.ts: ${usage}.`
|
|
7597
|
+
);
|
|
7598
|
+
}
|
|
7599
|
+
return decodeURIComponent(match[2]);
|
|
7600
|
+
}
|
|
6584
7601
|
function describeEntries(projectId, workspaceRoot, routePrefix, modules, closures, allDependencies, diagnostics, tags) {
|
|
6585
7602
|
const moduleByObject = /* @__PURE__ */ new Map();
|
|
6586
7603
|
for (const item of modules) moduleByObject.set(item.value, item);
|
|
6587
7604
|
const idBySource = /* @__PURE__ */ new Map();
|
|
6588
7605
|
for (const item of modules) {
|
|
6589
|
-
const relative3 =
|
|
7606
|
+
const relative3 = path9.relative(workspaceRoot, item.source);
|
|
6590
7607
|
if (!isWithin(workspaceRoot, item.source)) {
|
|
6591
7608
|
diagnostics.push({
|
|
6592
7609
|
code: "DISCOVERY_SOURCE_OUTSIDE_WORKSPACE",
|
|
@@ -6699,7 +7716,7 @@ function describeEntries(projectId, workspaceRoot, routePrefix, modules, closure
|
|
|
6699
7716
|
liveEntries.set(id, entry);
|
|
6700
7717
|
if (module.kind === "guide") {
|
|
6701
7718
|
const markdown = asArray2(entry.mdFile).map(
|
|
6702
|
-
(file) => normalizeAbsolute(String(file),
|
|
7719
|
+
(file) => normalizeAbsolute(String(file), path9.dirname(module.source))
|
|
6703
7720
|
);
|
|
6704
7721
|
for (const file of markdown) allDependencies.observeFile(file);
|
|
6705
7722
|
return {
|
|
@@ -6772,7 +7789,7 @@ function guideKeywords(mdFile, source, dependencies) {
|
|
|
6772
7789
|
const keywords = /* @__PURE__ */ new Set();
|
|
6773
7790
|
for (const file of asArray2(mdFile)) {
|
|
6774
7791
|
try {
|
|
6775
|
-
const text = dependencies.readFile(normalizeAbsolute(String(file),
|
|
7792
|
+
const text = dependencies.readFile(normalizeAbsolute(String(file), path9.dirname(source)));
|
|
6776
7793
|
const keyword = text ? matter2(text.toString("utf8")).data.keyword : void 0;
|
|
6777
7794
|
if (typeof keyword === "string" && keyword) keywords.add(`*${keyword}`);
|
|
6778
7795
|
} catch {
|
|
@@ -6823,6 +7840,58 @@ function validGlobalKeywords(value, source, diagnostics) {
|
|
|
6823
7840
|
}
|
|
6824
7841
|
return valid;
|
|
6825
7842
|
}
|
|
7843
|
+
function shikiLanguages(value, source, diagnostics) {
|
|
7844
|
+
if (value === void 0) return [];
|
|
7845
|
+
const invalid = (message2) => {
|
|
7846
|
+
diagnostics.push({
|
|
7847
|
+
code: "DISCOVERY_SHIKI_LANGUAGE_INVALID",
|
|
7848
|
+
severity: "error",
|
|
7849
|
+
stage: "evaluation",
|
|
7850
|
+
message: message2,
|
|
7851
|
+
source: { path: source }
|
|
7852
|
+
});
|
|
7853
|
+
return [];
|
|
7854
|
+
};
|
|
7855
|
+
if (!Array.isArray(value))
|
|
7856
|
+
return invalid("shiki.langs must be an array of Shiki language registrations.");
|
|
7857
|
+
const languages = [];
|
|
7858
|
+
for (const [index, entry] of value.entries()) {
|
|
7859
|
+
for (const item of Array.isArray(entry) ? entry : [entry]) {
|
|
7860
|
+
const json = plainJson(item, 0);
|
|
7861
|
+
if (!json || typeof json !== "object" || Array.isArray(json) || typeof json["name"] !== "string" || !json["name"] || typeof json["scopeName"] !== "string" || !json["scopeName"])
|
|
7862
|
+
return invalid(
|
|
7863
|
+
`shiki.langs[${index}] is not a Shiki language registration: plain JSON data with a name and a scopeName. Import the grammar instead of passing a function or a promise.`
|
|
7864
|
+
);
|
|
7865
|
+
languages.push(json);
|
|
7866
|
+
}
|
|
7867
|
+
}
|
|
7868
|
+
return languages;
|
|
7869
|
+
}
|
|
7870
|
+
function plainJson(value, depth) {
|
|
7871
|
+
if (depth > 256) return void 0;
|
|
7872
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") return value;
|
|
7873
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
7874
|
+
if (Array.isArray(value)) {
|
|
7875
|
+
const copy2 = [];
|
|
7876
|
+
for (const item of value) {
|
|
7877
|
+
const json = plainJson(item, depth + 1);
|
|
7878
|
+
if (json === void 0) return void 0;
|
|
7879
|
+
copy2.push(json);
|
|
7880
|
+
}
|
|
7881
|
+
return copy2;
|
|
7882
|
+
}
|
|
7883
|
+
if (typeof value !== "object") return void 0;
|
|
7884
|
+
const prototype = Object.getPrototypeOf(value);
|
|
7885
|
+
if (prototype !== null && Object.getPrototypeOf(prototype) !== null || Object.prototype.toString.call(value) !== "[object Object]")
|
|
7886
|
+
return void 0;
|
|
7887
|
+
const copy = {};
|
|
7888
|
+
for (const [key, item] of Object.entries(value)) {
|
|
7889
|
+
const json = plainJson(item, depth + 1);
|
|
7890
|
+
if (json === void 0) return void 0;
|
|
7891
|
+
copy[key] = json;
|
|
7892
|
+
}
|
|
7893
|
+
return copy;
|
|
7894
|
+
}
|
|
6826
7895
|
function normalizeKeywords(value) {
|
|
6827
7896
|
return Object.entries(value).sort(([left], [right]) => compareCodeUnits(left, right)).map(([key, keyword]) => ({
|
|
6828
7897
|
key,
|
|
@@ -6834,12 +7903,12 @@ function normalizeKeywords(value) {
|
|
|
6834
7903
|
}));
|
|
6835
7904
|
}
|
|
6836
7905
|
function observeResolutionCandidates(target, dependencies) {
|
|
6837
|
-
const extension =
|
|
7906
|
+
const extension = path9.extname(target);
|
|
6838
7907
|
const candidates = [".ts", ".tsx", ".js", ".mjs", ".cjs", ".json"].includes(extension) ? [target] : [
|
|
6839
7908
|
target,
|
|
6840
7909
|
...[".ts", ".tsx", ".js", ".mjs", ".cjs", ".json"].map((suffix) => `${target}${suffix}`),
|
|
6841
7910
|
...[".ts", ".tsx", ".js", ".mjs", ".cjs"].map(
|
|
6842
|
-
(suffix) =>
|
|
7911
|
+
(suffix) => path9.join(target, `index${suffix}`)
|
|
6843
7912
|
)
|
|
6844
7913
|
];
|
|
6845
7914
|
for (const candidate of candidates)
|
|
@@ -6851,7 +7920,7 @@ function observeResolutionCandidates(target, dependencies) {
|
|
|
6851
7920
|
return candidates.map(normalizePath2);
|
|
6852
7921
|
}
|
|
6853
7922
|
function kindFor(file) {
|
|
6854
|
-
const basename2 =
|
|
7923
|
+
const basename2 = path9.basename(file);
|
|
6855
7924
|
const kind = ENTRY_KIND.get(basename2);
|
|
6856
7925
|
if (!kind) throw new Error(`Unsupported description filename: ${file}`);
|
|
6857
7926
|
return kind;
|
|
@@ -6861,12 +7930,12 @@ function entryRoute(kind, entry, source) {
|
|
|
6861
7930
|
if (kind === "guide") {
|
|
6862
7931
|
if (typeof route === "object" && route !== null)
|
|
6863
7932
|
return normalizeRoute(
|
|
6864
|
-
String(route.path ??
|
|
7933
|
+
String(route.path ?? path9.basename(path9.dirname(source)))
|
|
6865
7934
|
);
|
|
6866
|
-
return normalizeRoute(String(route ??
|
|
7935
|
+
return normalizeRoute(String(route ?? path9.basename(path9.dirname(source))));
|
|
6867
7936
|
}
|
|
6868
7937
|
if (kind === "api") return normalizeRoute(String(route ?? "api"));
|
|
6869
|
-
return normalizeRoute(String(route ??
|
|
7938
|
+
return normalizeRoute(String(route ?? path9.basename(path9.dirname(source))));
|
|
6870
7939
|
}
|
|
6871
7940
|
function stableId(projectId, kind, relativeSource) {
|
|
6872
7941
|
return `${projectId}:${kind}:${sha256Hex(relativeSource).slice(0, 16)}`;
|
|
@@ -6879,23 +7948,23 @@ function digestDependencies(dependencies) {
|
|
|
6879
7948
|
);
|
|
6880
7949
|
}
|
|
6881
7950
|
function normalizeAbsolute(value, base) {
|
|
6882
|
-
const absolute =
|
|
7951
|
+
const absolute = path9.isAbsolute(value) ? path9.resolve(value) : path9.resolve(base ?? process.cwd(), value);
|
|
6883
7952
|
if (existsSync6(absolute)) return normalizePath2(realpathSync2.native(absolute));
|
|
6884
|
-
const existingParent = nearestExistingParent(
|
|
7953
|
+
const existingParent = nearestExistingParent(path9.dirname(absolute));
|
|
6885
7954
|
const canonicalParent = realpathSync2.native(existingParent);
|
|
6886
|
-
return normalizePath2(
|
|
7955
|
+
return normalizePath2(path9.join(canonicalParent, path9.relative(existingParent, absolute)));
|
|
6887
7956
|
}
|
|
6888
7957
|
function nearestExistingParent(value) {
|
|
6889
|
-
let
|
|
6890
|
-
while (!existsSync6(
|
|
6891
|
-
const parent =
|
|
6892
|
-
if (parent ===
|
|
6893
|
-
|
|
7958
|
+
let current2 = value;
|
|
7959
|
+
while (!existsSync6(current2)) {
|
|
7960
|
+
const parent = path9.dirname(current2);
|
|
7961
|
+
if (parent === current2) return current2;
|
|
7962
|
+
current2 = parent;
|
|
6894
7963
|
}
|
|
6895
|
-
return
|
|
7964
|
+
return current2;
|
|
6896
7965
|
}
|
|
6897
7966
|
function normalizePath2(value) {
|
|
6898
|
-
return value.replaceAll(
|
|
7967
|
+
return value.replaceAll(path9.sep, "/");
|
|
6899
7968
|
}
|
|
6900
7969
|
function normalizeRoute(value) {
|
|
6901
7970
|
return value.replaceAll("\\", "/").split("/").filter(Boolean).join("/");
|
|
@@ -6979,7 +8048,7 @@ var FUNCTION_KEYS = /* @__PURE__ */ new Set([
|
|
|
6979
8048
|
function canonicalValue(root) {
|
|
6980
8049
|
const seen = /* @__PURE__ */ new Map();
|
|
6981
8050
|
let functions = false;
|
|
6982
|
-
const
|
|
8051
|
+
const visit9 = (value2, at) => {
|
|
6983
8052
|
if (value2 === null || typeof value2 === "string" || typeof value2 === "boolean") return value2;
|
|
6984
8053
|
if (typeof value2 === "number")
|
|
6985
8054
|
return Number.isFinite(value2) ? value2 : { $number: String(value2) };
|
|
@@ -7013,11 +8082,11 @@ function canonicalValue(root) {
|
|
|
7013
8082
|
if (typeof key === "symbol" || skipped.has(key)) continue;
|
|
7014
8083
|
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
7015
8084
|
if (!("value" in descriptor)) throw new Unattested(`accessor at ${at}.${key}`);
|
|
7016
|
-
result.push([key,
|
|
8085
|
+
result.push([key, visit9(descriptor.value, `${at}.${key}`)]);
|
|
7017
8086
|
}
|
|
7018
8087
|
return result.sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
|
|
7019
8088
|
};
|
|
7020
|
-
const value =
|
|
8089
|
+
const value = visit9(root, "$");
|
|
7021
8090
|
return { value, functions };
|
|
7022
8091
|
}
|
|
7023
8092
|
function sortDependencies(dependencies) {
|
|
@@ -7035,8 +8104,8 @@ function dependenciesForEntry(all, source, related = []) {
|
|
|
7035
8104
|
return all.filter((item) => "path" in item && paths.has(item.path));
|
|
7036
8105
|
}
|
|
7037
8106
|
function isWithin(parent, child) {
|
|
7038
|
-
const relative3 =
|
|
7039
|
-
return relative3 !== ".." && !relative3.startsWith(`..${
|
|
8107
|
+
const relative3 = path9.relative(parent, child);
|
|
8108
|
+
return relative3 !== ".." && !relative3.startsWith(`..${path9.sep}`) && !path9.isAbsolute(relative3);
|
|
7040
8109
|
}
|
|
7041
8110
|
function throwIfAborted(signal) {
|
|
7042
8111
|
if (signal.aborted) throw signal.reason ?? new Error("Discovery was aborted.");
|
|
@@ -7065,27 +8134,27 @@ function awaitWithLimits(value, signal, timeoutMs) {
|
|
|
7065
8134
|
});
|
|
7066
8135
|
}
|
|
7067
8136
|
function jsonData(value, omitOptional = true) {
|
|
7068
|
-
const
|
|
7069
|
-
function
|
|
8137
|
+
const active2 = /* @__PURE__ */ new Set();
|
|
8138
|
+
function visit9(input) {
|
|
7070
8139
|
if (input === null || typeof input === "string" || typeof input === "boolean") return input;
|
|
7071
8140
|
if (typeof input === "number" && Number.isFinite(input)) return input;
|
|
7072
|
-
if (typeof input !== "object" || input === null ||
|
|
8141
|
+
if (typeof input !== "object" || input === null || active2.has(input)) {
|
|
7073
8142
|
throw new TypeError("Discovery produced a non-JSON value.");
|
|
7074
8143
|
}
|
|
7075
|
-
|
|
8144
|
+
active2.add(input);
|
|
7076
8145
|
try {
|
|
7077
|
-
if (Array.isArray(input)) return Array.from(input,
|
|
8146
|
+
if (Array.isArray(input)) return Array.from(input, visit9);
|
|
7078
8147
|
if (Object.prototype.toString.call(input) !== "[object Object]") {
|
|
7079
8148
|
throw new TypeError("Discovery produced a non-JSON object.");
|
|
7080
8149
|
}
|
|
7081
8150
|
return Object.fromEntries(
|
|
7082
|
-
Object.entries(input).filter(([, item]) => !omitOptional || item !== void 0).map(([key, item]) => [key,
|
|
8151
|
+
Object.entries(input).filter(([, item]) => !omitOptional || item !== void 0).map(([key, item]) => [key, visit9(item)])
|
|
7083
8152
|
);
|
|
7084
8153
|
} finally {
|
|
7085
|
-
|
|
8154
|
+
active2.delete(input);
|
|
7086
8155
|
}
|
|
7087
8156
|
}
|
|
7088
|
-
return
|
|
8157
|
+
return visit9(value);
|
|
7089
8158
|
}
|
|
7090
8159
|
function failure(dependencies, diagnostics) {
|
|
7091
8160
|
return { dependencies: dependencies.all(), diagnostics };
|
|
@@ -7107,7 +8176,7 @@ function isBuildFailure(error) {
|
|
|
7107
8176
|
}
|
|
7108
8177
|
|
|
7109
8178
|
// libs/builder/generator/outputs/index.ts
|
|
7110
|
-
import { existsSync as existsSync7, readFileSync as
|
|
8179
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
|
|
7111
8180
|
import { dirname, isAbsolute, posix, relative, resolve, sep } from "node:path";
|
|
7112
8181
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
7113
8182
|
import { Environment, Loader } from "nunjucks";
|
|
@@ -7142,8 +8211,43 @@ var STRUCTURAL_TEMPLATES = [
|
|
|
7142
8211
|
"api-list.ts.nunj",
|
|
7143
8212
|
"routes.ts.nunj",
|
|
7144
8213
|
"context.ts.nunj",
|
|
7145
|
-
"index.ts.nunj"
|
|
8214
|
+
"index.ts.nunj",
|
|
8215
|
+
"demo-routes.ts.nunj",
|
|
8216
|
+
"demo-app.ts.nunj"
|
|
7146
8217
|
];
|
|
8218
|
+
var DEFAULT_DEMO_PATH2 = "demo-preview";
|
|
8219
|
+
var DEMO_NAME = /^[A-Za-z0-9_$-]+$/;
|
|
8220
|
+
var DEMO_ACTION = /<ng-doc-demo\b[^>]*>\s*<div\b[^>]*\bid="options"[^>]*>([^<]*)<\/div>/g;
|
|
8221
|
+
function demoSettings(configuration) {
|
|
8222
|
+
const settings2 = configuration.demoApplication;
|
|
8223
|
+
return {
|
|
8224
|
+
pages: settings2?.pages ?? "isolated",
|
|
8225
|
+
isolated: settings2?.isolated === true,
|
|
8226
|
+
path: settings2?.path ?? DEFAULT_DEMO_PATH2,
|
|
8227
|
+
...settings2?.providers ? { providers: settings2.providers } : {}
|
|
8228
|
+
};
|
|
8229
|
+
}
|
|
8230
|
+
function decodeHtmlText(value) {
|
|
8231
|
+
return value.replace(
|
|
8232
|
+
/&(?:#x([0-9a-f]+)|#([0-9]+)|(amp|lt|gt|quot|apos));/gi,
|
|
8233
|
+
(all, hex, dec, name) => {
|
|
8234
|
+
if (hex) return String.fromCodePoint(parseInt(hex, 16));
|
|
8235
|
+
if (dec) return String.fromCodePoint(parseInt(dec, 10));
|
|
8236
|
+
return { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" }[String(name).toLowerCase()] ?? all;
|
|
8237
|
+
}
|
|
8238
|
+
);
|
|
8239
|
+
}
|
|
8240
|
+
function hasIsolatedDemo(html) {
|
|
8241
|
+
for (const match of html?.matchAll(DEMO_ACTION) ?? []) {
|
|
8242
|
+
try {
|
|
8243
|
+
if (JSON.parse(decodeHtmlText(match[1]))?.isolated === true) {
|
|
8244
|
+
return true;
|
|
8245
|
+
}
|
|
8246
|
+
} catch {
|
|
8247
|
+
}
|
|
8248
|
+
}
|
|
8249
|
+
return false;
|
|
8250
|
+
}
|
|
7147
8251
|
function pageAssemblyKey(request, templates) {
|
|
7148
8252
|
const text = canonicalJsonStrict({
|
|
7149
8253
|
schema: "page-assembly-key-v1",
|
|
@@ -7172,7 +8276,7 @@ function moduleSpecifier(fromDirectory, target) {
|
|
|
7172
8276
|
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
7173
8277
|
}
|
|
7174
8278
|
function templateString(value) {
|
|
7175
|
-
return String(value ?? "").replace(/`/g, "\\`").replace(/\$\{/g, "\\${").replace(/{/g, "\\{").replace(/}/g, "\\}");
|
|
8279
|
+
return String(value ?? "").replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${").replace(/{/g, "\\{").replace(/}/g, "\\}");
|
|
7176
8280
|
}
|
|
7177
8281
|
function escapeAttribute2(value) {
|
|
7178
8282
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -7205,24 +8309,24 @@ function safeRelative(value) {
|
|
|
7205
8309
|
function joinOutput(...parts) {
|
|
7206
8310
|
return safeRelative(posix.join(...parts.map(normalize)));
|
|
7207
8311
|
}
|
|
7208
|
-
function output(
|
|
7209
|
-
return { path:
|
|
8312
|
+
function output(path18, role, content) {
|
|
8313
|
+
return { path: path18, role, encoding: "utf8", content, digest: sha256Hex(content) };
|
|
7210
8314
|
}
|
|
7211
8315
|
function addOutput(outputs, candidate, diagnostics, ownerId) {
|
|
7212
|
-
const
|
|
7213
|
-
if (!
|
|
8316
|
+
const path18 = safeRelative(candidate.path);
|
|
8317
|
+
if (!path18) {
|
|
7214
8318
|
diagnostics.push(
|
|
7215
8319
|
diagnostic2("OUTPUT_PATH_INVALID", `Unsafe generated output path: ${candidate.path}`, ownerId)
|
|
7216
8320
|
);
|
|
7217
8321
|
return;
|
|
7218
8322
|
}
|
|
7219
|
-
if (outputs.has(
|
|
8323
|
+
if (outputs.has(path18)) {
|
|
7220
8324
|
diagnostics.push(
|
|
7221
|
-
diagnostic2("OUTPUT_COLLISION", `Generated output collision: ${
|
|
8325
|
+
diagnostic2("OUTPUT_COLLISION", `Generated output collision: ${path18}`, ownerId)
|
|
7222
8326
|
);
|
|
7223
8327
|
return;
|
|
7224
8328
|
}
|
|
7225
|
-
outputs.set(
|
|
8329
|
+
outputs.set(path18, { ...candidate, path: path18 });
|
|
7226
8330
|
}
|
|
7227
8331
|
function isWithin2(parent, child) {
|
|
7228
8332
|
const value = relative(resolve(parent), resolve(child));
|
|
@@ -7271,29 +8375,29 @@ function apiListType(declaration) {
|
|
|
7271
8375
|
return kind ? `${kind[0].toUpperCase()}${kind.slice(1)}` : "";
|
|
7272
8376
|
}
|
|
7273
8377
|
function strictJson(value) {
|
|
7274
|
-
const
|
|
7275
|
-
const
|
|
8378
|
+
const active2 = /* @__PURE__ */ new Set();
|
|
8379
|
+
const visit9 = (item) => {
|
|
7276
8380
|
if (item === null || typeof item === "string" || typeof item === "boolean") return;
|
|
7277
8381
|
if (typeof item === "number" && Number.isFinite(item) && !Object.is(item, -0)) return;
|
|
7278
|
-
if (typeof item !== "object" || item === null ||
|
|
8382
|
+
if (typeof item !== "object" || item === null || active2.has(item)) {
|
|
7279
8383
|
throw new TypeError("Aggregate JSON must be a finite, acyclic JSON tree.");
|
|
7280
8384
|
}
|
|
7281
|
-
|
|
8385
|
+
active2.add(item);
|
|
7282
8386
|
try {
|
|
7283
8387
|
if (Array.isArray(item)) {
|
|
7284
8388
|
if (Object.keys(item).length !== item.length)
|
|
7285
8389
|
throw new TypeError("Aggregate JSON arrays cannot be sparse.");
|
|
7286
|
-
item.forEach(
|
|
8390
|
+
item.forEach(visit9);
|
|
7287
8391
|
} else {
|
|
7288
8392
|
if (Object.prototype.toString.call(item) !== "[object Object]")
|
|
7289
8393
|
throw new TypeError("Aggregate JSON contains an unsupported object.");
|
|
7290
|
-
for (const child of Object.values(item))
|
|
8394
|
+
for (const child of Object.values(item)) visit9(child);
|
|
7291
8395
|
}
|
|
7292
8396
|
} finally {
|
|
7293
|
-
|
|
8397
|
+
active2.delete(item);
|
|
7294
8398
|
}
|
|
7295
8399
|
};
|
|
7296
|
-
|
|
8400
|
+
visit9(value);
|
|
7297
8401
|
return JSON.stringify(value);
|
|
7298
8402
|
}
|
|
7299
8403
|
function tree(values, diagnostics) {
|
|
@@ -7348,27 +8452,27 @@ function pruneEmptyCategories(nodes) {
|
|
|
7348
8452
|
}
|
|
7349
8453
|
function validateRoutePaths(nodes, diagnostics, parentPath = "", seen = /* @__PURE__ */ new Map()) {
|
|
7350
8454
|
for (const node of nodes) {
|
|
7351
|
-
const
|
|
7352
|
-
const owner = seen.get(
|
|
8455
|
+
const path18 = posix.join(parentPath, normalize(node.item.route)).replace(/^\/+|\/+$/g, "");
|
|
8456
|
+
const owner = seen.get(path18);
|
|
7353
8457
|
if (owner && owner !== node.item.id) {
|
|
7354
8458
|
diagnostics.push(
|
|
7355
8459
|
diagnostic2(
|
|
7356
8460
|
"OUTPUT_ROUTE_PATH_COLLISION",
|
|
7357
|
-
`Routes ${owner} and ${node.item.id} resolve to the same public path: ${
|
|
8461
|
+
`Routes ${owner} and ${node.item.id} resolve to the same public path: ${path18}`,
|
|
7358
8462
|
node.item.id
|
|
7359
8463
|
)
|
|
7360
8464
|
);
|
|
7361
8465
|
} else {
|
|
7362
|
-
seen.set(
|
|
8466
|
+
seen.set(path18, node.item.id);
|
|
7363
8467
|
}
|
|
7364
|
-
validateRoutePaths(node.children, diagnostics,
|
|
8468
|
+
validateRoutePaths(node.children, diagnostics, path18, seen);
|
|
7365
8469
|
}
|
|
7366
8470
|
}
|
|
7367
8471
|
function validateOutputOwnership(artifacts, aggregate, diagnostics) {
|
|
7368
8472
|
const owners = /* @__PURE__ */ new Map();
|
|
7369
8473
|
const observe2 = (candidate, ownerId) => {
|
|
7370
|
-
const
|
|
7371
|
-
if (!
|
|
8474
|
+
const path18 = safeRelative(candidate.path);
|
|
8475
|
+
if (!path18) {
|
|
7372
8476
|
diagnostics.push(
|
|
7373
8477
|
diagnostic2(
|
|
7374
8478
|
"OUTPUT_PATH_INVALID",
|
|
@@ -7378,18 +8482,18 @@ function validateOutputOwnership(artifacts, aggregate, diagnostics) {
|
|
|
7378
8482
|
);
|
|
7379
8483
|
return;
|
|
7380
8484
|
}
|
|
7381
|
-
const previous = owners.get(
|
|
8485
|
+
const previous = owners.get(path18);
|
|
7382
8486
|
if (previous) {
|
|
7383
8487
|
diagnostics.push(
|
|
7384
8488
|
diagnostic2(
|
|
7385
8489
|
"OUTPUT_CANDIDATE_COLLISION",
|
|
7386
|
-
`Artifacts ${previous} and ${ownerId} both own generated output ${
|
|
8490
|
+
`Artifacts ${previous} and ${ownerId} both own generated output ${path18}.`,
|
|
7387
8491
|
ownerId
|
|
7388
8492
|
)
|
|
7389
8493
|
);
|
|
7390
8494
|
return;
|
|
7391
8495
|
}
|
|
7392
|
-
owners.set(
|
|
8496
|
+
owners.set(path18, ownerId);
|
|
7393
8497
|
};
|
|
7394
8498
|
for (const artifact of artifacts) {
|
|
7395
8499
|
for (const candidate of artifact.outputs) observe2(candidate, artifact.id);
|
|
@@ -7398,11 +8502,11 @@ function validateOutputOwnership(artifacts, aggregate, diagnostics) {
|
|
|
7398
8502
|
}
|
|
7399
8503
|
function keywordMap(keywords) {
|
|
7400
8504
|
return Object.fromEntries(
|
|
7401
|
-
keywords.map(({ key, title, path:
|
|
8505
|
+
keywords.map(({ key, title, path: path18, type, languages, description }) => [
|
|
7402
8506
|
key,
|
|
7403
8507
|
{
|
|
7404
8508
|
title,
|
|
7405
|
-
path:
|
|
8509
|
+
path: path18,
|
|
7406
8510
|
...type === void 0 ? {} : { type },
|
|
7407
8511
|
...languages === void 0 ? {} : { languages },
|
|
7408
8512
|
...description === void 0 ? {} : { description }
|
|
@@ -7420,7 +8524,7 @@ var StructuralLoader = class extends Loader {
|
|
|
7420
8524
|
if (!isWithin2(this.root, source) || !existsSync7(source)) {
|
|
7421
8525
|
throw new Error(`Structural template not found: ${source}`);
|
|
7422
8526
|
}
|
|
7423
|
-
return { src:
|
|
8527
|
+
return { src: readFileSync7(source, "utf8"), path: source, noCache: true };
|
|
7424
8528
|
}
|
|
7425
8529
|
};
|
|
7426
8530
|
function render2(root, name, context) {
|
|
@@ -7431,7 +8535,7 @@ function render2(root, name, context) {
|
|
|
7431
8535
|
environment.addFilter("toTemplateString", templateString);
|
|
7432
8536
|
environment.addFilter(
|
|
7433
8537
|
"createImportPath",
|
|
7434
|
-
(
|
|
8538
|
+
(current2, target) => relativeImport(current2, target)
|
|
7435
8539
|
);
|
|
7436
8540
|
environment.addFilter("dump", (value) => strictJson(value));
|
|
7437
8541
|
environment.addFilter(
|
|
@@ -7628,7 +8732,7 @@ function validateDescriptorPartition(request, diagnostics) {
|
|
|
7628
8732
|
const markdown = descriptors.filter((descriptor) => descriptor.role === "guide-tab").map(
|
|
7629
8733
|
(descriptor) => descriptor.locator.kind === "guide-tab" ? descriptor.locator.markdown : ""
|
|
7630
8734
|
);
|
|
7631
|
-
if (markdown.length !== guide.markdown.length || new Set(markdown).size !== markdown.length || markdown.some((
|
|
8735
|
+
if (markdown.length !== guide.markdown.length || new Set(markdown).size !== markdown.length || markdown.some((path18, index) => path18 !== guide.markdown[index]) || descriptors.some((descriptor) => descriptor.role === "api-tab"))
|
|
7632
8736
|
diagnostics.push(
|
|
7633
8737
|
diagnostic2(
|
|
7634
8738
|
"OUTPUT_DESCRIPTOR_MEMBERSHIP",
|
|
@@ -7640,18 +8744,18 @@ function validateDescriptorPartition(request, diagnostics) {
|
|
|
7640
8744
|
const closures = new Map(descriptors.map((descriptor) => [descriptor.id, descriptor.closureIds]));
|
|
7641
8745
|
const visiting = /* @__PURE__ */ new Set();
|
|
7642
8746
|
const visited2 = /* @__PURE__ */ new Set();
|
|
7643
|
-
const
|
|
8747
|
+
const visit9 = (id) => {
|
|
7644
8748
|
if (visiting.has(id)) return false;
|
|
7645
8749
|
if (visited2.has(id)) return true;
|
|
7646
8750
|
visiting.add(id);
|
|
7647
8751
|
const ok = (closures.get(id) ?? []).every(
|
|
7648
|
-
(dependency) => ids.has(dependency) &&
|
|
8752
|
+
(dependency) => ids.has(dependency) && visit9(dependency)
|
|
7649
8753
|
);
|
|
7650
8754
|
visiting.delete(id);
|
|
7651
8755
|
visited2.add(id);
|
|
7652
8756
|
return ok;
|
|
7653
8757
|
};
|
|
7654
|
-
if (![...ids].every(
|
|
8758
|
+
if (![...ids].every(visit9))
|
|
7655
8759
|
diagnostics.push(
|
|
7656
8760
|
diagnostic2(
|
|
7657
8761
|
"OUTPUT_DESCRIPTOR_CLOSURE",
|
|
@@ -7706,15 +8810,15 @@ var OutputAssemblerImpl = class {
|
|
|
7706
8810
|
const dependencies = [];
|
|
7707
8811
|
const diagnostics = [];
|
|
7708
8812
|
for (const name of STRUCTURAL_TEMPLATES) {
|
|
7709
|
-
const
|
|
8813
|
+
const path18 = hostPath(resolve(this.templateRoot, name));
|
|
7710
8814
|
try {
|
|
7711
|
-
dependencies.push({ kind: "content", path:
|
|
8815
|
+
dependencies.push({ kind: "content", path: path18, digest: (await readTextFile(path18)).digest });
|
|
7712
8816
|
} catch (error) {
|
|
7713
|
-
dependencies.push({ kind: "existence", path:
|
|
8817
|
+
dependencies.push({ kind: "existence", path: path18, exists: false });
|
|
7714
8818
|
diagnostics.push(
|
|
7715
8819
|
diagnostic2(
|
|
7716
8820
|
"OUTPUT_TEMPLATE_READ",
|
|
7717
|
-
`Cannot read structural template ${
|
|
8821
|
+
`Cannot read structural template ${path18}: ${String(error)}`
|
|
7718
8822
|
)
|
|
7719
8823
|
);
|
|
7720
8824
|
}
|
|
@@ -7791,7 +8895,9 @@ var OutputAssemblerImpl = class {
|
|
|
7791
8895
|
// Every API list the site has, so the search palette requests no other one.
|
|
7792
8896
|
apiLists: request.entries.filter((entry) => entry.kind === "api").map((entry) => apiAssetRoute(entry, request.configuration))
|
|
7793
8897
|
});
|
|
7794
|
-
this.renderOutput(outputs, diagnostics, "index.ts", "angular", "index.ts.nunj", {
|
|
8898
|
+
this.renderOutput(outputs, diagnostics, "index.ts", "angular", "index.ts.nunj", {
|
|
8899
|
+
demoApplication: this.demoApplication(request, records, outputs, diagnostics)
|
|
8900
|
+
});
|
|
7795
8901
|
const searchPath = joinOutput(request.configuration.assetDirectory, "indexes.json");
|
|
7796
8902
|
const keywordPath = joinOutput(request.configuration.assetDirectory, "keywords.json");
|
|
7797
8903
|
if (!searchPath || !keywordPath) {
|
|
@@ -7855,6 +8961,8 @@ var OutputAssemblerImpl = class {
|
|
|
7855
8961
|
const wrapperPath = joinOutput(directory, "page.ts");
|
|
7856
8962
|
const demoPath = joinOutput(directory, "demo-assets.ts");
|
|
7857
8963
|
const playgroundPath = joinOutput(directory, "playgrounds.ts");
|
|
8964
|
+
const demoPages = this.demoRoutes(request, directory, [header2, ...tabs], outputs, diagnostics);
|
|
8965
|
+
const demoSettingsOfPage = demoSettings(request.configuration);
|
|
7858
8966
|
const tabEntries = {};
|
|
7859
8967
|
for (const tab of tabs) {
|
|
7860
8968
|
const tabPath = joinOutput(directory, tab.route || "index", "page.ts");
|
|
@@ -7884,6 +8992,10 @@ var OutputAssemblerImpl = class {
|
|
|
7884
8992
|
pageType: "guide",
|
|
7885
8993
|
entryPath: request.entry.runtimeImport.source,
|
|
7886
8994
|
entryHasImports: request.entry.hasImports,
|
|
8995
|
+
...demoPages ? {
|
|
8996
|
+
demoRoute: `${demoSettingsOfPage.path}/${request.entry.absoluteRoute}`,
|
|
8997
|
+
isolatedDemos: demoSettingsOfPage.isolated
|
|
8998
|
+
} : {},
|
|
7887
8999
|
demoAssetsPath: resolve(request.configuration.outputRoot, demoPath),
|
|
7888
9000
|
playgroundsPath: resolve(request.configuration.outputRoot, playgroundPath)
|
|
7889
9001
|
},
|
|
@@ -7979,8 +9091,55 @@ var OutputAssemblerImpl = class {
|
|
|
7979
9091
|
...request.entry.order === void 0 ? {} : { order: request.entry.order },
|
|
7980
9092
|
...request.entry.hidden === void 0 ? {} : { hidden: request.entry.hidden },
|
|
7981
9093
|
...request.metadata ? { metadata: request.metadata } : {},
|
|
7982
|
-
modulePath: wrapperPath
|
|
9094
|
+
modulePath: wrapperPath,
|
|
9095
|
+
...demoPages ? { demoModulePath: demoPages.path, demoNames: demoPages.names } : {}
|
|
9096
|
+
});
|
|
9097
|
+
}
|
|
9098
|
+
/**
|
|
9099
|
+
* Writes the guide's demo routes module (one route per demo, under the page's own providers)
|
|
9100
|
+
* when the guide gets demo pages: with `pages: 'all'`, or by default when its content has a demo
|
|
9101
|
+
* with `isolated: true`. Returns its path and the names of the demos that got a page, or
|
|
9102
|
+
* undefined.
|
|
9103
|
+
*/
|
|
9104
|
+
demoRoutes(request, directory, slots, outputs, diagnostics) {
|
|
9105
|
+
const settings2 = demoSettings(request.configuration);
|
|
9106
|
+
const names = Object.keys(request.semantics?.demos ?? {});
|
|
9107
|
+
if (settings2.pages === "none" || !names.length || settings2.pages === "isolated" && !slots.some((slot) => hasIsolatedDemo(slot.linked?.html))) {
|
|
9108
|
+
return void 0;
|
|
9109
|
+
}
|
|
9110
|
+
const demos = names.filter((name) => {
|
|
9111
|
+
if (DEMO_NAME.test(name)) return true;
|
|
9112
|
+
diagnostics.push({
|
|
9113
|
+
...diagnostic2(
|
|
9114
|
+
"OUTPUT_DEMO_NAME_INVALID",
|
|
9115
|
+
`Demo ${JSON.stringify(name)} has no demo page: a demo name must be letters, digits, '_', '$' or '-' to be its page's URL segment.`,
|
|
9116
|
+
request.entry.id
|
|
9117
|
+
),
|
|
9118
|
+
severity: "warning"
|
|
9119
|
+
});
|
|
9120
|
+
return false;
|
|
7983
9121
|
});
|
|
9122
|
+
const path18 = joinOutput(directory, "demo-routes.ts");
|
|
9123
|
+
if (!path18 || !demos.length) return void 0;
|
|
9124
|
+
this.renderOutput(
|
|
9125
|
+
outputs,
|
|
9126
|
+
diagnostics,
|
|
9127
|
+
path18,
|
|
9128
|
+
"angular",
|
|
9129
|
+
"demo-routes.ts.nunj",
|
|
9130
|
+
{
|
|
9131
|
+
entryImport: moduleSpecifier(
|
|
9132
|
+
dirname(resolve(request.configuration.outputRoot, path18)),
|
|
9133
|
+
request.entry.runtimeImport.source
|
|
9134
|
+
),
|
|
9135
|
+
demos: demos.map((name) => ({
|
|
9136
|
+
name,
|
|
9137
|
+
title: `${request.entry.title}: ${name}`
|
|
9138
|
+
}))
|
|
9139
|
+
},
|
|
9140
|
+
request.entry.id
|
|
9141
|
+
);
|
|
9142
|
+
return outputs.has(path18) ? { path: path18, names: demos } : void 0;
|
|
7984
9143
|
}
|
|
7985
9144
|
apiEntry(request, outputs, routes, diagnostics) {
|
|
7986
9145
|
const assetRoute = apiAssetRoute(request.entry, request.configuration);
|
|
@@ -8146,18 +9305,18 @@ var OutputAssemblerImpl = class {
|
|
|
8146
9305
|
...record.signature ? { signature: record.signature } : {}
|
|
8147
9306
|
}))
|
|
8148
9307
|
}));
|
|
8149
|
-
const
|
|
9308
|
+
const path18 = joinOutput(
|
|
8150
9309
|
request.configuration.assetDirectory,
|
|
8151
9310
|
apiAssetRoute(entry, request.configuration),
|
|
8152
9311
|
"api-list.json"
|
|
8153
9312
|
);
|
|
8154
|
-
if (!
|
|
9313
|
+
if (!path18) {
|
|
8155
9314
|
diagnostics.push(
|
|
8156
9315
|
diagnostic2("OUTPUT_PATH_INVALID", `Unsafe API asset route: ${entry.route}`)
|
|
8157
9316
|
);
|
|
8158
9317
|
continue;
|
|
8159
9318
|
}
|
|
8160
|
-
addOutput(outputs, output(
|
|
9319
|
+
addOutput(outputs, output(path18, "api-list", strictJson(lists)), diagnostics, entry.id);
|
|
8161
9320
|
}
|
|
8162
9321
|
}
|
|
8163
9322
|
addContentSource(outputs, diagnostics, componentPath, slot, configuration, ownerId) {
|
|
@@ -8210,11 +9369,48 @@ export default source;
|
|
|
8210
9369
|
ownerId
|
|
8211
9370
|
);
|
|
8212
9371
|
}
|
|
8213
|
-
|
|
8214
|
-
|
|
9372
|
+
/**
|
|
9373
|
+
* Writes `demo-app.ts`, the routes of the demo application (one lazy route per guide with demo
|
|
9374
|
+
* pages, under its categories' providers) and its `demoProviders` import, when a guide has demo
|
|
9375
|
+
* pages. Returns whether it did.
|
|
9376
|
+
*/
|
|
9377
|
+
demoApplication(request, records, outputs, diagnostics) {
|
|
9378
|
+
const settings2 = demoSettings(request.configuration);
|
|
9379
|
+
const outputRoot = resolve(request.configuration.outputRoot);
|
|
9380
|
+
const entries = new Map(request.entries.map((entry) => [entry.id, entry]));
|
|
9381
|
+
const categories = /* @__PURE__ */ new Map();
|
|
9382
|
+
const pages = records.filter((record) => record.demoModulePath && entries.get(record.id)?.kind === "guide").map((record) => {
|
|
9383
|
+
const chain = [];
|
|
9384
|
+
for (let parent = entries.get(record.id)?.parentId; parent !== void 0; parent = entries.get(parent)?.parentId) {
|
|
9385
|
+
const category = entries.get(parent);
|
|
9386
|
+
if (category?.kind !== "category") break;
|
|
9387
|
+
const identifier = categoryIdentifier(request.configuration.projectId, category.id);
|
|
9388
|
+
categories.set(identifier, moduleSpecifier(outputRoot, category.runtimeImport.source));
|
|
9389
|
+
chain.unshift(identifier);
|
|
9390
|
+
}
|
|
9391
|
+
const route = `${settings2.path}/${entries.get(record.id).absoluteRoute}`;
|
|
9392
|
+
return {
|
|
9393
|
+
path: route,
|
|
9394
|
+
demos: (record.demoNames ?? []).map((name) => `${route}/${name}`),
|
|
9395
|
+
categories: chain,
|
|
9396
|
+
importPath: moduleSpecifier(outputRoot, resolve(outputRoot, record.demoModulePath))
|
|
9397
|
+
};
|
|
9398
|
+
}).sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
|
|
9399
|
+
if (!pages.length) return false;
|
|
9400
|
+
this.renderOutput(outputs, diagnostics, "demo-app.ts", "routes", "demo-app.ts.nunj", {
|
|
9401
|
+
demoPath: settings2.path,
|
|
9402
|
+
demoPages: pages.flatMap((page) => page.demos),
|
|
9403
|
+
pages,
|
|
9404
|
+
categories: [...categories].sort(([left], [right]) => left < right ? -1 : 1),
|
|
9405
|
+
...settings2.providers ? { providersImport: moduleSpecifier(outputRoot, settings2.providers) } : {}
|
|
9406
|
+
});
|
|
9407
|
+
return true;
|
|
9408
|
+
}
|
|
9409
|
+
renderOutput(outputs, diagnostics, path18, role, template, context, ownerId) {
|
|
9410
|
+
const safe = safeRelative(path18);
|
|
8215
9411
|
if (!safe) {
|
|
8216
9412
|
diagnostics.push(
|
|
8217
|
-
diagnostic2("OUTPUT_PATH_INVALID", `Unsafe generated output path: ${
|
|
9413
|
+
diagnostic2("OUTPUT_PATH_INVALID", `Unsafe generated output path: ${path18}`, ownerId)
|
|
8218
9414
|
);
|
|
8219
9415
|
return;
|
|
8220
9416
|
}
|
|
@@ -8240,6 +9436,30 @@ function createOutputAssembler(options = {}) {
|
|
|
8240
9436
|
return new OutputAssemblerImpl(options);
|
|
8241
9437
|
}
|
|
8242
9438
|
|
|
9439
|
+
// libs/builder/helpers/format-cache.ts
|
|
9440
|
+
var active;
|
|
9441
|
+
function withFormatCodeCache(cache, run) {
|
|
9442
|
+
const previous = active;
|
|
9443
|
+
active = cache;
|
|
9444
|
+
try {
|
|
9445
|
+
return run();
|
|
9446
|
+
} finally {
|
|
9447
|
+
active = previous;
|
|
9448
|
+
}
|
|
9449
|
+
}
|
|
9450
|
+
function activeFormatCodeCache() {
|
|
9451
|
+
return active;
|
|
9452
|
+
}
|
|
9453
|
+
|
|
9454
|
+
// libs/builder/generator/semantic/formatting.ts
|
|
9455
|
+
var current;
|
|
9456
|
+
function useFormatCache(cache) {
|
|
9457
|
+
current = cache;
|
|
9458
|
+
}
|
|
9459
|
+
function formatting(run) {
|
|
9460
|
+
return withFormatCodeCache(current, run);
|
|
9461
|
+
}
|
|
9462
|
+
|
|
8243
9463
|
// libs/builder/generator/semantic/semantic-service.ts
|
|
8244
9464
|
import { dirname as dirname9, resolve as resolve9 } from "node:path";
|
|
8245
9465
|
import { setImmediate as setImmediate2 } from "node:timers";
|
|
@@ -8306,7 +9526,7 @@ function getComponentInputs(cls) {
|
|
|
8306
9526
|
|
|
8307
9527
|
// libs/builder/helpers/angular/get-component-source-files.ts
|
|
8308
9528
|
init_core();
|
|
8309
|
-
import
|
|
9529
|
+
import path10 from "path";
|
|
8310
9530
|
|
|
8311
9531
|
// libs/builder/helpers/angular/get-component-decorator.ts
|
|
8312
9532
|
import { Node as Node4 } from "ts-morph";
|
|
@@ -8348,12 +9568,12 @@ function getComponentSourceFiles(cls) {
|
|
|
8348
9568
|
const decoratorData = getComponentDecorator(cls);
|
|
8349
9569
|
if (decoratorData) {
|
|
8350
9570
|
const filePath = cls.getSourceFile().getFilePath();
|
|
8351
|
-
const fileDir =
|
|
9571
|
+
const fileDir = path10.dirname(filePath);
|
|
8352
9572
|
return asArray(
|
|
8353
9573
|
filePath,
|
|
8354
|
-
decoratorData.templateUrl ?
|
|
9574
|
+
decoratorData.templateUrl ? path10.join(fileDir, decoratorData.templateUrl) : [],
|
|
8355
9575
|
asArray(decoratorData.styleUrls, decoratorData.styleUrl).map(
|
|
8356
|
-
(styleUrl) =>
|
|
9576
|
+
(styleUrl) => path10.join(fileDir, styleUrl)
|
|
8357
9577
|
)
|
|
8358
9578
|
);
|
|
8359
9579
|
}
|
|
@@ -8626,15 +9846,18 @@ function collect(node, into, seen) {
|
|
|
8626
9846
|
}
|
|
8627
9847
|
}
|
|
8628
9848
|
if (Node13.isEnumDeclaration(declaration)) {
|
|
8629
|
-
declaration.getMembers().forEach((member) => into.push(member.getType().compilerType));
|
|
9849
|
+
declaration.getMembers().forEach((member) => into.push(regularType(member.getType().compilerType)));
|
|
8630
9850
|
return;
|
|
8631
9851
|
}
|
|
8632
9852
|
}
|
|
8633
9853
|
into.push(node.getType().compilerType);
|
|
8634
9854
|
}
|
|
9855
|
+
function regularType(type) {
|
|
9856
|
+
return type.regularType ?? type;
|
|
9857
|
+
}
|
|
8635
9858
|
|
|
8636
9859
|
// libs/builder/helpers/snippets-from-asset.ts
|
|
8637
|
-
import
|
|
9860
|
+
import path12 from "path";
|
|
8638
9861
|
|
|
8639
9862
|
// libs/builder/helpers/process-legacy-snippets.ts
|
|
8640
9863
|
init_core();
|
|
@@ -8687,35 +9910,7 @@ function removeSnippetsInCode(code) {
|
|
|
8687
9910
|
// libs/builder/helpers/process-snippets.ts
|
|
8688
9911
|
init_core();
|
|
8689
9912
|
import * as fs from "fs";
|
|
8690
|
-
import
|
|
8691
|
-
|
|
8692
|
-
// libs/builder/parsers/parse-snippet.ts
|
|
8693
|
-
import P5 from "parsimmon";
|
|
8694
|
-
function parseSnippet(string2) {
|
|
8695
|
-
const parser2 = P5.createLanguage({
|
|
8696
|
-
keyword: () => P5.string("snippet"),
|
|
8697
|
-
id: () => P5.string("#").then(P5.regexp(/[a-zA-Z0-9-]+/)).fallback(null).map((id) => ({ id })),
|
|
8698
|
-
lang: () => P5.string(":").then(P5.regexp(/[a-zA-Z0-9-]+/)).fallback(void 0).map((lang) => ({ lang })),
|
|
8699
|
-
icon: () => param("icon"),
|
|
8700
|
-
title: () => paramValue().map((title) => ({ title })),
|
|
8701
|
-
opened: () => P5.string("opened").result(true).fallback(void 0).map((opened) => ({ opened })),
|
|
8702
|
-
snippet: ({ keyword, id, lang, icon, title, opened }) => keyword.then(
|
|
8703
|
-
P5.seq(
|
|
8704
|
-
id,
|
|
8705
|
-
lang,
|
|
8706
|
-
P5.whitespace.then(title.or(icon).or(opened).sepBy(P5.whitespace)).fallback([])
|
|
8707
|
-
).map(([id2, lang2, rest]) => ({ ...id2, ...lang2, ...Object.assign({}, ...rest) }))
|
|
8708
|
-
),
|
|
8709
|
-
snippetFromFile: ({ lang, icon, title, opened }) => P5.seq(
|
|
8710
|
-
param("snippet-from-file", "fromFile"),
|
|
8711
|
-
lang,
|
|
8712
|
-
P5.whitespace.then(title.or(icon).or(opened).sepBy(P5.whitespace)).fallback([])
|
|
8713
|
-
).map(([id, lang2, rest]) => ({ ...id, ...lang2, ...Object.assign({}, ...rest) })),
|
|
8714
|
-
anySnippet: ({ snippet: snippet2, snippetFromFile }) => snippetFromFile.or(snippet2)
|
|
8715
|
-
});
|
|
8716
|
-
const result = parser2.anySnippet.parse(string2);
|
|
8717
|
-
return result.status ? result.value : void 0;
|
|
8718
|
-
}
|
|
9913
|
+
import path11 from "path";
|
|
8719
9914
|
|
|
8720
9915
|
// libs/builder/helpers/format-code.ts
|
|
8721
9916
|
import prettierSync from "@prettier/sync";
|
|
@@ -8724,16 +9919,19 @@ function formatCode(code, codeType = "TypeScript", configDirectory) {
|
|
|
8724
9919
|
try {
|
|
8725
9920
|
if (codeType) {
|
|
8726
9921
|
const parser2 = getPrettierParserFromCodeType(codeType);
|
|
8727
|
-
const
|
|
9922
|
+
const cache = activeFormatCodeCache();
|
|
9923
|
+
const resolve10 = () => prettierSync.resolveConfig(
|
|
8728
9924
|
// Prettier searches from a file's parent, so use a synthetic path inside the directory.
|
|
8729
9925
|
configDirectory ? join(configDirectory, "__ng_doc_format__.ts") : process.cwd(),
|
|
8730
9926
|
{ editorconfig: true, useCache: false }
|
|
8731
9927
|
);
|
|
8732
|
-
|
|
9928
|
+
const config = cache ? cache.config(configDirectory, resolve10) : resolve10();
|
|
9929
|
+
const format = () => prettierSync.format(code, {
|
|
8733
9930
|
...config,
|
|
8734
9931
|
parser: parser2,
|
|
8735
9932
|
embeddedLanguageFormatting: "auto"
|
|
8736
9933
|
}).trim();
|
|
9934
|
+
return cache && typeof parser2 === "string" ? cache.format({ code, parser: parser2, config }, format) : format();
|
|
8737
9935
|
}
|
|
8738
9936
|
return code.trim();
|
|
8739
9937
|
} catch (e) {
|
|
@@ -8806,9 +10004,9 @@ function processSnippets(code, basePath, configDirectory) {
|
|
|
8806
10004
|
const { title, lang, icon, opened, fromFile } = config;
|
|
8807
10005
|
const language = lang || (isHTMLComment ? "angular-html" : "angular-ts");
|
|
8808
10006
|
if (fromFile) {
|
|
8809
|
-
const snippetCode = fs.readFileSync(
|
|
10007
|
+
const snippetCode = fs.readFileSync(path11.join(basePath, fromFile), "utf-8");
|
|
8810
10008
|
result.push({
|
|
8811
|
-
title: title ??
|
|
10009
|
+
title: title ?? path11.basename(fromFile),
|
|
8812
10010
|
lang: language,
|
|
8813
10011
|
icon,
|
|
8814
10012
|
opened,
|
|
@@ -8857,7 +10055,7 @@ function removeSnippets(code) {
|
|
|
8857
10055
|
// libs/builder/helpers/snippets-from-asset.ts
|
|
8858
10056
|
function snippetsFromAsset(asset, inlineStylesType, configDirectory) {
|
|
8859
10057
|
const snippets = processLegacySnippets(asset.code).concat(
|
|
8860
|
-
processSnippets(asset.code,
|
|
10058
|
+
processSnippets(asset.code, path12.dirname(asset.filePath), configDirectory)
|
|
8861
10059
|
);
|
|
8862
10060
|
const codeType = codeTypeFromExt(asset.filePath);
|
|
8863
10061
|
const isStylesFile = ["CSS", "SCSS", "LESS", "SASS"].includes(codeType.toUpperCase());
|
|
@@ -8915,17 +10113,17 @@ var TrackedFiles = class extends ObservationRecorder {
|
|
|
8915
10113
|
super(initial, { normalize: normalize2, observer });
|
|
8916
10114
|
}
|
|
8917
10115
|
read(file) {
|
|
8918
|
-
const
|
|
8919
|
-
this.add({ kind: "existence", path:
|
|
10116
|
+
const path18 = normalize2(file);
|
|
10117
|
+
this.add({ kind: "existence", path: path18, exists: existsSync8(path18) });
|
|
8920
10118
|
try {
|
|
8921
|
-
const { text, digest: digest3 } = readText(
|
|
8922
|
-
this.add({ kind: "content", path:
|
|
10119
|
+
const { text, digest: digest3 } = readText(path18);
|
|
10120
|
+
this.add({ kind: "content", path: path18, digest: digest3 });
|
|
8923
10121
|
return text;
|
|
8924
10122
|
} catch (error) {
|
|
8925
10123
|
throw new SemanticFailure(
|
|
8926
10124
|
"SEMANTIC_INPUT_READ",
|
|
8927
10125
|
error instanceof Error ? error.message : String(error),
|
|
8928
|
-
{ path:
|
|
10126
|
+
{ path: path18 }
|
|
8929
10127
|
);
|
|
8930
10128
|
}
|
|
8931
10129
|
}
|
|
@@ -8964,8 +10162,8 @@ function recordDerivedQuery(identity, query) {
|
|
|
8964
10162
|
top()?.recordDerived(identity);
|
|
8965
10163
|
return suspendRecording(query);
|
|
8966
10164
|
}
|
|
8967
|
-
function recordLookup(
|
|
8968
|
-
top()?.record(
|
|
10165
|
+
function recordLookup(path18) {
|
|
10166
|
+
top()?.record(path18, "lookup");
|
|
8969
10167
|
}
|
|
8970
10168
|
var allocator = ts3.objectAllocator;
|
|
8971
10169
|
var SymbolObject = allocator.getSymbolConstructor();
|
|
@@ -8973,9 +10171,9 @@ var TypeObject = allocator.getTypeConstructor();
|
|
|
8973
10171
|
var SignatureObject = allocator.getSignatureConstructor();
|
|
8974
10172
|
var visited = /* @__PURE__ */ new WeakMap();
|
|
8975
10173
|
function fileOf(node) {
|
|
8976
|
-
let
|
|
8977
|
-
while (
|
|
8978
|
-
return
|
|
10174
|
+
let current2 = node;
|
|
10175
|
+
while (current2 && current2.kind !== ts3.SyntaxKind.SourceFile) current2 = current2.parent;
|
|
10176
|
+
return current2?.fileName;
|
|
8979
10177
|
}
|
|
8980
10178
|
function moduleSourceFile(specifier, context) {
|
|
8981
10179
|
const declaration = context.getSymbolAtLocation(specifier)?.declarations?.find((item) => ts3.isSourceFile(item));
|
|
@@ -8987,17 +10185,17 @@ function starClosure(source, context) {
|
|
|
8987
10185
|
const cached = context.stars.get(source.fileName);
|
|
8988
10186
|
if (cached) return cached;
|
|
8989
10187
|
const files = /* @__PURE__ */ new Set();
|
|
8990
|
-
const
|
|
10188
|
+
const visit9 = (file) => {
|
|
8991
10189
|
for (const statement of file.statements) {
|
|
8992
10190
|
if (!ts3.isExportDeclaration(statement) || statement.exportClause || !statement.moduleSpecifier)
|
|
8993
10191
|
continue;
|
|
8994
10192
|
const target = moduleSourceFile(statement.moduleSpecifier, context);
|
|
8995
10193
|
if (!target || files.has(target.fileName)) continue;
|
|
8996
10194
|
files.add(target.fileName);
|
|
8997
|
-
|
|
10195
|
+
visit9(target);
|
|
8998
10196
|
}
|
|
8999
10197
|
};
|
|
9000
|
-
|
|
10198
|
+
visit9(source);
|
|
9001
10199
|
const closure = [...files];
|
|
9002
10200
|
context.stars.set(source.fileName, closure);
|
|
9003
10201
|
return closure;
|
|
@@ -9523,7 +10721,7 @@ function structural(type) {
|
|
|
9523
10721
|
}
|
|
9524
10722
|
function reorder(root, print, checker, restore) {
|
|
9525
10723
|
const seen = /* @__PURE__ */ new Set();
|
|
9526
|
-
const
|
|
10724
|
+
const visit9 = (type, level) => {
|
|
9527
10725
|
if (!type || seen.has(type)) return;
|
|
9528
10726
|
seen.add(type);
|
|
9529
10727
|
const parts = type;
|
|
@@ -9533,16 +10731,16 @@ function reorder(root, print, checker, restore) {
|
|
|
9533
10731
|
...parts.resolvedTypeArguments ?? [],
|
|
9534
10732
|
...parts.aliasTypeArguments ?? []
|
|
9535
10733
|
])
|
|
9536
|
-
|
|
10734
|
+
visit9(inner, level);
|
|
9537
10735
|
if (level < DEPTH && structural(type))
|
|
9538
10736
|
suspendRecording(() => {
|
|
9539
10737
|
for (const property of checker.getPropertiesOfType(type))
|
|
9540
|
-
|
|
10738
|
+
visit9(checker.getTypeOfSymbol(property), level + 1);
|
|
9541
10739
|
for (const kind of [ts4.SignatureKind.Call, ts4.SignatureKind.Construct])
|
|
9542
10740
|
for (const signature2 of checker.getSignaturesOfType(type, kind)) {
|
|
9543
10741
|
for (const parameter2 of signature2.getParameters())
|
|
9544
|
-
|
|
9545
|
-
|
|
10742
|
+
visit9(checker.getTypeOfSymbol(parameter2), level + 1);
|
|
10743
|
+
visit9(checker.getReturnTypeOfSignature(signature2), level + 1);
|
|
9546
10744
|
}
|
|
9547
10745
|
});
|
|
9548
10746
|
if (type.flags & (ts4.TypeFlags.Union | ts4.TypeFlags.Intersection) && parts.types) {
|
|
@@ -9553,7 +10751,7 @@ function reorder(root, print, checker, restore) {
|
|
|
9553
10751
|
}
|
|
9554
10752
|
}
|
|
9555
10753
|
};
|
|
9556
|
-
|
|
10754
|
+
visit9(root, 0);
|
|
9557
10755
|
}
|
|
9558
10756
|
|
|
9559
10757
|
// libs/builder/generator/semantic/angular.ts
|
|
@@ -9568,6 +10766,18 @@ function canonicalMembers(type) {
|
|
|
9568
10766
|
)
|
|
9569
10767
|
).map((member) => wrappers.get(member));
|
|
9570
10768
|
}
|
|
10769
|
+
function playgroundOption(member) {
|
|
10770
|
+
if (member.isEnumLiteral()) {
|
|
10771
|
+
const value = member.getLiteralValue();
|
|
10772
|
+
const name = member.getSymbol()?.getName();
|
|
10773
|
+
if (name && (typeof value === "string" || typeof value === "number"))
|
|
10774
|
+
return { label: name, value };
|
|
10775
|
+
}
|
|
10776
|
+
return member.getText(
|
|
10777
|
+
void 0,
|
|
10778
|
+
TypeFormatFlags2.NoTruncation | TypeFormatFlags2.UseSingleQuotesForStringLiteralType
|
|
10779
|
+
);
|
|
10780
|
+
}
|
|
9571
10781
|
function unwrap(node, seen = /* @__PURE__ */ new Set()) {
|
|
9572
10782
|
if (!node || seen.has(node)) return void 0;
|
|
9573
10783
|
seen.add(node);
|
|
@@ -9616,31 +10826,49 @@ function literal(node) {
|
|
|
9616
10826
|
"Computed controls require the evaluated readGuideValues factory port"
|
|
9617
10827
|
);
|
|
9618
10828
|
}
|
|
9619
|
-
function
|
|
9620
|
-
return
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
10829
|
+
function displayFields(value) {
|
|
10830
|
+
return {
|
|
10831
|
+
...typeof value.label === "string" ? { label: value.label } : {},
|
|
10832
|
+
...typeof value.group === "string" ? { group: value.group } : {},
|
|
10833
|
+
...typeof value.order === "number" && Number.isFinite(value.order) ? { order: value.order } : {}
|
|
10834
|
+
};
|
|
10835
|
+
}
|
|
10836
|
+
function applyControls(properties, controls) {
|
|
10837
|
+
for (const [name, value] of Object.entries(controls)) {
|
|
10838
|
+
if (typeof value === "string") {
|
|
10839
|
+
properties[name] = { inputName: name, type: value, isManual: true };
|
|
10840
|
+
continue;
|
|
10841
|
+
}
|
|
10842
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
10843
|
+
throw new SemanticFailure("SEMANTIC_CONTROLS_SHAPE", `Invalid control ${name}`);
|
|
10844
|
+
}
|
|
10845
|
+
const type = value.type;
|
|
10846
|
+
if (type === void 0) {
|
|
10847
|
+
const detected = properties[name];
|
|
10848
|
+
if (!detected)
|
|
10849
|
+
throw new SemanticFailure(
|
|
10850
|
+
"SEMANTIC_CONTROLS_SHAPE",
|
|
10851
|
+
`Control ${name} has no type, and the target has no input ${name} to keep the control of`
|
|
10852
|
+
);
|
|
10853
|
+
properties[name] = {
|
|
10854
|
+
...detected,
|
|
10855
|
+
...typeof value.description === "string" ? { description: value.description } : {},
|
|
10856
|
+
...displayFields(value)
|
|
10857
|
+
};
|
|
10858
|
+
continue;
|
|
10859
|
+
}
|
|
10860
|
+
if (typeof type !== "string") {
|
|
10861
|
+
throw new SemanticFailure("SEMANTIC_CONTROLS_SHAPE", `Invalid control ${name}`);
|
|
10862
|
+
}
|
|
10863
|
+
properties[name] = {
|
|
10864
|
+
inputName: typeof value.alias === "string" ? value.alias : name,
|
|
10865
|
+
type,
|
|
10866
|
+
...typeof value.description === "string" ? { description: value.description } : {},
|
|
10867
|
+
...Array.isArray(value.options) && value.options.every((item) => typeof item === "string") ? { options: value.options } : {},
|
|
10868
|
+
isManual: true,
|
|
10869
|
+
...displayFields(value)
|
|
10870
|
+
};
|
|
10871
|
+
}
|
|
9644
10872
|
}
|
|
9645
10873
|
function assets(target, files, config) {
|
|
9646
10874
|
return getComponentSourceFiles(target).flatMap((file) => {
|
|
@@ -9663,7 +10891,9 @@ function assets(target, files, config) {
|
|
|
9663
10891
|
isEmpty: !code,
|
|
9664
10892
|
lang: title.replace("TypeScript", "angular-ts").replace("HTML", "angular-html")
|
|
9665
10893
|
};
|
|
9666
|
-
const snippets =
|
|
10894
|
+
const snippets = formatting(
|
|
10895
|
+
() => snippetsFromAsset(asset, config.inlineStyleLanguage, config.workspaceRoot)
|
|
10896
|
+
);
|
|
9667
10897
|
return (snippets.length ? snippets : [asset]).map((item) => ({
|
|
9668
10898
|
title: item.title,
|
|
9669
10899
|
source,
|
|
@@ -9750,12 +10980,7 @@ function guideSemantics(source, files, config, docs, values) {
|
|
|
9750
10980
|
),
|
|
9751
10981
|
description: Node16.isParameterDeclaration(input) ? docs.getJsDocParam(target.getMethodOrThrow("transform"), input.getName()) : docs.getJsDocDescription(input),
|
|
9752
10982
|
// In the written order: the checker's (stable) order sorts literals by value.
|
|
9753
|
-
options: writtenUnionOrder(input, type, canonicalMembers(type)).map(
|
|
9754
|
-
(part) => part.getText(
|
|
9755
|
-
void 0,
|
|
9756
|
-
TypeFormatFlags2.NoTruncation | TypeFormatFlags2.UseSingleQuotesForStringLiteralType
|
|
9757
|
-
)
|
|
9758
|
-
)
|
|
10983
|
+
options: writtenUnionOrder(input, type, canonicalMembers(type)).map(playgroundOption)
|
|
9759
10984
|
};
|
|
9760
10985
|
}
|
|
9761
10986
|
const controls = evaluated?.playgrounds?.[id]?.controls ?? (expression.getProperty("controls") ? literal(expression.getProperty("controls")) : {});
|
|
@@ -9764,7 +10989,7 @@ function guideSemantics(source, files, config, docs, values) {
|
|
|
9764
10989
|
"SEMANTIC_CONTROLS_SHAPE",
|
|
9765
10990
|
`Controls for ${id} must be a JSON object`
|
|
9766
10991
|
);
|
|
9767
|
-
|
|
10992
|
+
applyControls(properties, controls);
|
|
9768
10993
|
for (const [key, value] of Object.entries(properties)) {
|
|
9769
10994
|
if (!value || typeof value !== "object" || typeof value.type !== "string")
|
|
9770
10995
|
throw new SemanticFailure("SEMANTIC_CONTROLS_SHAPE", `Invalid control ${id}.${key}`);
|
|
@@ -10056,9 +11281,9 @@ function enumerateApi(state, entryId, files, diagnostics, context) {
|
|
|
10056
11281
|
const result = [];
|
|
10057
11282
|
const seen = /* @__PURE__ */ new Set();
|
|
10058
11283
|
for (const scope of entry.scopes)
|
|
10059
|
-
for (const
|
|
10060
|
-
recordLookup(
|
|
10061
|
-
const source = state.project.getSourceFileOrThrow(
|
|
11284
|
+
for (const path18 of state.scopes.get(`${entry.id}:${scope.id}`) ?? []) {
|
|
11285
|
+
recordLookup(path18);
|
|
11286
|
+
const source = state.project.getSourceFileOrThrow(path18);
|
|
10062
11287
|
for (const [name, nodes] of source.getExportedDeclarations()) {
|
|
10063
11288
|
const candidates = nodes.filter(supported);
|
|
10064
11289
|
if (!candidates.length) {
|
|
@@ -10067,7 +11292,7 @@ function enumerateApi(state, entryId, files, diagnostics, context) {
|
|
|
10067
11292
|
severity: "info",
|
|
10068
11293
|
stage: "semantic",
|
|
10069
11294
|
message: `Skipped unsupported exported declaration ${name}`,
|
|
10070
|
-
source: { path:
|
|
11295
|
+
source: { path: path18 }
|
|
10071
11296
|
});
|
|
10072
11297
|
continue;
|
|
10073
11298
|
}
|
|
@@ -10173,16 +11398,16 @@ var DerivedClassIndex = class {
|
|
|
10173
11398
|
referenceNames(expression.expression);
|
|
10174
11399
|
}
|
|
10175
11400
|
};
|
|
10176
|
-
const
|
|
11401
|
+
const visit9 = (node) => {
|
|
10177
11402
|
if (ts6.isClassDeclaration(node)) {
|
|
10178
11403
|
for (const clause of node.heritageClauses ?? [])
|
|
10179
11404
|
if (clause.token === ts6.SyntaxKind.ExtendsKeyword)
|
|
10180
11405
|
clause.types.forEach((type) => referenceNames(type.expression));
|
|
10181
11406
|
}
|
|
10182
|
-
ts6.forEachChild(node,
|
|
11407
|
+
ts6.forEachChild(node, visit9);
|
|
10183
11408
|
};
|
|
10184
11409
|
for (const source of program.getSourceFiles())
|
|
10185
|
-
if (source.text.includes("extends"))
|
|
11410
|
+
if (source.text.includes("extends")) visit9(source);
|
|
10186
11411
|
}
|
|
10187
11412
|
/** False only when no reference search can find a class deriving from `declaration`. */
|
|
10188
11413
|
mayHaveDerivedClasses(declaration) {
|
|
@@ -10275,7 +11500,7 @@ import { Project as Project3, ts as ts9 } from "ts-morph";
|
|
|
10275
11500
|
|
|
10276
11501
|
// libs/builder/generator/semantic/owned-roots.ts
|
|
10277
11502
|
import { minimatch as minimatch2 } from "minimatch";
|
|
10278
|
-
import { randomUUID as
|
|
11503
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
10279
11504
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
10280
11505
|
import { basename, dirname as dirname3, isAbsolute as isAbsolute2, join as join2, parse as parse3, posix as posix3 } from "node:path";
|
|
10281
11506
|
import { Project as Project2 } from "ts-morph";
|
|
@@ -10291,23 +11516,23 @@ var OwnedRoots = class {
|
|
|
10291
11516
|
}
|
|
10292
11517
|
/** The owned root containing a path, if any. */
|
|
10293
11518
|
describe(file) {
|
|
10294
|
-
const
|
|
10295
|
-
return this.roots.find((root) =>
|
|
11519
|
+
const path18 = normalize2(file);
|
|
11520
|
+
return this.roots.find((root) => path18 === root || path18.startsWith(`${root}/`));
|
|
10296
11521
|
}
|
|
10297
11522
|
/**
|
|
10298
11523
|
* A non-owned path that is a symlink into an owned root stays unresolved: it is read through
|
|
10299
11524
|
* its own path like any other input instead of resolving to a hidden owned file.
|
|
10300
11525
|
*/
|
|
10301
|
-
realpath(
|
|
10302
|
-
const real2 = resolve10(
|
|
10303
|
-
return this.has(real2) && !this.has(
|
|
11526
|
+
realpath(path18, resolve10) {
|
|
11527
|
+
const real2 = resolve10(path18);
|
|
11528
|
+
return this.has(real2) && !this.has(path18) ? path18 : real2;
|
|
10304
11529
|
}
|
|
10305
11530
|
/** Notes a raw text read of the program's file system (see {@link contentDigest}). */
|
|
10306
11531
|
recordRead(file, text) {
|
|
10307
|
-
const
|
|
11532
|
+
const path18 = normalize2(file);
|
|
10308
11533
|
if (text.charCodeAt(0) === 65279)
|
|
10309
|
-
this.marked.set(
|
|
10310
|
-
else this.marked.delete(
|
|
11534
|
+
this.marked.set(path18, { text: text.slice(1), digest: contentDigest(text) });
|
|
11535
|
+
else this.marked.delete(path18);
|
|
10311
11536
|
}
|
|
10312
11537
|
/**
|
|
10313
11538
|
* The content digest of a program file whose text is `text`. TypeScript drops a leading byte
|
|
@@ -10326,8 +11551,8 @@ var OwnedRoots = class {
|
|
|
10326
11551
|
fileExists: (file) => !this.has(file) && host.fileExists(file),
|
|
10327
11552
|
readFile: (file) => this.has(file) ? void 0 : host.readFile(file),
|
|
10328
11553
|
directoryExists: (directory) => !this.has(directory) && (host.directoryExists?.(directory) ?? true),
|
|
10329
|
-
getDirectories: (
|
|
10330
|
-
...host.realpath ? { realpath: (
|
|
11554
|
+
getDirectories: (path18) => this.has(path18) ? [] : (host.getDirectories?.(path18) ?? []).filter((name) => !this.has(join2(path18, name))),
|
|
11555
|
+
...host.realpath ? { realpath: (path18) => this.realpath(path18, (value) => host.realpath(value)) } : {}
|
|
10331
11556
|
};
|
|
10332
11557
|
}
|
|
10333
11558
|
/** The real ts-morph file system with owned paths absent. Writes are never issued by semantic. */
|
|
@@ -10336,13 +11561,13 @@ var OwnedRoots = class {
|
|
|
10336
11561
|
return new OwnedRootsFileSystem(realFileSystem(), this);
|
|
10337
11562
|
}
|
|
10338
11563
|
};
|
|
10339
|
-
function canonical2(
|
|
11564
|
+
function canonical2(path18) {
|
|
10340
11565
|
const missing = [];
|
|
10341
|
-
for (let cursor = normalize2(
|
|
11566
|
+
for (let cursor = normalize2(path18); ; cursor = dirname3(cursor)) {
|
|
10342
11567
|
try {
|
|
10343
11568
|
return normalize2(join2(realpathSync3(cursor), ...missing));
|
|
10344
11569
|
} catch {
|
|
10345
|
-
if (dirname3(cursor) === cursor) return normalize2(
|
|
11570
|
+
if (dirname3(cursor) === cursor) return normalize2(path18);
|
|
10346
11571
|
missing.unshift(basename(cursor));
|
|
10347
11572
|
}
|
|
10348
11573
|
}
|
|
@@ -10352,7 +11577,7 @@ var notFound;
|
|
|
10352
11577
|
function missingFileError(fileSystem) {
|
|
10353
11578
|
const probe2 = join2(
|
|
10354
11579
|
parse3(process.cwd()).root,
|
|
10355
|
-
`ngdoc-owned-root-probe-${
|
|
11580
|
+
`ngdoc-owned-root-probe-${randomUUID5()}`,
|
|
10356
11581
|
"missing.ts"
|
|
10357
11582
|
);
|
|
10358
11583
|
let observed;
|
|
@@ -10370,8 +11595,8 @@ function missingFileError(fileSystem) {
|
|
|
10370
11595
|
}
|
|
10371
11596
|
return type;
|
|
10372
11597
|
}
|
|
10373
|
-
function fileNotFound(
|
|
10374
|
-
return new notFound(
|
|
11598
|
+
function fileNotFound(path18) {
|
|
11599
|
+
return new notFound(path18);
|
|
10375
11600
|
}
|
|
10376
11601
|
function realFileSystem() {
|
|
10377
11602
|
return real ??= new Project2({ useInMemoryFileSystem: false }).getFileSystem();
|
|
@@ -10384,11 +11609,11 @@ var OwnedRootsFileSystem = class {
|
|
|
10384
11609
|
isCaseSensitive() {
|
|
10385
11610
|
return this.real.isCaseSensitive();
|
|
10386
11611
|
}
|
|
10387
|
-
delete(
|
|
10388
|
-
return this.real.delete(
|
|
11612
|
+
delete(path18) {
|
|
11613
|
+
return this.real.delete(path18);
|
|
10389
11614
|
}
|
|
10390
|
-
deleteSync(
|
|
10391
|
-
this.real.deleteSync(
|
|
11615
|
+
deleteSync(path18) {
|
|
11616
|
+
this.real.deleteSync(path18);
|
|
10392
11617
|
}
|
|
10393
11618
|
readDirSync(dirPath) {
|
|
10394
11619
|
if (this.owned.has(dirPath)) return [];
|
|
@@ -10444,8 +11669,8 @@ var OwnedRootsFileSystem = class {
|
|
|
10444
11669
|
directoryExistsSync(dirPath) {
|
|
10445
11670
|
return !this.owned.has(dirPath) && this.real.directoryExistsSync(dirPath);
|
|
10446
11671
|
}
|
|
10447
|
-
realpathSync(
|
|
10448
|
-
return this.owned.realpath(
|
|
11672
|
+
realpathSync(path18) {
|
|
11673
|
+
return this.owned.realpath(path18, (value) => this.real.realpathSync(value));
|
|
10449
11674
|
}
|
|
10450
11675
|
getCurrentDirectory() {
|
|
10451
11676
|
return this.real.getCurrentDirectory();
|
|
@@ -10483,8 +11708,8 @@ function ownedRootReach(workspaceRoot, include, exclude, roots) {
|
|
|
10483
11708
|
const base = normalize2(workspaceRoot);
|
|
10484
11709
|
const relative3 = (pattern) => posix3.normalize(isAbsolute2(pattern) ? posix3.relative(base, normalize2(pattern)) : pattern);
|
|
10485
11710
|
const excludes = exclude.map(relative3);
|
|
10486
|
-
const excluded = (
|
|
10487
|
-
const parts =
|
|
11711
|
+
const excluded = (path18) => {
|
|
11712
|
+
const parts = path18.split("/");
|
|
10488
11713
|
return parts.some((_, index) => {
|
|
10489
11714
|
const prefix = parts.slice(0, index + 1).join("/");
|
|
10490
11715
|
return excludes.some((pattern) => minimatch2(prefix, pattern, { dot: true }));
|
|
@@ -10537,8 +11762,8 @@ function staticBase(spec) {
|
|
|
10537
11762
|
if (index < 0) return { base: spec, rest: [] };
|
|
10538
11763
|
return { base: parts.slice(0, index).join("/") || "/", rest: parts.slice(index) };
|
|
10539
11764
|
}
|
|
10540
|
-
function inside(root,
|
|
10541
|
-
return
|
|
11765
|
+
function inside(root, path18) {
|
|
11766
|
+
return path18 === root || path18.startsWith(root === "/" ? "/" : `${root}/`);
|
|
10542
11767
|
}
|
|
10543
11768
|
function literal2(character) {
|
|
10544
11769
|
if (character === "!" || character === "\\") return "?";
|
|
@@ -10582,7 +11807,7 @@ function segmentPattern(segment, caseInsensitive) {
|
|
|
10582
11807
|
async function tsconfigMembershipDependencies(parsed, configFile, owned, specs = tsconfigSpecs(parsed, configFile)) {
|
|
10583
11808
|
const directory = normalize2(dirname4(configFile));
|
|
10584
11809
|
const caseInsensitive = !ts8.sys.useCaseSensitiveFileNames;
|
|
10585
|
-
const key = (
|
|
11810
|
+
const key = (path18) => caseInsensitive ? path18.toLowerCase() : path18;
|
|
10586
11811
|
const extensions = [
|
|
10587
11812
|
"ts",
|
|
10588
11813
|
"tsx",
|
|
@@ -10594,10 +11819,10 @@ async function tsconfigMembershipDependencies(parsed, configFile, owned, specs =
|
|
|
10594
11819
|
const dependencies = [];
|
|
10595
11820
|
const reproduced = /* @__PURE__ */ new Set();
|
|
10596
11821
|
for (const file of specs.files) {
|
|
10597
|
-
const
|
|
10598
|
-
if (owned.has(
|
|
10599
|
-
dependencies.push({ kind: "existence", path:
|
|
10600
|
-
reproduced.add(key(
|
|
11822
|
+
const path18 = normalize2(resolve4(directory, file));
|
|
11823
|
+
if (owned.has(path18)) continue;
|
|
11824
|
+
dependencies.push({ kind: "existence", path: path18, exists: existsSync9(path18) });
|
|
11825
|
+
reproduced.add(key(path18));
|
|
10601
11826
|
}
|
|
10602
11827
|
const globs = /* @__PURE__ */ new Map();
|
|
10603
11828
|
for (const spec of specs.include) {
|
|
@@ -10685,11 +11910,11 @@ async function tsconfigMembershipDependencies(parsed, configFile, owned, specs =
|
|
|
10685
11910
|
}
|
|
10686
11911
|
|
|
10687
11912
|
// libs/builder/generator/semantic/program-builder.ts
|
|
10688
|
-
function ownedOverlap(kind,
|
|
11913
|
+
function ownedOverlap(kind, path18, owned) {
|
|
10689
11914
|
return new SemanticFailure(
|
|
10690
11915
|
"SEMANTIC_OWNED_ROOT_OVERLAP",
|
|
10691
|
-
`${kind} ${
|
|
10692
|
-
{ path:
|
|
11916
|
+
`${kind} ${path18} lies under a generator-owned output or cache root (${owned.describe(path18)}). Generated output is never documented; configure outputRoot/cacheRoot outside documented sources.`,
|
|
11917
|
+
{ path: path18 }
|
|
10693
11918
|
);
|
|
10694
11919
|
}
|
|
10695
11920
|
var FORMATTER_CONFIGURATION_FILES = [
|
|
@@ -10717,9 +11942,9 @@ var FORMATTER_CONFIGURATION_FILES = [
|
|
|
10717
11942
|
function trackFormatterConfiguration(workspaceRoot, files) {
|
|
10718
11943
|
for (let directory = workspaceRoot; ; directory = dirname5(directory)) {
|
|
10719
11944
|
for (const name of FORMATTER_CONFIGURATION_FILES) {
|
|
10720
|
-
const
|
|
10721
|
-
files.add({ kind: "existence", path:
|
|
10722
|
-
if (existsSync10(
|
|
11945
|
+
const path18 = normalize2(resolve5(directory, name));
|
|
11946
|
+
files.add({ kind: "existence", path: path18, exists: existsSync10(path18) });
|
|
11947
|
+
if (existsSync10(path18)) files.read(path18);
|
|
10723
11948
|
}
|
|
10724
11949
|
if (dirname5(directory) === directory) break;
|
|
10725
11950
|
}
|
|
@@ -10831,9 +12056,9 @@ function syntaxFailure(program) {
|
|
|
10831
12056
|
import { existsSync as existsSync11 } from "node:fs";
|
|
10832
12057
|
import { dirname as dirname6, resolve as resolve6 } from "node:path";
|
|
10833
12058
|
import { ts as ts10 } from "ts-morph";
|
|
10834
|
-
function realpathOf(
|
|
12059
|
+
function realpathOf(path18) {
|
|
10835
12060
|
try {
|
|
10836
|
-
return ts10.sys.realpath ? ts10.sys.realpath(
|
|
12061
|
+
return ts10.sys.realpath ? ts10.sys.realpath(path18) : path18;
|
|
10837
12062
|
} catch {
|
|
10838
12063
|
return void 0;
|
|
10839
12064
|
}
|
|
@@ -10842,9 +12067,9 @@ function trackingHost(files, owned, probes) {
|
|
|
10842
12067
|
return owned.resolutionHost({
|
|
10843
12068
|
...ts10.sys,
|
|
10844
12069
|
fileExists: (file) => {
|
|
10845
|
-
const
|
|
10846
|
-
const exists = existsSync11(
|
|
10847
|
-
files.add({ kind: "existence", path:
|
|
12070
|
+
const path18 = normalize2(file);
|
|
12071
|
+
const exists = existsSync11(path18);
|
|
12072
|
+
files.add({ kind: "existence", path: path18, exists });
|
|
10848
12073
|
return exists;
|
|
10849
12074
|
},
|
|
10850
12075
|
readFile: (file) => {
|
|
@@ -10859,9 +12084,9 @@ function trackingHost(files, owned, probes) {
|
|
|
10859
12084
|
if (!exists) probes?.missing(normalize2(directory));
|
|
10860
12085
|
return exists;
|
|
10861
12086
|
},
|
|
10862
|
-
realpath: (
|
|
10863
|
-
const real2 = realpathOf(
|
|
10864
|
-
const from = normalize2(
|
|
12087
|
+
realpath: (path18) => {
|
|
12088
|
+
const real2 = realpathOf(path18) ?? path18;
|
|
12089
|
+
const from = normalize2(path18);
|
|
10865
12090
|
const to = normalize2(real2);
|
|
10866
12091
|
if (probes && from !== to) probes.realpath(from, to);
|
|
10867
12092
|
return real2;
|
|
@@ -10869,29 +12094,29 @@ function trackingHost(files, owned, probes) {
|
|
|
10869
12094
|
});
|
|
10870
12095
|
}
|
|
10871
12096
|
function trackSourceFile(source, options, host, files, owned, imports) {
|
|
10872
|
-
const
|
|
10873
|
-
files.add({ kind: "existence", path:
|
|
10874
|
-
files.add({ kind: "content", path:
|
|
12097
|
+
const path18 = normalize2(source.fileName);
|
|
12098
|
+
files.add({ kind: "existence", path: path18, exists: true });
|
|
12099
|
+
files.add({ kind: "content", path: path18, digest: owned.contentDigest(path18, source.text) });
|
|
10875
12100
|
const references2 = ts10.preProcessFile(source.text);
|
|
10876
12101
|
for (const item of references2.importedFiles) {
|
|
10877
|
-
const resolved = ts10.resolveModuleName(item.fileName,
|
|
12102
|
+
const resolved = ts10.resolveModuleName(item.fileName, path18, options, host).resolvedModule;
|
|
10878
12103
|
imports?.push(resolution("module", item.fileName, resolved?.resolvedFileName));
|
|
10879
12104
|
}
|
|
10880
12105
|
for (const item of references2.typeReferenceDirectives) {
|
|
10881
12106
|
const resolved = ts10.resolveTypeReferenceDirective(
|
|
10882
12107
|
item.fileName,
|
|
10883
|
-
|
|
12108
|
+
path18,
|
|
10884
12109
|
options,
|
|
10885
12110
|
host
|
|
10886
12111
|
).resolvedTypeReferenceDirective;
|
|
10887
12112
|
imports?.push(resolution("type-reference", item.fileName, resolved?.resolvedFileName));
|
|
10888
12113
|
}
|
|
10889
12114
|
for (const item of references2.referencedFiles) {
|
|
10890
|
-
const
|
|
10891
|
-
if (owned.has(
|
|
10892
|
-
const exists = existsSync11(
|
|
10893
|
-
files.add({ kind: "existence", path:
|
|
10894
|
-
imports?.push(resolution("reference", item.fileName, exists ?
|
|
12115
|
+
const path19 = normalize2(resolve6(dirname6(source.fileName), item.fileName));
|
|
12116
|
+
if (owned.has(path19)) continue;
|
|
12117
|
+
const exists = existsSync11(path19);
|
|
12118
|
+
files.add({ kind: "existence", path: path19, exists });
|
|
12119
|
+
imports?.push(resolution("reference", item.fileName, exists ? path19 : void 0));
|
|
10895
12120
|
}
|
|
10896
12121
|
}
|
|
10897
12122
|
function resolution(kind, specifier, resolved) {
|
|
@@ -10914,14 +12139,14 @@ function semanticDefinition(configuration, files, project) {
|
|
|
10914
12139
|
reason: "Whole TypeScript program, configuration, resolution libraries and source membership conservatively invalidate semantic consumers"
|
|
10915
12140
|
};
|
|
10916
12141
|
}
|
|
10917
|
-
function rawDigest(
|
|
12142
|
+
function rawDigest(path18) {
|
|
10918
12143
|
try {
|
|
10919
|
-
return readText(
|
|
12144
|
+
return readText(path18).digest;
|
|
10920
12145
|
} catch (error) {
|
|
10921
12146
|
throw new SemanticFailure(
|
|
10922
12147
|
"SEMANTIC_RETRACK",
|
|
10923
|
-
`${
|
|
10924
|
-
{ path:
|
|
12148
|
+
`${path18} cannot be read again: ${error instanceof Error ? error.message : String(error)}`,
|
|
12149
|
+
{ path: path18 }
|
|
10925
12150
|
);
|
|
10926
12151
|
}
|
|
10927
12152
|
}
|
|
@@ -10961,9 +12186,9 @@ var ProgramObservations = class {
|
|
|
10961
12186
|
const options = project.getCompilerOptions();
|
|
10962
12187
|
const host = trackingHost(this.aggregate, owned, this.probeSink);
|
|
10963
12188
|
for (const source of project.getProgram().compilerObject.getSourceFiles()) {
|
|
10964
|
-
const
|
|
10965
|
-
if (owned.has(
|
|
10966
|
-
const segment = this.open(
|
|
12189
|
+
const path18 = normalize2(source.fileName);
|
|
12190
|
+
if (owned.has(path18)) continue;
|
|
12191
|
+
const segment = this.open(path18);
|
|
10967
12192
|
try {
|
|
10968
12193
|
trackSourceFile(source, options, host, this.aggregate, owned, segment.imports);
|
|
10969
12194
|
} finally {
|
|
@@ -10990,8 +12215,8 @@ var ProgramObservations = class {
|
|
|
10990
12215
|
return [...this.importerSegments.keys()];
|
|
10991
12216
|
}
|
|
10992
12217
|
/** What tracking one program file observed, or undefined when it is not a tracked importer. */
|
|
10993
|
-
importer(
|
|
10994
|
-
const segment = this.importerSegments.get(normalize2(
|
|
12218
|
+
importer(path18) {
|
|
12219
|
+
const segment = this.importerSegments.get(normalize2(path18));
|
|
10995
12220
|
return segment ? {
|
|
10996
12221
|
path: segment.owner,
|
|
10997
12222
|
dependencies: segment.dependencies,
|
|
@@ -11001,7 +12226,7 @@ var ProgramObservations = class {
|
|
|
11001
12226
|
} : void 0;
|
|
11002
12227
|
}
|
|
11003
12228
|
/** The tracked program files with a reference that resolved to this file, in program order. */
|
|
11004
|
-
importersOf(
|
|
12229
|
+
importersOf(path18) {
|
|
11005
12230
|
if (!this.reverse) {
|
|
11006
12231
|
this.reverse = /* @__PURE__ */ new Map();
|
|
11007
12232
|
for (const [importer, segment] of this.importerSegments)
|
|
@@ -11012,7 +12237,7 @@ var ProgramObservations = class {
|
|
|
11012
12237
|
this.reverse.set(item, list);
|
|
11013
12238
|
}
|
|
11014
12239
|
}
|
|
11015
|
-
return [...this.reverse.get(normalize2(
|
|
12240
|
+
return [...this.reverse.get(normalize2(path18)) ?? []];
|
|
11016
12241
|
}
|
|
11017
12242
|
/**
|
|
11018
12243
|
* The aggregate replayed from the attribution log: every observation (without the definition),
|
|
@@ -11062,14 +12287,14 @@ var ProgramObservations = class {
|
|
|
11062
12287
|
const options = project.getCompilerOptions();
|
|
11063
12288
|
const retracked = [];
|
|
11064
12289
|
const targets = new Set([...paths].map(normalize2));
|
|
11065
|
-
for (const
|
|
11066
|
-
const segment = this.importerSegments.get(
|
|
11067
|
-
const source = segment ? program.getSourceFile(
|
|
12290
|
+
for (const path18 of targets) {
|
|
12291
|
+
const segment = this.importerSegments.get(path18);
|
|
12292
|
+
const source = segment ? program.getSourceFile(path18) : void 0;
|
|
11068
12293
|
if (!segment || !source)
|
|
11069
12294
|
throw new SemanticFailure(
|
|
11070
12295
|
"SEMANTIC_RETRACK",
|
|
11071
|
-
`${
|
|
11072
|
-
{ path:
|
|
12296
|
+
`${path18} is not a tracked file of the current program`,
|
|
12297
|
+
{ path: path18 }
|
|
11073
12298
|
);
|
|
11074
12299
|
segment.dependencies = [];
|
|
11075
12300
|
segment.missing = [];
|
|
@@ -11139,16 +12364,16 @@ var ProgramObservations = class {
|
|
|
11139
12364
|
this.importerSegments.clear();
|
|
11140
12365
|
const tracked = [];
|
|
11141
12366
|
for (const source of program.getSourceFiles()) {
|
|
11142
|
-
const
|
|
11143
|
-
if (owned.has(
|
|
11144
|
-
const kept2 = previous.get(
|
|
11145
|
-
if (kept2 && keep(
|
|
12367
|
+
const path18 = normalize2(source.fileName);
|
|
12368
|
+
if (owned.has(path18)) continue;
|
|
12369
|
+
const kept2 = previous.get(path18);
|
|
12370
|
+
if (kept2 && keep(path18)) {
|
|
11146
12371
|
segments.push(kept2);
|
|
11147
|
-
this.importerSegments.set(
|
|
12372
|
+
this.importerSegments.set(path18, kept2);
|
|
11148
12373
|
continue;
|
|
11149
12374
|
}
|
|
11150
12375
|
const segment = {
|
|
11151
|
-
owner:
|
|
12376
|
+
owner: path18,
|
|
11152
12377
|
dependencies: [],
|
|
11153
12378
|
missing: [],
|
|
11154
12379
|
realpaths: [],
|
|
@@ -11162,7 +12387,7 @@ var ProgramObservations = class {
|
|
|
11162
12387
|
trackSourceFile(source, options, host, files2, owned, segment.imports);
|
|
11163
12388
|
tracked.push(...segment.dependencies);
|
|
11164
12389
|
segments.push(segment);
|
|
11165
|
-
this.importerSegments.set(
|
|
12390
|
+
this.importerSegments.set(path18, segment);
|
|
11166
12391
|
}
|
|
11167
12392
|
segments.push(...tail);
|
|
11168
12393
|
this.segments.splice(0, this.segments.length, ...segments);
|
|
@@ -11183,16 +12408,16 @@ var ProgramObservations = class {
|
|
|
11183
12408
|
this.segment().dependencies.push(dependency);
|
|
11184
12409
|
});
|
|
11185
12410
|
}
|
|
11186
|
-
open(
|
|
12411
|
+
open(path18) {
|
|
11187
12412
|
const segment = {
|
|
11188
|
-
owner:
|
|
12413
|
+
owner: path18,
|
|
11189
12414
|
dependencies: [],
|
|
11190
12415
|
missing: [],
|
|
11191
12416
|
realpaths: [],
|
|
11192
12417
|
imports: []
|
|
11193
12418
|
};
|
|
11194
12419
|
this.segments.push(segment);
|
|
11195
|
-
this.importerSegments.set(
|
|
12420
|
+
this.importerSegments.set(path18, segment);
|
|
11196
12421
|
this.current = segment;
|
|
11197
12422
|
return segment;
|
|
11198
12423
|
}
|
|
@@ -11283,7 +12508,7 @@ function watchProgram(project, observations, owned, tsConfig, observedAtNs) {
|
|
|
11283
12508
|
const published = observations.files.all();
|
|
11284
12509
|
for (const dependency of published)
|
|
11285
12510
|
if (dependency.kind === "glob")
|
|
11286
|
-
listings.recordGlob(dependency, observedAtNs, (
|
|
12511
|
+
listings.recordGlob(dependency, observedAtNs, (path18) => owned.has(path18));
|
|
11287
12512
|
const stamps = new ObservationStamps((file) => readText(file).digest);
|
|
11288
12513
|
stamps.record([...published, ...hidden.all()], observedAtNs);
|
|
11289
12514
|
const probes = observations.probes;
|
|
@@ -11301,16 +12526,16 @@ function watchFacts(watch) {
|
|
|
11301
12526
|
return {
|
|
11302
12527
|
hidden: watch.hidden.all(),
|
|
11303
12528
|
missingDirectories: [...watch.missingDirectories],
|
|
11304
|
-
realpaths: watch.realpaths.map(([
|
|
12529
|
+
realpaths: watch.realpaths.map(([path18, real2]) => [path18, real2]),
|
|
11305
12530
|
directories
|
|
11306
12531
|
};
|
|
11307
12532
|
}
|
|
11308
12533
|
function watchFactsChange(facts) {
|
|
11309
12534
|
for (const directory of facts.missingDirectories)
|
|
11310
12535
|
if (ts12.sys.directoryExists(directory)) return `directory appeared: ${directory}`;
|
|
11311
|
-
for (const [
|
|
11312
|
-
const
|
|
11313
|
-
if (
|
|
12536
|
+
for (const [path18, real2] of facts.realpaths) {
|
|
12537
|
+
const current2 = realpathOf(path18);
|
|
12538
|
+
if (current2 === void 0 || normalize2(current2) !== real2) return `symlink retargeted: ${path18}`;
|
|
11314
12539
|
}
|
|
11315
12540
|
for (const directory of facts.directories)
|
|
11316
12541
|
if (!directoryListed(directory)) return `directory listing changed: ${directory.path}`;
|
|
@@ -11361,9 +12586,9 @@ function assessPatch(previous, changes) {
|
|
|
11361
12586
|
rehashed += sweep2.rehashed;
|
|
11362
12587
|
if (sweep2.changed) edited.add(dependency.path);
|
|
11363
12588
|
}
|
|
11364
|
-
for (const
|
|
11365
|
-
if (!importers.has(
|
|
11366
|
-
return { kind: "full", reason: `patched path is not a program file: ${
|
|
12589
|
+
for (const path18 of edited)
|
|
12590
|
+
if (!importers.has(path18))
|
|
12591
|
+
return { kind: "full", reason: `patched path is not a program file: ${path18}` };
|
|
11367
12592
|
if (edited.size > MAX_PATCHED_FILES)
|
|
11368
12593
|
return {
|
|
11369
12594
|
kind: "full",
|
|
@@ -11373,8 +12598,8 @@ function assessPatch(previous, changes) {
|
|
|
11373
12598
|
(dependency) => !(dependency.kind === "content" && importers.has(dependency.path))
|
|
11374
12599
|
);
|
|
11375
12600
|
const unexplained = changes.filter((change) => {
|
|
11376
|
-
const
|
|
11377
|
-
return !importers.has(
|
|
12601
|
+
const path18 = normalize2(change.path);
|
|
12602
|
+
return !importers.has(path18) || !existsSync12(path18);
|
|
11378
12603
|
});
|
|
11379
12604
|
const verified = holds2(watch, rest, unexplained);
|
|
11380
12605
|
if (typeof verified === "string") return { kind: "full", reason: verified };
|
|
@@ -11383,7 +12608,7 @@ function assessPatch(previous, changes) {
|
|
|
11383
12608
|
stamped: verified.stamped + stamped,
|
|
11384
12609
|
rehashed: verified.rehashed + rehashed
|
|
11385
12610
|
};
|
|
11386
|
-
return edited.size ? { kind: "patch", files: order.filter((
|
|
12611
|
+
return edited.size ? { kind: "patch", files: order.filter((path18) => edited.has(path18)), counters: counters2 } : { kind: "reuse", counters: counters2 };
|
|
11387
12612
|
}
|
|
11388
12613
|
function assessRestructure(previous, changes, discovery) {
|
|
11389
12614
|
const { watch, mirror } = previous;
|
|
@@ -11398,42 +12623,42 @@ function assessRestructure(previous, changes, discovery) {
|
|
|
11398
12623
|
const deleted = /* @__PURE__ */ new Set();
|
|
11399
12624
|
let stamped = 0;
|
|
11400
12625
|
let rehashed = 0;
|
|
11401
|
-
for (const
|
|
11402
|
-
const own = observations.importer(
|
|
11403
|
-
(dependency) => dependency.kind === "content" && dependency.path ===
|
|
12626
|
+
for (const path18 of layout.importers) {
|
|
12627
|
+
const own = observations.importer(path18).dependencies.filter(
|
|
12628
|
+
(dependency) => dependency.kind === "content" && dependency.path === path18
|
|
11404
12629
|
);
|
|
11405
12630
|
const sweep2 = watch.stamps.sweep(own);
|
|
11406
12631
|
stamped += sweep2.stamped;
|
|
11407
12632
|
rehashed += sweep2.rehashed;
|
|
11408
12633
|
if (!sweep2.changed) continue;
|
|
11409
|
-
if (existsSync12(
|
|
11410
|
-
else deleted.add(
|
|
12634
|
+
if (existsSync12(path18)) edited.add(path18);
|
|
12635
|
+
else deleted.add(path18);
|
|
11411
12636
|
}
|
|
11412
|
-
for (const
|
|
11413
|
-
if (!importers.has(
|
|
11414
|
-
return { kind: "full", reason: `patched path is not a program file: ${
|
|
12637
|
+
for (const path18 of edited)
|
|
12638
|
+
if (!importers.has(path18))
|
|
12639
|
+
return { kind: "full", reason: `patched path is not a program file: ${path18}` };
|
|
11415
12640
|
if (edited.size + deleted.size > MAX_PATCHED_FILES)
|
|
11416
12641
|
return {
|
|
11417
12642
|
kind: "full",
|
|
11418
12643
|
reason: `${edited.size + deleted.size} program files changed (at most ${MAX_PATCHED_FILES} are patched)`
|
|
11419
12644
|
};
|
|
11420
12645
|
const retracked = /* @__PURE__ */ new Set([...edited, ...deleted]);
|
|
11421
|
-
const kept2 = layout.importers.filter((
|
|
12646
|
+
const kept2 = layout.importers.filter((path18) => !retracked.has(path18));
|
|
11422
12647
|
const rest = [
|
|
11423
12648
|
// The program configuration (entry modules are read again with the membership).
|
|
11424
12649
|
...layout.membership.filter(
|
|
11425
12650
|
(dependency) => (dependency.kind === "content" || dependency.kind === "existence") && !entries.has(normalize2(dependency.path))
|
|
11426
12651
|
),
|
|
11427
|
-
...kept2.flatMap((
|
|
12652
|
+
...kept2.flatMap((path18) => observations.importer(path18).dependencies),
|
|
11428
12653
|
...layout.tail,
|
|
11429
12654
|
...watch.hidden.all()
|
|
11430
12655
|
];
|
|
11431
12656
|
const missing = [
|
|
11432
|
-
...kept2.flatMap((
|
|
12657
|
+
...kept2.flatMap((path18) => observations.importer(path18).missing),
|
|
11433
12658
|
...layout.tailMissing
|
|
11434
12659
|
];
|
|
11435
12660
|
const realpaths = [
|
|
11436
|
-
...kept2.flatMap((
|
|
12661
|
+
...kept2.flatMap((path18) => observations.importer(path18).realpaths),
|
|
11437
12662
|
...layout.tailRealpaths
|
|
11438
12663
|
];
|
|
11439
12664
|
const unexplained = changes.filter((change) => !edited.has(normalize2(change.path)));
|
|
@@ -11445,7 +12670,7 @@ function assessRestructure(previous, changes, discovery) {
|
|
|
11445
12670
|
if (typeof verified === "string") return { kind: "full", reason: verified };
|
|
11446
12671
|
return {
|
|
11447
12672
|
kind: "patch",
|
|
11448
|
-
files: layout.importers.filter((
|
|
12673
|
+
files: layout.importers.filter((path18) => edited.has(path18)),
|
|
11449
12674
|
counters: {
|
|
11450
12675
|
...verified,
|
|
11451
12676
|
stamped: verified.stamped + stamped,
|
|
@@ -11464,7 +12689,7 @@ function keyConfiguration(key) {
|
|
|
11464
12689
|
function entryPaths(key) {
|
|
11465
12690
|
try {
|
|
11466
12691
|
const [, entries] = JSON.parse(key);
|
|
11467
|
-
return entries.map(([, ,
|
|
12692
|
+
return entries.map(([, , path18]) => normalize2(path18));
|
|
11468
12693
|
} catch {
|
|
11469
12694
|
return [];
|
|
11470
12695
|
}
|
|
@@ -11484,9 +12709,9 @@ function holds2(watch, observations, changes, probes = {
|
|
|
11484
12709
|
if (sweep2.changed) return `${sweep2.changed.kind} observation changed: ${sweep2.changed.path}`;
|
|
11485
12710
|
for (const directory of probes.missing)
|
|
11486
12711
|
if (ts12.sys.directoryExists(directory)) return `directory appeared: ${directory}`;
|
|
11487
|
-
for (const [
|
|
11488
|
-
const
|
|
11489
|
-
if (
|
|
12712
|
+
for (const [path18, real2] of probes.realpaths) {
|
|
12713
|
+
const current2 = realpathOf(path18);
|
|
12714
|
+
if (current2 === void 0 || normalize2(current2) !== real2) return `symlink retargeted: ${path18}`;
|
|
11490
12715
|
}
|
|
11491
12716
|
const directories = probes.listings.sweep();
|
|
11492
12717
|
if (directories.changed) return `directory listing changed: ${directories.changed}`;
|
|
@@ -11514,29 +12739,29 @@ async function patchProgram(previous, assessment, discovery) {
|
|
|
11514
12739
|
const order = before.getSourceFiles().map((source) => source.fileName);
|
|
11515
12740
|
const observedAtNs = observationClockNs();
|
|
11516
12741
|
const plans = [];
|
|
11517
|
-
for (const
|
|
11518
|
-
const source = project.getSourceFile(
|
|
11519
|
-
const importer = mirror.observations.importer(
|
|
12742
|
+
for (const path18 of files) {
|
|
12743
|
+
const source = project.getSourceFile(path18);
|
|
12744
|
+
const importer = mirror.observations.importer(path18);
|
|
11520
12745
|
if (!source || !importer)
|
|
11521
|
-
return { kind: "refused", reason: `${
|
|
12746
|
+
return { kind: "refused", reason: `${path18} is not a file of the retained program` };
|
|
11522
12747
|
const compiled = source.compilerNode;
|
|
11523
12748
|
if (compiled.isDeclarationFile || before.isSourceFileDefaultLibrary(compiled) || before.isSourceFileFromExternalLibrary(compiled))
|
|
11524
|
-
return { kind: "refused", reason: `${
|
|
12749
|
+
return { kind: "refused", reason: `${path18} is a declaration or library file` };
|
|
11525
12750
|
let raw;
|
|
11526
12751
|
try {
|
|
11527
|
-
raw = readText(
|
|
12752
|
+
raw = readText(path18);
|
|
11528
12753
|
} catch (error) {
|
|
11529
12754
|
return {
|
|
11530
12755
|
kind: "refused",
|
|
11531
|
-
reason: `${
|
|
12756
|
+
reason: `${path18} cannot be read: ${error instanceof Error ? error.message : String(error)}`
|
|
11532
12757
|
};
|
|
11533
12758
|
}
|
|
11534
12759
|
const text = raw.text.charCodeAt(0) === 65279 ? raw.text.slice(1) : raw.text;
|
|
11535
|
-
const reason = patchable(
|
|
11536
|
-
if (reason) return { kind: "refused", reason: `${
|
|
11537
|
-
if (references(
|
|
11538
|
-
return discovery ? restructureProgram(previous, files, discovery) : { kind: "refused", reason: `${
|
|
11539
|
-
plans.push({ path:
|
|
12760
|
+
const reason = patchable(path18, compiled.text, "before") ?? patchable(path18, text, "after");
|
|
12761
|
+
if (reason) return { kind: "refused", reason: `${path18}: ${reason}` };
|
|
12762
|
+
if (references(path18, compiled.text) !== references(path18, text))
|
|
12763
|
+
return discovery ? restructureProgram(previous, files, discovery) : { kind: "refused", reason: `${path18}: its imports, directives or pragmas changed` };
|
|
12764
|
+
plans.push({ path: path18, source, raw, text, before: comparable(importer) });
|
|
11540
12765
|
}
|
|
11541
12766
|
for (const plan of plans) mirror.appliedSinceBase.set(plan.path, plan.raw.digest);
|
|
11542
12767
|
mirror.version += 1;
|
|
@@ -11602,7 +12827,7 @@ async function restructureProgram(previous, edited, discovery) {
|
|
|
11602
12827
|
if (!sameList(parentMost(roots), parentMost(mirror.roots)))
|
|
11603
12828
|
return { kind: "refused", reason: "the members' parent-most folders changed" };
|
|
11604
12829
|
const importers = new Set(mirror.observations.importers());
|
|
11605
|
-
const deleted = [...importers].filter((
|
|
12830
|
+
const deleted = [...importers].filter((path18) => !existsSync12(path18));
|
|
11606
12831
|
const added = roots.filter((root) => !importers.has(normalize2(root)));
|
|
11607
12832
|
if (edited.length + deleted.length + added.length > MAX_PATCHED_FILES)
|
|
11608
12833
|
return {
|
|
@@ -11611,50 +12836,50 @@ async function restructureProgram(previous, edited, discovery) {
|
|
|
11611
12836
|
};
|
|
11612
12837
|
const compiled = project.getProgram().compilerObject;
|
|
11613
12838
|
const plans = [];
|
|
11614
|
-
for (const
|
|
11615
|
-
const source = project.getSourceFile(
|
|
11616
|
-
const importer = mirror.observations.importer(
|
|
12839
|
+
for (const path18 of edited) {
|
|
12840
|
+
const source = project.getSourceFile(path18);
|
|
12841
|
+
const importer = mirror.observations.importer(path18);
|
|
11617
12842
|
if (!source || !importer)
|
|
11618
|
-
return { kind: "refused", reason: `${
|
|
12843
|
+
return { kind: "refused", reason: `${path18} is not a file of the retained program` };
|
|
11619
12844
|
if (source.compilerNode.isDeclarationFile || compiled.isSourceFileDefaultLibrary(source.compilerNode) || compiled.isSourceFileFromExternalLibrary(source.compilerNode))
|
|
11620
|
-
return { kind: "refused", reason: `${
|
|
12845
|
+
return { kind: "refused", reason: `${path18} is a declaration or library file` };
|
|
11621
12846
|
let raw;
|
|
11622
12847
|
try {
|
|
11623
|
-
raw = readText(
|
|
12848
|
+
raw = readText(path18);
|
|
11624
12849
|
} catch (error) {
|
|
11625
12850
|
return {
|
|
11626
12851
|
kind: "refused",
|
|
11627
|
-
reason: `${
|
|
12852
|
+
reason: `${path18} cannot be read: ${error instanceof Error ? error.message : String(error)}`
|
|
11628
12853
|
};
|
|
11629
12854
|
}
|
|
11630
12855
|
const text = raw.text.charCodeAt(0) === 65279 ? raw.text.slice(1) : raw.text;
|
|
11631
|
-
const reason = patchable(
|
|
11632
|
-
if (reason) return { kind: "refused", reason: `${
|
|
11633
|
-
plans.push({ path:
|
|
12856
|
+
const reason = patchable(path18, source.compilerNode.text, "before") ?? patchable(path18, text, "after");
|
|
12857
|
+
if (reason) return { kind: "refused", reason: `${path18}: ${reason}` };
|
|
12858
|
+
plans.push({ path: path18, source, raw, text, before: comparable(importer) });
|
|
11634
12859
|
}
|
|
11635
|
-
for (const
|
|
11636
|
-
const source = project.getSourceFile(
|
|
11637
|
-
const reason = source ? patchable(
|
|
11638
|
-
if (reason) return { kind: "refused", reason: `deleted ${
|
|
12860
|
+
for (const path18 of deleted) {
|
|
12861
|
+
const source = project.getSourceFile(path18);
|
|
12862
|
+
const reason = source ? patchable(path18, source.compilerNode.text, "before") : void 0;
|
|
12863
|
+
if (reason) return { kind: "refused", reason: `deleted ${path18}: ${reason}` };
|
|
11639
12864
|
}
|
|
11640
|
-
for (const
|
|
12865
|
+
for (const path18 of added) {
|
|
11641
12866
|
let text;
|
|
11642
12867
|
try {
|
|
11643
|
-
text = readText(
|
|
12868
|
+
text = readText(path18).text;
|
|
11644
12869
|
} catch (error) {
|
|
11645
12870
|
return {
|
|
11646
12871
|
kind: "refused",
|
|
11647
|
-
reason: `${
|
|
12872
|
+
reason: `${path18} cannot be read: ${error instanceof Error ? error.message : String(error)}`
|
|
11648
12873
|
};
|
|
11649
12874
|
}
|
|
11650
|
-
const reason = patchable(
|
|
11651
|
-
if (reason) return { kind: "refused", reason: `new ${
|
|
12875
|
+
const reason = patchable(path18, text.charCodeAt(0) === 65279 ? text.slice(1) : text, "after");
|
|
12876
|
+
if (reason) return { kind: "refused", reason: `new ${path18}: ${reason}` };
|
|
11652
12877
|
}
|
|
11653
12878
|
for (const plan of plans) mirror.appliedSinceBase.set(plan.path, plan.raw.digest);
|
|
11654
12879
|
mirror.version += 1;
|
|
11655
12880
|
let after;
|
|
11656
12881
|
const unchanged = new Set(
|
|
11657
|
-
[...importers].filter((
|
|
12882
|
+
[...importers].filter((path18) => !plans.some((plan) => plan.path === path18) && existsSync12(path18))
|
|
11658
12883
|
);
|
|
11659
12884
|
withPinnedRoots(
|
|
11660
12885
|
wrapper,
|
|
@@ -11664,13 +12889,13 @@ async function restructureProgram(previous, edited, discovery) {
|
|
|
11664
12889
|
owned.recordRead(plan.path, plan.raw.text);
|
|
11665
12890
|
if (plan.source.getFullText() !== plan.text) replaceSource(factory, plan.source, plan.text);
|
|
11666
12891
|
}
|
|
11667
|
-
for (const
|
|
12892
|
+
for (const path18 of deleted) cache.get(path18)?.forget();
|
|
11668
12893
|
for (const root of added) project.addSourceFileAtPath(root);
|
|
11669
12894
|
project.resolveSourceFileDependencies();
|
|
11670
12895
|
const files2 = new Set(
|
|
11671
12896
|
project.getProgram().compilerObject.getSourceFiles().map((source) => source.fileName)
|
|
11672
12897
|
);
|
|
11673
|
-
for (const
|
|
12898
|
+
for (const path18 of [...cache.paths()]) if (!files2.has(path18)) cache.get(path18)?.forget();
|
|
11674
12899
|
after = project.getProgram().compilerObject;
|
|
11675
12900
|
},
|
|
11676
12901
|
(host) => reusingResolutions(host, compiled, unchanged, project.getCompilerOptions())
|
|
@@ -11678,7 +12903,7 @@ async function restructureProgram(previous, edited, discovery) {
|
|
|
11678
12903
|
if (!sameList(after.getRootFileNames(), roots))
|
|
11679
12904
|
return { kind: "refused", reason: "the restructured program has other root files" };
|
|
11680
12905
|
const files = new Set(after.getSourceFiles().map((source) => normalize2(source.fileName)));
|
|
11681
|
-
const gone = deleted.find((
|
|
12906
|
+
const gone = deleted.find((path18) => files.has(path18));
|
|
11682
12907
|
if (gone) return { kind: "refused", reason: `the deleted ${gone} is still a program file` };
|
|
11683
12908
|
const failure2 = syntaxFailure(after);
|
|
11684
12909
|
if (failure2) return { kind: "refused", reason: `syntax errors: ${failure2.message}` };
|
|
@@ -11687,7 +12912,7 @@ async function restructureProgram(previous, edited, discovery) {
|
|
|
11687
12912
|
project,
|
|
11688
12913
|
owned,
|
|
11689
12914
|
membership,
|
|
11690
|
-
(
|
|
12915
|
+
(path18) => !retracked.has(path18) && existsSync12(path18)
|
|
11691
12916
|
);
|
|
11692
12917
|
const watch = mirror.watch;
|
|
11693
12918
|
watch.stamps.record(tracked, observedAtNs);
|
|
@@ -11697,7 +12922,7 @@ async function restructureProgram(previous, edited, discovery) {
|
|
|
11697
12922
|
const listings = watch.listings.withoutGlobs();
|
|
11698
12923
|
for (const dependency of mirror.observations.files.all())
|
|
11699
12924
|
if (dependency.kind === "glob")
|
|
11700
|
-
listings.recordGlob(dependency, observedAtNs, (
|
|
12925
|
+
listings.recordGlob(dependency, observedAtNs, (path18) => owned.has(path18));
|
|
11701
12926
|
watch.listings = listings;
|
|
11702
12927
|
mirror.roots = roots;
|
|
11703
12928
|
previous.scopes.clear();
|
|
@@ -11759,7 +12984,7 @@ function sourceCache(project) {
|
|
|
11759
12984
|
return void 0;
|
|
11760
12985
|
return {
|
|
11761
12986
|
paths: () => [...factory.getSourceFilePaths()],
|
|
11762
|
-
get: (
|
|
12987
|
+
get: (path18) => factory.getSourceFileFromCacheFromFilePath(fileSystem.getStandardizedAbsolutePath(path18)),
|
|
11763
12988
|
fileSystem: { globSync: (patterns) => fileSystem.globSync(patterns) }
|
|
11764
12989
|
};
|
|
11765
12990
|
}
|
|
@@ -11789,11 +13014,11 @@ function withPinnedRoots(program, roots, action, hostFor = (host) => host) {
|
|
|
11789
13014
|
}
|
|
11790
13015
|
var TYPESCRIPT_SOURCE = /\.(?:[cm]?ts|tsx)$/;
|
|
11791
13016
|
var DECLARATION = /\.d\.(?:[^/]*\.)?[cm]?ts$/;
|
|
11792
|
-
function patchable(
|
|
11793
|
-
if (!TYPESCRIPT_SOURCE.test(
|
|
13017
|
+
function patchable(path18, text, when) {
|
|
13018
|
+
if (!TYPESCRIPT_SOURCE.test(path18) || DECLARATION.test(path18))
|
|
11794
13019
|
return "not a TypeScript source file";
|
|
11795
|
-
if (
|
|
11796
|
-
const source = ts12.createSourceFile(
|
|
13020
|
+
if (path18.includes("/node_modules/")) return "a library file";
|
|
13021
|
+
const source = ts12.createSourceFile(path18, text, ts12.ScriptTarget.Latest, false);
|
|
11797
13022
|
if (!ts12.isExternalModule(source)) return `a script ${when} the edit`;
|
|
11798
13023
|
for (const statement of source.statements) {
|
|
11799
13024
|
if (ts12.isModuleDeclaration(statement) && (ts12.isStringLiteral(statement.name) || (statement.flags & ts12.NodeFlags.GlobalAugmentation) !== 0))
|
|
@@ -11802,9 +13027,9 @@ function patchable(path17, text, when) {
|
|
|
11802
13027
|
}
|
|
11803
13028
|
return void 0;
|
|
11804
13029
|
}
|
|
11805
|
-
function references(
|
|
13030
|
+
function references(path18, text) {
|
|
11806
13031
|
const info = ts12.preProcessFile(text, true, true);
|
|
11807
|
-
const pragmas = ts12.createSourceFile(
|
|
13032
|
+
const pragmas = ts12.createSourceFile(path18, text, ts12.ScriptTarget.Latest, false).pragmas;
|
|
11808
13033
|
const argumentsOf = (value) => Array.isArray(value) ? value.map(argumentsOf) : value?.arguments ?? null;
|
|
11809
13034
|
return JSON.stringify([
|
|
11810
13035
|
[...pragmas ?? /* @__PURE__ */ new Map()].map(([name, value]) => [name, argumentsOf(value)]),
|
|
@@ -12585,12 +13810,12 @@ function createJsDoc(markdown) {
|
|
|
12585
13810
|
const original = comment?.getStructure().tags ?? [];
|
|
12586
13811
|
if (!comment || !comment.getText().includes("```")) return original;
|
|
12587
13812
|
const ranges = [];
|
|
12588
|
-
const
|
|
13813
|
+
const visit9 = (node2) => {
|
|
12589
13814
|
if (node2 instanceof DocExcerpt && node2.excerptKind === ExcerptKind.FencedCode_Code)
|
|
12590
13815
|
ranges.push(node2.content.getContainingTextRange());
|
|
12591
|
-
node2.getChildNodes().forEach(
|
|
13816
|
+
node2.getChildNodes().forEach(visit9);
|
|
12592
13817
|
};
|
|
12593
|
-
|
|
13818
|
+
visit9(new TSDocParser().parseString(comment.getText().replace(/@/g, "a")).docComment);
|
|
12594
13819
|
const nativeTags = comment.getTags();
|
|
12595
13820
|
const validTags = nativeTags.filter((tag) => {
|
|
12596
13821
|
const start = tag.getStart() - comment.getStart();
|
|
@@ -12631,10 +13856,10 @@ function createJsDoc(markdown) {
|
|
|
12631
13856
|
}
|
|
12632
13857
|
var { compiler: nunjucksCompiler2, lib: nunjucksLib2 } = nunjucks2;
|
|
12633
13858
|
var compiledTemplates = /* @__PURE__ */ new Map();
|
|
12634
|
-
function compiledSource(
|
|
13859
|
+
function compiledSource(path18, text, environment) {
|
|
12635
13860
|
const cacheable = !environment.extensionsList.length;
|
|
12636
13861
|
const key = JSON.stringify([text, environment.asyncFilters, environment.opts]);
|
|
12637
|
-
const cached = compiledTemplates.get(
|
|
13862
|
+
const cached = compiledTemplates.get(path18);
|
|
12638
13863
|
if (cacheable && cached?.key === key) return { type: "code", obj: cached.code };
|
|
12639
13864
|
let code;
|
|
12640
13865
|
try {
|
|
@@ -12644,15 +13869,15 @@ function compiledSource(path17, text, environment) {
|
|
|
12644
13869
|
text,
|
|
12645
13870
|
environment.asyncFilters,
|
|
12646
13871
|
environment.extensionsList,
|
|
12647
|
-
|
|
13872
|
+
path18,
|
|
12648
13873
|
environment.opts
|
|
12649
13874
|
)
|
|
12650
13875
|
)();
|
|
12651
13876
|
} catch (error) {
|
|
12652
|
-
compiledTemplates.delete(
|
|
12653
|
-
throw nunjucksLib2._prettifyError(
|
|
13877
|
+
compiledTemplates.delete(path18);
|
|
13878
|
+
throw nunjucksLib2._prettifyError(path18, environment.opts.dev, error);
|
|
12654
13879
|
}
|
|
12655
|
-
if (cacheable) compiledTemplates.set(
|
|
13880
|
+
if (cacheable) compiledTemplates.set(path18, { key, code });
|
|
12656
13881
|
return { type: "code", obj: code };
|
|
12657
13882
|
}
|
|
12658
13883
|
function signalMember(node) {
|
|
@@ -12666,10 +13891,10 @@ function signalMember(node) {
|
|
|
12666
13891
|
function renderApiTemplate(template, context, root, files, markdown, configDirectory) {
|
|
12667
13892
|
class TrackedLoader extends Loader2 {
|
|
12668
13893
|
getSource(name) {
|
|
12669
|
-
const
|
|
12670
|
-
const text = files.read(
|
|
12671
|
-
const src = compiledSource(
|
|
12672
|
-
return { src, path:
|
|
13894
|
+
const path18 = hostPath(resolve7(root, name));
|
|
13895
|
+
const text = files.read(path18);
|
|
13896
|
+
const src = compiledSource(path18, text, environment);
|
|
13897
|
+
return { src, path: path18, noCache: true };
|
|
12673
13898
|
}
|
|
12674
13899
|
}
|
|
12675
13900
|
const docs = createJsDoc(markdown);
|
|
@@ -12736,17 +13961,17 @@ function requestedDeclaration(state, request, files, context) {
|
|
|
12736
13961
|
const [file, name, extra] = request.declarationPath.split("#");
|
|
12737
13962
|
if (!file || !name || extra)
|
|
12738
13963
|
throw new SemanticFailure("SEMANTIC_DECLARATION_PATH", "Expected path/to/file.ts#exportName");
|
|
12739
|
-
const
|
|
12740
|
-
if (state.owned.has(
|
|
12741
|
-
files.read(
|
|
12742
|
-
recordLookup(
|
|
12743
|
-
let source = state.project.getSourceFile(
|
|
13964
|
+
const path18 = normalize2(resolve8(state.discovery.configuration.workspaceRoot, file));
|
|
13965
|
+
if (state.owned.has(path18)) throw ownedOverlap("API declaration path", path18, state.owned);
|
|
13966
|
+
files.read(path18);
|
|
13967
|
+
recordLookup(path18);
|
|
13968
|
+
let source = state.project.getSourceFile(path18);
|
|
12744
13969
|
const added = !source;
|
|
12745
13970
|
if (!source) {
|
|
12746
13971
|
state.mutated = true;
|
|
12747
13972
|
const project = state.project;
|
|
12748
|
-
source = withRootsAppended(project,
|
|
12749
|
-
const added2 = project.addSourceFileAtPath(
|
|
13973
|
+
source = withRootsAppended(project, path18, () => {
|
|
13974
|
+
const added2 = project.addSourceFileAtPath(path18);
|
|
12750
13975
|
project.resolveSourceFileDependencies();
|
|
12751
13976
|
return added2;
|
|
12752
13977
|
});
|
|
@@ -12759,7 +13984,7 @@ function requestedDeclaration(state, request, files, context) {
|
|
|
12759
13984
|
throw new SemanticFailure(
|
|
12760
13985
|
"SEMANTIC_DECLARATION_MISSING",
|
|
12761
13986
|
`Cannot resolve exported declaration ${request.declarationPath}`,
|
|
12762
|
-
{ path:
|
|
13987
|
+
{ path: path18 }
|
|
12763
13988
|
);
|
|
12764
13989
|
return { node: declaration };
|
|
12765
13990
|
}
|
|
@@ -12793,25 +14018,29 @@ function renderFragment(state, request, files, context) {
|
|
|
12793
14018
|
const html = withIndexedDerivedClasses(
|
|
12794
14019
|
node,
|
|
12795
14020
|
state.project,
|
|
12796
|
-
() =>
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12801
|
-
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
|
|
12807
|
-
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12811
|
-
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
14021
|
+
() => formatting(
|
|
14022
|
+
() => renderApiTemplate(
|
|
14023
|
+
template,
|
|
14024
|
+
{
|
|
14025
|
+
declaration: node,
|
|
14026
|
+
docNode: documented,
|
|
14027
|
+
templateName: kind,
|
|
14028
|
+
scope,
|
|
14029
|
+
// The legacy engine passes no such flag, so the shared templates keep protected members.
|
|
14030
|
+
hideProtectedMembers: state.discovery.configuration.apiProtectedMembers === false,
|
|
14031
|
+
...request.kind === "api" ? {
|
|
14032
|
+
hideDescription: true,
|
|
14033
|
+
hideSeeAlso: true,
|
|
14034
|
+
hideUsageNotes: true,
|
|
14035
|
+
hideRemarks: true,
|
|
14036
|
+
hideExamples: true
|
|
14037
|
+
} : {}
|
|
14038
|
+
},
|
|
14039
|
+
context.templateRoot(),
|
|
14040
|
+
files,
|
|
14041
|
+
(text) => context.markdown(text, source, files),
|
|
14042
|
+
state.discovery.configuration.workspaceRoot
|
|
14043
|
+
)
|
|
12815
14044
|
)
|
|
12816
14045
|
);
|
|
12817
14046
|
return {
|
|
@@ -12834,10 +14063,10 @@ function trackWholeProgram(state, files, context) {
|
|
|
12834
14063
|
}
|
|
12835
14064
|
for (const dependency of state.tracked.dependencies) files.add(dependency);
|
|
12836
14065
|
}
|
|
12837
|
-
function withRootsAppended(project,
|
|
14066
|
+
function withRootsAppended(project, path18, add) {
|
|
12838
14067
|
const program = project.getProgram();
|
|
12839
14068
|
if (typeof program._reset !== "function") return add();
|
|
12840
|
-
const roots = [...project.getProgram().compilerObject.getRootFileNames(),
|
|
14069
|
+
const roots = [...project.getProgram().compilerObject.getRootFileNames(), path18];
|
|
12841
14070
|
let added;
|
|
12842
14071
|
withPinnedRoots(program, roots, () => {
|
|
12843
14072
|
added = add();
|
|
@@ -13036,8 +14265,8 @@ var ProgramIndex = class {
|
|
|
13036
14265
|
let value = this.stars.get(file);
|
|
13037
14266
|
if (value === void 0) {
|
|
13038
14267
|
const found = /* @__PURE__ */ new Set();
|
|
13039
|
-
const
|
|
13040
|
-
const source = this.program.getSourceFile(
|
|
14268
|
+
const visit9 = (current2) => {
|
|
14269
|
+
const source = this.program.getSourceFile(current2);
|
|
13041
14270
|
if (!source) return;
|
|
13042
14271
|
for (const statement of source.statements) {
|
|
13043
14272
|
if (!ts13.isExportDeclaration(statement) || statement.exportClause || !statement.moduleSpecifier || !ts13.isStringLiteralLike(statement.moduleSpecifier))
|
|
@@ -13045,11 +14274,11 @@ var ProgramIndex = class {
|
|
|
13045
14274
|
for (const target of this.moduleFiles(statement.moduleSpecifier, source)) {
|
|
13046
14275
|
if (found.has(target)) continue;
|
|
13047
14276
|
found.add(target);
|
|
13048
|
-
|
|
14277
|
+
visit9(target);
|
|
13049
14278
|
}
|
|
13050
14279
|
}
|
|
13051
14280
|
};
|
|
13052
|
-
|
|
14281
|
+
visit9(file);
|
|
13053
14282
|
value = [...found].sort(compare);
|
|
13054
14283
|
this.stars.set(file, value);
|
|
13055
14284
|
}
|
|
@@ -13347,12 +14576,12 @@ function isolatedShape(source, options) {
|
|
|
13347
14576
|
});
|
|
13348
14577
|
if (emitted.diagnostics?.length) return void 0;
|
|
13349
14578
|
const enums = [];
|
|
13350
|
-
const
|
|
14579
|
+
const visit9 = (node) => {
|
|
13351
14580
|
if (ts13.isEnumDeclaration(node))
|
|
13352
14581
|
enums.push(printer.printNode(ts13.EmitHint.Unspecified, node, source));
|
|
13353
|
-
else ts13.forEachChild(node,
|
|
14582
|
+
else ts13.forEachChild(node, visit9);
|
|
13354
14583
|
};
|
|
13355
|
-
|
|
14584
|
+
visit9(source);
|
|
13356
14585
|
return hash2("dts-shape-v1", "dts", emitted.outputText, enums);
|
|
13357
14586
|
}
|
|
13358
14587
|
function printedToken(source) {
|
|
@@ -14099,19 +15328,19 @@ async function patchMismatch(patched, result, discovery, signal) {
|
|
|
14099
15328
|
|
|
14100
15329
|
// libs/builder/generator/compiler/assemble.ts
|
|
14101
15330
|
import { existsSync as existsSync16 } from "node:fs";
|
|
14102
|
-
import
|
|
15331
|
+
import path17 from "node:path";
|
|
14103
15332
|
|
|
14104
15333
|
// libs/builder/generator/compiler/plan.ts
|
|
14105
|
-
import { randomUUID as
|
|
15334
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
14106
15335
|
import { existsSync as existsSync13 } from "node:fs";
|
|
14107
|
-
import { mkdir as
|
|
14108
|
-
import
|
|
15336
|
+
import { mkdir as mkdir6, readFile as readFile4, rename as rename7, rm as rm7, writeFile as writeFile7 } from "node:fs/promises";
|
|
15337
|
+
import path15 from "node:path";
|
|
14109
15338
|
|
|
14110
15339
|
// libs/builder/generator/compiler/fast-start.ts
|
|
14111
|
-
import { randomUUID as
|
|
14112
|
-
import { readFileSync as
|
|
14113
|
-
import { mkdir as
|
|
14114
|
-
import
|
|
15340
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
15341
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
15342
|
+
import { mkdir as mkdir5, rename as rename5, rm as rm5, writeFile as writeFile5 } from "node:fs/promises";
|
|
15343
|
+
import path13 from "node:path";
|
|
14115
15344
|
import { ts as ts15 } from "ts-morph";
|
|
14116
15345
|
var FAST_START_MISMATCH = "COMPILATION_FAST_START_MISMATCH";
|
|
14117
15346
|
var RECORD_VERSION = 1;
|
|
@@ -14133,7 +15362,7 @@ function fastStartMode(options, request) {
|
|
|
14133
15362
|
function fastStartPath(options, request, configuration) {
|
|
14134
15363
|
if (request.mode !== "development" || options.incrementalReuse === false || fastStartSwitch(options) === "off" || !configuration.cacheEnabled)
|
|
14135
15364
|
return void 0;
|
|
14136
|
-
return
|
|
15365
|
+
return path13.join(configuration.cacheRoot, `${hash(options.projectId)}.fast-start.json`);
|
|
14137
15366
|
}
|
|
14138
15367
|
function engineSwitches() {
|
|
14139
15368
|
return FLAGS.filter((flag) => flag.name !== FAST_START_FLAG).map((flag) => [
|
|
@@ -14183,22 +15412,22 @@ async function saveFastStart(file, input) {
|
|
|
14183
15412
|
const text = JSON.stringify(record);
|
|
14184
15413
|
const digest3 = contentDigest(text);
|
|
14185
15414
|
if (known2.get(file) === digest3 && currentDigest(file) === digest3) return;
|
|
14186
|
-
const temporary = `${file}.${
|
|
15415
|
+
const temporary = `${file}.${randomUUID6()}.tmp`;
|
|
14187
15416
|
try {
|
|
14188
|
-
await
|
|
15417
|
+
await mkdir5(path13.dirname(file), { recursive: true });
|
|
14189
15418
|
await sweepTemporaries(file);
|
|
14190
|
-
await
|
|
14191
|
-
await retryingRename(
|
|
15419
|
+
await writeFile5(temporary, text, { flag: "wx" });
|
|
15420
|
+
await retryingRename(rename5)(temporary, file);
|
|
14192
15421
|
known2.set(file, digest3);
|
|
14193
15422
|
} catch {
|
|
14194
15423
|
known2.delete(file);
|
|
14195
15424
|
} finally {
|
|
14196
|
-
await
|
|
15425
|
+
await rm5(temporary, { force: true }).catch(() => void 0);
|
|
14197
15426
|
}
|
|
14198
15427
|
}
|
|
14199
15428
|
function currentDigest(file) {
|
|
14200
15429
|
try {
|
|
14201
|
-
return bytesDigest(
|
|
15430
|
+
return bytesDigest(readFileSync9(file));
|
|
14202
15431
|
} catch {
|
|
14203
15432
|
return void 0;
|
|
14204
15433
|
}
|
|
@@ -14207,7 +15436,7 @@ async function restoreFastStart(input) {
|
|
|
14207
15436
|
const { file, options, found, signal } = input;
|
|
14208
15437
|
let record;
|
|
14209
15438
|
try {
|
|
14210
|
-
const bytes =
|
|
15439
|
+
const bytes = readFileSync9(file);
|
|
14211
15440
|
const value = JSON.parse(bytes.toString("utf8"));
|
|
14212
15441
|
if (!isRecord2(value)) return { reason: "the start record is invalid" };
|
|
14213
15442
|
record = value;
|
|
@@ -14265,7 +15494,7 @@ function physical(dependencies) {
|
|
|
14265
15494
|
);
|
|
14266
15495
|
}
|
|
14267
15496
|
function normalize3(value) {
|
|
14268
|
-
return
|
|
15497
|
+
return path13.resolve(value).replace(/\\/g, "/");
|
|
14269
15498
|
}
|
|
14270
15499
|
function members(values, roots) {
|
|
14271
15500
|
return JSON.stringify(
|
|
@@ -14281,8 +15510,8 @@ async function firstChange(inputs, ownedRoots) {
|
|
|
14281
15510
|
for (let index2 = next++; index2 < inputs.length && !found; index2 = next++) {
|
|
14282
15511
|
const input2 = inputs[index2];
|
|
14283
15512
|
const refreshed = await refresher.refresh([input2], []);
|
|
14284
|
-
const
|
|
14285
|
-
const same = !refreshed.diagnostics.some((item) => item.severity === "error") && (input2.kind === "content" ?
|
|
15513
|
+
const current2 = refreshed.dependencies[0];
|
|
15514
|
+
const same = !refreshed.diagnostics.some((item) => item.severity === "error") && (input2.kind === "content" ? current2?.kind === "content" && current2.digest === input2.digest : input2.kind === "existence" ? current2?.kind === "existence" && current2.exists === input2.exists : current2?.kind === "glob" && members(current2.members, ownedRoots) === members(input2.members, ownedRoots));
|
|
14286
15515
|
if (!same) {
|
|
14287
15516
|
changed[index2] = true;
|
|
14288
15517
|
found = true;
|
|
@@ -14323,12 +15552,12 @@ function isDependency2(value) {
|
|
|
14323
15552
|
}
|
|
14324
15553
|
|
|
14325
15554
|
// libs/builder/generator/compiler/memo.ts
|
|
14326
|
-
import { randomUUID as
|
|
14327
|
-
import { readFileSync as
|
|
14328
|
-
import { rename as
|
|
14329
|
-
import
|
|
15555
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
15556
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
15557
|
+
import { rename as rename6, rm as rm6, writeFile as writeFile6 } from "node:fs/promises";
|
|
15558
|
+
import path14 from "node:path";
|
|
14330
15559
|
var MEMO_SCHEMA_VERSION = 2;
|
|
14331
|
-
var memoPath = (root, projectId) =>
|
|
15560
|
+
var memoPath = (root, projectId) => path14.join(root, `${hash(projectId)}.compiler-memo.json`);
|
|
14332
15561
|
function createMemoState(enabled, root, options) {
|
|
14333
15562
|
let loaded;
|
|
14334
15563
|
const empty2 = () => ({
|
|
@@ -14345,7 +15574,7 @@ function createMemoState(enabled, root, options) {
|
|
|
14345
15574
|
loaded = empty2();
|
|
14346
15575
|
if (!enabled) return loaded;
|
|
14347
15576
|
try {
|
|
14348
|
-
const value = JSON.parse(
|
|
15577
|
+
const value = JSON.parse(readFileSync10(memoPath(root, options.projectId), "utf8"));
|
|
14349
15578
|
if (isMemoFile(value) && value.compilerVersion === options.compilerVersion && value.toolchainDigest === options.toolchainDigest)
|
|
14350
15579
|
loaded = value;
|
|
14351
15580
|
} catch {
|
|
@@ -14382,13 +15611,13 @@ function createMemoState(enabled, root, options) {
|
|
|
14382
15611
|
async save(projectId) {
|
|
14383
15612
|
if (!enabled) return;
|
|
14384
15613
|
const file = memoPath(root, projectId);
|
|
14385
|
-
const temporary = `${file}.${
|
|
15614
|
+
const temporary = `${file}.${randomUUID7()}.tmp`;
|
|
14386
15615
|
try {
|
|
14387
|
-
await
|
|
14388
|
-
await retryingRename(
|
|
15616
|
+
await writeFile6(temporary, JSON.stringify(next), { flag: "wx" });
|
|
15617
|
+
await retryingRename(rename6)(temporary, file);
|
|
14389
15618
|
} catch {
|
|
14390
15619
|
} finally {
|
|
14391
|
-
await
|
|
15620
|
+
await rm6(temporary, { force: true }).catch(() => void 0);
|
|
14392
15621
|
}
|
|
14393
15622
|
}
|
|
14394
15623
|
};
|
|
@@ -14478,14 +15707,20 @@ async function planGeneration(services, input) {
|
|
|
14478
15707
|
setup(outputDependencyResult.diagnostics, outputDependencyResult.dependencies);
|
|
14479
15708
|
const outputDependencies = outputDependencyResult.dependencies;
|
|
14480
15709
|
const highlight2 = createHighlightSession(options, request, configuration);
|
|
15710
|
+
const format = createFormatSession(options, request, configuration);
|
|
15711
|
+
useFormatCache(format);
|
|
15712
|
+
const grammars2 = grammarsSwitch(options);
|
|
14481
15713
|
const back = createRenderBack(options, highlight2, {
|
|
14482
15714
|
themes: configuration.themes,
|
|
15715
|
+
...configuration.shikiLangs ? { langs: configuration.shikiLangs } : {},
|
|
15716
|
+
...grammars2 === "all" ? { grammars: grammars2 } : {},
|
|
14483
15717
|
cache: highlight2 !== void 0
|
|
14484
15718
|
});
|
|
14485
15719
|
const compiler = new GeneratorContentCompiler(
|
|
14486
15720
|
{ configuration, semantic, templates: discovery.templates },
|
|
14487
15721
|
highlight2,
|
|
14488
|
-
back
|
|
15722
|
+
back,
|
|
15723
|
+
grammars2
|
|
14489
15724
|
);
|
|
14490
15725
|
return {
|
|
14491
15726
|
...services,
|
|
@@ -14508,6 +15743,7 @@ async function planGeneration(services, input) {
|
|
|
14508
15743
|
memo,
|
|
14509
15744
|
compiler,
|
|
14510
15745
|
...highlight2 ? { highlight: highlight2 } : {},
|
|
15746
|
+
...format ? { format } : {},
|
|
14511
15747
|
...back ? { back } : {},
|
|
14512
15748
|
scopedSemantic
|
|
14513
15749
|
};
|
|
@@ -14529,7 +15765,7 @@ function planContent(plan, units) {
|
|
|
14529
15765
|
plan.records.global("plan", { diagnostics, dependencies: [] });
|
|
14530
15766
|
}
|
|
14531
15767
|
var RESTORE_CONCURRENCY = 32;
|
|
14532
|
-
var indexPath = (root, projectId) =>
|
|
15768
|
+
var indexPath = (root, projectId) => path15.join(root, `${hash(projectId)}.compilation-index.json`);
|
|
14533
15769
|
async function restoreIndex(root, projectId, diagnostics) {
|
|
14534
15770
|
try {
|
|
14535
15771
|
const keys = JSON.parse(await readFile4(indexPath(root, projectId), "utf8"));
|
|
@@ -14572,18 +15808,18 @@ async function restoreIndex(root, projectId, diagnostics) {
|
|
|
14572
15808
|
}
|
|
14573
15809
|
}
|
|
14574
15810
|
async function saveIndex(root, projectId, artifacts) {
|
|
14575
|
-
await
|
|
15811
|
+
await mkdir6(root, { recursive: true });
|
|
14576
15812
|
const file = indexPath(root, projectId);
|
|
14577
|
-
const temporary = `${file}.${
|
|
15813
|
+
const temporary = `${file}.${randomUUID8()}.tmp`;
|
|
14578
15814
|
try {
|
|
14579
|
-
await
|
|
15815
|
+
await writeFile7(
|
|
14580
15816
|
temporary,
|
|
14581
15817
|
JSON.stringify(artifacts.map(({ identity, fingerprint }) => ({ identity, fingerprint }))),
|
|
14582
15818
|
{ flag: "wx" }
|
|
14583
15819
|
);
|
|
14584
|
-
await retryingRename(
|
|
15820
|
+
await retryingRename(rename7)(temporary, file);
|
|
14585
15821
|
} finally {
|
|
14586
|
-
await
|
|
15822
|
+
await rm7(temporary, { force: true });
|
|
14587
15823
|
}
|
|
14588
15824
|
}
|
|
14589
15825
|
|
|
@@ -14595,9 +15831,9 @@ import { existsSync as existsSync15, statSync as statSync3 } from "node:fs";
|
|
|
14595
15831
|
|
|
14596
15832
|
// libs/builder/generator/graph/unit-index.ts
|
|
14597
15833
|
import { existsSync as existsSync14, realpathSync as realpathSync4 } from "node:fs";
|
|
14598
|
-
import
|
|
15834
|
+
import path16 from "node:path";
|
|
14599
15835
|
function normalizePath3(file) {
|
|
14600
|
-
return file.charCodeAt(0) === 47 && !file.includes("/.") && !file.includes("//") && !file.includes("\\") && !file.endsWith("/") ? file :
|
|
15836
|
+
return file.charCodeAt(0) === 47 && !file.includes("/.") && !file.includes("//") && !file.includes("\\") && !file.endsWith("/") ? file : path16.resolve(file).replace(/\\/g, "/");
|
|
14601
15837
|
}
|
|
14602
15838
|
function rootKeyword(used) {
|
|
14603
15839
|
const match = /^[^.#]+/.exec(used);
|
|
@@ -14613,7 +15849,7 @@ var WINDOWS_DRIVE = /^[A-Za-z]:$/;
|
|
|
14613
15849
|
var WINDOWS_DRIVE_ROOT = /^[A-Za-z]:\/$/;
|
|
14614
15850
|
function parentDirectory(file) {
|
|
14615
15851
|
if (WINDOWS_DRIVE_ROOT.test(file)) return file;
|
|
14616
|
-
const parent =
|
|
15852
|
+
const parent = path16.posix.dirname(file);
|
|
14617
15853
|
return WINDOWS_DRIVE.test(parent) ? `${parent}/` : parent;
|
|
14618
15854
|
}
|
|
14619
15855
|
function createCanonicalAliases(ports = {}) {
|
|
@@ -14635,7 +15871,7 @@ function createCanonicalAliases(ports = {}) {
|
|
|
14635
15871
|
}
|
|
14636
15872
|
} else {
|
|
14637
15873
|
const parent = parentDirectory(directory);
|
|
14638
|
-
resolved = parent === directory ? directory :
|
|
15874
|
+
resolved = parent === directory ? directory : path16.posix.join(physicalDirectory(parent), path16.posix.basename(directory));
|
|
14639
15875
|
}
|
|
14640
15876
|
directories.set(directory, resolved);
|
|
14641
15877
|
return resolved;
|
|
@@ -14646,7 +15882,7 @@ function createCanonicalAliases(ports = {}) {
|
|
|
14646
15882
|
if (cached) return cached;
|
|
14647
15883
|
const normalized = normalize4(file);
|
|
14648
15884
|
const directory = parentDirectory(normalized);
|
|
14649
|
-
const physical2 = directory === normalized ? normalized : `${physicalDirectory(directory).replace(/\/$/, "")}/${
|
|
15885
|
+
const physical2 = directory === normalized ? normalized : `${physicalDirectory(directory).replace(/\/$/, "")}/${path16.posix.basename(normalized)}`;
|
|
14650
15886
|
const aliases = physical2 === normalized ? [normalized] : [normalized, physical2];
|
|
14651
15887
|
files.set(file, aliases);
|
|
14652
15888
|
return aliases;
|
|
@@ -15171,8 +16407,8 @@ function discoveryChanges(index, fresh, structural2 = false) {
|
|
|
15171
16407
|
entries.add(entry.id);
|
|
15172
16408
|
continue;
|
|
15173
16409
|
}
|
|
15174
|
-
const
|
|
15175
|
-
if (
|
|
16410
|
+
const current2 = indexEntry(entry);
|
|
16411
|
+
if (current2.masked !== retained.masked || current2.evaluated !== retained.evaluated || current2.markdown.size !== retained.markdown.size || [...current2.markdown].some(([file, digest3]) => retained.markdown.get(file) !== digest3))
|
|
15176
16412
|
entries.add(entry.id);
|
|
15177
16413
|
}
|
|
15178
16414
|
const ids = new Set(fresh.entries.map((entry) => entry.id));
|
|
@@ -15201,9 +16437,9 @@ var discoveryFacts = (found, templates) => ({
|
|
|
15201
16437
|
remoteKeywords: JSON.stringify(found.remoteKeywords),
|
|
15202
16438
|
templates: JSON.stringify(templates)
|
|
15203
16439
|
});
|
|
15204
|
-
function explained(
|
|
15205
|
-
if (read.has(
|
|
15206
|
-
const prefix = `${
|
|
16440
|
+
function explained(path18, read) {
|
|
16441
|
+
if (read.has(path18)) return true;
|
|
16442
|
+
const prefix = `${path18}/`;
|
|
15207
16443
|
for (const item of read) if (item.startsWith(prefix)) return true;
|
|
15208
16444
|
return false;
|
|
15209
16445
|
}
|
|
@@ -15216,8 +16452,8 @@ function sweep(build2, index) {
|
|
|
15216
16452
|
else if (observed === "present") {
|
|
15217
16453
|
same = existsSync15(file) && stampOf(file) === void 0;
|
|
15218
16454
|
} else {
|
|
15219
|
-
const
|
|
15220
|
-
same =
|
|
16455
|
+
const current2 = stampOf(file);
|
|
16456
|
+
same = current2 !== void 0 && sameStamp(current2, observed);
|
|
15221
16457
|
}
|
|
15222
16458
|
if (!same && index.hits(file).length) changed.push({ kind: "update", path: file });
|
|
15223
16459
|
}
|
|
@@ -15518,7 +16754,7 @@ var TargetedGeneration = class _TargetedGeneration {
|
|
|
15518
16754
|
for (const phase of ["discovery", "semantic"])
|
|
15519
16755
|
for (const contribution of plan.records.globalContributions(phase))
|
|
15520
16756
|
add(contribution.dependencies);
|
|
15521
|
-
return paths.filter((
|
|
16757
|
+
return paths.filter((path18) => !explained(path18, read));
|
|
15522
16758
|
}
|
|
15523
16759
|
/**
|
|
15524
16760
|
* Compares an API entry's fresh enumeration with its retained units: the entry's own unit holds
|
|
@@ -15578,11 +16814,11 @@ var TargetedGeneration = class _TargetedGeneration {
|
|
|
15578
16814
|
if (!recorded.size) return false;
|
|
15579
16815
|
const refreshed = await refresher.refresh([...recorded.values()], []);
|
|
15580
16816
|
if (refreshed.diagnostics.some((item) => item.severity === "error")) return true;
|
|
15581
|
-
const
|
|
16817
|
+
const current2 = new Map(
|
|
15582
16818
|
refreshed.dependencies.map((dependency) => [dependencyIdentity(dependency), dependency])
|
|
15583
16819
|
);
|
|
15584
16820
|
for (const [identity, dependency] of recorded) {
|
|
15585
|
-
const now =
|
|
16821
|
+
const now = current2.get(identity);
|
|
15586
16822
|
if (!now || !("digest" in now) || !("digest" in dependency) || now.digest !== dependency.digest)
|
|
15587
16823
|
return true;
|
|
15588
16824
|
}
|
|
@@ -15698,8 +16934,8 @@ var TargetedGeneration = class _TargetedGeneration {
|
|
|
15698
16934
|
closure(units, keywords) {
|
|
15699
16935
|
const index = this.committed.index;
|
|
15700
16936
|
const started = performance.now();
|
|
15701
|
-
const
|
|
15702
|
-
this.removedOwners = [...index.owners.keys()].filter((id) => !
|
|
16937
|
+
const current2 = new Set(units.map((unit) => unit.id));
|
|
16938
|
+
this.removedOwners = [...index.owners.keys()].filter((id) => !current2.has(id)).sort();
|
|
15703
16939
|
if (this.keywordFacts) {
|
|
15704
16940
|
const keys = /* @__PURE__ */ new Set();
|
|
15705
16941
|
for (const id of [...this.candidates, ...this.removedOwners])
|
|
@@ -15719,7 +16955,7 @@ var TargetedGeneration = class _TargetedGeneration {
|
|
|
15719
16955
|
this.facts.keysFrom = "all";
|
|
15720
16956
|
}
|
|
15721
16957
|
const consumers = [...index.consumersOf(this.keys)].filter(
|
|
15722
|
-
(id) => !this.candidates.has(id) &&
|
|
16958
|
+
(id) => !this.candidates.has(id) && current2.has(id)
|
|
15723
16959
|
);
|
|
15724
16960
|
this.linked = /* @__PURE__ */ new Set([...this.candidates, ...consumers]);
|
|
15725
16961
|
this.facts.keys = this.keys;
|
|
@@ -15747,7 +16983,7 @@ var TargetedGeneration = class _TargetedGeneration {
|
|
|
15747
16983
|
if (dependency.kind === "content" || dependency.kind === "existence")
|
|
15748
16984
|
read.add(normalizePath3(dependency.path));
|
|
15749
16985
|
}
|
|
15750
|
-
const missing = this.unknown.find((
|
|
16986
|
+
const missing = this.unknown.find((path18) => !explained(path18, read));
|
|
15751
16987
|
if (missing) throw new TargetedFallback(`unknown path not read by this generation: ${missing}`);
|
|
15752
16988
|
}
|
|
15753
16989
|
/** The units a targeted generation linked and assembled (for the report). */
|
|
@@ -15960,7 +17196,7 @@ function scopedSemanticSwitch(options) {
|
|
|
15960
17196
|
function scopedSemanticMode(options, request) {
|
|
15961
17197
|
return request.mode === "development" ? scopedSemanticSwitch(options) : "off";
|
|
15962
17198
|
}
|
|
15963
|
-
function closureRebuildReason(previous,
|
|
17199
|
+
function closureRebuildReason(previous, current2) {
|
|
15964
17200
|
const closures = (artifact) => {
|
|
15965
17201
|
const values = /* @__PURE__ */ new Map();
|
|
15966
17202
|
for (const dependency of [
|
|
@@ -15971,9 +17207,9 @@ function closureRebuildReason(previous, current) {
|
|
|
15971
17207
|
return values;
|
|
15972
17208
|
};
|
|
15973
17209
|
const before = closures(previous);
|
|
15974
|
-
const after = closures(
|
|
17210
|
+
const after = closures(current2);
|
|
15975
17211
|
const key = [.../* @__PURE__ */ new Set([...before.keys(), ...after.keys()])].sort().find((item) => before.get(item) !== after.get(item));
|
|
15976
|
-
return key === void 0 ? void 0 : { ownerId:
|
|
17212
|
+
return key === void 0 ? void 0 : { ownerId: current2.id, reason: "semantic", detail: `semantic closure changed: ${key}` };
|
|
15977
17213
|
}
|
|
15978
17214
|
async function verifyClosureReuse(plan, unit, descriptor, reused) {
|
|
15979
17215
|
if (plan.scopedSemantic === "off") return void 0;
|
|
@@ -16003,12 +17239,12 @@ async function verifyClosureReuse(plan, unit, descriptor, reused) {
|
|
|
16003
17239
|
};
|
|
16004
17240
|
}
|
|
16005
17241
|
function valueAt(value, at) {
|
|
16006
|
-
let
|
|
17242
|
+
let current2 = value;
|
|
16007
17243
|
for (const [, key, index] of at.matchAll(/\.([^.[]+)|\[(\d+)\]/g)) {
|
|
16008
|
-
if (
|
|
16009
|
-
|
|
17244
|
+
if (current2 === null || typeof current2 !== "object") return void 0;
|
|
17245
|
+
current2 = current2[key ?? Number(index)];
|
|
16010
17246
|
}
|
|
16011
|
-
return
|
|
17247
|
+
return current2 !== null && typeof current2 === "object" ? JSON.stringify(current2) : current2;
|
|
16012
17248
|
}
|
|
16013
17249
|
|
|
16014
17250
|
// libs/builder/generator/compiler/assemble.ts
|
|
@@ -16223,7 +17459,7 @@ function candidateSnapshot(plan, artifacts, keywordPlan, site) {
|
|
|
16223
17459
|
for (const output2 of artifact.outputs) {
|
|
16224
17460
|
if (plan.previousById.get(artifact.id)?.outputs.some(
|
|
16225
17461
|
(previousOutput) => previousOutput.path === output2.path && previousOutput.role === output2.role
|
|
16226
|
-
) && !existsSync16(
|
|
17462
|
+
) && !existsSync16(path17.resolve(configuration.outputRoot, output2.path))) {
|
|
16227
17463
|
records.reason({
|
|
16228
17464
|
ownerId: artifact.id,
|
|
16229
17465
|
reason: "output-missing",
|
|
@@ -17083,8 +18319,8 @@ async function renderFront(plan, unit, scope, rendered) {
|
|
|
17083
18319
|
function matchesDescriptorContent(descriptor, ir) {
|
|
17084
18320
|
return ir.schemaVersion === GENERATOR_SCHEMA_VERSION && ir.id === descriptor.id && ir.role === descriptor.role && ir.title === descriptor.title && ir.route === descriptor.route && ir.absoluteRoute === descriptor.absoluteRoute && sameValue(ir.searchBreadcrumbs ?? [], descriptor.searchBreadcrumbs) && ir.icon === descriptor.icon;
|
|
17085
18321
|
}
|
|
17086
|
-
function sameDescriptorPlan(previous,
|
|
17087
|
-
return !!previous && sameValue(previous,
|
|
18322
|
+
function sameDescriptorPlan(previous, current2) {
|
|
18323
|
+
return !!previous && sameValue(previous, current2);
|
|
17088
18324
|
}
|
|
17089
18325
|
|
|
17090
18326
|
// libs/builder/generator/compiler/retention.ts
|
|
@@ -17329,7 +18565,7 @@ function createCompilationService(options) {
|
|
|
17329
18565
|
};
|
|
17330
18566
|
const targetedResults = /* @__PURE__ */ new WeakSet();
|
|
17331
18567
|
let disposed = false;
|
|
17332
|
-
let
|
|
18568
|
+
let active2 = false;
|
|
17333
18569
|
let activeController;
|
|
17334
18570
|
let activeSettlement;
|
|
17335
18571
|
return {
|
|
@@ -17337,7 +18573,7 @@ function createCompilationService(options) {
|
|
|
17337
18573
|
async compile(request, signal, context) {
|
|
17338
18574
|
let records = new GenerationRecords();
|
|
17339
18575
|
const result = (candidate) => fold(records, candidate);
|
|
17340
|
-
if (disposed || signal.aborted ||
|
|
18576
|
+
if (disposed || signal.aborted || active2) {
|
|
17341
18577
|
records.global("failure", {
|
|
17342
18578
|
diagnostics: [
|
|
17343
18579
|
diagnostic(
|
|
@@ -17349,7 +18585,7 @@ function createCompilationService(options) {
|
|
|
17349
18585
|
});
|
|
17350
18586
|
return result();
|
|
17351
18587
|
}
|
|
17352
|
-
|
|
18588
|
+
active2 = true;
|
|
17353
18589
|
const releaseThreads = holdHtmlPool();
|
|
17354
18590
|
guideValues = /* @__PURE__ */ new Map();
|
|
17355
18591
|
const startedNs = BigInt(Date.now()) * 1000000n;
|
|
@@ -17478,6 +18714,8 @@ function createCompilationService(options) {
|
|
|
17478
18714
|
if (!scratch)
|
|
17479
18715
|
prestartRenderThreads(options, request, found.entries.length, {
|
|
17480
18716
|
themes: found.configuration.themes,
|
|
18717
|
+
...found.configuration.shikiLangs ? { langs: found.configuration.shikiLangs } : {},
|
|
18718
|
+
...grammarsSwitch(options) === "all" ? { grammars: "all" } : {},
|
|
17481
18719
|
cache: highlightCacheSwitch(options) !== "off"
|
|
17482
18720
|
});
|
|
17483
18721
|
await synchronize(true);
|
|
@@ -17663,8 +18901,9 @@ function createCompilationService(options) {
|
|
|
17663
18901
|
...reportError !== void 0 ? { error: reportError } : {}
|
|
17664
18902
|
});
|
|
17665
18903
|
signal.removeEventListener("abort", abort);
|
|
18904
|
+
useFormatCache(void 0);
|
|
17666
18905
|
releaseThreads();
|
|
17667
|
-
|
|
18906
|
+
active2 = false;
|
|
17668
18907
|
activeController = void 0;
|
|
17669
18908
|
settle();
|
|
17670
18909
|
activeSettlement = void 0;
|
|
@@ -17726,6 +18965,17 @@ async function runPhases(plan, found, scope, cache = true, progress) {
|
|
|
17726
18965
|
scope?.explain(artifacts, units);
|
|
17727
18966
|
progress?.phase("aggregate");
|
|
17728
18967
|
const site = aggregateUnits(plan, artifacts, keywordPlan);
|
|
18968
|
+
if (plan.format?.mismatches)
|
|
18969
|
+
records.global("aggregate", {
|
|
18970
|
+
diagnostics: [
|
|
18971
|
+
diagnostic(
|
|
18972
|
+
FORMAT_CACHE_MISMATCH,
|
|
18973
|
+
`${plan.format.mismatches} cached formatted signature(s), snippet(s) or formatter configuration(s) differ from formatting them again; the fresh formatting is used.`,
|
|
18974
|
+
"warning"
|
|
18975
|
+
)
|
|
18976
|
+
],
|
|
18977
|
+
dependencies: []
|
|
18978
|
+
});
|
|
17729
18979
|
if (signal.aborted || records.failed()) return done();
|
|
17730
18980
|
const candidate = candidateSnapshot(plan, artifacts, keywordPlan, site);
|
|
17731
18981
|
if (records.failed()) return done();
|
|
@@ -17736,9 +18986,9 @@ async function runPhases(plan, found, scope, cache = true, progress) {
|
|
|
17736
18986
|
artifacts,
|
|
17737
18987
|
scope ? (artifact) => artifact === plan.previousById.get(artifact.id) : void 0
|
|
17738
18988
|
);
|
|
17739
|
-
|
|
17740
|
-
|
|
17741
|
-
);
|
|
18989
|
+
const complete = !scope && units.every((unit) => unit.record.render.every((step) => step.projection !== "reuse"));
|
|
18990
|
+
await plan.highlight?.save(complete);
|
|
18991
|
+
await plan.format?.save(complete);
|
|
17742
18992
|
}
|
|
17743
18993
|
progress?.end();
|
|
17744
18994
|
if (signal.aborted) return done();
|