@keywaysh/cli 0.1.3 → 0.1.5
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/dist/cli.js +232 -43
- package/package.json +17 -13
package/dist/cli.js
CHANGED
|
@@ -102,7 +102,7 @@ var INTERNAL_POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
|
102
102
|
// package.json
|
|
103
103
|
var package_default = {
|
|
104
104
|
name: "@keywaysh/cli",
|
|
105
|
-
version: "0.1.
|
|
105
|
+
version: "0.1.5",
|
|
106
106
|
description: "One link to all your secrets",
|
|
107
107
|
type: "module",
|
|
108
108
|
bin: {
|
|
@@ -146,6 +146,7 @@ var package_default = {
|
|
|
146
146
|
node: ">=18.0.0"
|
|
147
147
|
},
|
|
148
148
|
dependencies: {
|
|
149
|
+
"balanced-match": "^3.0.1",
|
|
149
150
|
commander: "^14.0.0",
|
|
150
151
|
conf: "^15.0.2",
|
|
151
152
|
open: "^11.0.0",
|
|
@@ -154,6 +155,7 @@ var package_default = {
|
|
|
154
155
|
prompts: "^2.4.2"
|
|
155
156
|
},
|
|
156
157
|
devDependencies: {
|
|
158
|
+
"@types/balanced-match": "^3.0.2",
|
|
157
159
|
"@types/node": "^24.2.0",
|
|
158
160
|
"@types/prompts": "^2.4.9",
|
|
159
161
|
tsup: "^8.5.0",
|
|
@@ -491,6 +493,37 @@ async function executeSync(accessToken, repoFullName, options) {
|
|
|
491
493
|
const wrapped = await handleResponse(response);
|
|
492
494
|
return wrapped.data;
|
|
493
495
|
}
|
|
496
|
+
async function connectWithToken(accessToken, provider, providerToken) {
|
|
497
|
+
const response = await fetchWithTimeout(`${API_BASE_URL}/v1/integrations/${provider}/connect`, {
|
|
498
|
+
method: "POST",
|
|
499
|
+
headers: {
|
|
500
|
+
"Content-Type": "application/json",
|
|
501
|
+
"User-Agent": USER_AGENT,
|
|
502
|
+
Authorization: `Bearer ${accessToken}`
|
|
503
|
+
},
|
|
504
|
+
body: JSON.stringify({ token: providerToken })
|
|
505
|
+
});
|
|
506
|
+
const wrapped = await handleResponse(response);
|
|
507
|
+
return wrapped.data;
|
|
508
|
+
}
|
|
509
|
+
async function checkVaultExists(accessToken, repoFullName) {
|
|
510
|
+
const [owner, repo] = repoFullName.split("/");
|
|
511
|
+
try {
|
|
512
|
+
const response = await fetchWithTimeout(
|
|
513
|
+
`${API_BASE_URL}/v1/vaults/${owner}/${repo}`,
|
|
514
|
+
{
|
|
515
|
+
method: "GET",
|
|
516
|
+
headers: {
|
|
517
|
+
"User-Agent": USER_AGENT,
|
|
518
|
+
Authorization: `Bearer ${accessToken}`
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
);
|
|
522
|
+
return response.ok;
|
|
523
|
+
} catch {
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
494
527
|
async function getVaultEnvironments(accessToken, repoFullName) {
|
|
495
528
|
const [owner, repo] = repoFullName.split("/");
|
|
496
529
|
try {
|
|
@@ -655,23 +688,76 @@ import fs3 from "fs";
|
|
|
655
688
|
import path3 from "path";
|
|
656
689
|
import prompts from "prompts";
|
|
657
690
|
import pc2 from "picocolors";
|
|
691
|
+
import balanced from "balanced-match";
|
|
658
692
|
function generateBadge(repo) {
|
|
659
693
|
return `[](https://www.keyway.sh/vaults/${repo})`;
|
|
660
694
|
}
|
|
695
|
+
var BADGE_PREFIX = /\[!\[[^\]]*\]\([^)]*\)\]\(/g;
|
|
696
|
+
var H1_PATTERN = /^#\s+/;
|
|
697
|
+
var CODE_FENCE = /^```/;
|
|
698
|
+
function findLastBadgeEnd(line) {
|
|
699
|
+
let lastEnd = -1;
|
|
700
|
+
let match;
|
|
701
|
+
BADGE_PREFIX.lastIndex = 0;
|
|
702
|
+
while ((match = BADGE_PREFIX.exec(line)) !== null) {
|
|
703
|
+
const prefixEnd = match.index + match[0].length - 1;
|
|
704
|
+
const remainder = line.substring(prefixEnd);
|
|
705
|
+
const balancedMatch = balanced("(", ")", remainder);
|
|
706
|
+
if (balancedMatch) {
|
|
707
|
+
lastEnd = prefixEnd + balancedMatch.end + 1;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
return lastEnd;
|
|
711
|
+
}
|
|
661
712
|
function insertBadgeIntoReadme(readmeContent, badge) {
|
|
662
713
|
if (readmeContent.includes("keyway.sh/badge.svg")) {
|
|
663
714
|
return readmeContent;
|
|
664
715
|
}
|
|
665
716
|
const lines = readmeContent.split(/\r?\n/);
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
717
|
+
let inCodeBlock = false;
|
|
718
|
+
let inHtmlComment = false;
|
|
719
|
+
let lastBadgeLine = -1;
|
|
720
|
+
let lastBadgeEndIndex = -1;
|
|
721
|
+
let firstH1Line = -1;
|
|
722
|
+
for (let i = 0; i < lines.length; i++) {
|
|
723
|
+
const line = lines[i];
|
|
724
|
+
const trimmed = line.trim();
|
|
725
|
+
if (CODE_FENCE.test(trimmed)) {
|
|
726
|
+
inCodeBlock = !inCodeBlock;
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
if (inCodeBlock) continue;
|
|
730
|
+
if (trimmed.includes("<!--")) inHtmlComment = true;
|
|
731
|
+
if (trimmed.includes("-->")) {
|
|
732
|
+
inHtmlComment = false;
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
if (inHtmlComment) continue;
|
|
736
|
+
BADGE_PREFIX.lastIndex = 0;
|
|
737
|
+
if (BADGE_PREFIX.test(line)) {
|
|
738
|
+
lastBadgeLine = i;
|
|
739
|
+
lastBadgeEndIndex = findLastBadgeEnd(line);
|
|
740
|
+
}
|
|
741
|
+
if (firstH1Line === -1 && H1_PATTERN.test(line)) {
|
|
742
|
+
firstH1Line = i;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (lastBadgeLine >= 0 && lastBadgeEndIndex > 0) {
|
|
746
|
+
const line = lines[lastBadgeLine];
|
|
747
|
+
lines[lastBadgeLine] = line.slice(0, lastBadgeEndIndex) + " " + badge + line.slice(lastBadgeEndIndex);
|
|
748
|
+
return lines.join("\n");
|
|
749
|
+
}
|
|
750
|
+
if (firstH1Line >= 0) {
|
|
751
|
+
const before = lines.slice(0, firstH1Line + 1);
|
|
752
|
+
const after = lines.slice(firstH1Line + 1);
|
|
670
753
|
while (after.length > 0 && after[0].trim() === "") {
|
|
671
754
|
after.shift();
|
|
672
755
|
}
|
|
673
|
-
|
|
674
|
-
|
|
756
|
+
if (after.length > 0) {
|
|
757
|
+
return [...before, "", badge, "", ...after].join("\n");
|
|
758
|
+
} else {
|
|
759
|
+
return [...before, "", badge, ""].join("\n");
|
|
760
|
+
}
|
|
675
761
|
}
|
|
676
762
|
return `${badge}
|
|
677
763
|
|
|
@@ -1315,6 +1401,15 @@ async function initCommand(options = {}) {
|
|
|
1315
1401
|
allowPrompt: options.loginPrompt !== false
|
|
1316
1402
|
});
|
|
1317
1403
|
trackEvent(AnalyticsEvents.CLI_INIT, { repoFullName, githubAppInstalled: true });
|
|
1404
|
+
const vaultExists = await checkVaultExists(accessToken, repoFullName);
|
|
1405
|
+
if (vaultExists) {
|
|
1406
|
+
console.log(pc5.green("\n\u2713 Already initialized!\n"));
|
|
1407
|
+
console.log(` ${pc5.yellow("\u2192")} Run ${pc5.cyan("keyway push")} to sync your secrets`);
|
|
1408
|
+
console.log(` ${pc5.blue("\u2394")} Dashboard: ${pc5.underline(dashboardLink)}`);
|
|
1409
|
+
console.log("");
|
|
1410
|
+
await shutdownAnalytics();
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1318
1413
|
await initVault(repoFullName, accessToken);
|
|
1319
1414
|
console.log(pc5.green("\u2713 Vault created!"));
|
|
1320
1415
|
try {
|
|
@@ -1785,6 +1880,86 @@ Summary: ${formatSummary(results)}`);
|
|
|
1785
1880
|
import pc8 from "picocolors";
|
|
1786
1881
|
import open3 from "open";
|
|
1787
1882
|
import prompts6 from "prompts";
|
|
1883
|
+
var TOKEN_AUTH_PROVIDERS = ["railway"];
|
|
1884
|
+
function getTokenCreationUrl(provider) {
|
|
1885
|
+
switch (provider) {
|
|
1886
|
+
case "railway":
|
|
1887
|
+
return "https://railway.com/account/tokens";
|
|
1888
|
+
default:
|
|
1889
|
+
return "";
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
async function connectWithTokenFlow(accessToken, provider, displayName) {
|
|
1893
|
+
const tokenUrl = getTokenCreationUrl(provider);
|
|
1894
|
+
console.log(pc8.gray(`Create a ${displayName} API Token at:`));
|
|
1895
|
+
console.log(pc8.cyan(`\u2192 ${tokenUrl}
|
|
1896
|
+
`));
|
|
1897
|
+
if (provider === "railway") {
|
|
1898
|
+
console.log(pc8.yellow("Tip: Select the workspace containing your projects."));
|
|
1899
|
+
console.log(pc8.yellow(` Do NOT use "No workspace" - it won't have access to your projects.
|
|
1900
|
+
`));
|
|
1901
|
+
}
|
|
1902
|
+
const { token } = await prompts6({
|
|
1903
|
+
type: "password",
|
|
1904
|
+
name: "token",
|
|
1905
|
+
message: `${displayName} API Token:`
|
|
1906
|
+
});
|
|
1907
|
+
if (!token) {
|
|
1908
|
+
console.log(pc8.gray("Cancelled."));
|
|
1909
|
+
return false;
|
|
1910
|
+
}
|
|
1911
|
+
console.log(pc8.gray("\nValidating token..."));
|
|
1912
|
+
try {
|
|
1913
|
+
const result = await connectWithToken(accessToken, provider, token);
|
|
1914
|
+
if (result.success) {
|
|
1915
|
+
console.log(pc8.green(`
|
|
1916
|
+
\u2713 Connected to ${displayName}!`));
|
|
1917
|
+
console.log(pc8.gray(` Account: ${result.user.username}`));
|
|
1918
|
+
if (result.user.teamName) {
|
|
1919
|
+
console.log(pc8.gray(` Team: ${result.user.teamName}`));
|
|
1920
|
+
}
|
|
1921
|
+
return true;
|
|
1922
|
+
} else {
|
|
1923
|
+
console.log(pc8.red("\n\u2717 Connection failed."));
|
|
1924
|
+
return false;
|
|
1925
|
+
}
|
|
1926
|
+
} catch (error) {
|
|
1927
|
+
const message = error instanceof Error ? error.message : "Token validation failed";
|
|
1928
|
+
console.log(pc8.red(`
|
|
1929
|
+
\u2717 ${message}`));
|
|
1930
|
+
return false;
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
async function connectWithOAuthFlow(accessToken, provider, displayName) {
|
|
1934
|
+
const authUrl = getProviderAuthUrl(provider);
|
|
1935
|
+
const startTime = /* @__PURE__ */ new Date();
|
|
1936
|
+
console.log(pc8.gray("Opening browser for authorization..."));
|
|
1937
|
+
console.log(pc8.gray(`If the browser doesn't open, visit: ${authUrl}`));
|
|
1938
|
+
await open3(authUrl).catch(() => {
|
|
1939
|
+
});
|
|
1940
|
+
console.log(pc8.gray("Waiting for authorization..."));
|
|
1941
|
+
const maxAttempts = 60;
|
|
1942
|
+
let attempts = 0;
|
|
1943
|
+
while (attempts < maxAttempts) {
|
|
1944
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
1945
|
+
attempts++;
|
|
1946
|
+
try {
|
|
1947
|
+
const { connections } = await getConnections(accessToken);
|
|
1948
|
+
const newConn = connections.find(
|
|
1949
|
+
(c) => c.provider === provider && new Date(c.createdAt) > startTime
|
|
1950
|
+
);
|
|
1951
|
+
if (newConn) {
|
|
1952
|
+
console.log(pc8.green(`
|
|
1953
|
+
\u2713 Connected to ${displayName}!`));
|
|
1954
|
+
return true;
|
|
1955
|
+
}
|
|
1956
|
+
} catch {
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
console.log(pc8.red("\n\u2717 Authorization timeout."));
|
|
1960
|
+
console.log(pc8.gray("Run `keyway connections` to check if the connection was established."));
|
|
1961
|
+
return false;
|
|
1962
|
+
}
|
|
1788
1963
|
async function connectCommand(provider, options = {}) {
|
|
1789
1964
|
try {
|
|
1790
1965
|
const accessToken = await ensureLogin({ allowPrompt: options.loginPrompt !== false });
|
|
@@ -1818,36 +1993,11 @@ async function connectCommand(provider, options = {}) {
|
|
|
1818
1993
|
console.log(pc8.blue(`
|
|
1819
1994
|
Connecting to ${providerInfo.displayName}...
|
|
1820
1995
|
`));
|
|
1821
|
-
const authUrl = getProviderAuthUrl(provider.toLowerCase());
|
|
1822
|
-
const startTime = /* @__PURE__ */ new Date();
|
|
1823
|
-
console.log(pc8.gray("Opening browser for authorization..."));
|
|
1824
|
-
console.log(pc8.gray(`If the browser doesn't open, visit: ${authUrl}`));
|
|
1825
|
-
await open3(authUrl).catch(() => {
|
|
1826
|
-
});
|
|
1827
|
-
console.log(pc8.gray("Waiting for authorization..."));
|
|
1828
|
-
const maxAttempts = 60;
|
|
1829
|
-
let attempts = 0;
|
|
1830
1996
|
let connected = false;
|
|
1831
|
-
|
|
1832
|
-
await
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
const { connections: connections2 } = await getConnections(accessToken);
|
|
1836
|
-
const newConn = connections2.find(
|
|
1837
|
-
(c) => c.provider === provider.toLowerCase() && new Date(c.createdAt) > startTime
|
|
1838
|
-
);
|
|
1839
|
-
if (newConn) {
|
|
1840
|
-
connected = true;
|
|
1841
|
-
console.log(pc8.green(`
|
|
1842
|
-
\u2713 Connected to ${providerInfo.displayName}!`));
|
|
1843
|
-
break;
|
|
1844
|
-
}
|
|
1845
|
-
} catch {
|
|
1846
|
-
}
|
|
1847
|
-
}
|
|
1848
|
-
if (!connected) {
|
|
1849
|
-
console.log(pc8.red("\n\u2717 Authorization timeout."));
|
|
1850
|
-
console.log(pc8.gray("Run `keyway connections` to check if the connection was established."));
|
|
1997
|
+
if (TOKEN_AUTH_PROVIDERS.includes(provider.toLowerCase())) {
|
|
1998
|
+
connected = await connectWithTokenFlow(accessToken, provider.toLowerCase(), providerInfo.displayName);
|
|
1999
|
+
} else {
|
|
2000
|
+
connected = await connectWithOAuthFlow(accessToken, provider.toLowerCase(), providerInfo.displayName);
|
|
1851
2001
|
}
|
|
1852
2002
|
trackEvent(AnalyticsEvents.CLI_CONNECT, {
|
|
1853
2003
|
provider: provider.toLowerCase(),
|
|
@@ -1871,7 +2021,7 @@ async function connectionsCommand(options = {}) {
|
|
|
1871
2021
|
if (connections.length === 0) {
|
|
1872
2022
|
console.log(pc8.gray("No provider connections found."));
|
|
1873
2023
|
console.log(pc8.gray("\nConnect to a provider with: keyway connect <provider>"));
|
|
1874
|
-
console.log(pc8.gray("Available providers: vercel"));
|
|
2024
|
+
console.log(pc8.gray("Available providers: vercel, railway"));
|
|
1875
2025
|
return;
|
|
1876
2026
|
}
|
|
1877
2027
|
console.log(pc8.blue("\n\u{1F4E1} Provider Connections\n"));
|
|
@@ -1941,6 +2091,25 @@ function mapToVercelEnvironment(keywayEnv) {
|
|
|
1941
2091
|
};
|
|
1942
2092
|
return mapping[keywayEnv.toLowerCase()] || "production";
|
|
1943
2093
|
}
|
|
2094
|
+
function mapToRailwayEnvironment(keywayEnv) {
|
|
2095
|
+
const mapping = {
|
|
2096
|
+
production: "production",
|
|
2097
|
+
staging: "staging",
|
|
2098
|
+
dev: "development",
|
|
2099
|
+
development: "development"
|
|
2100
|
+
};
|
|
2101
|
+
return mapping[keywayEnv.toLowerCase()] || "production";
|
|
2102
|
+
}
|
|
2103
|
+
function mapToProviderEnvironment(provider, keywayEnv) {
|
|
2104
|
+
switch (provider.toLowerCase()) {
|
|
2105
|
+
case "vercel":
|
|
2106
|
+
return mapToVercelEnvironment(keywayEnv);
|
|
2107
|
+
case "railway":
|
|
2108
|
+
return mapToRailwayEnvironment(keywayEnv);
|
|
2109
|
+
default:
|
|
2110
|
+
return keywayEnv;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
1944
2113
|
function findMatchingProject(projects, repoFullName) {
|
|
1945
2114
|
const repoFullNameLower = repoFullName.toLowerCase();
|
|
1946
2115
|
const repoName = repoFullName.split("/")[1]?.toLowerCase();
|
|
@@ -2018,12 +2187,32 @@ async function syncCommand(provider, options = {}) {
|
|
|
2018
2187
|
process.exit(1);
|
|
2019
2188
|
}
|
|
2020
2189
|
console.log(pc9.gray(`Repository: ${repoFullName}`));
|
|
2021
|
-
|
|
2022
|
-
|
|
2190
|
+
let { connections } = await getConnections(accessToken);
|
|
2191
|
+
let connection = connections.find((c) => c.provider === provider.toLowerCase());
|
|
2023
2192
|
if (!connection) {
|
|
2024
|
-
|
|
2025
|
-
console.log(pc9.
|
|
2026
|
-
|
|
2193
|
+
const providerDisplayName = provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
2194
|
+
console.log(pc9.yellow(`
|
|
2195
|
+
Not connected to ${providerDisplayName}.`));
|
|
2196
|
+
const { shouldConnect } = await prompts7({
|
|
2197
|
+
type: "confirm",
|
|
2198
|
+
name: "shouldConnect",
|
|
2199
|
+
message: `Connect to ${providerDisplayName} now?`,
|
|
2200
|
+
initial: true
|
|
2201
|
+
});
|
|
2202
|
+
if (!shouldConnect) {
|
|
2203
|
+
console.log(pc9.gray("Cancelled."));
|
|
2204
|
+
process.exit(0);
|
|
2205
|
+
}
|
|
2206
|
+
await connectCommand(provider, { loginPrompt: false });
|
|
2207
|
+
const refreshed = await getConnections(accessToken);
|
|
2208
|
+
connections = refreshed.connections;
|
|
2209
|
+
connection = connections.find((c) => c.provider === provider.toLowerCase());
|
|
2210
|
+
if (!connection) {
|
|
2211
|
+
console.error(pc9.red(`
|
|
2212
|
+
Connection to ${providerDisplayName} failed.`));
|
|
2213
|
+
process.exit(1);
|
|
2214
|
+
}
|
|
2215
|
+
console.log("");
|
|
2027
2216
|
}
|
|
2028
2217
|
const { projects } = await getConnectionProjects(accessToken, connection.id);
|
|
2029
2218
|
if (projects.length === 0) {
|
|
@@ -2151,7 +2340,7 @@ async function syncCommand(provider, options = {}) {
|
|
|
2151
2340
|
}
|
|
2152
2341
|
keywayEnv = selectedEnv;
|
|
2153
2342
|
if (!options.providerEnv) {
|
|
2154
|
-
providerEnv =
|
|
2343
|
+
providerEnv = mapToProviderEnvironment(provider, keywayEnv);
|
|
2155
2344
|
}
|
|
2156
2345
|
}
|
|
2157
2346
|
if (needsDirectionPrompt) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keywaysh/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "One link to all your secrets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"dev": "pnpm exec tsx src/cli.ts",
|
|
15
|
+
"dev:local": "NODE_TLS_REJECT_UNAUTHORIZED=0 KEYWAY_API_URL=https://localhost/api pnpm exec tsx src/cli.ts",
|
|
16
|
+
"build": "pnpm exec tsup",
|
|
17
|
+
"build:watch": "pnpm exec tsup --watch",
|
|
18
|
+
"prepublishOnly": "pnpm run build",
|
|
19
|
+
"test": "pnpm exec vitest run",
|
|
20
|
+
"test:watch": "pnpm exec vitest",
|
|
21
|
+
"release": "npm version patch && git push && git push --tags",
|
|
22
|
+
"release:minor": "npm version minor && git push && git push --tags",
|
|
23
|
+
"release:major": "npm version major && git push && git push --tags"
|
|
24
|
+
},
|
|
13
25
|
"keywords": [
|
|
14
26
|
"secrets",
|
|
15
27
|
"env",
|
|
@@ -27,10 +39,12 @@
|
|
|
27
39
|
"bugs": {
|
|
28
40
|
"url": "https://github.com/keywaysh/cli/issues"
|
|
29
41
|
},
|
|
42
|
+
"packageManager": "pnpm@10.6.1",
|
|
30
43
|
"engines": {
|
|
31
44
|
"node": ">=18.0.0"
|
|
32
45
|
},
|
|
33
46
|
"dependencies": {
|
|
47
|
+
"balanced-match": "^3.0.1",
|
|
34
48
|
"commander": "^14.0.0",
|
|
35
49
|
"conf": "^15.0.2",
|
|
36
50
|
"open": "^11.0.0",
|
|
@@ -39,22 +53,12 @@
|
|
|
39
53
|
"prompts": "^2.4.2"
|
|
40
54
|
},
|
|
41
55
|
"devDependencies": {
|
|
56
|
+
"@types/balanced-match": "^3.0.2",
|
|
42
57
|
"@types/node": "^24.2.0",
|
|
43
58
|
"@types/prompts": "^2.4.9",
|
|
44
59
|
"tsup": "^8.5.0",
|
|
45
60
|
"tsx": "^4.20.3",
|
|
46
61
|
"typescript": "^5.9.2",
|
|
47
62
|
"vitest": "^3.2.4"
|
|
48
|
-
},
|
|
49
|
-
"scripts": {
|
|
50
|
-
"dev": "pnpm exec tsx src/cli.ts",
|
|
51
|
-
"dev:local": "NODE_TLS_REJECT_UNAUTHORIZED=0 KEYWAY_API_URL=https://localhost/api pnpm exec tsx src/cli.ts",
|
|
52
|
-
"build": "pnpm exec tsup",
|
|
53
|
-
"build:watch": "pnpm exec tsup --watch",
|
|
54
|
-
"test": "pnpm exec vitest run",
|
|
55
|
-
"test:watch": "pnpm exec vitest",
|
|
56
|
-
"release": "npm version patch && git push && git push --tags",
|
|
57
|
-
"release:minor": "npm version minor && git push && git push --tags",
|
|
58
|
-
"release:major": "npm version major && git push && git push --tags"
|
|
59
63
|
}
|
|
60
|
-
}
|
|
64
|
+
}
|