@lambdatest/smartui-cli 4.0.8 → 4.0.10
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 +68 -0
- package/dist/index.cjs +127 -18
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# SmartUI-CLI
|
|
2
|
+
|
|
3
|
+
<img height="400" src="https://user-images.githubusercontent.com/126776938/232535511-8d51cf1b-1a33-48fc-825c-b13e7a9ec388.png">
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.lambdatest.com/blog/?utm_source=github&utm_medium=repo&utm_campaign=playwright-sample" target="_bank">Blog</a>
|
|
7
|
+
⋅
|
|
8
|
+
<a href="https://www.lambdatest.com/support/docs/?utm_source=github&utm_medium=repo&utm_campaign=playwright-sample" target="_bank">Docs</a>
|
|
9
|
+
⋅
|
|
10
|
+
<a href="https://www.lambdatest.com/learning-hub/?utm_source=github&utm_medium=repo&utm_campaign=playwright-sample" target="_bank">Learning Hub</a>
|
|
11
|
+
⋅
|
|
12
|
+
<a href="https://www.lambdatest.com/newsletter/?utm_source=github&utm_medium=repo&utm_campaign=playwright-sample" target="_bank">Newsletter</a>
|
|
13
|
+
⋅
|
|
14
|
+
<a href="https://www.lambdatest.com/certifications/?utm_source=github&utm_medium=repo&utm_campaign=playwright-sample" target="_bank">Certifications</a>
|
|
15
|
+
⋅
|
|
16
|
+
<a href="https://www.youtube.com/c/LambdaTest" target="_bank">YouTube</a>
|
|
17
|
+
</p>
|
|
18
|
+
 
|
|
19
|
+
 
|
|
20
|
+
 
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
[<img height="58" width="200" src="https://user-images.githubusercontent.com/70570645/171866795-52c11b49-0728-4229-b073-4b704209ddde.png">](https://accounts.lambdatest.com/register?utm_source=github&utm_medium=repo&utm_campaign=playwright-sample)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
The **SmartUI-CLI** allows you to capture visual snapshots of your web applications, upload images, and run visual regression tests using [LambdaTest's SmartUI](https://www.lambdatest.com/visual-regression-testing) platform directly from the command line.
|
|
28
|
+
|
|
29
|
+
- [Installation](#installation)
|
|
30
|
+
- [Commands](#commands)
|
|
31
|
+
- [Documentation](#documentation)
|
|
32
|
+
- [Issues](#issues)
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```sh-session
|
|
37
|
+
$ npm install smartui-cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Note:**
|
|
41
|
+
If you face any problems executing tests with SmartUI-CLI `versions >= v4.x.x`, upgrade your Node.js version to `v20.3` or above.
|
|
42
|
+
|
|
43
|
+
## Commands
|
|
44
|
+
- `npx smartui exec` - Capture DOM assets for visual testing across multiple browsers and resolutions.
|
|
45
|
+
- `npx smartui capture` - Bulk capture static URLs for visual testing.
|
|
46
|
+
- `npx smartui upload` - Upload custom images or screenshots for visual comparison.
|
|
47
|
+
- `npx smartui upload-figma` - Upload Figma design images for visual comparison.
|
|
48
|
+
- `npx smartui config` - Creates configuration file according to the usecase.
|
|
49
|
+
|
|
50
|
+
### Documentation
|
|
51
|
+
|
|
52
|
+
In addition to its core functionalities, the SmartUI CLI leverages LambdaTest's cloud infrastructure for robust, scalable visual regression testing across various browsers and devices.
|
|
53
|
+
|
|
54
|
+
- [SmartUI Selenium SDK](https://www.lambdatest.com/support/docs/smartui-selenium-java-sdk) - A complete SDK to capture DOM assets for visual tests.
|
|
55
|
+
- [LambdaTest Documentation](https://www.lambdatest.com/support/docs/) - Official LambdaTest documentation for SmartUI and other integrations.
|
|
56
|
+
- [Bulk capturing static URLs with SmartUI](https://www.lambdatest.com/support/docs/smartui-cli/) - Documentation for capturing satatic urls in bulk with SmartUI
|
|
57
|
+
- [Bring your own screenshots](https://www.lambdatest.com/support/docs/smartui-cli-upload/) - Documentation for capturing satatic urls in bulk
|
|
58
|
+
- [Figma CLI](https://www.lambdatest.com/support/docs/smartui-cli-figma/) - Documentation for uploading figma components to SmartUI
|
|
59
|
+
|
|
60
|
+
### Issues
|
|
61
|
+
|
|
62
|
+
If you encounter problems with SmartUI-CLI, [add an issue on GitHub](https://github.com/LambdaTest/smartui-cli/issues/new).
|
|
63
|
+
|
|
64
|
+
For other support issues, reach out via [LambdaTest Support](https://www.lambdatest.com/support).
|
|
65
|
+
|
|
66
|
+
------
|
|
67
|
+
|
|
68
|
+
[Know more](https://www.lambdatest.com/visual-regression-testing) about SmartUI and it's AI enabled comparison engines.
|
package/dist/index.cjs
CHANGED
|
@@ -199,6 +199,8 @@ var constants_default = {
|
|
|
199
199
|
FILE_EXTENSION_GIFS: "gif",
|
|
200
200
|
// Default scrollTime
|
|
201
201
|
DEFAULT_SCROLL_TIME: 8,
|
|
202
|
+
// Default page load time
|
|
203
|
+
DEFAULT_PAGE_LOAD_TIMEOUT: 18e4,
|
|
202
204
|
// Magic Numbers
|
|
203
205
|
MAGIC_NUMBERS: [
|
|
204
206
|
{ ext: "jpg", magic: Buffer.from([255, 216, 255]) },
|
|
@@ -851,6 +853,8 @@ var env_default = () => {
|
|
|
851
853
|
SMARTUI_DO_NOT_USE_CAPTURED_COOKIES,
|
|
852
854
|
HTTP_PROXY,
|
|
853
855
|
HTTPS_PROXY,
|
|
856
|
+
SMARTUI_HTTP_PROXY,
|
|
857
|
+
SMARTUI_HTTPS_PROXY,
|
|
854
858
|
GITHUB_ACTIONS,
|
|
855
859
|
FIGMA_TOKEN,
|
|
856
860
|
LT_USERNAME,
|
|
@@ -865,6 +869,8 @@ var env_default = () => {
|
|
|
865
869
|
SMARTUI_GIT_INFO_FILEPATH,
|
|
866
870
|
HTTP_PROXY,
|
|
867
871
|
HTTPS_PROXY,
|
|
872
|
+
SMARTUI_HTTP_PROXY,
|
|
873
|
+
SMARTUI_HTTPS_PROXY,
|
|
868
874
|
GITHUB_ACTIONS,
|
|
869
875
|
FIGMA_TOKEN,
|
|
870
876
|
LT_USERNAME,
|
|
@@ -949,7 +955,7 @@ var auth_default = (ctx) => {
|
|
|
949
955
|
};
|
|
950
956
|
|
|
951
957
|
// package.json
|
|
952
|
-
var version = "4.0.
|
|
958
|
+
var version = "4.0.10";
|
|
953
959
|
var package_default = {
|
|
954
960
|
name: "@lambdatest/smartui-cli",
|
|
955
961
|
version,
|
|
@@ -959,7 +965,8 @@ var package_default = {
|
|
|
959
965
|
],
|
|
960
966
|
scripts: {
|
|
961
967
|
build: "tsup",
|
|
962
|
-
release: "pnpm run build && pnpm publish --access public --no-git-checks"
|
|
968
|
+
release: "pnpm run build && pnpm publish --access public --no-git-checks",
|
|
969
|
+
"local-build": "pnpm run build && pnpm pack"
|
|
963
970
|
},
|
|
964
971
|
bin: {
|
|
965
972
|
smartui: "./dist/index.cjs"
|
|
@@ -1100,13 +1107,13 @@ var httpClient = class {
|
|
|
1100
1107
|
}).then(() => {
|
|
1101
1108
|
log2.debug(`${ssName} for ${browserName} ${viewport} uploaded successfully`);
|
|
1102
1109
|
}).catch((error) => {
|
|
1103
|
-
|
|
1110
|
+
log2.error(`Unable to upload screenshot ${JSON.stringify(error)}`);
|
|
1111
|
+
if (error && error.response && error.response.data && error.response.data.error) {
|
|
1104
1112
|
throw new Error(error.response.data.error.message);
|
|
1105
1113
|
}
|
|
1106
|
-
if (error
|
|
1107
|
-
throw new Error(
|
|
1114
|
+
if (error) {
|
|
1115
|
+
throw new Error(JSON.stringify(error));
|
|
1108
1116
|
}
|
|
1109
|
-
throw new Error(error.message);
|
|
1110
1117
|
});
|
|
1111
1118
|
}
|
|
1112
1119
|
checkUpdate(log2) {
|
|
@@ -1179,6 +1186,7 @@ var ctx_default = (options) => {
|
|
|
1179
1186
|
let extensionFiles;
|
|
1180
1187
|
let ignoreStripExtension;
|
|
1181
1188
|
let ignoreFilePattern;
|
|
1189
|
+
let parallelObj;
|
|
1182
1190
|
let fetchResultObj;
|
|
1183
1191
|
let fetchResultsFileObj;
|
|
1184
1192
|
try {
|
|
@@ -1200,6 +1208,7 @@ var ctx_default = (options) => {
|
|
|
1200
1208
|
extensionFiles = options.files || ["png", "jpeg", "jpg"];
|
|
1201
1209
|
ignoreStripExtension = options.removeExtensions || false;
|
|
1202
1210
|
ignoreFilePattern = options.ignoreDir || [];
|
|
1211
|
+
parallelObj = options.parallel ? options.parallel === true ? 1 : options.parallel : 1;
|
|
1203
1212
|
if (options.fetchResults) {
|
|
1204
1213
|
if (options.fetchResults !== true && !options.fetchResults.endsWith(".json")) {
|
|
1205
1214
|
console.error("Error: The file extension for --fetch-results must be .json");
|
|
@@ -1264,7 +1273,8 @@ var ctx_default = (options) => {
|
|
|
1264
1273
|
},
|
|
1265
1274
|
args: {},
|
|
1266
1275
|
options: {
|
|
1267
|
-
parallel:
|
|
1276
|
+
parallel: parallelObj,
|
|
1277
|
+
force: options.force ? true : false,
|
|
1268
1278
|
markBaseline: options.markBaseline ? true : false,
|
|
1269
1279
|
buildName: options.buildName || "",
|
|
1270
1280
|
port,
|
|
@@ -1409,8 +1419,10 @@ function scrollToBottomAndBackToTop({
|
|
|
1409
1419
|
}
|
|
1410
1420
|
function launchBrowsers(ctx) {
|
|
1411
1421
|
return __async(this, null, function* () {
|
|
1422
|
+
var _a;
|
|
1412
1423
|
let browsers = {};
|
|
1413
|
-
|
|
1424
|
+
const isHeadless = ((_a = process.env.HEADLESS) == null ? void 0 : _a.toLowerCase()) === "false" ? false : true;
|
|
1425
|
+
let launchOptions = { headless: isHeadless };
|
|
1414
1426
|
if (ctx.config.web) {
|
|
1415
1427
|
for (const browser of ctx.config.web.browsers) {
|
|
1416
1428
|
switch (browser) {
|
|
@@ -1748,20 +1760,23 @@ var REQUEST_TIMEOUT = 1e4;
|
|
|
1748
1760
|
var MIN_VIEWPORT_HEIGHT = 1080;
|
|
1749
1761
|
function processSnapshot(snapshot, ctx) {
|
|
1750
1762
|
return __async(this, null, function* () {
|
|
1751
|
-
var _a;
|
|
1763
|
+
var _a, _b;
|
|
1752
1764
|
updateLogContext({ task: "discovery" });
|
|
1753
1765
|
ctx.log.debug(`Processing snapshot ${snapshot.name} ${snapshot.url}`);
|
|
1766
|
+
const isHeadless = ((_a = process.env.HEADLESS) == null ? void 0 : _a.toLowerCase()) === "false" ? false : true;
|
|
1754
1767
|
let launchOptions = {
|
|
1755
|
-
headless:
|
|
1768
|
+
headless: isHeadless,
|
|
1756
1769
|
args: constants_default.LAUNCH_ARGS
|
|
1757
1770
|
};
|
|
1758
1771
|
let contextOptions = {
|
|
1759
1772
|
javaScriptEnabled: ctx.config.cliEnableJavaScript,
|
|
1760
1773
|
userAgent: constants_default.CHROME_USER_AGENT
|
|
1761
1774
|
};
|
|
1762
|
-
if (!((
|
|
1775
|
+
if (!((_b = ctx.browser) == null ? void 0 : _b.isConnected())) {
|
|
1763
1776
|
if (ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY)
|
|
1764
1777
|
launchOptions.proxy = { server: ctx.env.HTTP_PROXY || ctx.env.HTTPS_PROXY };
|
|
1778
|
+
if (ctx.env.SMARTUI_HTTP_PROXY || ctx.env.SMARTUI_HTTPS_PROXY)
|
|
1779
|
+
launchOptions.proxy = { server: ctx.env.SMARTUI_HTTP_PROXY || ctx.env.SMARTUI_HTTPS_PROXY };
|
|
1765
1780
|
ctx.browser = yield test.chromium.launch(launchOptions);
|
|
1766
1781
|
ctx.log.debug(`Chromium launched with options ${JSON.stringify(launchOptions)}`);
|
|
1767
1782
|
}
|
|
@@ -2426,7 +2441,7 @@ configFigma.name("config:create-figma").description("Create figma designs config
|
|
|
2426
2441
|
});
|
|
2427
2442
|
function captureScreenshotsForConfig(_0, _1, _2, _3, _4) {
|
|
2428
2443
|
return __async(this, arguments, function* (ctx, browsers, { name, url, waitForTimeout }, browserName, renderViewports) {
|
|
2429
|
-
let pageOptions = { waitUntil: process.env.SMARTUI_PAGE_WAIT_UNTIL_EVENT || "load" };
|
|
2444
|
+
let pageOptions = { waitUntil: process.env.SMARTUI_PAGE_WAIT_UNTIL_EVENT || "load", timeout: ctx.config.waitForPageRender || constants_default.DEFAULT_PAGE_LOAD_TIMEOUT };
|
|
2430
2445
|
let ssId = name.toLowerCase().replace(/\s/g, "_");
|
|
2431
2446
|
let context;
|
|
2432
2447
|
let contextOptions = {};
|
|
@@ -2639,6 +2654,88 @@ function uploadScreenshots(ctx) {
|
|
|
2639
2654
|
}
|
|
2640
2655
|
});
|
|
2641
2656
|
}
|
|
2657
|
+
function captureScreenshotsConcurrent(ctx) {
|
|
2658
|
+
return __async(this, null, function* () {
|
|
2659
|
+
delDir("screenshots");
|
|
2660
|
+
let totalSnapshots = ctx.webStaticConfig && ctx.webStaticConfig.length;
|
|
2661
|
+
let browserInstances = ctx.options.parallel || 1;
|
|
2662
|
+
let optimizeBrowserInstances = 0;
|
|
2663
|
+
optimizeBrowserInstances = Math.floor(Math.log2(totalSnapshots));
|
|
2664
|
+
if (optimizeBrowserInstances < 1) {
|
|
2665
|
+
optimizeBrowserInstances = 1;
|
|
2666
|
+
}
|
|
2667
|
+
if (optimizeBrowserInstances > browserInstances) {
|
|
2668
|
+
optimizeBrowserInstances = browserInstances;
|
|
2669
|
+
}
|
|
2670
|
+
if (ctx.options.force && browserInstances > 1) {
|
|
2671
|
+
optimizeBrowserInstances = browserInstances;
|
|
2672
|
+
}
|
|
2673
|
+
let urlsPerInstance = 0;
|
|
2674
|
+
if (optimizeBrowserInstances == 1) {
|
|
2675
|
+
urlsPerInstance = totalSnapshots;
|
|
2676
|
+
} else {
|
|
2677
|
+
urlsPerInstance = Math.ceil(totalSnapshots / optimizeBrowserInstances);
|
|
2678
|
+
}
|
|
2679
|
+
ctx.log.debug(`*** browserInstances requested ${ctx.options.parallel} `);
|
|
2680
|
+
ctx.log.debug(`*** optimizeBrowserInstances ${optimizeBrowserInstances} `);
|
|
2681
|
+
ctx.log.debug(`*** urlsPerInstance ${urlsPerInstance}`);
|
|
2682
|
+
ctx.task.output = `URLs : ${totalSnapshots} || Parallel Browser Instances: ${optimizeBrowserInstances}
|
|
2683
|
+
`;
|
|
2684
|
+
let staticURLChunks = splitURLs(ctx.webStaticConfig, urlsPerInstance);
|
|
2685
|
+
let totalCapturedScreenshots = 0;
|
|
2686
|
+
let output = "";
|
|
2687
|
+
const responses = yield Promise.all(staticURLChunks.map((urlConfig) => __async(this, null, function* () {
|
|
2688
|
+
let { capturedScreenshots, finalOutput } = yield processChunk(ctx, urlConfig);
|
|
2689
|
+
return { capturedScreenshots, finalOutput };
|
|
2690
|
+
})));
|
|
2691
|
+
responses.forEach((response) => {
|
|
2692
|
+
totalCapturedScreenshots += response.capturedScreenshots;
|
|
2693
|
+
output += response.finalOutput;
|
|
2694
|
+
});
|
|
2695
|
+
delDir("screenshots");
|
|
2696
|
+
return { totalCapturedScreenshots, output };
|
|
2697
|
+
});
|
|
2698
|
+
}
|
|
2699
|
+
function splitURLs(arr, chunkSize) {
|
|
2700
|
+
const result = [];
|
|
2701
|
+
for (let i = 0; i < arr.length; i += chunkSize) {
|
|
2702
|
+
result.push(arr.slice(i, i + chunkSize));
|
|
2703
|
+
}
|
|
2704
|
+
return result;
|
|
2705
|
+
}
|
|
2706
|
+
function processChunk(ctx, urlConfig) {
|
|
2707
|
+
return __async(this, null, function* () {
|
|
2708
|
+
let browsers = {};
|
|
2709
|
+
let capturedScreenshots = 0;
|
|
2710
|
+
let finalOutput = "";
|
|
2711
|
+
try {
|
|
2712
|
+
browsers = yield launchBrowsers(ctx);
|
|
2713
|
+
} catch (error) {
|
|
2714
|
+
yield closeBrowsers(browsers);
|
|
2715
|
+
ctx.log.debug(error);
|
|
2716
|
+
throw new Error(`Failed launching browsers ${error}`);
|
|
2717
|
+
}
|
|
2718
|
+
for (let staticConfig of urlConfig) {
|
|
2719
|
+
try {
|
|
2720
|
+
yield captureScreenshotsAsync(ctx, staticConfig, browsers);
|
|
2721
|
+
delDir(`screenshots/${staticConfig.name.toLowerCase().replace(/\s/g, "_")}`);
|
|
2722
|
+
let output = `${chalk6__default.default.gray(staticConfig.name)} ${chalk6__default.default.green("\u2713")}
|
|
2723
|
+
`;
|
|
2724
|
+
ctx.task.output = ctx.task.output ? ctx.task.output + output : output;
|
|
2725
|
+
finalOutput += output;
|
|
2726
|
+
capturedScreenshots++;
|
|
2727
|
+
} catch (error) {
|
|
2728
|
+
ctx.log.debug(`screenshot capture failed for ${JSON.stringify(staticConfig)}; error: ${error}`);
|
|
2729
|
+
let output = `${chalk6__default.default.gray(staticConfig.name)} ${chalk6__default.default.red("\u2717")}
|
|
2730
|
+
`;
|
|
2731
|
+
ctx.task.output += output;
|
|
2732
|
+
finalOutput += output;
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
yield closeBrowsers(browsers);
|
|
2736
|
+
return { capturedScreenshots, finalOutput };
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2642
2739
|
var captureScreenshots_default = (ctx) => {
|
|
2643
2740
|
return {
|
|
2644
2741
|
title: "Capturing screenshots",
|
|
@@ -2649,9 +2746,16 @@ var captureScreenshots_default = (ctx) => {
|
|
|
2649
2746
|
startPolling(ctx2, task);
|
|
2650
2747
|
}
|
|
2651
2748
|
updateLogContext({ task: "capture" });
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2749
|
+
if (ctx2.options.parallel) {
|
|
2750
|
+
let { totalCapturedScreenshots, output } = yield captureScreenshotsConcurrent(ctx2);
|
|
2751
|
+
if (totalCapturedScreenshots != ctx2.webStaticConfig.length) {
|
|
2752
|
+
throw new Error(output);
|
|
2753
|
+
}
|
|
2754
|
+
} else {
|
|
2755
|
+
let { capturedScreenshots, output } = yield captureScreenshots(ctx2);
|
|
2756
|
+
if (capturedScreenshots != ctx2.webStaticConfig.length) {
|
|
2757
|
+
throw new Error(output);
|
|
2758
|
+
}
|
|
2655
2759
|
}
|
|
2656
2760
|
task.title = "Screenshots captured successfully";
|
|
2657
2761
|
} catch (error) {
|
|
@@ -2667,21 +2771,26 @@ var captureScreenshots_default = (ctx) => {
|
|
|
2667
2771
|
|
|
2668
2772
|
// src/commander/capture.ts
|
|
2669
2773
|
var command2 = new commander.Command();
|
|
2670
|
-
command2.name("capture").description("Capture screenshots of static sites").argument("<file>", "Web static config file").option("--parallel", "
|
|
2774
|
+
command2.name("capture").description("Capture screenshots of static sites").argument("<file>", "Web static config file").option("-C, --parallel [number]", "Specify the number of instances per browser", parseInt).option("-F, --force", "forcefully apply the specified parallel instances per browser").option("--fetch-results [filename]", "Fetch results and optionally specify an output file, e.g., <filename>.json").action(function(file, _, command5) {
|
|
2671
2775
|
return __async(this, null, function* () {
|
|
2672
2776
|
let ctx = ctx_default(command5.optsWithGlobals());
|
|
2673
2777
|
if (!fs5__default.default.existsSync(file)) {
|
|
2674
|
-
|
|
2778
|
+
ctx.log.error(`Web Static Config file ${file} not found.`);
|
|
2675
2779
|
return;
|
|
2676
2780
|
}
|
|
2677
2781
|
try {
|
|
2678
2782
|
ctx.webStaticConfig = JSON.parse(fs5__default.default.readFileSync(file, "utf8"));
|
|
2679
2783
|
if (!validateWebStaticConfig(ctx.webStaticConfig))
|
|
2680
2784
|
throw new Error(validateWebStaticConfig.errors[0].message);
|
|
2785
|
+
if (ctx.webStaticConfig && ctx.webStaticConfig.length === 0) {
|
|
2786
|
+
ctx.log.error(`No URLs found in the specified config file -> ${file}`);
|
|
2787
|
+
return;
|
|
2788
|
+
}
|
|
2681
2789
|
} catch (error) {
|
|
2682
|
-
|
|
2790
|
+
ctx.log.error(`Invalid Web Static Config; ${error.message}`);
|
|
2683
2791
|
return;
|
|
2684
2792
|
}
|
|
2793
|
+
ctx.log.debug(ctx.config);
|
|
2685
2794
|
let tasks = new listr2.Listr(
|
|
2686
2795
|
[
|
|
2687
2796
|
auth_default(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lambdatest/smartui-cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.10",
|
|
4
4
|
"description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/**/*"
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsup",
|
|
46
|
-
"release": "pnpm run build && pnpm publish --access public --no-git-checks"
|
|
46
|
+
"release": "pnpm run build && pnpm publish --access public --no-git-checks",
|
|
47
|
+
"local-build": "pnpm run build && pnpm pack"
|
|
47
48
|
}
|
|
48
49
|
}
|