@vue-puzzle-vcode/shared 2.0.0 → 2.0.2
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/README.md +9 -0
- package/dist/index.cjs +44 -3
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +41 -4
- package/package.json +6 -4
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @vue-puzzle-vcode/shared
|
|
2
|
+
|
|
3
|
+
vue-puzzle-vcode 的共享纯函数工具库:Canvas 拼图绘制、拼图块路径、数学/随机数等。无任何框架依赖。
|
|
4
|
+
|
|
5
|
+
> 内部包,被 [`@vue-puzzle-vcode/core`](https://www.npmjs.com/package/@vue-puzzle-vcode/core) 与 [`@vue-puzzle-vcode/ui`](https://www.npmjs.com/package/@vue-puzzle-vcode/ui) 依赖,通常无需直接安装。
|
|
6
|
+
|
|
7
|
+
## 文档
|
|
8
|
+
|
|
9
|
+
完整文档与在线 Demo 见主仓库:[github.com/daguanren21/vue-puzzle-vcode](https://github.com/daguanren21/vue-puzzle-vcode#readme)
|
package/dist/index.cjs
CHANGED
|
@@ -5,9 +5,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
5
5
|
* Pure, framework-agnostic utilities: math + canvas drawing for the
|
|
6
6
|
* sliding-puzzle captcha. No Vue imports here — safe to bundle anywhere.
|
|
7
7
|
*/
|
|
8
|
-
/** Random integer in [min, max]. */
|
|
8
|
+
/** Random integer in [min, max] (inclusive). */
|
|
9
9
|
function randomInt(min, max) {
|
|
10
|
-
|
|
10
|
+
if (max < min) return min;
|
|
11
|
+
return min + Math.floor(Math.random() * (max - min + 1));
|
|
11
12
|
}
|
|
12
13
|
/** Clamp `v` into [min, max]. */
|
|
13
14
|
function clamp(v, min, max) {
|
|
@@ -28,6 +29,41 @@ function computeSliderBaseSize(sliderSize, canvasWidth) {
|
|
|
28
29
|
return Math.max(Math.min(Math.round(sliderSize), Math.round(canvasWidth * .5)), 10);
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
32
|
+
* Usable track length (canvasWidth - sliderBaseSize), floored at 1 so the
|
|
33
|
+
* drag-compensation term never divides by zero.
|
|
34
|
+
*/
|
|
35
|
+
function computeTrackTravel(canvasWidth, sliderBaseSize) {
|
|
36
|
+
return Math.max(1, canvasWidth - sliderBaseSize);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Horizontal offset of the floating puzzle piece, kept in sync with the
|
|
40
|
+
* slider. Compensates for puzzle-vs-slider width mismatch across the track.
|
|
41
|
+
*/
|
|
42
|
+
function computePuzzleTranslateX(styleWidth, sliderBaseSize, puzzleBaseSize, trackTravel) {
|
|
43
|
+
const dragged = styleWidth - sliderBaseSize;
|
|
44
|
+
return dragged - (puzzleBaseSize - sliderBaseSize) * (dragged / trackTravel);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Absolute pixel deviation used for pass/fail. The trailing `-3` undoes the
|
|
48
|
+
* shadow crop offset applied when the piece was copied off the main canvas.
|
|
49
|
+
*/
|
|
50
|
+
function computeDragDeviation(pinX, styleWidth, sliderBaseSize, puzzleBaseSize, trackTravel) {
|
|
51
|
+
const dragged = styleWidth - sliderBaseSize;
|
|
52
|
+
return Math.abs(pinX - dragged + (puzzleBaseSize - sliderBaseSize) * (dragged / trackTravel) - 3);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Source rectangle used to copy the puzzle piece (and its drop shadow) off
|
|
56
|
+
* the main canvas. `sw`/`sh` are WIDTH/HEIGHT for `getImageData`.
|
|
57
|
+
*/
|
|
58
|
+
function computePuzzleCropRect(pinX, pinY, puzzleBaseSize) {
|
|
59
|
+
return {
|
|
60
|
+
sx: pinX - 3,
|
|
61
|
+
sy: pinY - 20,
|
|
62
|
+
sw: puzzleBaseSize + 8,
|
|
63
|
+
sh: puzzleBaseSize + 25
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
31
67
|
* object-fit: cover mapping of an image onto a canvas.
|
|
32
68
|
* Returns [x, y, width, height] for drawImage.
|
|
33
69
|
*/
|
|
@@ -160,7 +196,8 @@ function drawPuzzleFrame(canvases, img, opts) {
|
|
|
160
196
|
ctx.shadowBlur = Math.min(Math.ceil(8 * puzzleScale), 12);
|
|
161
197
|
ctx.fillStyle = "#ffffaa";
|
|
162
198
|
ctx.fill();
|
|
163
|
-
const
|
|
199
|
+
const { sx, sy, sw, sh } = computePuzzleCropRect(pinX, pinY, puzzleBaseSize);
|
|
200
|
+
const imgData = ctx.getImageData(sx, sy, sw, sh);
|
|
164
201
|
ctx2.putImageData(imgData, 0, pinY - 20);
|
|
165
202
|
ctx.restore();
|
|
166
203
|
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
@@ -193,8 +230,12 @@ const RESET_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAA
|
|
|
193
230
|
//#endregion
|
|
194
231
|
exports.RESET_ICON = RESET_ICON;
|
|
195
232
|
exports.clamp = clamp;
|
|
233
|
+
exports.computeDragDeviation = computeDragDeviation;
|
|
196
234
|
exports.computePuzzleBaseSize = computePuzzleBaseSize;
|
|
235
|
+
exports.computePuzzleCropRect = computePuzzleCropRect;
|
|
236
|
+
exports.computePuzzleTranslateX = computePuzzleTranslateX;
|
|
197
237
|
exports.computeSliderBaseSize = computeSliderBaseSize;
|
|
238
|
+
exports.computeTrackTravel = computeTrackTravel;
|
|
198
239
|
exports.coverSize = coverSize;
|
|
199
240
|
exports.drawPuzzleFrame = drawPuzzleFrame;
|
|
200
241
|
exports.generateRandomImage = generateRandomImage;
|
package/dist/index.d.cts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Pure, framework-agnostic utilities: math + canvas drawing for the
|
|
5
5
|
* sliding-puzzle captcha. No Vue imports here — safe to bundle anywhere.
|
|
6
6
|
*/
|
|
7
|
-
/** Random integer in [min, max]. */
|
|
7
|
+
/** Random integer in [min, max] (inclusive). */
|
|
8
8
|
declare function randomInt(min: number, max: number): number;
|
|
9
9
|
/** Clamp `v` into [min, max]. */
|
|
10
10
|
declare function clamp(v: number, min: number, max: number): number;
|
|
@@ -18,6 +18,31 @@ declare function computePuzzleBaseSize(puzzleScale: number): number;
|
|
|
18
18
|
* Faithful port of the original `sliderBaseSize` computed.
|
|
19
19
|
*/
|
|
20
20
|
declare function computeSliderBaseSize(sliderSize: number, canvasWidth: number): number;
|
|
21
|
+
/**
|
|
22
|
+
* Usable track length (canvasWidth - sliderBaseSize), floored at 1 so the
|
|
23
|
+
* drag-compensation term never divides by zero.
|
|
24
|
+
*/
|
|
25
|
+
declare function computeTrackTravel(canvasWidth: number, sliderBaseSize: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Horizontal offset of the floating puzzle piece, kept in sync with the
|
|
28
|
+
* slider. Compensates for puzzle-vs-slider width mismatch across the track.
|
|
29
|
+
*/
|
|
30
|
+
declare function computePuzzleTranslateX(styleWidth: number, sliderBaseSize: number, puzzleBaseSize: number, trackTravel: number): number;
|
|
31
|
+
/**
|
|
32
|
+
* Absolute pixel deviation used for pass/fail. The trailing `-3` undoes the
|
|
33
|
+
* shadow crop offset applied when the piece was copied off the main canvas.
|
|
34
|
+
*/
|
|
35
|
+
declare function computeDragDeviation(pinX: number, styleWidth: number, sliderBaseSize: number, puzzleBaseSize: number, trackTravel: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Source rectangle used to copy the puzzle piece (and its drop shadow) off
|
|
38
|
+
* the main canvas. `sw`/`sh` are WIDTH/HEIGHT for `getImageData`.
|
|
39
|
+
*/
|
|
40
|
+
declare function computePuzzleCropRect(pinX: number, pinY: number, puzzleBaseSize: number): {
|
|
41
|
+
sx: number;
|
|
42
|
+
sy: number;
|
|
43
|
+
sw: number;
|
|
44
|
+
sh: number;
|
|
45
|
+
};
|
|
21
46
|
/**
|
|
22
47
|
* object-fit: cover mapping of an image onto a canvas.
|
|
23
48
|
* Returns [x, y, width, height] for drawImage.
|
|
@@ -64,4 +89,4 @@ declare function drawPuzzleFrame(canvases: PuzzleCanvases, img: HTMLImageElement
|
|
|
64
89
|
*/
|
|
65
90
|
declare const RESET_ICON: string;
|
|
66
91
|
//#endregion
|
|
67
|
-
export { DrawPuzzleFrameOptions, PuzzleCanvases, RESET_ICON, clamp, computePuzzleBaseSize, computeSliderBaseSize, coverSize, drawPuzzleFrame, generateRandomImage, loadImage, randomInt, tracePuzzlePath };
|
|
92
|
+
export { DrawPuzzleFrameOptions, PuzzleCanvases, RESET_ICON, clamp, computeDragDeviation, computePuzzleBaseSize, computePuzzleCropRect, computePuzzleTranslateX, computeSliderBaseSize, computeTrackTravel, coverSize, drawPuzzleFrame, generateRandomImage, loadImage, randomInt, tracePuzzlePath };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Pure, framework-agnostic utilities: math + canvas drawing for the
|
|
5
5
|
* sliding-puzzle captcha. No Vue imports here — safe to bundle anywhere.
|
|
6
6
|
*/
|
|
7
|
-
/** Random integer in [min, max]. */
|
|
7
|
+
/** Random integer in [min, max] (inclusive). */
|
|
8
8
|
declare function randomInt(min: number, max: number): number;
|
|
9
9
|
/** Clamp `v` into [min, max]. */
|
|
10
10
|
declare function clamp(v: number, min: number, max: number): number;
|
|
@@ -18,6 +18,31 @@ declare function computePuzzleBaseSize(puzzleScale: number): number;
|
|
|
18
18
|
* Faithful port of the original `sliderBaseSize` computed.
|
|
19
19
|
*/
|
|
20
20
|
declare function computeSliderBaseSize(sliderSize: number, canvasWidth: number): number;
|
|
21
|
+
/**
|
|
22
|
+
* Usable track length (canvasWidth - sliderBaseSize), floored at 1 so the
|
|
23
|
+
* drag-compensation term never divides by zero.
|
|
24
|
+
*/
|
|
25
|
+
declare function computeTrackTravel(canvasWidth: number, sliderBaseSize: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Horizontal offset of the floating puzzle piece, kept in sync with the
|
|
28
|
+
* slider. Compensates for puzzle-vs-slider width mismatch across the track.
|
|
29
|
+
*/
|
|
30
|
+
declare function computePuzzleTranslateX(styleWidth: number, sliderBaseSize: number, puzzleBaseSize: number, trackTravel: number): number;
|
|
31
|
+
/**
|
|
32
|
+
* Absolute pixel deviation used for pass/fail. The trailing `-3` undoes the
|
|
33
|
+
* shadow crop offset applied when the piece was copied off the main canvas.
|
|
34
|
+
*/
|
|
35
|
+
declare function computeDragDeviation(pinX: number, styleWidth: number, sliderBaseSize: number, puzzleBaseSize: number, trackTravel: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Source rectangle used to copy the puzzle piece (and its drop shadow) off
|
|
38
|
+
* the main canvas. `sw`/`sh` are WIDTH/HEIGHT for `getImageData`.
|
|
39
|
+
*/
|
|
40
|
+
declare function computePuzzleCropRect(pinX: number, pinY: number, puzzleBaseSize: number): {
|
|
41
|
+
sx: number;
|
|
42
|
+
sy: number;
|
|
43
|
+
sw: number;
|
|
44
|
+
sh: number;
|
|
45
|
+
};
|
|
21
46
|
/**
|
|
22
47
|
* object-fit: cover mapping of an image onto a canvas.
|
|
23
48
|
* Returns [x, y, width, height] for drawImage.
|
|
@@ -64,4 +89,4 @@ declare function drawPuzzleFrame(canvases: PuzzleCanvases, img: HTMLImageElement
|
|
|
64
89
|
*/
|
|
65
90
|
declare const RESET_ICON: string;
|
|
66
91
|
//#endregion
|
|
67
|
-
export { DrawPuzzleFrameOptions, PuzzleCanvases, RESET_ICON, clamp, computePuzzleBaseSize, computeSliderBaseSize, coverSize, drawPuzzleFrame, generateRandomImage, loadImage, randomInt, tracePuzzlePath };
|
|
92
|
+
export { DrawPuzzleFrameOptions, PuzzleCanvases, RESET_ICON, clamp, computeDragDeviation, computePuzzleBaseSize, computePuzzleCropRect, computePuzzleTranslateX, computeSliderBaseSize, computeTrackTravel, coverSize, drawPuzzleFrame, generateRandomImage, loadImage, randomInt, tracePuzzlePath };
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* Pure, framework-agnostic utilities: math + canvas drawing for the
|
|
5
5
|
* sliding-puzzle captcha. No Vue imports here — safe to bundle anywhere.
|
|
6
6
|
*/
|
|
7
|
-
/** Random integer in [min, max]. */
|
|
7
|
+
/** Random integer in [min, max] (inclusive). */
|
|
8
8
|
function randomInt(min, max) {
|
|
9
|
-
|
|
9
|
+
if (max < min) return min;
|
|
10
|
+
return min + Math.floor(Math.random() * (max - min + 1));
|
|
10
11
|
}
|
|
11
12
|
/** Clamp `v` into [min, max]. */
|
|
12
13
|
function clamp(v, min, max) {
|
|
@@ -27,6 +28,41 @@ function computeSliderBaseSize(sliderSize, canvasWidth) {
|
|
|
27
28
|
return Math.max(Math.min(Math.round(sliderSize), Math.round(canvasWidth * .5)), 10);
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
31
|
+
* Usable track length (canvasWidth - sliderBaseSize), floored at 1 so the
|
|
32
|
+
* drag-compensation term never divides by zero.
|
|
33
|
+
*/
|
|
34
|
+
function computeTrackTravel(canvasWidth, sliderBaseSize) {
|
|
35
|
+
return Math.max(1, canvasWidth - sliderBaseSize);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Horizontal offset of the floating puzzle piece, kept in sync with the
|
|
39
|
+
* slider. Compensates for puzzle-vs-slider width mismatch across the track.
|
|
40
|
+
*/
|
|
41
|
+
function computePuzzleTranslateX(styleWidth, sliderBaseSize, puzzleBaseSize, trackTravel) {
|
|
42
|
+
const dragged = styleWidth - sliderBaseSize;
|
|
43
|
+
return dragged - (puzzleBaseSize - sliderBaseSize) * (dragged / trackTravel);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Absolute pixel deviation used for pass/fail. The trailing `-3` undoes the
|
|
47
|
+
* shadow crop offset applied when the piece was copied off the main canvas.
|
|
48
|
+
*/
|
|
49
|
+
function computeDragDeviation(pinX, styleWidth, sliderBaseSize, puzzleBaseSize, trackTravel) {
|
|
50
|
+
const dragged = styleWidth - sliderBaseSize;
|
|
51
|
+
return Math.abs(pinX - dragged + (puzzleBaseSize - sliderBaseSize) * (dragged / trackTravel) - 3);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Source rectangle used to copy the puzzle piece (and its drop shadow) off
|
|
55
|
+
* the main canvas. `sw`/`sh` are WIDTH/HEIGHT for `getImageData`.
|
|
56
|
+
*/
|
|
57
|
+
function computePuzzleCropRect(pinX, pinY, puzzleBaseSize) {
|
|
58
|
+
return {
|
|
59
|
+
sx: pinX - 3,
|
|
60
|
+
sy: pinY - 20,
|
|
61
|
+
sw: puzzleBaseSize + 8,
|
|
62
|
+
sh: puzzleBaseSize + 25
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
30
66
|
* object-fit: cover mapping of an image onto a canvas.
|
|
31
67
|
* Returns [x, y, width, height] for drawImage.
|
|
32
68
|
*/
|
|
@@ -159,7 +195,8 @@ function drawPuzzleFrame(canvases, img, opts) {
|
|
|
159
195
|
ctx.shadowBlur = Math.min(Math.ceil(8 * puzzleScale), 12);
|
|
160
196
|
ctx.fillStyle = "#ffffaa";
|
|
161
197
|
ctx.fill();
|
|
162
|
-
const
|
|
198
|
+
const { sx, sy, sw, sh } = computePuzzleCropRect(pinX, pinY, puzzleBaseSize);
|
|
199
|
+
const imgData = ctx.getImageData(sx, sy, sw, sh);
|
|
163
200
|
ctx2.putImageData(imgData, 0, pinY - 20);
|
|
164
201
|
ctx.restore();
|
|
165
202
|
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
@@ -190,4 +227,4 @@ function drawPuzzleFrame(canvases, img, opts) {
|
|
|
190
227
|
*/
|
|
191
228
|
const RESET_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAELklEQVRYR+2YW2wUZRTH//9vtlCo\nF9IoIklT3PqgPGi326hoetuaGEhIr9SgCYkkgt2WGOQVCca+GavWdr0GjD4YhG3RB3hply1LQA1t\nEQIxEXapGI2pEkys9LIzx2ylYWfY6e5sF0oi+7hzzvl+3/9855xvhrjNf7zN+XAHcL4Z+n8o6JWT\neYt++W25S596AIZy6TB+n3yo+Nchlk8vmIIVowdXU9c3Q1gDSilBlQwjgBAYFGDvdF58/4milqvZ\nwDpOcXWsb5Uh8hmBqkwXFMhlCN8aX5LXNbRy/T+Z+iXsHAFWRXs3QGQPyLucLDJrK5DgUXdTsxPf\njAEro8E3Ce50EtxsKxPTwCPH3U2jTmJkBJgWTnAMxDeGMEoa0xQ+LJQnCD4HYFkCyAC3RdwN3U7g\nMkpxRTTYrMD91sCJIgCxV5R6O1Jcfy7VwonqLoj9/CqB2kF341qncGkBvRe+ureAWpRgoalCBecM\nFzcdK24YymZRJz5zprgq1tsJwXYL3CVZGvdGHmwZc7JQtra2gE+f712ep2QUYP714DJhaJrXLqXZ\nQszlZwtYdSHoB9ljVk/ePVrSZFL0ZkAlxzQBVseCT8WhZhRThtFB8plk9Zi/qCi8cv0fNxvKFrDy\n4oF11NXXIFy2EII4iBcG3Y03VLZT8OqRd5aFPduvOEpxRayvXolxAKB2g6NgEhobBlc1HHYKY7Wv\nHf5wtVAPgegIlbbZ9seUZ7AyFnwewi9pGoUyDmhrB931kfnC1ZwOeKlLP8GZJi6QLSFP2yep4toX\nSbT3ZQAfX3O6omt8Nhd9r/aHQAUMOQywYBZo5uZD2ThQ2rbPCjlnH6yI9rUryE5DU75ctJaake46\nBe4DuDjF8dFBNA94/AdtiySVxIlpMlTS8td801o70vMigM9huTda2lhcKHVHPO2HZv/P6LIwX7hk\n/+qzPSvUJGMkrg8AQYTkroRdXMlE+HH/twsG6BsOdJHYZlaO/lBZ6weOiiSXqs3Gqj0TeAxx+T75\nDIpgwjC0onD51pQD4JaluPrkR/cpFT9DcoVp84LOgTL/DjtBbglgou+puHwB8lEznPxJw1XSX77V\ntgizBvQNBw4RMqB7xt4Lc3c8lQKJaQHoO4R8ydz0/7MWoCXk8c85MrMC9J3qaafw/WtQlwXST+F3\nBnAeYB4obgJ1BJIuG+YtiKAjVOZ/Pd1ZdwzoG+4uBtSPpjaRbhXLcwF3hzytb2TilgVgT5BkYybB\nrTYC+Rvg5nRpdTRJrIs8+VPXPQXj2i4ItxC4O2NQQUQnN4U9rRcz9nH64p4ceM2lziX5Y4s3KHCd\nUHwE77ecMkMEp6BwhIa2Z6DslZRvfulgHafYLuCas58WLp2aLCFUga70qxOFU6dPFL2W1feYeaU4\n3Y5z/TxnCuYabMEuC043ckdBp4pZ7f8FE5psOI1g6fwAAAAASUVORK5CYII=";
|
|
192
229
|
//#endregion
|
|
193
|
-
export { RESET_ICON, clamp, computePuzzleBaseSize, computeSliderBaseSize, coverSize, drawPuzzleFrame, generateRandomImage, loadImage, randomInt, tracePuzzlePath };
|
|
230
|
+
export { RESET_ICON, clamp, computeDragDeviation, computePuzzleBaseSize, computePuzzleCropRect, computePuzzleTranslateX, computeSliderBaseSize, computeTrackTravel, coverSize, drawPuzzleFrame, generateRandomImage, loadImage, randomInt, tracePuzzlePath };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue-puzzle-vcode/shared",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Shared pure utilities for vue-puzzle-vcode (canvas drawing, math)",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/
|
|
8
|
+
"url": "git+https://github.com/daguanren21/vue-puzzle-vcode.git",
|
|
9
9
|
"directory": "packages/shared"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"sideEffects": false,
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"tsdown": "0.22.14",
|
|
33
|
-
"typescript": "7.0.2"
|
|
33
|
+
"typescript": "7.0.2",
|
|
34
|
+
"vitest": "4.1.10"
|
|
34
35
|
},
|
|
35
36
|
"publishConfig": {
|
|
36
37
|
"access": "public"
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
"scripts": {
|
|
39
40
|
"build": "tsdown",
|
|
40
41
|
"dev": "tsdown --watch",
|
|
41
|
-
"typecheck": "tsc --noEmit"
|
|
42
|
+
"typecheck": "tsc --noEmit",
|
|
43
|
+
"test": "vitest run --root ../.. packages/shared/test"
|
|
42
44
|
}
|
|
43
45
|
}
|