@svelte-vitals/core 0.55.2 → 0.55.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -2
- package/dist/internal.d.ts +487 -11
- package/dist/internal.js +387 -98
- package/dist/{json-BQf9Qb2D.d.ts → json-DmLgFEwV.d.ts} +85 -10
- package/dist/{markdown-DgHBAvYl.js → markdown-CsQNXeWj.js} +895 -158
- package/package.json +4 -4
package/dist/internal.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
//#region src/head.ts
|
|
3
|
-
const JS_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
4
|
-
"application/ecmascript",
|
|
5
|
-
"application/javascript",
|
|
6
|
-
"application/x-ecmascript",
|
|
7
|
-
"application/x-javascript",
|
|
8
|
-
"text/ecmascript",
|
|
9
|
-
"text/javascript",
|
|
10
|
-
"text/javascript1.0",
|
|
11
|
-
"text/javascript1.1",
|
|
12
|
-
"text/javascript1.2",
|
|
13
|
-
"text/javascript1.3",
|
|
14
|
-
"text/javascript1.4",
|
|
15
|
-
"text/javascript1.5",
|
|
16
|
-
"text/jscript",
|
|
17
|
-
"text/livescript",
|
|
18
|
-
"text/x-ecmascript",
|
|
19
|
-
"text/x-javascript"
|
|
20
|
-
]);
|
|
21
|
-
/** HTML strips only ASCII whitespace from a `type` before matching — `trim()` would also strip
|
|
22
|
-
* U+00A0 etc. and misread a data block as a classic script. */
|
|
23
|
-
const ASCII_WHITESPACE_EDGES = /^[\t\n\f\r ]+|[\t\n\f\r ]+$/g;
|
|
24
|
-
/**
|
|
25
|
-
* Whether a `type` attribute (undefined = absent) makes a `<script>` a classic,
|
|
26
|
-
* render-blocking-capable script. Per the HTML spec, absent and the literal empty string are
|
|
27
|
-
* classic; any other value is ASCII-whitespace-stripped and must match a JavaScript MIME type —
|
|
28
|
-
* so a whitespace-only `type` is a data block, not a classic script.
|
|
29
|
-
*/
|
|
30
|
-
function isClassicScriptType(type) {
|
|
31
|
-
if (type === void 0 || type === "") return true;
|
|
32
|
-
return JS_MIME_TYPES.has(type.replace(ASCII_WHITESPACE_EDGES, "").toLowerCase());
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
1
|
+
import { $ as performanceLoadWaterfall, $n as shouldSkipRangeCheck, $t as securityJavascriptUrl, A as a11yPatternTitle, An as splitTokens, Ar as seoTitlePresence, At as parseModuleProgram, B as a11yPlaceholderLabelOption, Bn as seoJsonLdDateFormat, Bt as attrTextOf, C as a11yPermittedContents, Cn as IDREF_ATTRS, Cr as seoCanonicalUrl, Ct as collectBrowserGuardImports, D as a11yDeprecatedAttr, Dn as foldOccurrences, Dr as layoutNeverRenders, Dt as collectSuppressions, E as a11yDisallowedAriaProps, En as decodeFragmentId, Er as seoDescriptionPresence, Et as collectProgramBindings, F as a11yPositiveTabindex, Fn as seoCharset, Fr as docsUrlFor, Ft as walkEstree, G as a11yInteractiveNesting, Gn as seoViewport, Gt as parseSvelte, H as a11yLabelHasControl, Hn as seoJsonLdDeprecatedType, Ht as attrValueOf, I as isInteractiveContainer, In as seoDescriptionLength, Ir as isPenalized, It as walkEvalScope, J as a11yUnknownAriaAttribute, Jn as seoTwitterCard, Jt as architecturePropCount, K as a11yInvalidAriaValue, Kn as seoOgUrl, Kt as textFromNodes, L as isInteractiveElement, Ln as seoTitleLength, Lt as walkScoped, M as a11yNoDuplicateDt, Mn as resolveRole, Mr as effectiveSeverity, Mt as scopeIntroducedNames, N as a11yNoAutofocus, Nn as seoHreflang, Nr as hasFailureAtOrAbove, Nt as unwrapExport, O as a11yDeprecatedElement, On as isTopFragment, Or as pageRendersOnlyWhenBuilding, Ot as collectSvelteLifecycleImports, P as a11yNoAccesskey, Pn as seoImageAlt, Pr as summarize, Pt as unwrapTs, Q as performanceSequentialAwaits, Qn as resolveRuleOptions, Qt as securityHandlerStateWrite, R as literalTabindexValue, Rn as seoJsonLdRequiredProps, Rr as defaultConfig, Rt as CHILD_NODE_KEYS, S as a11yRequiredElement, Sn as ASIDE_DEMOTING_TAGS, Sr as seoOgImage, St as collectBrowserGlobalRefs, T as a11yDeprecatedAria, Tn as SECTIONING_TAGS, Tr as isClassicScriptType, Tt as collectNamedImportAliases, U as a11yAccessibleName, Un as seoJsonLdValidity, Ut as findAttr, V as a11yUseList, Vn as seoJsonLdRelativeUrl, Vt as attrValue, W as a11yAriaHiddenFocus, Wn as seoSitemapInRobots, Wt as lineOf, X as performanceIframeLoading, Xn as performancePreconnect, Xt as securitySharedStateImport, Y as a11yInvalidRole, Yn as seoIndexability, Yt as architectureComponentSize, Z as performanceStateRaw, Zn as isPlainObject, Zt as securityServerModuleState, _ as a11yNoMissingIdRef, _n as seoHeadingLevelSkip, _r as seoHtmlLang, _t as parseKitModuleFacts, a as formatJsonReport, an as correctnessOrphanEffect, ar as formatFailedRuleWarning, at as architectureReservedNamePlacement, b as a11yDuplicateLandmark, bn as seoSingleH1, br as seoJsonLd, bt as WALK_IGNORED_KEYS, c as computeScore, cn as correctnessNonreactiveBuiltinState, cr as withFailedRulesOff, ct as architectureUnitEntryFile, d as messageText, dn as correctnessUnmutatedState, dr as performanceLcpImage, dt as collectFalseExports, en as securityRawHtml, er as validateRuleSetting, et as performanceMinifyDisabled, f as ruleMetaById, fn as correctnessEffectAsOnMount, fr as performanceFontPreloadCrossorigin, ft as collectTopLevelBindings, g as a11yUnverifiedIdRef, gn as seoSsrDisabled, gr as performanceImageDimensions, gt as parseInMemoryExports, h as explainRule, hn as correctnessEachKey, hr as performanceImageLoadingHint, ht as parseFalseExports, i as buildJsonReport, in as correctnessOrphanLifecycle, ir as compileOverrides, it as architectureRouteComponentImport, j as a11yAbbrTitle, jn as stripTextDirective, jr as classify, jt as rootObjectName, k as HTML_SPEC, kn as resolveLandmark, kr as routeNeverSsr, kt as matchLifecycleCall, l as formatGithubReport, ln as correctnessStalePropDerivation, lr as withIndexableOff, lt as architecturePrivateScopeImport, m as allRules, mn as correctnessEachIndexKey, mr as performanceResponsiveImage, mt as parseExitFactoryExports, n as mdEscape, nn as correctnessServerBrowserGlobal, nr as applyOverrides, nt as performanceHeavyImport, o as formatJsonReportChunks, on as correctnessAutoplayMuted, or as selectRules, ot as architectureReservedDirectoryNames, p as severityToSarifLevel, pn as correctnessEffectAsDerived, pr as performancePreloadMissingAs, pt as parseClientExports, q as a11yRequiredAriaProps, qn as seoOgDescription, qt as valueFromNodes, r as terminalSafe, rn as correctnessBasePathNavigation, rr as applyRuleSeverities, rt as architectureDocLinkTarget, s as computeHealth, sn as correctnessCheckableBindValue, sr as settingSeverity, st as architectureDirectoryNaming, t as formatMarkdownReport, tn as correctnessInstanceBrowserGlobal, tr as SEARCH_RESULT_RULES, tt as performanceNamespaceImport, u as SEVERITY_RANK, un as correctnessPropMutation, ur as performanceRenderBlockingScript, ut as DEFAULT_KIT_ALIASES, v as a11yIdDuplication, vn as seoDuplicateDescription, vr as seoSitemapXml, vt as resolveRepoLocalPath, w as a11yDisallowedElement, wn as NAMING_ATTRS, wr as hasRel, wt as collectDerivedGuardBindings, x as a11yDoctype, xn as ANCESTRY_DEPENDENT_TAGS, xr as seoOgTitle, xt as addBoundNames, y as a11yTopLevelLandmark, yn as seoDuplicateTitle, yr as seoRobotsTxt, yt as isRootRelativePath, z as a11yRequireDatetime, zn as seoJsonLdPlaceholder, zr as defaultProject, zt as attrText } from "./markdown-CsQNXeWj.js";
|
|
35
2
|
//#region src/images.ts
|
|
36
3
|
/** A `.svg` path (query and fragment ignored) or an inline `data:image/svg+xml` URI. */
|
|
37
4
|
function isSvgSrc(src) {
|
|
@@ -161,21 +128,46 @@ function collectConstantLists(programs, fragment, opts = {}) {
|
|
|
161
128
|
const stmt = opts.exported ? unwrapExport(top) : top;
|
|
162
129
|
if (stmt?.type !== "VariableDeclaration" || stmt.kind !== "const") continue;
|
|
163
130
|
for (const d of stmt.declarations ?? []) {
|
|
164
|
-
const init = unwrapTs(d?.init);
|
|
131
|
+
const init = opts.sets ? setLiteralList(unwrapTs(d?.init)) : unwrapTs(d?.init);
|
|
165
132
|
if (d?.id?.type === "Identifier" && init?.type === "ArrayExpression") {
|
|
166
133
|
if (!(init.elements ?? []).some((el) => el?.type === "SpreadElement")) candidates.set(d.id.name, d.id);
|
|
167
134
|
}
|
|
168
135
|
}
|
|
169
136
|
}
|
|
170
137
|
if (candidates.size === 0) return /* @__PURE__ */ new Set();
|
|
138
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
139
|
+
if (opts.exported) for (const program of programs) walkEstree(program, (n) => {
|
|
140
|
+
if (n.type !== "VariableDeclaration" || n.kind !== "const") return;
|
|
141
|
+
for (const d of n.declarations ?? []) {
|
|
142
|
+
const init = unwrapTs(d?.init);
|
|
143
|
+
const list = (init?.type === "ConditionalExpression" ? [init.consequent, init.alternate] : init?.type === "LogicalExpression" && init.operator !== "&&" ? [init.left, init.right] : [init]).map((b) => unwrapTs(b)).find((b) => b?.type === "Identifier" && candidates.has(b.name));
|
|
144
|
+
if (d?.id?.type !== "Identifier" || !list || candidates.has(d.id.name)) continue;
|
|
145
|
+
safe.add(list);
|
|
146
|
+
aliases.set(d.id.name, list.name);
|
|
147
|
+
candidates.set(d.id.name, d.id);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
171
150
|
for (const node of candidates.values()) safe.add(node);
|
|
172
151
|
const namespaces = new Set([...opts.imports ?? []].filter(([, b]) => b.imported === "*").map(([local]) => local));
|
|
173
152
|
const unsafe = /* @__PURE__ */ new Set();
|
|
174
153
|
const roots = [...programs, fragment];
|
|
175
154
|
const listOf = (n) => n?.type === "Identifier" && candidates.has(n.name) ? n.name : void 0;
|
|
155
|
+
const outerList = listOf;
|
|
176
156
|
const nsMember = (n) => n?.type === "MemberExpression" && !n.computed && namespaces.has(listOf(n.object)) ? `${n.object.name}.${n.property.name}` : void 0;
|
|
157
|
+
const outerMember = nsMember;
|
|
177
158
|
const members = /* @__PURE__ */ new Set();
|
|
178
|
-
|
|
159
|
+
const declared = /* @__PURE__ */ new Set();
|
|
160
|
+
for (const program of programs) {
|
|
161
|
+
const imported = /* @__PURE__ */ new Set();
|
|
162
|
+
for (const top of program.body ?? []) if (top?.type === "ImportDeclaration") for (const s of top.specifiers ?? []) imported.add(s?.local?.name);
|
|
163
|
+
for (const name of collectProgramBindings(program)) if (!imported.has(name)) declared.add(name);
|
|
164
|
+
}
|
|
165
|
+
for (const root of roots) walkScoped(root, (n, shadowed) => {
|
|
166
|
+
const listOf = (x) => {
|
|
167
|
+
const name = outerList(x);
|
|
168
|
+
return name && !shadowed.has(name) ? name : void 0;
|
|
169
|
+
};
|
|
170
|
+
const nsMember = (x) => x?.type === "MemberExpression" && listOf(x.object) ? outerMember(x) : void 0;
|
|
179
171
|
if (n.type === "EachBlock" && (listOf(n.expression) || nsMember(n.expression))) safe.add(n.expression);
|
|
180
172
|
if (n.type === "ForOfStatement" && (listOf(n.right) || nsMember(n.right))) safe.add(n.right);
|
|
181
173
|
if (n.type === "ArrayExpression") {
|
|
@@ -183,29 +175,46 @@ function collectConstantLists(programs, fragment, opts = {}) {
|
|
|
183
175
|
}
|
|
184
176
|
if (nsMember(n)) members.add(nsMember(n));
|
|
185
177
|
if (n.type === "MemberExpression") {
|
|
186
|
-
|
|
187
|
-
if (
|
|
178
|
+
const object = n.object ? unwrapTs(n.object) : n.object;
|
|
179
|
+
if (listOf(object) && !(n.computed && namespaces.has(object.name))) safe.add(object);
|
|
180
|
+
if (nsMember(object)) safe.add(object);
|
|
188
181
|
if (!n.computed) safe.add(n.property);
|
|
189
182
|
}
|
|
190
183
|
const target = n.type === "AssignmentExpression" ? n.left : n.type === "UpdateExpression" ? n.argument : void 0;
|
|
191
|
-
|
|
192
|
-
|
|
184
|
+
let root = target;
|
|
185
|
+
while (root && (root.type === "MemberExpression" || root.type.startsWith("TS"))) root = root.type === "MemberExpression" ? root.object : root.expression;
|
|
186
|
+
if (target?.type === "MemberExpression" && listOf(root)) unsafe.add(listOf(root));
|
|
187
|
+
const called = n.type === "CallExpression" && n.callee?.type === "MemberExpression" ? unwrapTs(n.callee.object) : void 0;
|
|
193
188
|
const calledList = listOf(called) ?? nsMember(called);
|
|
194
189
|
if (calledList) {
|
|
195
190
|
const { computed, property } = n.callee;
|
|
196
191
|
const method = !computed ? property?.name : property?.type === "Literal" && typeof property.value === "string" ? property.value : void 0;
|
|
197
192
|
if (computed && method === void 0 || method !== void 0 && MUTATING_METHODS.has(method)) unsafe.add(calledList);
|
|
198
193
|
}
|
|
194
|
+
const callee = n.type === "CallExpression" || n.type === "NewExpression" ? rootObjectName(n.callee) : void 0;
|
|
195
|
+
if (opts.exported && callee !== void 0 && !declared.has(callee) && !shadowed.has(callee)) {
|
|
196
|
+
for (const arg of n.arguments ?? []) if (listOf(unwrapTs(arg))) safe.add(unwrapTs(arg));
|
|
197
|
+
}
|
|
199
198
|
if (n.type === "BindDirective" && listOf(rootObjectNode(n.expression))) unsafe.add(listOf(rootObjectNode(n.expression)));
|
|
200
199
|
if (n.type === "Property" && !n.computed && !n.shorthand) safe.add(n.key);
|
|
201
200
|
});
|
|
202
|
-
for (const root of roots) walkEvalScope(root, (n) => {
|
|
201
|
+
for (const root of roots) walkEvalScope(root, (n, shadowed) => {
|
|
203
202
|
if (n.type.startsWith("TS") && !TS_VALUE_NODES.has(n.type)) return true;
|
|
204
203
|
const name = listOf(n) ?? nsMember(n);
|
|
205
|
-
if (name && !safe.has(n)) unsafe.add(name);
|
|
204
|
+
if (name && !safe.has(n) && !shadowed.has(name.split(".")[0])) unsafe.add(name);
|
|
206
205
|
return false;
|
|
207
206
|
}, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
|
|
208
|
-
|
|
207
|
+
for (const [alias, list] of aliases) if (unsafe.has(alias)) unsafe.add(list);
|
|
208
|
+
return new Set([...candidates.keys(), ...members].filter((key) => !aliases.has(key) && !unsafe.has(key) && !unsafe.has(key.split(".")[0])));
|
|
209
|
+
}
|
|
210
|
+
/** A component's script `const` lists that nothing in its scripts or template can change. */
|
|
211
|
+
function collectComponentConstantLists(ast, opts = {}) {
|
|
212
|
+
return collectConstantLists([ast.module?.content, ast.instance?.content].filter(Boolean), ast.fragment ?? ast, opts);
|
|
213
|
+
}
|
|
214
|
+
/** The array literal of `new Set([…])`, or the node itself. */
|
|
215
|
+
function setLiteralList(n) {
|
|
216
|
+
const arg = n?.type === "NewExpression" && n.callee?.type === "Identifier" && n.callee.name === "Set" ? n.arguments : void 0;
|
|
217
|
+
return arg?.length === 1 && unwrapTs(arg[0])?.type === "ArrayExpression" ? unwrapTs(arg[0]) : n;
|
|
209
218
|
}
|
|
210
219
|
/**
|
|
211
220
|
* Export names of a module's constant lists — `export const X = [ … ]`, or a local one exported by
|
|
@@ -288,6 +297,14 @@ function isEffectRootCall(node) {
|
|
|
288
297
|
* `$state.raw(...)`, or `$state.frozen(...)` — but NOT readers like
|
|
289
298
|
* `$state.snapshot(...)`, which would otherwise pollute the state-name set (correctness/effect-as-derived).
|
|
290
299
|
*/
|
|
300
|
+
/** An absent argument or a literal no reader can write through: `0`, `'x'`, `null`, `-1`, `` `x` ``. */
|
|
301
|
+
function isPrimitiveLiteral(node) {
|
|
302
|
+
if (node === void 0) return true;
|
|
303
|
+
if (node.type === "Literal") return !("regex" in node);
|
|
304
|
+
if (node.type === "TemplateLiteral") return node.expressions.length === 0;
|
|
305
|
+
if (node.type === "UnaryExpression") return node.argument?.type === "Literal";
|
|
306
|
+
return node.type === "Identifier" && node.name === "undefined";
|
|
307
|
+
}
|
|
291
308
|
function isStateDeclaration(node) {
|
|
292
309
|
const c = node?.callee;
|
|
293
310
|
if (c?.type === "Identifier") return c.name === "$state";
|
|
@@ -296,7 +313,18 @@ function isStateDeclaration(node) {
|
|
|
296
313
|
}
|
|
297
314
|
/** True when a function's body does nothing but assign to `$state` identifiers (correctness/effect-as-derived). */
|
|
298
315
|
function bodyOnlyAssignsState(fn, stateNames) {
|
|
299
|
-
const
|
|
316
|
+
const readsItself = (expr) => {
|
|
317
|
+
let reads = false;
|
|
318
|
+
const names = /* @__PURE__ */ new Set();
|
|
319
|
+
walkEstree(expr.right, (n) => {
|
|
320
|
+
if (n?.type === "MemberExpression" && !n.computed) names.add(n.property);
|
|
321
|
+
if (n?.type === "Property" && !n.computed && !n.shorthand) names.add(n.key);
|
|
322
|
+
if (n?.type === "TSTypeQuery") names.add(n.exprName);
|
|
323
|
+
reads ||= n?.type === "Identifier" && n.name === expr.left.name && !names.has(n);
|
|
324
|
+
});
|
|
325
|
+
return reads;
|
|
326
|
+
};
|
|
327
|
+
const isStateAssign = (expr) => expr?.type === "AssignmentExpression" && expr.operator === "=" && expr.left?.type === "Identifier" && stateNames.has(expr.left.name) && !readsItself(expr);
|
|
300
328
|
const body = fn?.body;
|
|
301
329
|
if (!body) return false;
|
|
302
330
|
if (body.type !== "BlockStatement") return isStateAssign(body);
|
|
@@ -310,6 +338,36 @@ function isDerivedDeclaration(node) {
|
|
|
310
338
|
if (c?.type === "MemberExpression" && c.object?.type === "Identifier" && c.object.name === "$derived") return c.property?.type === "Identifier" && c.property.name === "by";
|
|
311
339
|
return false;
|
|
312
340
|
}
|
|
341
|
+
const OBJECT_TYPES = /* @__PURE__ */ new Set([
|
|
342
|
+
"TSArrayType",
|
|
343
|
+
"TSTupleType",
|
|
344
|
+
"TSTypeLiteral"
|
|
345
|
+
]);
|
|
346
|
+
const OBJECT_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
347
|
+
"Array",
|
|
348
|
+
"ReadonlyArray",
|
|
349
|
+
"Record",
|
|
350
|
+
"Map",
|
|
351
|
+
"Set",
|
|
352
|
+
"WeakMap",
|
|
353
|
+
"WeakSet",
|
|
354
|
+
"Date"
|
|
355
|
+
]);
|
|
356
|
+
const OBJECT_VALUES = /* @__PURE__ */ new Set([
|
|
357
|
+
"ObjectExpression",
|
|
358
|
+
"ArrayExpression",
|
|
359
|
+
"NewExpression"
|
|
360
|
+
]);
|
|
361
|
+
/** A `$state` call whose initial value or type argument is an object, array or class instance. */
|
|
362
|
+
function isObjectState(call) {
|
|
363
|
+
const arg = unwrapTs(call.arguments?.[0]);
|
|
364
|
+
if (isPrimitiveLiteral(arg)) return false;
|
|
365
|
+
if (OBJECT_VALUES.has(arg?.type)) return true;
|
|
366
|
+
if (arg?.type === "LogicalExpression" && arg.operator !== "&&" && !isPrimitiveLiteral(unwrapTs(arg.left)) && OBJECT_VALUES.has(unwrapTs(arg.right)?.type)) return true;
|
|
367
|
+
const type = (call.typeArguments ?? call.typeParameters)?.params?.[0];
|
|
368
|
+
if (type?.type === "TSTypeReference") return OBJECT_TYPE_NAMES.has(type.typeName?.name);
|
|
369
|
+
return OBJECT_TYPES.has(type?.type);
|
|
370
|
+
}
|
|
313
371
|
function collectStateWrites(root, stateNames, acc, kinds, localStates = false) {
|
|
314
372
|
const record = (name, kind) => {
|
|
315
373
|
acc.add(name);
|
|
@@ -319,14 +377,38 @@ function collectStateWrites(root, stateNames, acc, kinds, localStates = false) {
|
|
|
319
377
|
set.add(kind);
|
|
320
378
|
}
|
|
321
379
|
};
|
|
380
|
+
const primitiveStates = /* @__PURE__ */ new Set();
|
|
381
|
+
const objectStates = /* @__PURE__ */ new Set();
|
|
382
|
+
const heldObjects = /* @__PURE__ */ new Set();
|
|
383
|
+
walkEstree(root, (n) => {
|
|
384
|
+
const init = n?.type === "VariableDeclarator" ? unwrapTs(n.init) : void 0;
|
|
385
|
+
if (n?.id?.type !== "Identifier" || !isStateDeclaration(init)) return;
|
|
386
|
+
(isPrimitiveLiteral(init.arguments?.[0]) ? primitiveStates : objectStates).add(n.id.name);
|
|
387
|
+
if (localStates && isObjectState(init)) heldObjects.add(n.id.name);
|
|
388
|
+
});
|
|
389
|
+
for (const name of objectStates) primitiveStates.delete(name);
|
|
390
|
+
const aliasOf = /* @__PURE__ */ new Map();
|
|
391
|
+
const reassigned = /* @__PURE__ */ new Set();
|
|
392
|
+
if (localStates) walkEstree(root, (n) => {
|
|
393
|
+
const target = n?.type === "AssignmentExpression" ? n.left : n?.type === "UpdateExpression" ? n.argument : void 0;
|
|
394
|
+
if (target?.type === "Identifier") reassigned.add(target.name);
|
|
395
|
+
});
|
|
396
|
+
if (localStates) for (let pass = 0; pass < 2; pass++) walkEstree(root, (n) => {
|
|
397
|
+
const [id, from] = n?.type === "VariableDeclarator" && unwrapTs(n.init)?.type === "MemberExpression" ? [n.id, n.init] : n?.type === "ForOfStatement" && n.left?.type === "VariableDeclaration" ? [n.left.declarations?.[0]?.id, n.right] : [void 0, void 0];
|
|
398
|
+
const r = rootObjectName(unwrapTs(from));
|
|
399
|
+
const owner = r && (stateNames.has(r) ? r : aliasOf.get(r));
|
|
400
|
+
if (id?.type === "Identifier" && owner && !stateNames.has(id.name) && !reassigned.has(id.name)) aliasOf.set(id.name, owner);
|
|
401
|
+
});
|
|
322
402
|
const visit = (stateNames) => (n, scope) => {
|
|
323
403
|
const shadowed = (name) => name === void 0 || scope.has(name);
|
|
404
|
+
const mutated = (r) => {
|
|
405
|
+
if (r && stateNames.has(r) && !shadowed(r)) record(r, "mutate");
|
|
406
|
+
else if (r && stateNames.has(aliasOf.get(r))) record(aliasOf.get(r), "mutate");
|
|
407
|
+
};
|
|
324
408
|
if (n?.type === "AssignmentExpression") {
|
|
325
409
|
if (n.left?.type === "Identifier" && stateNames.has(n.left.name) && !shadowed(n.left.name)) record(n.left.name, "reassign");
|
|
326
|
-
else if (n.left?.type === "MemberExpression")
|
|
327
|
-
|
|
328
|
-
if (r && stateNames.has(r) && !shadowed(r)) record(r, "mutate");
|
|
329
|
-
} else if (n.left?.type === "ObjectPattern" || n.left?.type === "ArrayPattern") {
|
|
410
|
+
else if (n.left?.type === "MemberExpression") mutated(rootObjectName(n.left));
|
|
411
|
+
else if (n.left?.type === "ObjectPattern" || n.left?.type === "ArrayPattern") {
|
|
330
412
|
const bound = /* @__PURE__ */ new Set();
|
|
331
413
|
addBoundNames(n.left, bound);
|
|
332
414
|
for (const name of bound) if (stateNames.has(name) && !shadowed(name)) record(name, "reassign");
|
|
@@ -334,24 +416,30 @@ function collectStateWrites(root, stateNames, acc, kinds, localStates = false) {
|
|
|
334
416
|
} else if (n?.type === "UpdateExpression") {
|
|
335
417
|
if (n.argument?.type === "Identifier") {
|
|
336
418
|
if (stateNames.has(n.argument.name) && !shadowed(n.argument.name)) record(n.argument.name, "reassign");
|
|
337
|
-
} else
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
} else if (n?.type === "UnaryExpression" && n.operator === "delete") {
|
|
342
|
-
const r = rootObjectName(n.argument);
|
|
343
|
-
if (r && stateNames.has(r) && !shadowed(r)) record(r, "mutate");
|
|
344
|
-
} else if (n?.type === "CallExpression") {
|
|
345
|
-
if (n.callee?.type === "MemberExpression") {
|
|
346
|
-
const r = rootObjectName(n.callee);
|
|
347
|
-
if (r && stateNames.has(r) && !shadowed(r)) record(r, "mutate");
|
|
348
|
-
}
|
|
419
|
+
} else mutated(rootObjectName(n.argument));
|
|
420
|
+
} else if (n?.type === "UnaryExpression" && n.operator === "delete") mutated(rootObjectName(n.argument));
|
|
421
|
+
else if (n?.type === "CallExpression") {
|
|
422
|
+
if (n.callee?.type === "MemberExpression") mutated(rootObjectName(n.callee));
|
|
349
423
|
for (const a of n.arguments ?? []) {
|
|
350
424
|
const arg = a?.type === "SpreadElement" ? a.argument : a;
|
|
351
425
|
const r = rootObjectName(arg);
|
|
352
426
|
if (r && stateNames.has(r) && !shadowed(r)) record(r, "escape");
|
|
353
427
|
}
|
|
354
|
-
}
|
|
428
|
+
} else if (n?.type === "ReturnStatement") {
|
|
429
|
+
const out = unwrapTs(n.argument);
|
|
430
|
+
const r = out?.type === "Identifier" ? out.name : void 0;
|
|
431
|
+
if (r && stateNames.has(r) && !shadowed(r) && !primitiveStates.has(r)) record(r, "escape");
|
|
432
|
+
} else if (heldObjects.size > 0 && (n?.type === "ObjectExpression" || n?.type === "ArrayExpression")) {
|
|
433
|
+
const values = n.type === "ObjectExpression" ? (n.properties ?? []).map((p) => p?.value) : n.elements;
|
|
434
|
+
for (const v of values ?? []) {
|
|
435
|
+
const placed = unwrapTs(v);
|
|
436
|
+
const r = placed?.type === "Identifier" ? placed.name : void 0;
|
|
437
|
+
if (r && heldObjects.has(r) && stateNames.has(r) && !shadowed(r)) record(r, "escape");
|
|
438
|
+
}
|
|
439
|
+
} else if ((n?.type === "Property" || n?.type === "MethodDefinition") && n.kind === "get") walkEstree(n.value?.body, (m) => {
|
|
440
|
+
const r = m?.type === "ReturnStatement" ? rootObjectName(m.argument) : void 0;
|
|
441
|
+
if (r && stateNames.has(r) && !shadowed(r) && !primitiveStates.has(r)) record(r, "escape");
|
|
442
|
+
});
|
|
355
443
|
};
|
|
356
444
|
walkScoped(root, visit(stateNames));
|
|
357
445
|
if (!localStates) return;
|
|
@@ -1739,6 +1827,7 @@ function isPropsCall(node) {
|
|
|
1739
1827
|
}
|
|
1740
1828
|
/** Whether a CallExpression is a `$bindable(...)` call (a destructured prop's default value). */
|
|
1741
1829
|
function isBindableCall(node) {
|
|
1830
|
+
node = unwrapTs(node);
|
|
1742
1831
|
return node?.type === "CallExpression" && node.callee?.type === "Identifier" && node.callee.name === "$bindable";
|
|
1743
1832
|
}
|
|
1744
1833
|
/**
|
|
@@ -1809,6 +1898,92 @@ const MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
1809
1898
|
"delete",
|
|
1810
1899
|
"clear"
|
|
1811
1900
|
]);
|
|
1901
|
+
/** Built-in types whose own methods include the mutating method names above. */
|
|
1902
|
+
const COLLECTION_TYPES = /* @__PURE__ */ new Set([
|
|
1903
|
+
"Array",
|
|
1904
|
+
"ReadonlyArray",
|
|
1905
|
+
"Set",
|
|
1906
|
+
"ReadonlySet",
|
|
1907
|
+
"Map",
|
|
1908
|
+
"ReadonlyMap",
|
|
1909
|
+
"WeakMap",
|
|
1910
|
+
"WeakSet",
|
|
1911
|
+
"SvelteSet",
|
|
1912
|
+
"SvelteMap",
|
|
1913
|
+
"URLSearchParams",
|
|
1914
|
+
"SvelteURLSearchParams",
|
|
1915
|
+
"FormData",
|
|
1916
|
+
"Headers",
|
|
1917
|
+
"Int8Array",
|
|
1918
|
+
"Uint8Array",
|
|
1919
|
+
"Uint8ClampedArray",
|
|
1920
|
+
"Int16Array",
|
|
1921
|
+
"Uint16Array",
|
|
1922
|
+
"Int32Array",
|
|
1923
|
+
"Uint32Array",
|
|
1924
|
+
"Float16Array",
|
|
1925
|
+
"Float32Array",
|
|
1926
|
+
"Float64Array",
|
|
1927
|
+
"BigInt64Array",
|
|
1928
|
+
"BigUint64Array"
|
|
1929
|
+
]);
|
|
1930
|
+
const NON_COLLECTION_NODES = /* @__PURE__ */ new Set([
|
|
1931
|
+
"TSStringKeyword",
|
|
1932
|
+
"TSNumberKeyword",
|
|
1933
|
+
"TSBooleanKeyword",
|
|
1934
|
+
"TSBigIntKeyword",
|
|
1935
|
+
"TSNullKeyword",
|
|
1936
|
+
"TSUndefinedKeyword",
|
|
1937
|
+
"TSFunctionType",
|
|
1938
|
+
"TSTypeLiteral",
|
|
1939
|
+
"TSLiteralType"
|
|
1940
|
+
]);
|
|
1941
|
+
/**
|
|
1942
|
+
* The props whose declared type, from the `$props()` annotation, is known not to be a collection: a
|
|
1943
|
+
* method called on one is its own API (`queryClient.clear()`), not an array, Set or Map mutation.
|
|
1944
|
+
* A named type counts unless it is a built-in collection or a same-file alias of one.
|
|
1945
|
+
*/
|
|
1946
|
+
function nonCollectionProps(program) {
|
|
1947
|
+
const decls = /* @__PURE__ */ new Map();
|
|
1948
|
+
walkEstree(program, (n) => {
|
|
1949
|
+
if ((n.type === "TSInterfaceDeclaration" || n.type === "TSTypeAliasDeclaration") && n.id?.name) decls.set(n.id.name, n);
|
|
1950
|
+
});
|
|
1951
|
+
const unwrap = (t) => t?.type === "TSTypeAnnotation" ? t.typeAnnotation : t;
|
|
1952
|
+
const nonCollection = (t, depth) => {
|
|
1953
|
+
t = unwrap(t);
|
|
1954
|
+
if (!t || depth > 4) return false;
|
|
1955
|
+
if (NON_COLLECTION_NODES.has(t.type)) return true;
|
|
1956
|
+
if (t.type === "TSUnionType") return t.types.every((u) => nonCollection(u, depth + 1));
|
|
1957
|
+
if (t.type !== "TSTypeReference" || t.typeName?.type !== "Identifier") return false;
|
|
1958
|
+
const name = t.typeName.name;
|
|
1959
|
+
if (COLLECTION_TYPES.has(name)) return false;
|
|
1960
|
+
const decl = decls.get(name);
|
|
1961
|
+
if (decl?.type === "TSTypeAliasDeclaration") return nonCollection(decl.typeAnnotation, depth + 1);
|
|
1962
|
+
if (decl?.type === "TSInterfaceDeclaration") return !(decl.extends ?? []).some((h) => COLLECTION_TYPES.has(h.expression?.name));
|
|
1963
|
+
return !(t.typeArguments ?? t.typeParameters)?.params?.length;
|
|
1964
|
+
};
|
|
1965
|
+
const membersOf = (t, depth) => {
|
|
1966
|
+
t = unwrap(t);
|
|
1967
|
+
if (t?.type === "TSTypeLiteral") return t.members;
|
|
1968
|
+
if (t?.type !== "TSTypeReference" || depth > 4) return void 0;
|
|
1969
|
+
const decl = decls.get(t.typeName?.name);
|
|
1970
|
+
if (decl?.type === "TSInterfaceDeclaration") return decl.body?.body;
|
|
1971
|
+
return decl?.type === "TSTypeAliasDeclaration" ? membersOf(decl.typeAnnotation, depth + 1) : void 0;
|
|
1972
|
+
};
|
|
1973
|
+
const names = /* @__PURE__ */ new Set();
|
|
1974
|
+
walkEstree(program, (n) => {
|
|
1975
|
+
if (n.type !== "VariableDeclarator" || !n.init || !isPropsCall(unwrapTs(n.init))) return;
|
|
1976
|
+
if (n.id?.type !== "ObjectPattern") return;
|
|
1977
|
+
const types = /* @__PURE__ */ new Map();
|
|
1978
|
+
for (const m of membersOf(n.id.typeAnnotation, 0) ?? []) if (m.type === "TSPropertySignature" && m.key?.type === "Identifier") types.set(m.key.name, m.typeAnnotation);
|
|
1979
|
+
for (const p of n.id.properties ?? []) {
|
|
1980
|
+
if (p?.type !== "Property" || p.key?.type !== "Identifier" || !types.has(p.key.name)) continue;
|
|
1981
|
+
const local = p.value?.type === "AssignmentPattern" ? p.value.left : p.value;
|
|
1982
|
+
if (local?.type === "Identifier" && nonCollection(types.get(p.key.name), 0)) names.add(local.name);
|
|
1983
|
+
}
|
|
1984
|
+
});
|
|
1985
|
+
return names;
|
|
1986
|
+
}
|
|
1812
1987
|
/**
|
|
1813
1988
|
* Flag mutations of a non-`$bindable` prop (correctness/prop-mutation): a member-expression write
|
|
1814
1989
|
* (`prop.x = …`, `prop.x += …`, `prop.x++`), `delete prop.x`, or a call to a mutating
|
|
@@ -1820,16 +1995,18 @@ const MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
1820
1995
|
* A `legacy` (export let) prop is flagged only for `delete` and mutating method calls — the legacy
|
|
1821
1996
|
* compiler turns a member write or update into an invalidating assignment (`prop(prop().x = …, true)`).
|
|
1822
1997
|
*/
|
|
1823
|
-
function collectPropMutations(root, propNames, source, acc, legacy) {
|
|
1998
|
+
function collectPropMutations(root, propNames, source, acc, legacy, ownApi = /* @__PURE__ */ new Set()) {
|
|
1824
1999
|
if (propNames.size === 0) return;
|
|
1825
2000
|
const exemptCalls = /* @__PURE__ */ new Set();
|
|
2001
|
+
const returnedToProp = /* @__PURE__ */ new Set();
|
|
1826
2002
|
if (legacy.size > 0) walkEstree(root, (fn) => {
|
|
1827
|
-
|
|
2003
|
+
const body = isDeferredBody(fn) ? fn.body : fn.type === "LabeledStatement" && fn.label?.name === "$" ? fn.body : void 0;
|
|
2004
|
+
if (!body) return;
|
|
1828
2005
|
const assigned = /* @__PURE__ */ new Set();
|
|
1829
|
-
walkScoped(
|
|
2006
|
+
walkScoped(body, (m, scope) => {
|
|
1830
2007
|
if (m.type === "AssignmentExpression" && m.left?.type === "Identifier" && !scope.has(m.left.name)) assigned.add(m.left.name);
|
|
1831
2008
|
});
|
|
1832
|
-
walkEstree(
|
|
2009
|
+
walkEstree(body, (m) => {
|
|
1833
2010
|
const r = m.type === "CallExpression" ? rootObjectName(m.callee?.object) : m.type === "UnaryExpression" && m.operator === "delete" ? rootObjectName(m.argument) : void 0;
|
|
1834
2011
|
if (r && legacy.has(r) && assigned.has(r)) exemptCalls.add(m);
|
|
1835
2012
|
});
|
|
@@ -1837,6 +2014,20 @@ function collectPropMutations(root, propNames, source, acc, legacy) {
|
|
|
1837
2014
|
walkEstree(root, (m) => {
|
|
1838
2015
|
const call = m.type === "AssignmentExpression" && m.left?.type === "Identifier" ? m.right : void 0;
|
|
1839
2016
|
if (call?.type === "CallExpression" && rootObjectName(call.callee?.object) === m.left.name && call.arguments?.length === 1 && call.arguments[0]?.type === "ObjectExpression") exemptCalls.add(call);
|
|
2017
|
+
const awaited = m.type === "AwaitExpression" ? unwrapTs(m.argument) : void 0;
|
|
2018
|
+
if (awaited?.type === "CallExpression") exemptCalls.add(awaited);
|
|
2019
|
+
const chained = m.type === "CallExpression" && m.callee?.type === "MemberExpression" && !m.callee.computed && [
|
|
2020
|
+
"then",
|
|
2021
|
+
"catch",
|
|
2022
|
+
"finally"
|
|
2023
|
+
].includes(m.callee.property?.name) ? unwrapTs(m.callee.object) : void 0;
|
|
2024
|
+
if (chained?.type === "CallExpression") exemptCalls.add(chained);
|
|
2025
|
+
if (m.type === "AssignmentExpression" && m.left?.type === "Identifier") {
|
|
2026
|
+
let back = unwrapTs(m.right);
|
|
2027
|
+
if (back?.type === "LogicalExpression") back = unwrapTs(back.left);
|
|
2028
|
+
if (back?.type === "ChainExpression") back = back.expression;
|
|
2029
|
+
if (back?.type === "CallExpression" && back.callee.type === "MemberExpression" && rootObjectName(back.callee.object) === m.left.name) returnedToProp.add(back);
|
|
2030
|
+
}
|
|
1840
2031
|
});
|
|
1841
2032
|
walkScoped(root, (n, scope) => {
|
|
1842
2033
|
const flag = (r) => {
|
|
@@ -1855,6 +2046,8 @@ function collectPropMutations(root, propNames, source, acc, legacy) {
|
|
|
1855
2046
|
} else if (n.type === "UnaryExpression" && n.operator === "delete") flag(rootObjectName(n.argument));
|
|
1856
2047
|
else if (n.type === "CallExpression" && n.callee?.type === "MemberExpression") {
|
|
1857
2048
|
const method = n.callee.property?.type === "Identifier" ? n.callee.property.name : void 0;
|
|
2049
|
+
const receiver = unwrapTs(n.callee.object);
|
|
2050
|
+
if (receiver?.type === "Identifier" && ownApi.has(receiver.name) && !returnedToProp.has(n)) return;
|
|
1858
2051
|
if (method && MUTATING_METHODS.has(method)) flag(rootObjectName(n.callee.object));
|
|
1859
2052
|
}
|
|
1860
2053
|
});
|
|
@@ -1904,7 +2097,7 @@ function collectImportSources(program, source, acc) {
|
|
|
1904
2097
|
}
|
|
1905
2098
|
/** A specifier is "bare" (a node_modules package) when it is not relative/absolute/alias-local. */
|
|
1906
2099
|
function isBareSpecifier(s) {
|
|
1907
|
-
return !/^[./$#]/.test(s);
|
|
2100
|
+
return !/^([./$#]|@\/|~\/)/.test(s);
|
|
1908
2101
|
}
|
|
1909
2102
|
/**
|
|
1910
2103
|
* Whether `name` is used anywhere in `roots` other than as the object of a static member access
|
|
@@ -1921,6 +2114,8 @@ function namespaceUsedDynamically(name, roots) {
|
|
|
1921
2114
|
if (!n.computed) staticOrDeclaring.add(n.property);
|
|
1922
2115
|
} else if ((n.type === "Property" && !n.shorthand || n.type === "TSPropertySignature" || n.type === "TSMethodSignature") && !n.computed) staticOrDeclaring.add(n.key);
|
|
1923
2116
|
else if (n.type === "ImportNamespaceSpecifier") staticOrDeclaring.add(n.local);
|
|
2117
|
+
else if (n.type === "ImportSpecifier" && n.imported !== n.local) staticOrDeclaring.add(n.imported);
|
|
2118
|
+
else if (n.type === "ExportSpecifier" && n.exported !== n.local) staticOrDeclaring.add(n.exported);
|
|
1924
2119
|
else if (n.type === "TSQualifiedName" || n.type === "TSTypeQuery") {
|
|
1925
2120
|
const id = n.type === "TSQualifiedName" ? n.left : n.exprName;
|
|
1926
2121
|
if (id?.type === "Identifier") staticOrDeclaring.add(id);
|
|
@@ -2312,8 +2507,9 @@ function parseComponentFacts(source, filename) {
|
|
|
2312
2507
|
const legacyPropNames = collectLegacyPropNames(program);
|
|
2313
2508
|
const nonBindableProps = /* @__PURE__ */ new Set([...collectPropNames(program, false), ...legacyPropNames]);
|
|
2314
2509
|
const rawMutations = [];
|
|
2315
|
-
|
|
2316
|
-
|
|
2510
|
+
const ownApi = nonCollectionProps(program);
|
|
2511
|
+
collectPropMutations(program, nonBindableProps, source, rawMutations, legacyPropNames, ownApi);
|
|
2512
|
+
if (ast.fragment) collectPropMutations(ast.fragment, nonBindableProps, source, rawMutations, legacyPropNames, ownApi);
|
|
2317
2513
|
const isLegacy = legacyPropNames.size > 0;
|
|
2318
2514
|
for (const m of rawMutations) mutatedProps.push(legacyPropNames.has(m.name) ? {
|
|
2319
2515
|
...m,
|
|
@@ -2731,7 +2927,7 @@ async function collectKitModuleFacts(rt, cwd, aliases) {
|
|
|
2731
2927
|
"src/hooks.server.{ts,js}"
|
|
2732
2928
|
].map((p) => rt.glob(p, cwd)));
|
|
2733
2929
|
const files = [...new Set(lists.flat())];
|
|
2734
|
-
return arbitrateServerStoreWrites(rt, cwd, await Promise.all(files.sort().map(async (rel) => {
|
|
2930
|
+
return decideLoadFactories(rt, cwd, await decideFlagGuards(rt, cwd, await dropClientWrites(rt, cwd, await arbitrateServerStoreWrites(rt, cwd, await Promise.all(files.sort().map(async (rel) => {
|
|
2735
2931
|
const kind = kindOf(rel);
|
|
2736
2932
|
let source;
|
|
2737
2933
|
try {
|
|
@@ -2755,7 +2951,7 @@ async function collectKitModuleFacts(rt, cwd, aliases) {
|
|
|
2755
2951
|
parseFailed: true
|
|
2756
2952
|
};
|
|
2757
2953
|
}
|
|
2758
|
-
})));
|
|
2954
|
+
}))), aliases)));
|
|
2759
2955
|
}
|
|
2760
2956
|
/**
|
|
2761
2957
|
* The files a resolved specifier may name, in resolution order. An extensionless path takes an
|
|
@@ -2773,20 +2969,58 @@ function moduleCandidates(repoPath) {
|
|
|
2773
2969
|
`${repoPath}/index.js`
|
|
2774
2970
|
];
|
|
2775
2971
|
}
|
|
2776
|
-
/**
|
|
2777
|
-
|
|
2778
|
-
* container. Returns an empty set when the file cannot be found or read: unresolvable means
|
|
2779
|
-
* unarbitrated, which leaves the write exempt.
|
|
2780
|
-
*/
|
|
2781
|
-
async function inMemoryExportsOf(rt, cwd, repoPath) {
|
|
2972
|
+
/** Read a module and parse it with `parse`; empty when it cannot be found or read. */
|
|
2973
|
+
async function exportsOf(rt, cwd, repoPath, parse) {
|
|
2782
2974
|
for (const rel of moduleCandidates(repoPath)) try {
|
|
2783
2975
|
if (!await rt.exists(rt.join(cwd, rel))) continue;
|
|
2784
|
-
return
|
|
2976
|
+
return parse(await rt.readFile(rt.join(cwd, rel)), rel);
|
|
2785
2977
|
} catch {
|
|
2786
2978
|
return /* @__PURE__ */ new Set();
|
|
2787
2979
|
}
|
|
2788
2980
|
return /* @__PURE__ */ new Set();
|
|
2789
2981
|
}
|
|
2982
|
+
/** Drop the handler `.set()`/`.update()` writes whose target module exports a persistence client under that name. */
|
|
2983
|
+
async function dropClientWrites(rt, cwd, facts, aliases) {
|
|
2984
|
+
const targets = [...new Set(facts.flatMap((f) => (f.storeWriteTargets ?? []).map((w) => w.resolved)))];
|
|
2985
|
+
if (targets.length === 0) return facts;
|
|
2986
|
+
const byPath = new Map(await Promise.all(targets.map(async (t) => [t, await exportsOf(rt, cwd, t, (src, file) => parseClientExports(src, file, aliases))])));
|
|
2987
|
+
return facts.map((f) => {
|
|
2988
|
+
const clients = (f.storeWriteTargets ?? []).filter((w) => byPath.get(w.resolved)?.has(w.imported));
|
|
2989
|
+
if (clients.length === 0) return f;
|
|
2990
|
+
const drop = (w) => w.via === "set-call" && clients.some((c) => c.name === w.name && c.line === w.line);
|
|
2991
|
+
return {
|
|
2992
|
+
...f,
|
|
2993
|
+
importedStateWrites: f.importedStateWrites.filter((w) => !drop(w))
|
|
2994
|
+
};
|
|
2995
|
+
});
|
|
2996
|
+
}
|
|
2997
|
+
/** A `load` an imported factory builds never renders when the function the factory returns always exits. */
|
|
2998
|
+
async function decideLoadFactories(rt, cwd, facts) {
|
|
2999
|
+
const targets = [...new Set(facts.flatMap((f) => f.pendingLoadFactory ? [f.pendingLoadFactory.resolved] : []))];
|
|
3000
|
+
if (targets.length === 0) return facts;
|
|
3001
|
+
const byPath = new Map(await Promise.all(targets.map(async (t) => [t, await exportsOf(rt, cwd, t, parseExitFactoryExports)])));
|
|
3002
|
+
return facts.map((f) => {
|
|
3003
|
+
const g = f.pendingLoadFactory;
|
|
3004
|
+
return g && byPath.get(g.resolved)?.has(g.name) ? {
|
|
3005
|
+
...f,
|
|
3006
|
+
loadNeverRenders: true
|
|
3007
|
+
} : f;
|
|
3008
|
+
});
|
|
3009
|
+
}
|
|
3010
|
+
/** A load whose leading guard exits on an imported flag that is the literal `false` never renders. */
|
|
3011
|
+
async function decideFlagGuards(rt, cwd, facts) {
|
|
3012
|
+
const targets = [...new Set(facts.flatMap((f) => f.pendingFlagGuard ? [f.pendingFlagGuard.resolved] : []))];
|
|
3013
|
+
if (targets.length === 0) return facts;
|
|
3014
|
+
const byPath = new Map(await Promise.all(targets.map(async (t) => [t, await exportsOf(rt, cwd, t, parseFalseExports)])));
|
|
3015
|
+
return facts.map((f) => {
|
|
3016
|
+
const g = f.pendingFlagGuard;
|
|
3017
|
+
const key = g && (g.member ? `${g.name}.${g.member}` : g.name);
|
|
3018
|
+
return g && byPath.get(g.resolved)?.has(key) ? {
|
|
3019
|
+
...f,
|
|
3020
|
+
loadNeverRenders: true
|
|
3021
|
+
} : f;
|
|
3022
|
+
});
|
|
3023
|
+
}
|
|
2790
3024
|
/**
|
|
2791
3025
|
* Decide the `.set()`/`.update()` calls the parse could not: a call on a binding exported from
|
|
2792
3026
|
* under the `$lib` server root is shared module state when that binding is an in-memory
|
|
@@ -2796,7 +3030,7 @@ async function inMemoryExportsOf(rt, cwd, repoPath) {
|
|
|
2796
3030
|
async function arbitrateServerStoreWrites(rt, cwd, facts) {
|
|
2797
3031
|
const targets = [...new Set(facts.flatMap((f) => f.pendingServerStoreWrites.map((w) => w.resolved)))];
|
|
2798
3032
|
if (targets.length === 0) return facts;
|
|
2799
|
-
const byPath = new Map(await Promise.all(targets.map(async (t) => [t, await
|
|
3033
|
+
const byPath = new Map(await Promise.all(targets.map(async (t) => [t, await exportsOf(rt, cwd, t, parseInMemoryExports)])));
|
|
2800
3034
|
return facts.map((f) => {
|
|
2801
3035
|
const promoted = f.pendingServerStoreWrites.filter((w) => byPath.get(w.resolved)?.has(w.imported)).map((w) => ({
|
|
2802
3036
|
name: w.name,
|
|
@@ -2926,28 +3160,51 @@ function findMinifyDisabled(source) {
|
|
|
2926
3160
|
}
|
|
2927
3161
|
//#endregion
|
|
2928
3162
|
//#region src/svelte-config-parse.ts
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
3163
|
+
function isServedBase(value) {
|
|
3164
|
+
return typeof value === "string" && value.startsWith("/") && !value.endsWith("/");
|
|
3165
|
+
}
|
|
3166
|
+
/** The top-level bindings declared `const`: a `let` may be reassigned on the way to the export. */
|
|
3167
|
+
function constBindings(program, bindings) {
|
|
3168
|
+
const names = /* @__PURE__ */ new Set();
|
|
3169
|
+
for (const stmt of program.body) {
|
|
3170
|
+
const decl = stmt.type === "ExportNamedDeclaration" ? stmt.declaration : stmt;
|
|
3171
|
+
if (decl?.type !== "VariableDeclaration" || decl.kind !== "const") continue;
|
|
3172
|
+
for (const d of decl.declarations) if (d.id.type === "Identifier") names.add(d.id.name);
|
|
3173
|
+
}
|
|
3174
|
+
return new Map([...bindings].filter(([name]) => names.has(name)));
|
|
3175
|
+
}
|
|
3176
|
+
/** Whether no branch of a `?:` / `||` / `&&` / `??` tree is a literal base an app can be served under. */
|
|
3177
|
+
function neverABase(expr, consts) {
|
|
3178
|
+
const e = resolveBinding(expr, consts);
|
|
3179
|
+
if (e.type === "Literal") return !isServedBase(e.value);
|
|
3180
|
+
if (e.type === "ConditionalExpression") return neverABase(e.consequent, consts) && neverABase(e.alternate, consts);
|
|
3181
|
+
if (e.type === "LogicalExpression") return neverABase(e.left, consts) && neverABase(e.right, consts);
|
|
2935
3182
|
return false;
|
|
2936
3183
|
}
|
|
3184
|
+
/** `expr` with top-level `const` names followed to their initializers (`paths: { base }` naming `const base = ''`). */
|
|
3185
|
+
function resolveBinding(expr, consts) {
|
|
3186
|
+
let e = unwrapTs(expr);
|
|
3187
|
+
for (let i = 0; i < 4 && e.type === "Identifier"; i++) {
|
|
3188
|
+
const next = consts.get(e.name);
|
|
3189
|
+
if (!next) break;
|
|
3190
|
+
e = unwrapTs(next);
|
|
3191
|
+
}
|
|
3192
|
+
return e;
|
|
3193
|
+
}
|
|
2937
3194
|
/**
|
|
2938
3195
|
* `paths.base` off a resolved Kit-config object: `{ value }` for a non-empty string literal,
|
|
2939
3196
|
* `{}` for any other expression (base exists, value unknowable — the `dev ? '' : '/repo'`
|
|
2940
|
-
* deploy form), and undefined when absent or when
|
|
3197
|
+
* deploy form), and undefined when absent or when no value it can take is a base SvelteKit serves under.
|
|
2941
3198
|
*/
|
|
2942
|
-
function basePathOf(kitConfig, bindings) {
|
|
3199
|
+
function basePathOf(kitConfig, bindings, consts) {
|
|
2943
3200
|
const paths = propOf(kitConfig, "paths");
|
|
2944
3201
|
const pathsObj = paths ? unwrapToObjectExpression(paths.value, bindings) : void 0;
|
|
2945
3202
|
if (!pathsObj) return void 0;
|
|
2946
3203
|
const base = propOf(pathsObj, "base");
|
|
2947
3204
|
if (!base) return void 0;
|
|
2948
|
-
const value =
|
|
2949
|
-
if (value.type === "Literal") return
|
|
2950
|
-
return
|
|
3205
|
+
const value = resolveBinding(base.value, consts);
|
|
3206
|
+
if (value.type === "Literal") return isServedBase(value.value) ? { value: value.value } : void 0;
|
|
3207
|
+
return neverABase(value, consts) ? void 0 : {};
|
|
2951
3208
|
}
|
|
2952
3209
|
/** A property's key when it is a plain (non-computed) string or identifier key. */
|
|
2953
3210
|
function keyNameOf(p) {
|
|
@@ -3173,7 +3430,33 @@ function findKitPathsBaseInSvelteConfig(source) {
|
|
|
3173
3430
|
const bindings = collectTopLevelBindings(program);
|
|
3174
3431
|
const kit = propOf(config, "kit");
|
|
3175
3432
|
const kitObj = kit ? unwrapToObjectExpression(kit.value, bindings) : void 0;
|
|
3176
|
-
return kitObj ? basePathOf(kitObj, bindings) : void 0;
|
|
3433
|
+
return kitObj ? basePathOf(kitObj, bindings, constBindings(program, bindings)) : void 0;
|
|
3434
|
+
}
|
|
3435
|
+
/**
|
|
3436
|
+
* `unwrapToObjectExpression`, but only where the literal is the value: a call passing more than one
|
|
3437
|
+
* argument (`mergeConfigs(a, b)`) or a spread could make it something else.
|
|
3438
|
+
*/
|
|
3439
|
+
function knownObject(expr, bindings) {
|
|
3440
|
+
let current = expr;
|
|
3441
|
+
for (let i = 0; i < 4 && current; i++) {
|
|
3442
|
+
const e = unwrapTs(current);
|
|
3443
|
+
if (e.type === "ObjectExpression") return e.properties.some((p) => p.type === "SpreadElement") ? void 0 : e;
|
|
3444
|
+
if (e.type === "Identifier") current = bindings.get(e.name);
|
|
3445
|
+
else if (e.type === "CallExpression" && e.arguments.length === 1) current = e.arguments[0];
|
|
3446
|
+
else return void 0;
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
/** Whether `kit.router.type` is the literal `'hash'` in a config whose value is known. */
|
|
3450
|
+
function findKitHashRouterInSvelteConfig(source) {
|
|
3451
|
+
const program = programOf(source, "svelte.config.js");
|
|
3452
|
+
if (!program) return false;
|
|
3453
|
+
const bindings = collectTopLevelBindings(program);
|
|
3454
|
+
const objectAt = (obj, key) => {
|
|
3455
|
+
const p = obj && propOf(obj, key);
|
|
3456
|
+
return p ? knownObject(p.value, bindings) : void 0;
|
|
3457
|
+
};
|
|
3458
|
+
const router = objectAt(objectAt(knownObject(findExportedExpression(program), bindings), "kit"), "router");
|
|
3459
|
+
return stringLiteralOf(router && propOf(router, "type")?.value) === "hash";
|
|
3177
3460
|
}
|
|
3178
3461
|
/**
|
|
3179
3462
|
* Local names bound to `sveltekit` imported from '@sveltejs/kit/vite'. When no such import is
|
|
@@ -3206,7 +3489,7 @@ function findKitPathsBaseInViteConfig(source) {
|
|
|
3206
3489
|
if (arg === void 0) return none;
|
|
3207
3490
|
const kitConfig = unwrapToObjectExpression(arg, bindings);
|
|
3208
3491
|
if (!kitConfig) return { kind: "unresolvable" };
|
|
3209
|
-
const base = basePathOf(kitConfig, bindings);
|
|
3492
|
+
const base = basePathOf(kitConfig, bindings, constBindings(program, bindings));
|
|
3210
3493
|
return base ? {
|
|
3211
3494
|
kind: "resolved",
|
|
3212
3495
|
base
|
|
@@ -3468,11 +3751,17 @@ const SITEMAP_SOURCE_PATHS = [
|
|
|
3468
3751
|
"src/routes/sitemap.xml/+server.js"
|
|
3469
3752
|
];
|
|
3470
3753
|
/** The `+server` endpoints above, wherever (group) directories nest them — filter with `servesRootFile`. */
|
|
3471
|
-
const ROOT_FILE_ENDPOINT_GLOB = "src/routes/**/{robots.txt,sitemap
|
|
3472
|
-
/**
|
|
3754
|
+
const ROOT_FILE_ENDPOINT_GLOB = "src/routes/**/{robots.txt,sitemap*.xml}/+server.{ts,js}";
|
|
3755
|
+
/**
|
|
3756
|
+
* Whether a `+server` endpoint serves `/<file>`: (group) directories add no URL segment, and an optional
|
|
3757
|
+
* parameter in the name (`sitemap[[page]].xml`) still answers the bare name.
|
|
3758
|
+
*/
|
|
3473
3759
|
function servesRootFile(rel, file) {
|
|
3474
3760
|
const segments = rel.split("/");
|
|
3475
|
-
|
|
3761
|
+
const dot = file.lastIndexOf(".");
|
|
3762
|
+
const optional = new RegExp(`^${file.slice(0, dot)}\\[\\[[^\\]]+\\]\\]\\${file.slice(dot)}$`);
|
|
3763
|
+
const dir = segments.at(-2) ?? "";
|
|
3764
|
+
return segments[0] === "src" && segments[1] === "routes" && (dir === file || optional.test(dir)) && /^\+server\.(ts|js)$/.test(segments.at(-1) ?? "") && segments.slice(2, -2).every((s) => /^\(.+\)$/.test(s));
|
|
3476
3765
|
}
|
|
3477
3766
|
/** Vite's own config resolution order — only the first existing file is the one Vite loads. */
|
|
3478
3767
|
const VITE_CONFIG_FILES = [
|
|
@@ -3545,7 +3834,7 @@ async function runRules(rules, ctx) {
|
|
|
3545
3834
|
}));
|
|
3546
3835
|
const results = [];
|
|
3547
3836
|
const failedRules = [];
|
|
3548
|
-
for (const outcome of perRule) if (Array.isArray(outcome)) results.push(
|
|
3837
|
+
for (const outcome of perRule) if (Array.isArray(outcome)) for (const r of outcome) results.push(r);
|
|
3549
3838
|
else failedRules.push(outcome);
|
|
3550
3839
|
return {
|
|
3551
3840
|
results,
|
|
@@ -3717,7 +4006,7 @@ function formatConsoleReport(results, config, options = {}) {
|
|
|
3717
4006
|
}
|
|
3718
4007
|
lines.push("");
|
|
3719
4008
|
}
|
|
3720
|
-
if (options.byRoute)
|
|
4009
|
+
if (options.byRoute) for (const line of byRouteTree(p, results, config, options.verbose ?? false)) lines.push(line);
|
|
3721
4010
|
if (options.verbose && summary.dynamic > 0) lines.push(p.dim("↯ = set dynamically (verified at runtime)."));
|
|
3722
4011
|
return lines.join("\n").replace(/\n+$/, "\n");
|
|
3723
4012
|
}
|
|
@@ -3744,7 +4033,7 @@ function formatAgentReport(results, config) {
|
|
|
3744
4033
|
if (!groups.has(key)) groups.set(key, []);
|
|
3745
4034
|
groups.get(key).push(r);
|
|
3746
4035
|
}
|
|
3747
|
-
const groupSeverity = (rs) =>
|
|
4036
|
+
const groupSeverity = (rs) => rs.reduce((min, r) => Math.min(min, SEVERITY_RANK[effectiveSeverity(r, config)]), Infinity);
|
|
3748
4037
|
const orderedGroups = [...groups.entries()].sort((a, b) => groupSeverity(a[1]) - groupSeverity(b[1]) || a[0].localeCompare(b[0]));
|
|
3749
4038
|
for (const [loc, rs] of orderedGroups) {
|
|
3750
4039
|
rs.sort((x, y) => SEVERITY_RANK[effectiveSeverity(x, config)] - SEVERITY_RANK[effectiveSeverity(y, config)] || x.id.localeCompare(y.id));
|
|
@@ -4580,4 +4869,4 @@ function formatHtmlReport(results, config, meta) {
|
|
|
4580
4869
|
return buildHtmlDocument(buildJsonReport(results, config, meta), meta);
|
|
4581
4870
|
}
|
|
4582
4871
|
//#endregion
|
|
4583
|
-
export { ANCESTRY_DEPENDENT_TAGS, APP_SCRIPT, ASIDE_DEMOTING_TAGS, CHILD_NODE_KEYS, IDREF_ATTRS, NAMING_ATTRS, ROBOTS_SOURCE_PATHS, ROOT_FILE_ENDPOINT_GLOB, SEARCH_RESULT_RULES, SECTIONING_TAGS, SITEMAP_SOURCE_PATHS, SVELTE_CONFIG_FILES, VITE_CONFIG_FILES, a11yAbbrTitle, a11yAccessibleName, a11yAriaHiddenFocus, a11yDeprecatedAria, a11yDeprecatedAttr, a11yDeprecatedElement, a11yDisallowedAriaProps, a11yDisallowedElement, a11yDoctype, a11yDuplicateLandmark, a11yIdDuplication, a11yInteractiveNesting, a11yInvalidAriaValue, a11yInvalidRole, a11yLabelHasControl, a11yNoAccesskey, a11yNoAutofocus, a11yNoDuplicateDt, a11yNoMissingIdRef, a11yPatternTitle, a11yPermittedContents, a11yPlaceholderLabelOption, a11yPositiveTabindex, a11yRequireDatetime, a11yRequiredAriaProps, a11yRequiredElement, a11yTopLevelLandmark, a11yUnknownAriaAttribute, a11yUnverifiedIdRef, a11yUseList, addFactsDirectives, allRules, architectureComponentSize, architectureDirectoryNaming, architectureDocLinkTarget, architecturePrivateScopeImport, architecturePropCount, architectureReservedDirectoryNames, architectureReservedNamePlacement, architectureRouteComponentImport, architectureUnitEntryFile, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentFacts, collectConstantListExports, collectKitModuleFacts, collectSourceFiles, collectSuppressions, compileOverrides, computeHealth, computeScore, correctnessAutoplayMuted, correctnessBasePathNavigation, correctnessCheckableBindValue, correctnessEachIndexKey, correctnessEachKey, correctnessEffectAsDerived, correctnessEffectAsOnMount, correctnessInstanceBrowserGlobal, correctnessNonreactiveBuiltinState, correctnessOrphanEffect, correctnessOrphanLifecycle, correctnessPropMutation, correctnessServerBrowserGlobal, correctnessStalePropDerivation, correctnessUnmutatedState, declaredInstalledPackages, declaredLocalPackages, decodeFragmentId, defaultConfig, defaultProject, docsUrlFor, effectiveSeverity, emptyComponentFacts, escapeHtml, explainRule, findAttr, findMinifyDisabled, foldOccurrences, formatAgentReport, formatConsoleReport, formatFailedRuleWarning, formatGithubReport, formatHtmlReport, formatJsonReport, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, isClassicScriptType, isPenalized, isPlainObject, isSvgSrc, isTopFragment, lineOf, noColorPalette, packageJsonWorkspaceGlobs, parseComponentFacts, parseModuleProgram, parseSvelte, performanceFontPreloadCrossorigin, performanceHeavyImport, performanceIframeLoading, performanceImageDimensions, performanceImageLoadingHint, performanceLcpImage, performanceLoadWaterfall, performanceMinifyDisabled, performanceNamespaceImport, performancePreconnect, performancePreloadMissingAs, performanceRenderBlockingScript, performanceResponsiveImage, performanceSequentialAwaits, performanceStateRaw, pnpmWorkspaceGlobs, renderAppShell, resolveKitAliases, resolveKitPathsBase, resolveLandmark, resolveRepoLocalPath, resolveRuleOptions, routeNeverSsr, runAnalysis, runRules, safeHref, scoreColor, securityHandlerStateWrite, securityJavascriptUrl, securityRawHtml, securityServerModuleState, securitySharedStateImport, selectRules, seoCanonicalUrl, seoCharset, seoDescriptionLength, seoDescriptionPresence, seoDuplicateDescription, seoDuplicateTitle, seoHeadingLevelSkip, seoHreflang, seoHtmlLang, seoImageAlt, seoIndexability, seoJsonLd, seoJsonLdDateFormat, seoJsonLdDeprecatedType, seoJsonLdPlaceholder, seoJsonLdRelativeUrl, seoJsonLdRequiredProps, seoJsonLdValidity, seoOgDescription, seoOgImage, seoOgTitle, seoOgUrl, seoRobotsTxt, seoSingleH1, seoSitemapInRobots, seoSitemapXml, seoSsrDisabled, seoTitleLength, seoTitlePresence, seoTwitterCard, seoViewport, servesRootFile, settingSeverity, shouldSkipRangeCheck, skippedFileWarnings, splitTokens, stripTextDirective, summarize, terminalSafe, textFromNodes, unknownDirectiveIds, validateRuleSetting, valueFromNodes, withFailedRulesOff, withIndexableOff, withInstalledPackages, withPackageImports, withReadLimit, withWorkspacePackages };
|
|
4872
|
+
export { ANCESTRY_DEPENDENT_TAGS, APP_SCRIPT, ASIDE_DEMOTING_TAGS, CHILD_NODE_KEYS, IDREF_ATTRS, NAMING_ATTRS, ROBOTS_SOURCE_PATHS, ROOT_FILE_ENDPOINT_GLOB, SEARCH_RESULT_RULES, SECTIONING_TAGS, SITEMAP_SOURCE_PATHS, SVELTE_CONFIG_FILES, VITE_CONFIG_FILES, a11yAbbrTitle, a11yAccessibleName, a11yAriaHiddenFocus, a11yDeprecatedAria, a11yDeprecatedAttr, a11yDeprecatedElement, a11yDisallowedAriaProps, a11yDisallowedElement, a11yDoctype, a11yDuplicateLandmark, a11yIdDuplication, a11yInteractiveNesting, a11yInvalidAriaValue, a11yInvalidRole, a11yLabelHasControl, a11yNoAccesskey, a11yNoAutofocus, a11yNoDuplicateDt, a11yNoMissingIdRef, a11yPatternTitle, a11yPermittedContents, a11yPlaceholderLabelOption, a11yPositiveTabindex, a11yRequireDatetime, a11yRequiredAriaProps, a11yRequiredElement, a11yTopLevelLandmark, a11yUnknownAriaAttribute, a11yUnverifiedIdRef, a11yUseList, addFactsDirectives, allRules, architectureComponentSize, architectureDirectoryNaming, architectureDocLinkTarget, architecturePrivateScopeImport, architecturePropCount, architectureReservedDirectoryNames, architectureReservedNamePlacement, architectureRouteComponentImport, architectureUnitEntryFile, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentConstantLists, collectComponentFacts, collectConstantListExports, collectFalseExports, collectKitModuleFacts, collectSourceFiles, collectSuppressions, compileOverrides, computeHealth, computeScore, correctnessAutoplayMuted, correctnessBasePathNavigation, correctnessCheckableBindValue, correctnessEachIndexKey, correctnessEachKey, correctnessEffectAsDerived, correctnessEffectAsOnMount, correctnessInstanceBrowserGlobal, correctnessNonreactiveBuiltinState, correctnessOrphanEffect, correctnessOrphanLifecycle, correctnessPropMutation, correctnessServerBrowserGlobal, correctnessStalePropDerivation, correctnessUnmutatedState, declaredInstalledPackages, declaredLocalPackages, decodeFragmentId, defaultConfig, defaultProject, docsUrlFor, effectiveSeverity, emptyComponentFacts, escapeHtml, explainRule, findAttr, findKitHashRouterInSvelteConfig, findMinifyDisabled, foldOccurrences, formatAgentReport, formatConsoleReport, formatFailedRuleWarning, formatGithubReport, formatHtmlReport, formatJsonReport, formatJsonReportChunks, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, hasRel, isClassicScriptType, isPenalized, isPlainObject, isSvgSrc, isTopFragment, layoutNeverRenders, lineOf, noColorPalette, packageJsonWorkspaceGlobs, pageRendersOnlyWhenBuilding, parseComponentFacts, parseModuleProgram, parseSvelte, performanceFontPreloadCrossorigin, performanceHeavyImport, performanceIframeLoading, performanceImageDimensions, performanceImageLoadingHint, performanceLcpImage, performanceLoadWaterfall, performanceMinifyDisabled, performanceNamespaceImport, performancePreconnect, performancePreloadMissingAs, performanceRenderBlockingScript, performanceResponsiveImage, performanceSequentialAwaits, performanceStateRaw, pnpmWorkspaceGlobs, renderAppShell, resolveKitAliases, resolveKitPathsBase, resolveLandmark, resolveRepoLocalPath, resolveRuleOptions, routeNeverSsr, runAnalysis, runRules, safeHref, scoreColor, securityHandlerStateWrite, securityJavascriptUrl, securityRawHtml, securityServerModuleState, securitySharedStateImport, selectRules, seoCanonicalUrl, seoCharset, seoDescriptionLength, seoDescriptionPresence, seoDuplicateDescription, seoDuplicateTitle, seoHeadingLevelSkip, seoHreflang, seoHtmlLang, seoImageAlt, seoIndexability, seoJsonLd, seoJsonLdDateFormat, seoJsonLdDeprecatedType, seoJsonLdPlaceholder, seoJsonLdRelativeUrl, seoJsonLdRequiredProps, seoJsonLdValidity, seoOgDescription, seoOgImage, seoOgTitle, seoOgUrl, seoRobotsTxt, seoSingleH1, seoSitemapInRobots, seoSitemapXml, seoSsrDisabled, seoTitleLength, seoTitlePresence, seoTwitterCard, seoViewport, servesRootFile, settingSeverity, shouldSkipRangeCheck, skippedFileWarnings, splitTokens, stripTextDirective, summarize, terminalSafe, textFromNodes, unknownDirectiveIds, unwrapTs, validateRuleSetting, valueFromNodes, walkEstree, withFailedRulesOff, withIndexableOff, withInstalledPackages, withPackageImports, withReadLimit, withWorkspacePackages };
|