vite-plugin-qingkuai 1.0.22 → 1.0.24

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.
@@ -0,0 +1,106 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+ inputs:
9
+ tag:
10
+ type: string
11
+ required: false
12
+ description: "Optional tag to release (for example: v1.0.66). Leave empty to auto-create from package version."
13
+
14
+ permissions:
15
+ contents: write
16
+ id-token: write
17
+
18
+ jobs:
19
+ release:
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - name: Checkout source
24
+ uses: actions/checkout@v6
25
+ with:
26
+ fetch-depth: 0
27
+
28
+ - name: Resolve release tag
29
+ id: tag
30
+ env:
31
+ INPUT_TAG: ${{ inputs.tag }}
32
+ REF_NAME: ${{ github.ref_name }}
33
+ EVENT_NAME: ${{ github.event_name }}
34
+ run: |
35
+ if [[ "$EVENT_NAME" == "push" ]]; then
36
+ echo "value=$REF_NAME" >> "$GITHUB_OUTPUT"
37
+ exit 0
38
+ fi
39
+
40
+ if [[ -n "$INPUT_TAG" ]]; then
41
+ echo "value=$INPUT_TAG" >> "$GITHUB_OUTPUT"
42
+ exit 0
43
+ fi
44
+
45
+ package_version="$(node -p 'require("./package.json").version')"
46
+ echo "value=v$package_version" >> "$GITHUB_OUTPUT"
47
+
48
+ - name: Ensure tag exists on workflow dispatch
49
+ if: ${{ github.event_name == 'workflow_dispatch' }}
50
+ env:
51
+ TAG: ${{ steps.tag.outputs.value }}
52
+ run: |
53
+ git fetch origin --tags --prune
54
+
55
+ if git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null; then
56
+ echo "Tag already exists: $TAG"
57
+ else
58
+ git config user.name "github-actions[bot]"
59
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
60
+ git tag "$TAG"
61
+ git push origin "$TAG"
62
+ echo "Created and pushed tag: $TAG"
63
+ fi
64
+
65
+ - name: Checkout resolved tag
66
+ env:
67
+ TAG: ${{ steps.tag.outputs.value }}
68
+ run: |
69
+ git fetch origin --tags --prune
70
+ git checkout "refs/tags/$TAG"
71
+
72
+ - name: Setup pnpm
73
+ uses: pnpm/action-setup@v6
74
+
75
+ - name: Setup Node.js
76
+ uses: actions/setup-node@v6
77
+ with:
78
+ node-version: 24
79
+ cache: pnpm
80
+ registry-url: https://registry.npmjs.org
81
+
82
+ - name: Install dependencies
83
+ run: pnpm install --frozen-lockfile --ignore-scripts
84
+
85
+ - name: Validate tag equals package version
86
+ env:
87
+ TAG: ${{ steps.tag.outputs.value }}
88
+ run: |
89
+ package_version="$(node -p 'require("./package.json").version')"
90
+ if [[ "v$package_version" != "$TAG" ]]; then
91
+ echo "Tag and package.json version mismatch: $TAG vs v$package_version"
92
+ exit 1
93
+ fi
94
+
95
+ - name: Build
96
+ run: pnpm build
97
+
98
+ - name: Publish package to npm (Trusted Publishing)
99
+ run: npm publish --access public --provenance
100
+
101
+ - name: Create GitHub Release
102
+ uses: softprops/action-gh-release@v2
103
+ with:
104
+ tag_name: ${{ steps.tag.outputs.value }}
105
+ name: ${{ steps.tag.outputs.value }}
106
+ body: "Release ${{ steps.tag.outputs.value }}"
@@ -0,0 +1 @@
1
+ pnpm lint-staged
package/dist/index.cjs CHANGED
@@ -30,6 +30,9 @@ function _interopNamespaceDefault(e) {
30
30
 
31
31
  var vite__namespace = /*#__PURE__*/_interopNamespaceDefault(vite);
32
32
 
33
+ function isNumber(v) {
34
+ return typeof v === "number";
35
+ }
33
36
  function isUndefined(v) {
34
37
  return void 0 === v;
35
38
  }
@@ -211,24 +214,66 @@ function qingkuai(options = {}) {
211
214
  }
212
215
  let virtualFileName;
213
216
  const compileRes = compileResultCache.get(fileId);
214
- const style = compileRes.styleDescriptors[index];
217
+ const styleDescriptor = compileRes.styleDescriptors[index];
215
218
  while (true) {
216
219
  const hash = nodeCrypto.randomBytes(6).toString("hex");
217
- virtualFileName = `${fileId}.${hash}.${style.lang}`;
220
+ virtualFileName = `${fileId}.${hash}.${styleDescriptor.lang}`;
218
221
  if (!nodeFs.existsSync(virtualFileName)) {
219
222
  break;
220
223
  }
221
224
  }
222
- const preprocessRes = await vite__namespace.preprocessCSS(style.code, virtualFileName, {
223
- ...viteConfig,
224
- css: {
225
- ...viteConfig.css,
226
- postcss: {
227
- from: virtualFileName
225
+ let preprocessRes;
226
+ try {
227
+ preprocessRes = await vite__namespace.preprocessCSS(styleDescriptor.code, virtualFileName, {
228
+ ...viteConfig,
229
+ css: {
230
+ ...viteConfig.css,
231
+ postcss: {
232
+ from: virtualFileName
233
+ }
234
+ }
235
+ });
236
+ } catch (err) {
237
+ let errorPos = null;
238
+ const lac = new linesAndColumns.LinesAndColumns(styleDescriptor.code);
239
+ switch (styleDescriptor.lang) {
240
+ case "css":
241
+ case "less":
242
+ case "stylus": {
243
+ delete err.loc;
244
+ err.message += `
245
+
246
+ Caused by: "${fileId}".`;
247
+ break;
248
+ }
249
+ case "sass":
250
+ case "scss": {
251
+ if (err.sassMessage) {
252
+ err.message = err.sassMessage;
253
+ }
254
+ if (isNumber(err.line) && isNumber(err.column)) {
255
+ errorPos = lac.indexForLocation({
256
+ line: err.line - 1,
257
+ column: err.column - 1
258
+ });
259
+ }
260
+ break;
228
261
  }
229
262
  }
230
- });
231
- if (!cssSourcemap || style.global) {
263
+ if (isNumber(errorPos) && !isNaN(errorPos)) {
264
+ const loc = lac.locationForIndex(errorPos + styleDescriptor.loc.start.index);
265
+ if (loc) {
266
+ err.loc = {
267
+ file: fileId,
268
+ line: loc.line + 1,
269
+ column: loc.column
270
+ };
271
+ delete err.frame;
272
+ }
273
+ }
274
+ return this.error(err);
275
+ }
276
+ if (!cssSourcemap || styleDescriptor.global) {
232
277
  return preprocessRes;
233
278
  }
234
279
  const assertedPreprocessMap = preprocessRes.map;
@@ -248,8 +293,8 @@ function qingkuai(options = {}) {
248
293
  offsetSourceMap(
249
294
  attachScopeResult.mappings,
250
295
  currentSourceIndex,
251
- style.loc.start.line - 1,
252
- style.loc.start.column - 1
296
+ styleDescriptor.loc.start.line - 1,
297
+ styleDescriptor.loc.start.column - 1
253
298
  )
254
299
  );
255
300
  if (attachScopeResult.error) {
@@ -271,11 +316,11 @@ function qingkuai(options = {}) {
271
316
  }
272
317
  });
273
318
  }
274
- const preprocessedIndex = new linesAndColumns.LinesAndColumns(style.code).indexForLocation({
319
+ const preprocessedIndex = new linesAndColumns.LinesAndColumns(styleDescriptor.code).indexForLocation({
275
320
  line: preprocessedPosition.line - 1,
276
321
  column: preprocessedPosition.column
277
322
  }) || 0;
278
- const position = compileRes.positions[style.loc.start.index + preprocessedIndex];
323
+ const position = compileRes.positions[styleDescriptor.loc.start.index + preprocessedIndex];
279
324
  this.error({
280
325
  message: attachScopeResult.error.message,
281
326
  loc: {
@@ -383,8 +428,10 @@ function qingkuai(options = {}) {
383
428
  })
384
429
  };
385
430
  } catch (err) {
386
- if (err.loc && "start" in err.loc && "index" in err.loc.start) {
387
- err.pos = err.loc.start.index, this.error(err);
431
+ if (compiler.isCompileError(err)) {
432
+ this.error(err.message, err.loc.start.index);
433
+ } else if (err.cause && isNumber(err.cause.pos)) {
434
+ this.error(err, err.cause.pos);
388
435
  } else {
389
436
  this.error(
390
437
  "Qingkuai compile result is invalid. Please report this at https://github.com/qingkuai-js/qingkuai/issues and include your .qk source for reproduction."
package/dist/index.js CHANGED
@@ -2,13 +2,16 @@ import * as vite from 'vite';
2
2
  import nodeFs from 'node:fs';
3
3
  import nodePath from 'node:path';
4
4
  import nodeCrypto from 'node:crypto';
5
- import { util, compile } from 'qingkuai/compiler';
5
+ import { util, compile, isCompileError } from 'qingkuai/compiler';
6
6
  import { LinesAndColumns } from 'lines-and-columns';
7
7
  import { decode, encode } from '@jridgewell/sourcemap-codec';
8
8
  import postcss from 'postcss';
9
9
  import selectorParser from 'postcss-selector-parser';
10
10
  import { SourceMapConsumer } from 'source-map-js';
11
11
 
12
+ function isNumber(v) {
13
+ return typeof v === "number";
14
+ }
12
15
  function isUndefined(v) {
13
16
  return void 0 === v;
14
17
  }
@@ -190,24 +193,66 @@ function qingkuai(options = {}) {
190
193
  }
191
194
  let virtualFileName;
192
195
  const compileRes = compileResultCache.get(fileId);
193
- const style = compileRes.styleDescriptors[index];
196
+ const styleDescriptor = compileRes.styleDescriptors[index];
194
197
  while (true) {
195
198
  const hash = nodeCrypto.randomBytes(6).toString("hex");
196
- virtualFileName = `${fileId}.${hash}.${style.lang}`;
199
+ virtualFileName = `${fileId}.${hash}.${styleDescriptor.lang}`;
197
200
  if (!nodeFs.existsSync(virtualFileName)) {
198
201
  break;
199
202
  }
200
203
  }
201
- const preprocessRes = await vite.preprocessCSS(style.code, virtualFileName, {
202
- ...viteConfig,
203
- css: {
204
- ...viteConfig.css,
205
- postcss: {
206
- from: virtualFileName
204
+ let preprocessRes;
205
+ try {
206
+ preprocessRes = await vite.preprocessCSS(styleDescriptor.code, virtualFileName, {
207
+ ...viteConfig,
208
+ css: {
209
+ ...viteConfig.css,
210
+ postcss: {
211
+ from: virtualFileName
212
+ }
213
+ }
214
+ });
215
+ } catch (err) {
216
+ let errorPos = null;
217
+ const lac = new LinesAndColumns(styleDescriptor.code);
218
+ switch (styleDescriptor.lang) {
219
+ case "css":
220
+ case "less":
221
+ case "stylus": {
222
+ delete err.loc;
223
+ err.message += `
224
+
225
+ Caused by: "${fileId}".`;
226
+ break;
227
+ }
228
+ case "sass":
229
+ case "scss": {
230
+ if (err.sassMessage) {
231
+ err.message = err.sassMessage;
232
+ }
233
+ if (isNumber(err.line) && isNumber(err.column)) {
234
+ errorPos = lac.indexForLocation({
235
+ line: err.line - 1,
236
+ column: err.column - 1
237
+ });
238
+ }
239
+ break;
207
240
  }
208
241
  }
209
- });
210
- if (!cssSourcemap || style.global) {
242
+ if (isNumber(errorPos) && !isNaN(errorPos)) {
243
+ const loc = lac.locationForIndex(errorPos + styleDescriptor.loc.start.index);
244
+ if (loc) {
245
+ err.loc = {
246
+ file: fileId,
247
+ line: loc.line + 1,
248
+ column: loc.column
249
+ };
250
+ delete err.frame;
251
+ }
252
+ }
253
+ return this.error(err);
254
+ }
255
+ if (!cssSourcemap || styleDescriptor.global) {
211
256
  return preprocessRes;
212
257
  }
213
258
  const assertedPreprocessMap = preprocessRes.map;
@@ -227,8 +272,8 @@ function qingkuai(options = {}) {
227
272
  offsetSourceMap(
228
273
  attachScopeResult.mappings,
229
274
  currentSourceIndex,
230
- style.loc.start.line - 1,
231
- style.loc.start.column - 1
275
+ styleDescriptor.loc.start.line - 1,
276
+ styleDescriptor.loc.start.column - 1
232
277
  )
233
278
  );
234
279
  if (attachScopeResult.error) {
@@ -250,11 +295,11 @@ function qingkuai(options = {}) {
250
295
  }
251
296
  });
252
297
  }
253
- const preprocessedIndex = new LinesAndColumns(style.code).indexForLocation({
298
+ const preprocessedIndex = new LinesAndColumns(styleDescriptor.code).indexForLocation({
254
299
  line: preprocessedPosition.line - 1,
255
300
  column: preprocessedPosition.column
256
301
  }) || 0;
257
- const position = compileRes.positions[style.loc.start.index + preprocessedIndex];
302
+ const position = compileRes.positions[styleDescriptor.loc.start.index + preprocessedIndex];
258
303
  this.error({
259
304
  message: attachScopeResult.error.message,
260
305
  loc: {
@@ -362,8 +407,10 @@ function qingkuai(options = {}) {
362
407
  })
363
408
  };
364
409
  } catch (err) {
365
- if (err.loc && "start" in err.loc && "index" in err.loc.start) {
366
- err.pos = err.loc.start.index, this.error(err);
410
+ if (isCompileError(err)) {
411
+ this.error(err.message, err.loc.start.index);
412
+ } else if (err.cause && isNumber(err.cause.pos)) {
413
+ this.error(err, err.cause.pos);
367
414
  } else {
368
415
  this.error(
369
416
  "Qingkuai compile result is invalid. Please report this at https://github.com/qingkuai-js/qingkuai/issues and include your .qk source for reproduction."
package/package.json CHANGED
@@ -1,46 +1,57 @@
1
1
  {
2
- "name": "vite-plugin-qingkuai",
3
- "author": "mlgq",
4
- "license": "MIT",
5
- "version": "1.0.22",
6
- "type": "module",
7
- "keywords": [
8
- "vite",
9
- "qingkuai",
10
- "vite plugin",
11
- "vite-plugin"
12
- ],
13
- "exports": {
14
- ".": {
15
- "import": "./dist/index.js",
16
- "require": "./dist/index.cjs"
17
- }
18
- },
19
- "scripts": {
20
- "dev": "rollup -c -w",
21
- "build": "rimraf dist && tsc && rollup -c && rimraf dist/temp-types",
22
- "postpublish": "curl -X PUT 'https://registry-direct.npmmirror.com/-/package/vite-plugin-qingkuai/syncs'"
23
- },
24
- "devDependencies": {
25
- "@types/fs-extra": "^11.0.4",
26
- "@types/node": "^22.13.14",
27
- "fs-extra": "^11.3.0",
28
- "qingkuai": "^1.0.45",
29
- "rimraf": "^6.0.1",
30
- "rollup": "^4.38.0",
31
- "rollup-plugin-dts": "^6.2.1",
32
- "rollup-plugin-esbuild": "^6.2.1",
33
- "vite": "8.0.0"
34
- },
35
- "peerDependencies": {
36
- "qingkuai": ">=1.0.50",
37
- "vite": ">=6.2.4 <9"
38
- },
39
- "dependencies": {
40
- "@jridgewell/sourcemap-codec": "^1.5.0",
41
- "lines-and-columns": "^2.0.4",
42
- "postcss": "^8.5.3",
43
- "postcss-selector-parser": "^7.1.0",
44
- "source-map-js": "^1.2.1"
2
+ "name": "vite-plugin-qingkuai",
3
+ "author": "mlgq",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "version": "1.0.24",
7
+ "packageManager": "pnpm@9.9.0",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs"
45
12
  }
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/qingkuai-js/vite-plugin.git"
17
+ },
18
+ "lint-staged": {
19
+ "*.{ts,js,mjs,cjs,json,md,yml,yaml}": "prettier --write"
20
+ },
21
+ "scripts": {
22
+ "dev": "rollup -c -w",
23
+ "release": "node scripts/release.js",
24
+ "build": "rimraf dist && tsc && rollup -c && rimraf dist/temp-types",
25
+ "postpublish": "curl -X PUT 'https://registry-direct.npmmirror.com/-/package/vite-plugin-qingkuai/syncs'"
26
+ },
27
+ "devDependencies": {
28
+ "@types/fs-extra": "^11.0.4",
29
+ "@types/node": "^22.13.14",
30
+ "fs-extra": "^11.3.0",
31
+ "husky": "^9.1.7",
32
+ "lint-staged": "^17.3.0",
33
+ "qingkuai": "^1.0.83",
34
+ "rimraf": "^6.0.1",
35
+ "rollup": "^4.38.0",
36
+ "rollup-plugin-dts": "^6.2.1",
37
+ "rollup-plugin-esbuild": "^6.2.1",
38
+ "vite": "8.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "qingkuai": ">=1.0.50",
42
+ "vite": ">=6.2.4 <9"
43
+ },
44
+ "dependencies": {
45
+ "@jridgewell/sourcemap-codec": "^1.5.0",
46
+ "lines-and-columns": "^2.0.4",
47
+ "postcss": "^8.5.3",
48
+ "postcss-selector-parser": "^7.1.0",
49
+ "source-map-js": "^1.2.1"
50
+ },
51
+ "keywords": [
52
+ "vite",
53
+ "qingkuai",
54
+ "vite plugin",
55
+ "vite-plugin"
56
+ ]
46
57
  }
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env node
2
+ import nodeFs from "node:fs"
3
+ import nodePath from "node:path"
4
+
5
+ import { spawnSync } from "node:child_process"
6
+
7
+ const ROOT = nodePath.resolve(process.cwd())
8
+ const PKG_PATH = nodePath.join(ROOT, "package.json")
9
+
10
+ main()
11
+
12
+ function readPackageJson() {
13
+ return JSON.parse(nodeFs.readFileSync(PKG_PATH, "utf-8"))
14
+ }
15
+
16
+ function writePackageJson(pkg) {
17
+ nodeFs.writeFileSync(PKG_PATH, JSON.stringify(pkg, null, 2) + "\n", "utf-8")
18
+ }
19
+
20
+ function bumpVersion(version) {
21
+ const parts = version.split(".").map(Number)
22
+ if (parts.length !== 3 || parts.some(n => Number.isNaN(n) || n < 0)) {
23
+ throw new Error(`Unsupported version format: ${version}`)
24
+ }
25
+ parts[2] += 1
26
+ return parts.join(".")
27
+ }
28
+
29
+ async function run(command, args, opts = {}) {
30
+ const result = spawnSync(command, args, { stdio: "inherit", ...opts })
31
+ if (result.error) {
32
+ throw result.error
33
+ }
34
+ if (result.status !== 0) {
35
+ throw new Error(`Command failed: ${command} ${args.join(" ")}`)
36
+ }
37
+ return result
38
+ }
39
+
40
+ function verifyCleanWorkingTree() {
41
+ const result = spawnSync("git", ["status", "--porcelain"], {
42
+ encoding: "utf-8",
43
+ stdio: ["ignore", "pipe", "inherit"]
44
+ })
45
+ if (result.error) {
46
+ throw result.error
47
+ }
48
+ if (result.status !== 0) {
49
+ throw new Error("Failed to check git working tree status")
50
+ }
51
+ if (result.stdout.trim()) {
52
+ throw new Error(
53
+ "Git working tree is not clean. Please commit or stash your changes before releasing."
54
+ )
55
+ }
56
+ }
57
+
58
+ async function release() {
59
+ verifyCleanWorkingTree()
60
+ const pkg = readPackageJson()
61
+ const currentVersion = pkg.version
62
+ if (!currentVersion) {
63
+ throw new Error("package.json is missing version")
64
+ }
65
+
66
+ const arg = process.argv[2]
67
+ const newVersion = arg ? arg.replace(/^v/, "") : bumpVersion(currentVersion)
68
+ const tag = `v${newVersion}`
69
+
70
+ if (newVersion === currentVersion) {
71
+ console.log(`Version unchanged: ${newVersion}`)
72
+ return
73
+ }
74
+
75
+ pkg.version = newVersion
76
+ writePackageJson(pkg)
77
+
78
+ await run("git", ["add", "package.json"])
79
+ await run("git", ["commit", "-m", `release: bump version to ${tag}`])
80
+ await run("git", ["tag", tag])
81
+ await run("git", ["push"])
82
+ await run("git", ["push", "origin", tag])
83
+
84
+ console.log(`Released ${tag}`)
85
+ }
86
+
87
+ async function main() {
88
+ try {
89
+ await release()
90
+ } catch (error) {
91
+ console.error(error instanceof Error ? error.message : error)
92
+ process.exit(1)
93
+ }
94
+ }
@@ -1,3 +0,0 @@
1
- {
2
- "recommendations": []
3
- }