@ismail-elkorchi/css-parser 0.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/LICENSE +21 -0
- package/README.md +100 -0
- package/THIRD_PARTY_NOTICES.md +19 -0
- package/dist/internal/csstree-runtime.d.ts +20 -0
- package/dist/internal/csstree-runtime.js +21 -0
- package/dist/internal/encoding/mod.d.ts +1 -0
- package/dist/internal/encoding/mod.js +1 -0
- package/dist/internal/encoding/sniff.d.ts +14 -0
- package/dist/internal/encoding/sniff.js +95 -0
- package/dist/internal/serializer/mod.d.ts +1 -0
- package/dist/internal/serializer/mod.js +1 -0
- package/dist/internal/serializer/serialize.d.ts +3 -0
- package/dist/internal/serializer/serialize.js +89 -0
- package/dist/internal/tokenizer/mod.d.ts +2 -0
- package/dist/internal/tokenizer/mod.js +1 -0
- package/dist/internal/tokenizer/tokenize.d.ts +2 -0
- package/dist/internal/tokenizer/tokenize.js +39 -0
- package/dist/internal/tokenizer/tokens.d.ts +23 -0
- package/dist/internal/tokenizer/tokens.js +1 -0
- package/dist/internal/tree/build.d.ts +2 -0
- package/dist/internal/tree/build.js +85 -0
- package/dist/internal/tree/mod.d.ts +2 -0
- package/dist/internal/tree/mod.js +1 -0
- package/dist/internal/tree/types.d.ts +25 -0
- package/dist/internal/tree/types.js +1 -0
- package/dist/internal/vendor/csstree/LICENSE +19 -0
- package/dist/internal/vendor/csstree/csstree.esm.js +12 -0
- package/dist/internal/version.d.ts +1 -0
- package/dist/internal/version.js +1 -0
- package/dist/mod.d.ts +1 -0
- package/dist/mod.js +1 -0
- package/dist/public/index.d.ts +1 -0
- package/dist/public/index.js +1 -0
- package/dist/public/mod.d.ts +35 -0
- package/dist/public/mod.js +1740 -0
- package/dist/public/types.d.ts +279 -0
- package/dist/public/types.js +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
export type NodeId = number;
|
|
2
|
+
export type ParseContext = "stylesheet" | "atrule" | "atrulePrelude" | "mediaQueryList" | "mediaQuery" | "condition" | "rule" | "selectorList" | "selector" | "block" | "declarationList" | "declaration" | "value";
|
|
3
|
+
export interface Span {
|
|
4
|
+
readonly start: number;
|
|
5
|
+
readonly end: number;
|
|
6
|
+
}
|
|
7
|
+
export type SpanProvenance = "input" | "none";
|
|
8
|
+
export interface ParseError {
|
|
9
|
+
readonly code: "BUDGET_EXCEEDED" | "STREAM_READ_FAILED" | "UNSUPPORTED_ENCODING" | "INVALID_PARSE_CONTEXT" | "PARSER_ERROR";
|
|
10
|
+
readonly parseErrorId: string;
|
|
11
|
+
readonly message: string;
|
|
12
|
+
readonly span?: Span;
|
|
13
|
+
readonly line?: number;
|
|
14
|
+
readonly column?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface BudgetOptions {
|
|
17
|
+
readonly maxInputBytes?: number;
|
|
18
|
+
readonly maxBufferedBytes?: number;
|
|
19
|
+
readonly maxTokens?: number;
|
|
20
|
+
readonly maxNodes?: number;
|
|
21
|
+
readonly maxDepth?: number;
|
|
22
|
+
readonly maxTraceEvents?: number;
|
|
23
|
+
readonly maxTraceBytes?: number;
|
|
24
|
+
readonly maxTimeMs?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ParseOptions {
|
|
27
|
+
readonly captureSpans?: boolean;
|
|
28
|
+
readonly includeSpans?: boolean;
|
|
29
|
+
readonly trace?: boolean;
|
|
30
|
+
readonly transportEncodingLabel?: string;
|
|
31
|
+
readonly context?: ParseContext;
|
|
32
|
+
readonly budgets?: BudgetOptions;
|
|
33
|
+
}
|
|
34
|
+
export interface TokenizeOptions {
|
|
35
|
+
readonly transportEncodingLabel?: string;
|
|
36
|
+
readonly budgets?: BudgetOptions;
|
|
37
|
+
}
|
|
38
|
+
export interface StartEndToken {
|
|
39
|
+
readonly kind: string;
|
|
40
|
+
readonly rawKind: string;
|
|
41
|
+
readonly value: string;
|
|
42
|
+
readonly start: number;
|
|
43
|
+
readonly end: number;
|
|
44
|
+
}
|
|
45
|
+
export type Token = StartEndToken;
|
|
46
|
+
export interface TraceDecodeEvent {
|
|
47
|
+
readonly seq: number;
|
|
48
|
+
readonly kind: "decode";
|
|
49
|
+
readonly source: "input" | "sniff";
|
|
50
|
+
readonly encoding: string;
|
|
51
|
+
readonly sniffSource: "input" | "bom" | "transport" | "charset" | "default";
|
|
52
|
+
}
|
|
53
|
+
export interface TraceTokenEvent {
|
|
54
|
+
readonly seq: number;
|
|
55
|
+
readonly kind: "token";
|
|
56
|
+
readonly count: number;
|
|
57
|
+
}
|
|
58
|
+
export interface TraceParseEvent {
|
|
59
|
+
readonly seq: number;
|
|
60
|
+
readonly kind: "parse";
|
|
61
|
+
readonly context: ParseContext;
|
|
62
|
+
readonly nodeCount: number;
|
|
63
|
+
readonly errorCount: number;
|
|
64
|
+
}
|
|
65
|
+
export interface TraceParseErrorEvent {
|
|
66
|
+
readonly seq: number;
|
|
67
|
+
readonly kind: "parseError";
|
|
68
|
+
readonly parseErrorId: string;
|
|
69
|
+
readonly startOffset: number | null;
|
|
70
|
+
readonly endOffset: number | null;
|
|
71
|
+
}
|
|
72
|
+
export interface TraceBudgetEvent {
|
|
73
|
+
readonly seq: number;
|
|
74
|
+
readonly kind: "budget";
|
|
75
|
+
readonly budget: BudgetExceededPayload["budget"];
|
|
76
|
+
readonly limit: number | null;
|
|
77
|
+
readonly actual: number;
|
|
78
|
+
readonly status: "ok" | "exceeded";
|
|
79
|
+
}
|
|
80
|
+
export interface TraceStreamEvent {
|
|
81
|
+
readonly seq: number;
|
|
82
|
+
readonly kind: "stream";
|
|
83
|
+
readonly bytesRead: number;
|
|
84
|
+
}
|
|
85
|
+
export type TraceEvent = TraceDecodeEvent | TraceTokenEvent | TraceParseEvent | TraceParseErrorEvent | TraceBudgetEvent | TraceStreamEvent;
|
|
86
|
+
export interface CssNode {
|
|
87
|
+
readonly id: NodeId;
|
|
88
|
+
readonly type: string;
|
|
89
|
+
readonly spanProvenance?: SpanProvenance;
|
|
90
|
+
readonly span?: Span;
|
|
91
|
+
readonly [key: string]: unknown;
|
|
92
|
+
}
|
|
93
|
+
export type NodeVisitor = (node: CssNode, depth: number) => void;
|
|
94
|
+
export interface StyleSheetTree {
|
|
95
|
+
readonly id: NodeId;
|
|
96
|
+
readonly kind: "stylesheet";
|
|
97
|
+
readonly context: "stylesheet";
|
|
98
|
+
readonly root: CssNode;
|
|
99
|
+
readonly children: readonly CssNode[];
|
|
100
|
+
readonly errors: readonly ParseError[];
|
|
101
|
+
readonly trace?: readonly TraceEvent[];
|
|
102
|
+
}
|
|
103
|
+
export interface FragmentTree {
|
|
104
|
+
readonly id: NodeId;
|
|
105
|
+
readonly kind: "fragment";
|
|
106
|
+
readonly context: ParseContext;
|
|
107
|
+
readonly root: CssNode;
|
|
108
|
+
readonly children: readonly CssNode[];
|
|
109
|
+
readonly errors: readonly ParseError[];
|
|
110
|
+
readonly trace?: readonly TraceEvent[];
|
|
111
|
+
}
|
|
112
|
+
export interface OutlineEntry {
|
|
113
|
+
readonly nodeId: NodeId;
|
|
114
|
+
readonly depth: number;
|
|
115
|
+
readonly type: string;
|
|
116
|
+
readonly text: string;
|
|
117
|
+
}
|
|
118
|
+
export interface Outline {
|
|
119
|
+
readonly entries: readonly OutlineEntry[];
|
|
120
|
+
}
|
|
121
|
+
export interface Chunk {
|
|
122
|
+
readonly index: number;
|
|
123
|
+
readonly nodeId: NodeId;
|
|
124
|
+
readonly content: string;
|
|
125
|
+
readonly nodes: number;
|
|
126
|
+
}
|
|
127
|
+
export interface ChunkOptions {
|
|
128
|
+
readonly maxChars?: number;
|
|
129
|
+
readonly maxNodes?: number;
|
|
130
|
+
readonly maxBytes?: number;
|
|
131
|
+
}
|
|
132
|
+
export interface BudgetExceededPayload {
|
|
133
|
+
readonly code: "BUDGET_EXCEEDED";
|
|
134
|
+
readonly budget: "maxInputBytes" | "maxBufferedBytes" | "maxTokens" | "maxNodes" | "maxDepth" | "maxTraceEvents" | "maxTraceBytes" | "maxTimeMs";
|
|
135
|
+
readonly limit: number;
|
|
136
|
+
readonly actual: number;
|
|
137
|
+
}
|
|
138
|
+
export interface RemoveNodeEdit {
|
|
139
|
+
readonly kind: "removeNode";
|
|
140
|
+
readonly target: NodeId;
|
|
141
|
+
}
|
|
142
|
+
export interface ReplaceNodeEdit {
|
|
143
|
+
readonly kind: "replaceNode";
|
|
144
|
+
readonly target: NodeId;
|
|
145
|
+
readonly css: string;
|
|
146
|
+
}
|
|
147
|
+
export interface InsertCssBeforeEdit {
|
|
148
|
+
readonly kind: "insertCssBefore";
|
|
149
|
+
readonly target: NodeId;
|
|
150
|
+
readonly css: string;
|
|
151
|
+
}
|
|
152
|
+
export interface InsertCssAfterEdit {
|
|
153
|
+
readonly kind: "insertCssAfter";
|
|
154
|
+
readonly target: NodeId;
|
|
155
|
+
readonly css: string;
|
|
156
|
+
}
|
|
157
|
+
export type Edit = RemoveNodeEdit | ReplaceNodeEdit | InsertCssBeforeEdit | InsertCssAfterEdit;
|
|
158
|
+
export interface PatchSliceStep {
|
|
159
|
+
readonly kind: "slice";
|
|
160
|
+
readonly start: number;
|
|
161
|
+
readonly end: number;
|
|
162
|
+
}
|
|
163
|
+
export interface PatchInsertStep {
|
|
164
|
+
readonly kind: "insert";
|
|
165
|
+
readonly at: number;
|
|
166
|
+
readonly text: string;
|
|
167
|
+
}
|
|
168
|
+
export type PatchStep = PatchSliceStep | PatchInsertStep;
|
|
169
|
+
export interface PatchPlan {
|
|
170
|
+
readonly steps: readonly PatchStep[];
|
|
171
|
+
readonly result: string;
|
|
172
|
+
}
|
|
173
|
+
export interface PatchPlanningErrorPayload {
|
|
174
|
+
readonly code: "NODE_NOT_FOUND" | "MISSING_NODE_SPAN" | "NON_INPUT_SPAN_PROVENANCE" | "OVERLAPPING_EDITS" | "INVALID_EDIT_TARGET";
|
|
175
|
+
readonly target?: NodeId;
|
|
176
|
+
readonly detail?: string;
|
|
177
|
+
}
|
|
178
|
+
export interface SelectorAttributeLike {
|
|
179
|
+
readonly name: string;
|
|
180
|
+
readonly value: string;
|
|
181
|
+
}
|
|
182
|
+
export interface SelectorNodeLike {
|
|
183
|
+
readonly kind?: string;
|
|
184
|
+
readonly type?: string;
|
|
185
|
+
readonly tagName?: string;
|
|
186
|
+
readonly attributes?: readonly SelectorAttributeLike[];
|
|
187
|
+
readonly children?: readonly SelectorNodeLike[];
|
|
188
|
+
readonly [key: string]: unknown;
|
|
189
|
+
}
|
|
190
|
+
export type SelectorCombinator = " " | ">";
|
|
191
|
+
export interface SelectorSimpleType {
|
|
192
|
+
readonly kind: "type";
|
|
193
|
+
readonly name: string;
|
|
194
|
+
readonly universal: boolean;
|
|
195
|
+
}
|
|
196
|
+
export interface SelectorSimpleId {
|
|
197
|
+
readonly kind: "id";
|
|
198
|
+
readonly value: string;
|
|
199
|
+
}
|
|
200
|
+
export interface SelectorSimpleClass {
|
|
201
|
+
readonly kind: "class";
|
|
202
|
+
readonly value: string;
|
|
203
|
+
}
|
|
204
|
+
export interface SelectorSimpleAttribute {
|
|
205
|
+
readonly kind: "attribute";
|
|
206
|
+
readonly name: string;
|
|
207
|
+
readonly matcher: null | "=" | "~=" | "|=" | "^=" | "$=" | "*=";
|
|
208
|
+
readonly value: string | null;
|
|
209
|
+
readonly flags: string | null;
|
|
210
|
+
}
|
|
211
|
+
export type SelectorSimple = SelectorSimpleType | SelectorSimpleId | SelectorSimpleClass | SelectorSimpleAttribute;
|
|
212
|
+
export interface CompiledSelectorCompound {
|
|
213
|
+
readonly simpleSelectors: readonly SelectorSimple[];
|
|
214
|
+
}
|
|
215
|
+
export interface SelectorUnsupportedPart {
|
|
216
|
+
readonly selectorIndex: number;
|
|
217
|
+
readonly partType: string;
|
|
218
|
+
readonly detail: string;
|
|
219
|
+
}
|
|
220
|
+
export interface CompiledSelector {
|
|
221
|
+
readonly selectorIndex: number;
|
|
222
|
+
readonly compounds: readonly CompiledSelectorCompound[];
|
|
223
|
+
readonly combinators: readonly SelectorCombinator[];
|
|
224
|
+
readonly supported: boolean;
|
|
225
|
+
readonly unsupportedParts: readonly SelectorUnsupportedPart[];
|
|
226
|
+
}
|
|
227
|
+
export interface CompiledSelectorList {
|
|
228
|
+
readonly source: string;
|
|
229
|
+
readonly parseErrors: readonly ParseError[];
|
|
230
|
+
readonly selectors: readonly CompiledSelector[];
|
|
231
|
+
readonly supported: boolean;
|
|
232
|
+
readonly unsupportedParts: readonly SelectorUnsupportedPart[];
|
|
233
|
+
}
|
|
234
|
+
export interface SelectorQueryOptions {
|
|
235
|
+
readonly strict?: boolean;
|
|
236
|
+
readonly maxVisitedNodes?: number;
|
|
237
|
+
}
|
|
238
|
+
export interface StyleSignalSpecificity {
|
|
239
|
+
readonly a: number;
|
|
240
|
+
readonly b: number;
|
|
241
|
+
readonly c: number;
|
|
242
|
+
}
|
|
243
|
+
export interface StyleDeclarationSignal {
|
|
244
|
+
readonly declarationNodeId: NodeId;
|
|
245
|
+
readonly property: string;
|
|
246
|
+
readonly value: string;
|
|
247
|
+
readonly important: boolean;
|
|
248
|
+
readonly declarationOrder: number;
|
|
249
|
+
}
|
|
250
|
+
export interface StyleRuleSignal {
|
|
251
|
+
readonly ruleNodeId: NodeId;
|
|
252
|
+
readonly selectorText: string;
|
|
253
|
+
readonly selector: CompiledSelectorList;
|
|
254
|
+
readonly selectorSupported: boolean;
|
|
255
|
+
readonly specificityMax: StyleSignalSpecificity;
|
|
256
|
+
readonly cascadeOrder: number;
|
|
257
|
+
readonly declarations: readonly StyleDeclarationSignal[];
|
|
258
|
+
}
|
|
259
|
+
export interface StyleSignalOptions {
|
|
260
|
+
readonly includeUnsupportedSelectors?: boolean;
|
|
261
|
+
readonly strictSelectors?: boolean;
|
|
262
|
+
}
|
|
263
|
+
export type RenderSignalClass = "visibility-hidden-subtree" | "visibility-hidden-self" | "control-affordance";
|
|
264
|
+
export interface RenderSignal {
|
|
265
|
+
readonly signalClass: RenderSignalClass;
|
|
266
|
+
readonly source: "rule" | "inline";
|
|
267
|
+
readonly property: string;
|
|
268
|
+
readonly value: string;
|
|
269
|
+
readonly important: boolean;
|
|
270
|
+
readonly declarationOrder: number;
|
|
271
|
+
readonly selectorText: string | null;
|
|
272
|
+
readonly declarationNodeId: NodeId;
|
|
273
|
+
readonly ruleNodeId: NodeId | null;
|
|
274
|
+
readonly cascadeOrder: number | null;
|
|
275
|
+
}
|
|
276
|
+
export interface RenderSignalOptions extends StyleSignalOptions {
|
|
277
|
+
readonly includeControlAffordance?: boolean;
|
|
278
|
+
readonly includeVisibilitySignals?: boolean;
|
|
279
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ismail-elkorchi/css-parser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Deterministic CSS parser for automation workflows across Node, Deno, Bun, and modern browsers.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Ismail-elkorchi/css-parser.git"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"packageManager": "npm@11.10.0",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=24.0.0",
|
|
17
|
+
"npm": ">=11.0.0"
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/mod.js",
|
|
20
|
+
"types": "./dist/mod.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/mod.d.ts",
|
|
24
|
+
"import": "./dist/mod.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"THIRD_PARTY_NOTICES.md"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"lint": "eslint . --max-warnings=0",
|
|
35
|
+
"fmt": "eslint . --fix --max-warnings=0",
|
|
36
|
+
"typecheck": "tsc --noEmit -p tsconfig.build.json",
|
|
37
|
+
"build": "tsc -p tsconfig.build.json && node scripts/build/copy-vendor.mjs",
|
|
38
|
+
"test": "npm run test:control",
|
|
39
|
+
"test:control": "npm run build && node --test test/control/**/*.test.js tests/control/**/*.test.js && node scripts/eval/write-stub-reports.mjs",
|
|
40
|
+
"test:conformance": "node scripts/conformance/run-all.mjs",
|
|
41
|
+
"test:encoding": "npm run build && node scripts/conformance/run-encoding-fixtures.mjs",
|
|
42
|
+
"test:tokenizer": "npm run build && node scripts/conformance/run-tokenizer-fixtures.mjs",
|
|
43
|
+
"test:tree": "npm run build && node scripts/conformance/run-tree-fixtures.mjs",
|
|
44
|
+
"test:serializer": "npm run build && node scripts/conformance/run-serializer-fixtures.mjs",
|
|
45
|
+
"test:holdout": "npm run build && node scripts/conformance/run-holdout-fixtures.mjs",
|
|
46
|
+
"test:browser-diff": "npm run build && node scripts/oracles/run-browser-diff.mjs",
|
|
47
|
+
"test:fuzz": "npm run build && node scripts/fuzz/run-fuzz.mjs",
|
|
48
|
+
"test:bench": "npm run build && node --expose-gc scripts/bench/run-bench.mjs",
|
|
49
|
+
"test:bench:stability": "npm run build && node --expose-gc scripts/bench/run-bench-stability.mjs",
|
|
50
|
+
"examples:run": "npm run build && node examples/run-all.mjs",
|
|
51
|
+
"check:fast": "npm run lint && npm run typecheck && npm run test:control && npm run examples:run",
|
|
52
|
+
"docs:lint:jsr": "deno doc --lint --sloppy-imports jsr/mod.ts",
|
|
53
|
+
"docs:test:jsr": "deno test --doc --no-check --sloppy-imports jsr/mod.ts",
|
|
54
|
+
"smoke:node": "npm run build && node scripts/smoke/control.mjs --runtime=node --report=reports/smoke-node.json",
|
|
55
|
+
"smoke:deno": "npm run build && deno run --allow-read --allow-write=reports --allow-env scripts/smoke/control.mjs --runtime=deno --report=reports/smoke-deno.json",
|
|
56
|
+
"smoke:bun": "npm run build && bun run scripts/smoke/control.mjs --runtime=bun --report=reports/smoke-bun.json",
|
|
57
|
+
"smoke:browser": "npm run build && node scripts/smoke/browser-smoke.mjs --report=reports/smoke-browser.json",
|
|
58
|
+
"smoke:all": "npm run smoke:node && npm run smoke:deno && npm run smoke:bun",
|
|
59
|
+
"deps:freshness": "npm outdated || true",
|
|
60
|
+
"pack:check": "node scripts/eval/pack-check.mjs",
|
|
61
|
+
"realworld:import": "node scripts/realworld/import-css-corpus.mjs",
|
|
62
|
+
"realworld:bench": "npm run build && node scripts/bench/bench-realworld-css.mjs",
|
|
63
|
+
"realworld:signals": "npm run build && node scripts/realworld/write-render-signals-report.mjs",
|
|
64
|
+
"realworld:bench:selectors": "npm run build && node --expose-gc scripts/bench/run-selector-bench.mjs",
|
|
65
|
+
"realworld:bench:selectors:stability": "npm run build && node scripts/bench/run-selector-bench-stability.mjs",
|
|
66
|
+
"realworld:check": "node scripts/realworld/check-realworld-targets.mjs",
|
|
67
|
+
"eval:realworld": "npm run realworld:bench && npm run realworld:signals && npm run realworld:bench:selectors && npm run realworld:bench:selectors:stability && npm run realworld:check && node scripts/realworld/eval-realworld.mjs",
|
|
68
|
+
"mutation:pilot": "npm run build && node scripts/mutation/run-pilot.mjs --config=scripts/mutation/pilot-config.json --out=docs/reference/mutation-pilot-report.json",
|
|
69
|
+
"eval:ci": "node scripts/eval/run-eval.mjs --profile=ci",
|
|
70
|
+
"eval:release": "node scripts/eval/run-eval.mjs --profile=release",
|
|
71
|
+
"eval:hard-gate": "node scripts/eval/run-eval.mjs --profile=hard-gate"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {},
|
|
74
|
+
"overrides": {
|
|
75
|
+
"ajv": "6.14.0"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@eslint/js": "9.39.3",
|
|
79
|
+
"eslint": "9.39.3",
|
|
80
|
+
"eslint-import-resolver-typescript": "4.4.4",
|
|
81
|
+
"eslint-plugin-boundaries": "5.4.0",
|
|
82
|
+
"eslint-plugin-import": "2.32.0",
|
|
83
|
+
"playwright": "1.58.2",
|
|
84
|
+
"typescript": "5.9.3",
|
|
85
|
+
"typescript-eslint": "8.56.0"
|
|
86
|
+
}
|
|
87
|
+
}
|