@dainprotocol/cli 1.2.26 → 1.2.30

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.
@@ -44,45 +44,51 @@ var ora_1 = __importDefault(require("ora"));
44
44
  var utils_1 = require("../utils");
45
45
  function status(options, preDefinedDeploymentId, preDefinedEnvironmentName, preDefinedServiceId) {
46
46
  return __awaiter(this, void 0, void 0, function () {
47
- var config, orgId, _a, apiKey, deploymentId, statusUrl, spinner, response, result, error_1;
48
- return __generator(this, function (_b) {
49
- switch (_b.label) {
47
+ var config, orgId, apiKey, deploymentId, serviceId, statusUrl, spinner, response, result, error_1;
48
+ return __generator(this, function (_a) {
49
+ switch (_a.label) {
50
50
  case 0:
51
51
  config = (0, utils_1.getDainConfig)(options.config);
52
- orgId = "hackathon";
53
- _a = initializeConfig(config, orgId, preDefinedDeploymentId, preDefinedEnvironmentName, preDefinedServiceId), apiKey = _a.apiKey, deploymentId = _a.deploymentId, statusUrl = _a.statusUrl;
54
- if (!orgId || !deploymentId) {
55
- (0, utils_1.logError)("Org ID or deployment ID not found");
56
- return [2 /*return*/];
52
+ orgId = (0, utils_1.resolveOrgId)(config);
53
+ apiKey = config["api-key"];
54
+ deploymentId = preDefinedDeploymentId || config["deployment-id"];
55
+ serviceId = preDefinedServiceId || config["service-id"];
56
+ if (!orgId) {
57
+ (0, utils_1.logError)("Org ID not found. Ensure your API key or DAIN_ORG_ID is set.");
58
+ process.exit(1);
57
59
  }
60
+ if (!deploymentId || !serviceId) {
61
+ (0, utils_1.logError)("Deployment ID or service ID not found");
62
+ process.exit(1);
63
+ }
64
+ statusUrl = (0, utils_1.buildPlatformUrl)(config, orgId, "status", {
65
+ deploymentId: deploymentId,
66
+ environment: preDefinedEnvironmentName,
67
+ serviceId: serviceId,
68
+ });
58
69
  spinner = (0, ora_1.default)("Checking status for project ".concat(config["project-id"], "...")).start();
59
- _b.label = 1;
70
+ _a.label = 1;
60
71
  case 1:
61
- _b.trys.push([1, 4, , 5]);
62
- return [4 /*yield*/, fetch(statusUrl, {
72
+ _a.trys.push([1, 4, , 5]);
73
+ return [4 /*yield*/, (0, utils_1.fetchWithTimeout)(statusUrl, {
63
74
  method: "GET",
64
- headers: {
65
- "Content-Type": "application/json",
66
- "X-DAIN-SIGNATORY-ADDRESS": "TODO: X-DAIN-SIGNATORY-ADDRESS",
67
- "X-DAIN-SIGNATURE": "TODO: X-DAIN-SIGNATORY-SIGNATURE",
68
- Authorization: "Bearer ".concat(apiKey),
69
- },
75
+ headers: { "Content-Type": "application/json", Authorization: "Bearer ".concat(apiKey) },
70
76
  })];
71
77
  case 2:
72
- response = _b.sent();
78
+ response = _a.sent();
73
79
  if (!response.ok) {
74
- throw new Error("Status check failed: ".concat(response.statusText));
80
+ throw new Error("Status check failed: ".concat(response.status, " ").concat(response.statusText));
75
81
  }
76
82
  return [4 /*yield*/, response.json()];
77
83
  case 3:
78
- result = _b.sent();
84
+ result = _a.sent();
79
85
  spinner.info("Status: " + result.message);
80
86
  if (!preDefinedDeploymentId) {
81
87
  process.exit(0);
82
88
  }
83
89
  return [2 /*return*/, result];
84
90
  case 4:
85
- error_1 = _b.sent();
91
+ error_1 = _a.sent();
86
92
  spinner.fail("Failed to retrieve project status.");
87
93
  (0, utils_1.logError)("Error during status check", error_1);
88
94
  process.exit(1);
@@ -92,13 +98,3 @@ function status(options, preDefinedDeploymentId, preDefinedEnvironmentName, preD
92
98
  });
93
99
  });
94
100
  }
95
- var initializeConfig = function (config, orgId, preDefinedDeploymentId, preDefinedEnvironment, preDefinedServiceId) {
96
- var baseUrl = config["platform-base-url"] || "https://codegen-deploy-service.dainapp.com/";
97
- var apiKey = config["api-key"];
98
- var orgIdToBeUsed = orgId || (0, utils_1.extractOrgId)(apiKey);
99
- var deploymentId = preDefinedDeploymentId || config["deployment-id"];
100
- var environment = preDefinedEnvironment || config["environment"];
101
- var serviceId = preDefinedServiceId || config["service-id"];
102
- var statusUrl = "".concat(baseUrl, "/codegen-deploy/status/").concat(orgIdToBeUsed, "/").concat(serviceId, "/").concat(deploymentId, "/").concat(environment);
103
- return { baseUrl: baseUrl, apiKey: apiKey, orgIdToBeUsed: orgIdToBeUsed, deploymentId: deploymentId, statusUrl: statusUrl };
104
- };
@@ -40,64 +40,52 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
40
40
  };
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
42
  exports.default = undeploy;
43
- var utils_1 = require("../utils");
44
43
  var ora_1 = __importDefault(require("ora"));
44
+ var utils_1 = require("../utils");
45
45
  function undeploy(options) {
46
46
  return __awaiter(this, void 0, void 0, function () {
47
- var config, spinner, orgId, _a, apiKey, deploymentId, undeployUrl, response, error_1;
48
- return __generator(this, function (_b) {
49
- switch (_b.label) {
47
+ var config, orgId, apiKey, deploymentId, serviceId, spinner, undeployUrl, response, error_1;
48
+ return __generator(this, function (_a) {
49
+ switch (_a.label) {
50
50
  case 0:
51
51
  config = (0, utils_1.getDainConfig)(options.config);
52
- spinner = (0, ora_1.default)("Undeploying deployment ".concat(config["deployment-id"], "...")).start();
53
- _b.label = 1;
54
- case 1:
55
- _b.trys.push([1, 3, 4, 5]);
56
- orgId = "hackathon";
57
- _a = initializeConfig(config, orgId), apiKey = _a.apiKey, deploymentId = _a.deploymentId, undeployUrl = _a.undeployUrl;
58
- if (!orgId || !deploymentId) {
59
- (0, utils_1.logError)("Org ID or deployment ID not found");
60
- return [2 /*return*/];
52
+ orgId = (0, utils_1.resolveOrgId)(config);
53
+ apiKey = config["api-key"];
54
+ deploymentId = config["deployment-id"];
55
+ serviceId = config["service-id"];
56
+ spinner = (0, ora_1.default)("Undeploying deployment ".concat(deploymentId, "...")).start();
57
+ if (!orgId) {
58
+ (0, utils_1.logError)("Org ID not found. Ensure your API key or DAIN_ORG_ID is set.");
59
+ process.exit(1);
60
+ }
61
+ if (!deploymentId || !serviceId) {
62
+ (0, utils_1.logError)("Deployment ID or service ID not found");
63
+ process.exit(1);
61
64
  }
62
- return [4 /*yield*/, fetch(undeployUrl, {
65
+ undeployUrl = (0, utils_1.buildPlatformUrl)(config, orgId, "undeploy");
66
+ _a.label = 1;
67
+ case 1:
68
+ _a.trys.push([1, 3, , 4]);
69
+ return [4 /*yield*/, (0, utils_1.fetchWithTimeout)(undeployUrl, {
63
70
  method: "DELETE",
64
- headers: {
65
- "Content-Type": "application/json",
66
- "X-DAIN-SIGNATORY-ADDRESS": "TODO: X-DAIN-SIGNATORY-ADDRESS",
67
- "X-DAIN-SIGNATURE": "TODO: X-DAIN-SIGNATORY-SIGNATURE",
68
- Authorization: "Bearer ".concat(apiKey),
69
- },
71
+ headers: { "Content-Type": "application/json", Authorization: "Bearer ".concat(apiKey) },
70
72
  })];
71
73
  case 2:
72
- response = _b.sent();
74
+ response = _a.sent();
73
75
  if (!response.ok) {
74
- throw new Error("Undeployment failed: ".concat(response.statusText));
76
+ throw new Error("Undeployment failed: ".concat(response.status, " ").concat(response.statusText));
75
77
  }
76
78
  spinner.succeed("Undeployment completed successfully.");
77
- spinner.info("Undeployment completed with status code: ".concat(response.status));
78
- return [3 /*break*/, 5];
79
+ process.exit(0);
80
+ return [3 /*break*/, 4];
79
81
  case 3:
80
- error_1 = _b.sent();
82
+ error_1 = _a.sent();
81
83
  spinner.fail("Failed to undeploy project.");
82
84
  (0, utils_1.logError)("Error during undeployment", error_1);
83
85
  process.exit(1);
84
- return [3 /*break*/, 5];
85
- case 4:
86
- spinner.stop();
87
- process.exit(0);
88
- return [7 /*endfinally*/];
89
- case 5: return [2 /*return*/];
86
+ return [3 /*break*/, 4];
87
+ case 4: return [2 /*return*/];
90
88
  }
91
89
  });
92
90
  });
93
91
  }
94
- var initializeConfig = function (config, orgId) {
95
- var baseUrl = config["platform-base-url"] || "https://codegen-deploy-service.dainapp.com/";
96
- var apiKey = config["api-key"];
97
- var orgIdToBeUsed = orgId || (0, utils_1.extractOrgId)(apiKey);
98
- var deploymentId = config["deployment-id"];
99
- var environment = config["environment"];
100
- var serviceId = config["service-id"];
101
- var undeployUrl = "".concat(baseUrl, "/codegen-deploy/undeploy/").concat(orgIdToBeUsed, "/").concat(serviceId, "/").concat(deploymentId, "/").concat(environment);
102
- return { baseUrl: baseUrl, apiKey: apiKey, orgIdToBeUsed: orgIdToBeUsed, deploymentId: deploymentId, undeployUrl: undeployUrl };
103
- };
package/dist/index.js CHANGED
@@ -14,7 +14,6 @@ var testchat_1 = __importDefault(require("./commands/testchat"));
14
14
  var status_1 = __importDefault(require("./commands/status"));
15
15
  var undeploy_1 = __importDefault(require("./commands/undeploy"));
16
16
  var logs_1 = __importDefault(require("./commands/logs"));
17
- var help_1 = __importDefault(require("./commands/help"));
18
17
  var program = new commander_1.Command();
19
18
  program
20
19
  .name('dain')
@@ -91,12 +90,6 @@ program
91
90
  .action(function (options) {
92
91
  (0, logs_1.default)(options);
93
92
  });
94
- program
95
- .command('help')
96
- .description('Show the help')
97
- .action(function () {
98
- (0, help_1.default)();
99
- });
100
93
  program.parse(process.argv);
101
94
  // Add a catch-all command for unknown commands
102
95
  program.on('command:*', function () {
@@ -6,7 +6,7 @@
6
6
  "out-dir": "dist",
7
7
  "environment": "development",
8
8
  "version": "1.0.0",
9
- "tunnel-base-url": "wss:///tunnel.dain-local.com",
9
+ "tunnel-base-url": "wss://tunnel.dain-local.com",
10
10
  "deployment-id": "",
11
11
  "service-id": ""
12
12
  }
package/dist/utils.js CHANGED
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -39,6 +50,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
39
50
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
51
  };
41
52
  Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.DEFAULT_API_BASE_URL = exports.DEFAULT_PLATFORM_BASE_URL = exports.DEFAULT_TUNNEL_BASE_URL = void 0;
54
+ exports.normalizeBaseUrl = normalizeBaseUrl;
55
+ exports.joinUrl = joinUrl;
56
+ exports.parseEnvContent = parseEnvContent;
42
57
  exports.getDainConfig = getDainConfig;
43
58
  exports.displayTunnelUrl = displayTunnelUrl;
44
59
  exports.setupProxy = setupProxy;
@@ -47,51 +62,87 @@ exports.logSuccess = logSuccess;
47
62
  exports.logInfo = logInfo;
48
63
  exports.getStaticFilesPath = getStaticFilesPath;
49
64
  exports.extractOrgId = extractOrgId;
65
+ exports.resolveOrgId = resolveOrgId;
66
+ exports.fetchWithTimeout = fetchWithTimeout;
67
+ exports.buildPlatformUrl = buildPlatformUrl;
50
68
  var fs_1 = __importDefault(require("fs"));
51
69
  var path_1 = __importDefault(require("path"));
52
70
  var client_1 = require("@dainprotocol/tunnel/client");
53
71
  var ora_1 = __importDefault(require("ora"));
54
72
  var chalk_1 = __importDefault(require("chalk"));
55
73
  var dotenv_1 = __importDefault(require("dotenv"));
74
+ exports.DEFAULT_TUNNEL_BASE_URL = "wss://tunnel.dain-local.com";
75
+ exports.DEFAULT_PLATFORM_BASE_URL = "https://codegen-deploy-service.dainapp.com";
76
+ exports.DEFAULT_API_BASE_URL = "https://dain-platform-ochre.vercel.app";
77
+ function normalizeBaseUrl(value) {
78
+ var trimmed = value.trim();
79
+ if (!trimmed)
80
+ return trimmed;
81
+ try {
82
+ return new URL(trimmed).toString().replace(/\/+$/, "");
83
+ }
84
+ catch (_a) {
85
+ return trimmed.replace(/\/+$/, "");
86
+ }
87
+ }
88
+ function joinUrl(baseUrl, pathname) {
89
+ return "".concat(normalizeBaseUrl(baseUrl), "/").concat(pathname.replace(/^\/+/, ""));
90
+ }
91
+ function parseEnvContent(envContent) {
92
+ return Object.entries(dotenv_1.default.parse(envContent))
93
+ .map(function (_a) {
94
+ var name = _a[0], value = _a[1];
95
+ return ({ name: name.trim(), value: value });
96
+ })
97
+ .filter(function (env) { return env.name !== "" && env.value !== ""; });
98
+ }
99
+ function parseDainApiKey(apiKey) {
100
+ if (!(apiKey === null || apiKey === void 0 ? void 0 : apiKey.startsWith("sk_agent_")))
101
+ return null;
102
+ var parts = apiKey.split("_");
103
+ if (parts.length < 5)
104
+ return null;
105
+ if (parts[2] === "org") {
106
+ if (!parts[3] || parts[4] !== "agent" || !parts[5])
107
+ return null;
108
+ var secret_1 = parts.slice(6).join("_");
109
+ return secret_1 ? { agentId: parts[5], orgId: parts[3], secret: secret_1 } : null;
110
+ }
111
+ var secret = parts.slice(4).join("_");
112
+ return parts[2] && parts[3] && secret ? { agentId: parts[2], orgId: parts[3], secret: secret } : null;
113
+ }
56
114
  function loadEnvFiles() {
57
- var envFiles = [".env.local", ".env", ".env.development", ".env.production"];
58
- envFiles.forEach(function (file) {
115
+ [".env.local", ".env", ".env.development", ".env.production"].forEach(function (file) {
59
116
  var envPath = path_1.default.join(process.cwd(), file);
60
- if (fs_1.default.existsSync(envPath)) {
117
+ if (fs_1.default.existsSync(envPath))
61
118
  dotenv_1.default.config({ path: envPath });
62
- }
63
119
  });
64
120
  }
65
121
  function getDainConfig(configFile) {
66
- loadEnvFiles(); // Loads all env files first
67
- var defaultConfigPath = path_1.default.join(process.cwd(), "dain.json");
68
- var configPath = configFile ? path_1.default.join(process.cwd(), configFile) : defaultConfigPath;
122
+ loadEnvFiles();
123
+ var configPath = path_1.default.join(process.cwd(), configFile || "dain.json");
69
124
  if (!fs_1.default.existsSync(configPath)) {
70
125
  logError("Configuration file not found: ".concat(configPath));
71
126
  process.exit(1);
72
127
  }
73
128
  try {
74
- var configData = fs_1.default.readFileSync(configPath, "utf8");
75
- var config = JSON.parse(configData);
76
- // Validate required fields
77
- if (!config["main-file"]) {
129
+ var config = JSON.parse(fs_1.default.readFileSync(configPath, "utf8"));
130
+ if (!config["main-file"])
78
131
  throw new Error("Configuration must include 'main-file'");
79
- }
80
- // Set default values for optional fields
81
- config["environment"] = config["environment"] || "development";
82
- config["version"] = config["version"] || "1.0.0";
83
- config["out-dir"] = config["out-dir"] || "dist"; // Default to 'dist' if not specified
84
- config["tunnel-base-url"] = config["tunnel-base-url"] || "wss://tunnel.dain-local.com"; // Default value if not specified
85
- config["runtime"] = config["runtime"] || "node"; // Add this line
86
- // Handle API key
87
- if (!config["api-key"] ||
88
- config["api-key"] === "env" ||
89
- config["api-key"] === "MUST PUT IN .env.development as DAIN_API_KEY=YOUR_API_KEY") {
132
+ config.environment || (config.environment = "development");
133
+ config.version || (config.version = "1.0.0");
134
+ config["out-dir"] || (config["out-dir"] = "dist");
135
+ config.runtime || (config.runtime = "node");
136
+ config["tunnel-base-url"] = normalizeBaseUrl(config["tunnel-base-url"] || exports.DEFAULT_TUNNEL_BASE_URL);
137
+ if (config["platform-base-url"])
138
+ config["platform-base-url"] = normalizeBaseUrl(config["platform-base-url"]);
139
+ if (config["api-base-url"])
140
+ config["api-base-url"] = normalizeBaseUrl(config["api-base-url"]);
141
+ if (!config["api-key"] || config["api-key"] === "env" || config["api-key"].startsWith("MUST PUT")) {
90
142
  config["api-key"] = process.env.DAIN_API_KEY;
91
143
  }
92
- if (!config["api-key"]) {
144
+ if (!config["api-key"])
93
145
  throw new Error("API key is not set in config or DAIN_API_KEY environment variable");
94
- }
95
146
  return config;
96
147
  }
97
148
  catch (error) {
@@ -99,13 +150,7 @@ function getDainConfig(configFile) {
99
150
  }
100
151
  }
101
152
  function displayTunnelUrl(tunnelUrl) {
102
- var divider = chalk_1.default.green("------------------------------------------------------------");
103
- var header = chalk_1.default.green("Your service is available publicly at:");
104
- var url = chalk_1.default.cyan.underline(tunnelUrl);
105
- var info = chalk_1.default.yellow("This service URL can be connected to by a DAIN client or assistant");
106
- var subInfo = chalk_1.default.yellow("(such as butterfly in development mode)");
107
- var warning = chalk_1.default.red("You should not visit this URL directly");
108
- console.log("\n".concat(divider, "\n").concat(header, "\n").concat(url, "\n\n").concat(info, "\n").concat(subInfo, "\n\n").concat(warning, "\n").concat(divider, "\n"));
153
+ console.log("\n".concat(chalk_1.default.green("------------------------------------------------------------"), "\n").concat(chalk_1.default.green("Your service is available publicly at:"), "\n").concat(chalk_1.default.cyan.underline(tunnelUrl), "\n\n").concat(chalk_1.default.yellow("This service URL can be connected to by a DAIN client or assistant"), "\n").concat(chalk_1.default.yellow("(such as butterfly in development mode)"), "\n\n").concat(chalk_1.default.red("You should not visit this URL directly"), "\n").concat(chalk_1.default.green("------------------------------------------------------------"), "\n"));
109
154
  }
110
155
  function setupProxy(port, apiKey, config) {
111
156
  return __awaiter(this, void 0, void 0, function () {
@@ -117,12 +162,11 @@ function setupProxy(port, apiKey, config) {
117
162
  _a.label = 1;
118
163
  case 1:
119
164
  _a.trys.push([1, 3, , 4]);
120
- client = new client_1.DainTunnel(config["tunnel-base-url"] || "wss://tunnel.dain-local.com", apiKey);
165
+ client = new client_1.DainTunnel(config["tunnel-base-url"] || exports.DEFAULT_TUNNEL_BASE_URL, apiKey);
121
166
  return [4 /*yield*/, client.start(parseInt(port))];
122
167
  case 2:
123
168
  tunnelUrl = _a.sent();
124
169
  spinner.succeed("Proxy setup complete");
125
- displayTunnelUrl(tunnelUrl);
126
170
  return [2 /*return*/, { client: client, tunnelUrl: tunnelUrl }];
127
171
  case 3:
128
172
  error_1 = _a.sent();
@@ -136,9 +180,8 @@ function setupProxy(port, apiKey, config) {
136
180
  }
137
181
  function logError(message, error) {
138
182
  console.error(chalk_1.default.red("\nError: ".concat(message)));
139
- if (error) {
183
+ if (error)
140
184
  console.error(chalk_1.default.red(error));
141
- }
142
185
  }
143
186
  function logSuccess(message) {
144
187
  console.log(chalk_1.default.green("\nSuccess: ".concat(message)));
@@ -150,6 +193,38 @@ function getStaticFilesPath() {
150
193
  return path_1.default.join(process.cwd(), "static");
151
194
  }
152
195
  function extractOrgId(apiKey) {
153
- var apiKeySplit = apiKey === null || apiKey === void 0 ? void 0 : apiKey.split("_");
154
- return apiKeySplit ? apiKeySplit[2] : "";
196
+ var _a;
197
+ return ((_a = parseDainApiKey(apiKey)) === null || _a === void 0 ? void 0 : _a.orgId) || "";
198
+ }
199
+ function resolveOrgId(config) {
200
+ return config["org-id"] || process.env.DAIN_ORG_ID || extractOrgId(config["api-key"]);
201
+ }
202
+ function fetchWithTimeout(url_1, options_1) {
203
+ return __awaiter(this, arguments, void 0, function (url, options, timeoutMs) {
204
+ var controller, timeoutId;
205
+ if (timeoutMs === void 0) { timeoutMs = 30000; }
206
+ return __generator(this, function (_a) {
207
+ switch (_a.label) {
208
+ case 0:
209
+ controller = new AbortController();
210
+ timeoutId = setTimeout(function () { return controller.abort(); }, timeoutMs);
211
+ _a.label = 1;
212
+ case 1:
213
+ _a.trys.push([1, , 3, 4]);
214
+ return [4 /*yield*/, fetch(url, __assign(__assign({}, options), { signal: controller.signal }))];
215
+ case 2: return [2 /*return*/, _a.sent()];
216
+ case 3:
217
+ clearTimeout(timeoutId);
218
+ return [7 /*endfinally*/];
219
+ case 4: return [2 /*return*/];
220
+ }
221
+ });
222
+ });
223
+ }
224
+ function buildPlatformUrl(config, orgId, endpoint, overrides) {
225
+ var baseUrl = config["platform-base-url"] || exports.DEFAULT_PLATFORM_BASE_URL;
226
+ var deploymentId = (overrides === null || overrides === void 0 ? void 0 : overrides.deploymentId) || config["deployment-id"];
227
+ var environment = (overrides === null || overrides === void 0 ? void 0 : overrides.environment) || config["environment"];
228
+ var serviceId = (overrides === null || overrides === void 0 ? void 0 : overrides.serviceId) || config["service-id"];
229
+ return joinUrl(baseUrl, "/codegen-deploy/".concat(endpoint, "/").concat(orgId, "/").concat(serviceId, "/").concat(deploymentId, "/").concat(environment));
155
230
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dainprotocol/cli",
3
- "version": "1.2.26",
3
+ "version": "1.2.30",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,6 +10,13 @@
10
10
  "bin": {
11
11
  "dain": "./dist/index.js"
12
12
  },
13
+ "scripts": {
14
+ "build": "tsc && cp -r templates dist/",
15
+ "test": "jest",
16
+ "test:watch": "jest --watch",
17
+ "test:coverage": "jest --coverage",
18
+ "prepublishOnly": "pnpm run build && pnpm test"
19
+ },
13
20
  "files": [
14
21
  "dist",
15
22
  "README.md"
@@ -34,11 +41,11 @@
34
41
  },
35
42
  "devDependencies": {
36
43
  "@types/archiver": "^6.0.3",
44
+ "@types/jest": "^30.0.0",
37
45
  "@types/node": "^22.5.4",
46
+ "jest": "^30.2.0",
47
+ "ts-jest": "^29.4.6",
38
48
  "ts-node": "^10.9.2",
39
49
  "typescript": "^5.9.3"
40
- },
41
- "scripts": {
42
- "build": "tsc && cp -r templates dist/"
43
50
  }
44
- }
51
+ }