oxlint-plugin-vize 0.434.0 → 0.439.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.
@@ -1,3 +1,23 @@
1
+ import fs from "node:fs";
2
+ import { createHash } from "node:crypto";
3
+ import { isUtf8 } from "node:buffer";
4
+ //#region src/file-kinds.ts
5
+ function isVueLikeFile(filename) {
6
+ return hasVueLikeExtension(filename);
7
+ }
8
+ function isPatinaFile(filename) {
9
+ return isVueLikeFile(filename) || isScriptLikeFile(filename);
10
+ }
11
+ function isScriptLikeFile(filename) {
12
+ return /\.(?:[cm]?[jt]sx?)$/u.test(filename);
13
+ }
14
+ function hasVueLikeExtension(filename) {
15
+ return filename.endsWith(".vue") || filename.endsWith(".html") || filename.endsWith(".htm");
16
+ }
17
+ function isStandaloneHtmlFile(filename) {
18
+ return filename.endsWith(".html") || filename.endsWith(".htm");
19
+ }
20
+ //#endregion
1
21
  //#region src/sfc-blocks.ts
2
22
  function extractSfcBlocks(source) {
3
23
  const blocks = [];
@@ -120,38 +140,44 @@ function resolveBlockKind(tagName, openTag) {
120
140
  return "custom";
121
141
  }
122
142
  //#endregion
123
- //#region src/file-kinds.ts
124
- function isVueLikeFile(filename) {
125
- return hasVueLikeExtension(filename);
126
- }
127
- function isPatinaFile(filename) {
128
- return isVueLikeFile(filename) || isScriptLikeFile(filename);
129
- }
130
- function isScriptLikeFile(filename) {
131
- return /\.(?:[cm]?[jt]sx?)$/u.test(filename);
132
- }
133
- function hasVueLikeExtension(filename) {
134
- return filename.endsWith(".vue") || filename.endsWith(".html") || filename.endsWith(".htm");
135
- }
136
- function isStandaloneHtmlFile(filename) {
137
- return filename.endsWith(".html") || filename.endsWith(".htm");
138
- }
139
- //#endregion
140
143
  //#region src/workaround.ts
141
144
  const SCRIPTLESS_WORKAROUND_MARKER = "oxlint-plugin-vize-scriptless";
142
145
  const SCRIPTLESS_WORKAROUND_OPEN_TAG_PREFIX = `<script setup lang="ts" data-${SCRIPTLESS_WORKAROUND_MARKER}="`;
143
146
  const SCRIPTLESS_WORKAROUND_FILENAME_ATTR = `data-${SCRIPTLESS_WORKAROUND_MARKER}="`;
144
147
  const LOCATION_BRIDGE_MARKER = "/*vize-location-bridge*/";
148
+ const ORIGINAL_PAYLOAD_PREFIX = "<!--vize-original-source:";
149
+ /** Validate the original bytes before decoding reuse can enter native linting. */
150
+ function readOriginalWorkaroundSource(filename) {
151
+ const bytes = fs.readFileSync(filename);
152
+ if (!isUtf8(bytes)) throw new Error("Vize carrier cannot preserve non-UTF8 original file bytes.");
153
+ return bytes.toString("utf8");
154
+ }
155
+ function validateWorkaroundAuthority(state, physical) {
156
+ if (state.usesOriginalLocations && state.filename !== physical && readOriginalWorkaroundSource(state.filename) !== state.source) throw new Error("Vize carrier source no longer matches the original file bytes.");
157
+ }
145
158
  function hasScriptLikeBlock(source) {
146
159
  return extractSfcBlocks(source).some((block) => block.kind === "script" || block.kind === "script-setup");
147
160
  }
148
161
  function appendScriptlessWorkaround(source, filename) {
149
- return `${createWorkaroundScript(source, filename)}${source}`;
162
+ return prepareWorkaroundSource(source, filename).source;
163
+ }
164
+ /** Keep original coordinates in one safe host script and an exact source payload. */
165
+ function prepareWorkaroundSource(source, filename) {
166
+ const openTag = `${SCRIPTLESS_WORKAROUND_OPEN_TAG_PREFIX}${encodeWorkaroundFilename(filename)}">`;
167
+ const script = `${openTag}${createWhitespaceMirror(source)}${LOCATION_BRIDGE_MARKER}<\/script>\n`;
168
+ return {
169
+ source: `${script}${ORIGINAL_PAYLOAD_PREFIX}${createHash("sha256").update(filename).update("\0").update(source).digest("hex")}:${Buffer.from(source, "utf8").toString("base64url")}-->`,
170
+ locations: {
171
+ source,
172
+ scriptStart: openTag.length,
173
+ originalStart: Buffer.byteLength(script, "utf8")
174
+ }
175
+ };
150
176
  }
151
177
  function isLocationBridgeProgram(extractedScript) {
152
178
  return extractedScript.trimEnd().endsWith(LOCATION_BRIDGE_MARKER);
153
179
  }
154
- function resolveWorkaroundSource(source, fallbackFilename) {
180
+ function resolveWorkaroundSource(source, fallbackFilename, readOriginalSource) {
155
181
  const workaroundBlock = getPrependedWorkaroundBlock(source);
156
182
  if (workaroundBlock == null) return {
157
183
  filename: fallbackFilename,
@@ -161,9 +187,12 @@ function resolveWorkaroundSource(source, fallbackFilename) {
161
187
  let strippedSourceStart = workaroundBlock.closeTagEnd;
162
188
  if (source.charCodeAt(strippedSourceStart) === 13) strippedSourceStart += 1;
163
189
  if (source.charCodeAt(strippedSourceStart) === 10) strippedSourceStart += 1;
190
+ const decodedFilename = decodeWorkaroundFilename(workaroundBlock.encodedFilename) ?? fallbackFilename;
191
+ const strippedSource = workaroundBlock.originalSource ?? source.slice(strippedSourceStart);
192
+ if (readOriginalSource && readOriginalSource(decodedFilename) !== strippedSource) throw new Error("Vize carrier source no longer matches the original file bytes.");
164
193
  return {
165
- filename: decodeWorkaroundFilename(workaroundBlock.encodedFilename) ?? fallbackFilename,
166
- source: source.slice(strippedSourceStart),
194
+ filename: decodedFilename,
195
+ source: strippedSource,
167
196
  usesOriginalLocations: true
168
197
  };
169
198
  }
@@ -179,10 +208,20 @@ function getPrependedWorkaroundBlock(source) {
179
208
  const closeTagEnd = contentEnd + 9;
180
209
  const strippedSourceStart = sourceStartAfterSyntheticBlock(source, closeTagEnd);
181
210
  if (strippedSourceStart == null) return null;
182
- if (firstBlock.content !== createWhitespaceMirror(source.slice(strippedSourceStart)) + LOCATION_BRIDGE_MARKER) return null;
211
+ const tail = source.slice(strippedSourceStart);
212
+ let originalSource;
213
+ if (tail.startsWith(ORIGINAL_PAYLOAD_PREFIX)) {
214
+ const payload = /^<!--vize-original-source:([a-f0-9]{64}):([A-Za-z0-9_-]*)-->$/u.exec(tail);
215
+ if (payload == null) throw new Error("Invalid Vize original-source carrier payload.");
216
+ const originalFilename = decodeWorkaroundFilename(encodedFilename);
217
+ if (originalFilename == null || encodeWorkaroundFilename(originalFilename) !== encodedFilename) throw new Error("Invalid Vize original-source carrier filename.");
218
+ originalSource = Buffer.from(payload[2], "base64url").toString("utf8");
219
+ if (Buffer.from(originalSource, "utf8").toString("base64url") !== payload[2] || createHash("sha256").update(originalFilename).update("\0").update(originalSource).digest("hex") !== payload[1] || firstBlock.content !== createWhitespaceMirror(originalSource) + LOCATION_BRIDGE_MARKER) throw new Error("Vize original-source carrier bytes do not match their complete source mirror.");
220
+ } else if (firstBlock.content !== createWhitespaceMirror(tail) + LOCATION_BRIDGE_MARKER) return null;
183
221
  return {
184
222
  closeTagEnd,
185
- encodedFilename
223
+ encodedFilename,
224
+ originalSource
186
225
  };
187
226
  }
188
227
  function sourceStartAfterSyntheticBlock(source, closeTagEnd) {
@@ -197,11 +236,8 @@ function encodedFilenameFromWorkaroundOpenTag(openTag) {
197
236
  if (encodedFilenameStart < SCRIPTLESS_WORKAROUND_FILENAME_ATTR.length || encodedFilenameEnd === -1) return null;
198
237
  return openTag.slice(encodedFilenameStart, encodedFilenameEnd);
199
238
  }
200
- function createWorkaroundScript(source, filename) {
201
- return `${SCRIPTLESS_WORKAROUND_OPEN_TAG_PREFIX}${encodeWorkaroundFilename(filename)}">${createWhitespaceMirror(source)}${LOCATION_BRIDGE_MARKER}<\/script>\n`;
202
- }
203
239
  function createWhitespaceMirror(source) {
204
- return source.replaceAll(/[^\r\n]/gu, " ");
240
+ return source.replaceAll(/[^\r\n]/gu, (character) => character.length === 2 ? " " : " ");
205
241
  }
206
242
  function encodeWorkaroundFilename(filename) {
207
243
  return Buffer.from(filename, "utf8").toString("base64url");
@@ -255,4 +291,4 @@ if (import.meta.vitest) {
255
291
  });
256
292
  }
257
293
  //#endregion
258
- export { isPatinaFile as a, compareLineColumn as c, getDiagnosticBlock as d, hasVueLikeExtension as i, extractSfcBlocks as l, isLocationBridgeProgram as n, isScriptLikeFile as o, resolveWorkaroundSource as r, isStandaloneHtmlFile as s, appendScriptlessWorkaround as t, formatBlockLabel as u };
294
+ export { validateWorkaroundAuthority as a, formatBlockLabel as c, isPatinaFile as d, isScriptLikeFile as f, resolveWorkaroundSource as i, getDiagnosticBlock as l, prepareWorkaroundSource as n, compareLineColumn as o, isStandaloneHtmlFile as p, readOriginalWorkaroundSource as r, extractSfcBlocks as s, isLocationBridgeProgram as t, hasVueLikeExtension as u };
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "devDependencies": {
13
13
  "@tsdown/css": "0.22.14",
14
14
  "@types/node": "25.9.2",
15
- "@vizejs/native": "0.434.0",
15
+ "@vizejs/native": "0.439.0",
16
16
  "tsdown": "0.22.14",
17
17
  "typescript": "6.0.3",
18
18
  "vite": "npm:@voidzero-dev/vite-plus-core@0.1.24",
@@ -49,14 +49,14 @@
49
49
  },
50
50
  "name": "oxlint-plugin-vize",
51
51
  "optionalDependencies": {
52
- "@vizejs/native-darwin-arm64": "0.434.0",
53
- "@vizejs/native-darwin-x64": "0.434.0",
54
- "@vizejs/native-linux-arm64-gnu": "0.434.0",
55
- "@vizejs/native-linux-arm64-musl": "0.434.0",
56
- "@vizejs/native-linux-x64-gnu": "0.434.0",
57
- "@vizejs/native-linux-x64-musl": "0.434.0",
58
- "@vizejs/native-win32-arm64-msvc": "0.434.0",
59
- "@vizejs/native-win32-x64-msvc": "0.434.0"
52
+ "@vizejs/native-darwin-arm64": "0.439.0",
53
+ "@vizejs/native-darwin-x64": "0.439.0",
54
+ "@vizejs/native-linux-arm64-gnu": "0.439.0",
55
+ "@vizejs/native-linux-arm64-musl": "0.439.0",
56
+ "@vizejs/native-linux-x64-gnu": "0.439.0",
57
+ "@vizejs/native-linux-x64-musl": "0.439.0",
58
+ "@vizejs/native-win32-arm64-msvc": "0.439.0",
59
+ "@vizejs/native-win32-x64-msvc": "0.439.0"
60
60
  },
61
61
  "publishConfig": {
62
62
  "access": "public"
@@ -68,12 +68,12 @@
68
68
  },
69
69
  "type": "module",
70
70
  "types": "./dist/index.d.mts",
71
- "version": "0.434.0",
71
+ "version": "0.439.0",
72
72
  "scripts": {
73
73
  "build": "vp pack",
74
74
  "check": "vp check src vite.config.ts",
75
75
  "check:fix": "vp check --fix src vite.config.ts",
76
76
  "fmt": "vp fmt --write src vite.config.ts",
77
- "test": "vp pack && vp test run src/file-state.test.ts && node src/test.ts && node src/script-location.test.ts && node src/casing-options.test.ts"
77
+ "test": "vp pack && vp test run src/file-state.test.ts src/batched-rules.test.ts src/script-safe-source.test.ts src/active-rule-collection.test.ts && node src/test.ts && node src/script-location.test.ts && node src/casing-options.test.ts && node src/template-style-fixes.test.mjs"
78
78
  }
79
79
  }