@weavix/cli 0.1.0-dev → 0.3.0
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 +26 -51
- package/build/index.js +728 -1838
- package/build/templates/_shared/.arcignore +2 -1
- package/build/templates/_shared/manifest.schema.json +23 -11
- package/build/templates/_shared/package.json +10 -10
- package/build/templates/_shared/vite.config.ts +2 -0
- package/package.json +2 -2
- package/build/templates/issue.floatingbottom.action/index.html +0 -14
- package/build/templates/issue.floatingbottom.action/src/App.tsx +0 -28
package/build/index.js
CHANGED
|
@@ -40,6 +40,20 @@ var CLI_NAME, CLI_DESCRIPTION, CLI_HELP_TEXT, init_meta = __esm({
|
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
+
// src/utils/verbose.ts
|
|
44
|
+
function setVerboseEnabled(value) {
|
|
45
|
+
verboseEnabled = value;
|
|
46
|
+
}
|
|
47
|
+
function isVerboseEnabled() {
|
|
48
|
+
return verboseEnabled;
|
|
49
|
+
}
|
|
50
|
+
var verboseEnabled, init_verbose = __esm({
|
|
51
|
+
"src/utils/verbose.ts"() {
|
|
52
|
+
"use strict";
|
|
53
|
+
verboseEnabled = !1;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
43
57
|
// src/utils/logger.ts
|
|
44
58
|
function success(message) {
|
|
45
59
|
console.info(import_picocolors.default.green(`\u2705 ${message}`)), newLine();
|
|
@@ -54,6 +68,9 @@ function warning(message) {
|
|
|
54
68
|
function info(message) {
|
|
55
69
|
console.info(message), newLine();
|
|
56
70
|
}
|
|
71
|
+
function verbose(message) {
|
|
72
|
+
isVerboseEnabled() && (console.info(import_picocolors.default.dim(message)), newLine());
|
|
73
|
+
}
|
|
57
74
|
function suggest(command) {
|
|
58
75
|
console.info(`Run: ${command}`), newLine();
|
|
59
76
|
}
|
|
@@ -73,11 +90,13 @@ var import_picocolors, logger, logger_default, init_logger = __esm({
|
|
|
73
90
|
"src/utils/logger.ts"() {
|
|
74
91
|
"use strict";
|
|
75
92
|
import_picocolors = __toESM(require("picocolors"));
|
|
93
|
+
init_verbose();
|
|
76
94
|
logger = {
|
|
77
95
|
success,
|
|
78
96
|
error,
|
|
79
97
|
warning,
|
|
80
98
|
info,
|
|
99
|
+
verbose,
|
|
81
100
|
suggest,
|
|
82
101
|
newLine,
|
|
83
102
|
separator,
|
|
@@ -86,102 +105,95 @@ var import_picocolors, logger, logger_default, init_logger = __esm({
|
|
|
86
105
|
}
|
|
87
106
|
});
|
|
88
107
|
|
|
89
|
-
// src/
|
|
90
|
-
|
|
108
|
+
// src/core/cliConfig/manager.ts
|
|
109
|
+
function getConfigPath() {
|
|
110
|
+
return CONFIG_FILE;
|
|
111
|
+
}
|
|
112
|
+
function readConfig() {
|
|
113
|
+
if (cached !== void 0)
|
|
114
|
+
return cached;
|
|
91
115
|
if (!(0, import_fs.existsSync)(CONFIG_FILE))
|
|
92
|
-
return null;
|
|
93
|
-
|
|
94
|
-
|
|
116
|
+
return cached = null, cached;
|
|
117
|
+
try {
|
|
118
|
+
cached = JSON.parse((0, import_fs.readFileSync)(CONFIG_FILE, "utf-8"));
|
|
119
|
+
} catch {
|
|
120
|
+
cached = null;
|
|
121
|
+
}
|
|
122
|
+
return cached;
|
|
95
123
|
}
|
|
96
|
-
|
|
97
|
-
(0, import_fs.existsSync)(CONFIG_DIR) || (0, import_fs.mkdirSync)(CONFIG_DIR, { recursive: !0, mode: 448 }),
|
|
124
|
+
function writeConfig(config) {
|
|
125
|
+
(0, import_fs.existsSync)(CONFIG_DIR) || (0, import_fs.mkdirSync)(CONFIG_DIR, { recursive: !0, mode: 448 }), (0, import_fs.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 384 }), cached = config;
|
|
98
126
|
}
|
|
99
|
-
|
|
100
|
-
(0, import_fs.existsSync)(CONFIG_FILE) &&
|
|
127
|
+
function clearConfig() {
|
|
128
|
+
(0, import_fs.existsSync)(CONFIG_FILE) && (0, import_fs.rmSync)(CONFIG_FILE), cached = null;
|
|
101
129
|
}
|
|
102
|
-
var import_fs,
|
|
103
|
-
"src/
|
|
130
|
+
var import_fs, os, import_path, CONFIG_DIR, CONFIG_FILE, cached, init_manager = __esm({
|
|
131
|
+
"src/core/cliConfig/manager.ts"() {
|
|
104
132
|
"use strict";
|
|
105
|
-
import_fs = require("fs"),
|
|
133
|
+
import_fs = require("fs"), os = __toESM(require("os")), import_path = __toESM(require("path")), CONFIG_DIR = import_path.default.join(os.homedir(), ".tracker-cli"), CONFIG_FILE = import_path.default.join(CONFIG_DIR, "config.json");
|
|
106
134
|
}
|
|
107
135
|
});
|
|
108
136
|
|
|
109
|
-
// src/
|
|
110
|
-
function
|
|
111
|
-
return
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
};
|
|
137
|
+
// src/core/cliConfig/registerCommand.ts
|
|
138
|
+
async function promptString(message, current) {
|
|
139
|
+
return (await (0, import_prompts.input)({
|
|
140
|
+
message: current ? `${message} (current: ${current})` : `${message} (optional)`,
|
|
141
|
+
default: current,
|
|
142
|
+
required: !1
|
|
143
|
+
}))?.trim() || void 0;
|
|
118
144
|
}
|
|
119
|
-
async function
|
|
120
|
-
let
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
awsRegion: awsRegion.trim(),
|
|
148
|
-
staticBucket: staticBucket.trim(),
|
|
149
|
-
configBucket: configBucket.trim()
|
|
150
|
-
};
|
|
151
|
-
mdsEndpoint.trim() && (config.mdsEndpoint = mdsEndpoint.trim()), platformApiUrl.trim() && (config.platformApiUrl = platformApiUrl.trim()), trackerApiUrl.trim() && (config.trackerApiUrl = trackerApiUrl.trim()), await writeConfig(config), logger_default.success(`Configuration saved to ${CONFIG_FILE_PATH}`);
|
|
145
|
+
async function runConfigSet(cliName) {
|
|
146
|
+
let existing = readConfig() ?? {};
|
|
147
|
+
logger_default.info(
|
|
148
|
+
"Configure CLI overrides. Empty input clears the value (and falls back to defaults where applicable)."
|
|
149
|
+
);
|
|
150
|
+
let s3Endpoint = await promptString("S3 endpoint", existing.s3?.endpoint), s3Region = await promptString("S3 region", existing.s3?.region), mdsEndpoint = await promptString("MDS endpoint", existing.mds?.endpoint), productionStatic = await promptString(
|
|
151
|
+
"Production bucket (static)",
|
|
152
|
+
existing.buckets?.production?.static
|
|
153
|
+
), productionConfig = await promptString(
|
|
154
|
+
"Production bucket (config)",
|
|
155
|
+
existing.buckets?.production?.config
|
|
156
|
+
), pluginDownloadProduction = await promptString(
|
|
157
|
+
"Plugin download base URL",
|
|
158
|
+
existing.pluginDownloadBase?.production
|
|
159
|
+
), platformBaseUrl = await promptString(
|
|
160
|
+
"Platform API base URL",
|
|
161
|
+
existing.api?.platformBaseUrl
|
|
162
|
+
), oauthUrl = await promptString("OAuth token URL", existing.auth?.oauthUrl);
|
|
163
|
+
writeConfig({
|
|
164
|
+
s3: { endpoint: s3Endpoint, region: s3Region },
|
|
165
|
+
mds: { endpoint: mdsEndpoint },
|
|
166
|
+
buckets: {
|
|
167
|
+
production: { static: productionStatic, config: productionConfig }
|
|
168
|
+
},
|
|
169
|
+
pluginDownloadBase: { production: pluginDownloadProduction },
|
|
170
|
+
api: { platformBaseUrl },
|
|
171
|
+
auth: { oauthUrl }
|
|
172
|
+
}), logger_default.success(`Configuration saved \u2192 ${getConfigPath()}`), logger_default.info(`Inspect with "${cliName} config show" or revert with "${cliName} config clear".`);
|
|
152
173
|
}
|
|
153
|
-
|
|
154
|
-
let cfg =
|
|
174
|
+
function runConfigShow(cliName) {
|
|
175
|
+
let cfg = readConfig();
|
|
155
176
|
if (!cfg) {
|
|
156
|
-
logger_default.info(
|
|
177
|
+
logger_default.info(
|
|
178
|
+
`No configuration found at ${getConfigPath()}. Run "${cliName} config set" to create one.`
|
|
179
|
+
);
|
|
157
180
|
return;
|
|
158
181
|
}
|
|
159
|
-
logger_default.info(JSON.stringify(cfg, null, 2));
|
|
182
|
+
logger_default.info(`Configuration at ${getConfigPath()}:`), logger_default.info(JSON.stringify(cfg, null, 2));
|
|
160
183
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
logger_default.info("No configuration to clear.");
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
if (!await (0, import_prompts.confirm)({
|
|
167
|
-
message: `Remove configuration at ${CONFIG_FILE_PATH}?`,
|
|
168
|
-
default: !1
|
|
169
|
-
})) {
|
|
170
|
-
logger_default.info("Cancelled.");
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
await clearConfig(), logger_default.success("Configuration removed.");
|
|
184
|
+
function runConfigClear() {
|
|
185
|
+
clearConfig(), logger_default.success(`Configuration removed (${getConfigPath()})`);
|
|
174
186
|
}
|
|
175
|
-
function registerConfigCommand(program) {
|
|
176
|
-
let config = program.command("config").description("manage CLI configuration
|
|
177
|
-
config.command("set").description("set configuration interactively").action(
|
|
187
|
+
function registerConfigCommand(program, cliName) {
|
|
188
|
+
let config = program.command("config").description("manage CLI configuration");
|
|
189
|
+
config.command("set").description("set CLI configuration values interactively").action(() => runConfigSet(cliName)), config.command("show").description("display current CLI configuration").action(() => runConfigShow(cliName)), config.command("clear").description("remove stored CLI configuration").action(runConfigClear);
|
|
178
190
|
}
|
|
179
|
-
var import_prompts,
|
|
180
|
-
"src/
|
|
191
|
+
var import_prompts, init_registerCommand = __esm({
|
|
192
|
+
"src/core/cliConfig/registerCommand.ts"() {
|
|
181
193
|
"use strict";
|
|
182
194
|
import_prompts = require("@inquirer/prompts");
|
|
183
195
|
init_logger();
|
|
184
|
-
|
|
196
|
+
init_manager();
|
|
185
197
|
}
|
|
186
198
|
});
|
|
187
199
|
|
|
@@ -191,97 +203,170 @@ __export(registerCommands_exports, {
|
|
|
191
203
|
registerDistributionCommands: () => registerDistributionCommands
|
|
192
204
|
});
|
|
193
205
|
function registerDistributionCommands(program) {
|
|
194
|
-
registerConfigCommand(program);
|
|
206
|
+
registerConfigCommand(program, CLI_NAME);
|
|
195
207
|
}
|
|
196
208
|
var init_registerCommands = __esm({
|
|
197
209
|
"src/distributions/external/registerCommands.ts"() {
|
|
198
210
|
"use strict";
|
|
199
|
-
|
|
211
|
+
init_registerCommand();
|
|
212
|
+
init_meta();
|
|
200
213
|
}
|
|
201
214
|
});
|
|
202
215
|
|
|
203
|
-
// src/distributions/external/
|
|
204
|
-
var
|
|
205
|
-
__export(
|
|
206
|
-
|
|
207
|
-
|
|
216
|
+
// src/distributions/external/hosts.ts
|
|
217
|
+
var hosts_exports = {};
|
|
218
|
+
__export(hosts_exports, {
|
|
219
|
+
getBuckets: () => getBuckets,
|
|
220
|
+
getMdsEndpoint: () => getMdsEndpoint,
|
|
221
|
+
getOAuthTokenUrl: () => getOAuthTokenUrl,
|
|
222
|
+
getPlatformBaseUrl: () => getPlatformBaseUrl,
|
|
223
|
+
getPluginDownloadBase: () => getPluginDownloadBase,
|
|
224
|
+
getS3Endpoint: () => getS3Endpoint,
|
|
225
|
+
getS3Region: () => getS3Region,
|
|
226
|
+
getTrackerBaseUrl: () => getTrackerBaseUrl,
|
|
227
|
+
getUpdateCheckInfo: () => getUpdateCheckInfo
|
|
208
228
|
});
|
|
209
|
-
|
|
229
|
+
function requireConfig() {
|
|
230
|
+
let cfg = readConfig();
|
|
231
|
+
if (!cfg)
|
|
232
|
+
throw new Error('CLI is not configured. Run "weavix config set" to configure.');
|
|
233
|
+
return cfg;
|
|
234
|
+
}
|
|
235
|
+
function getS3Endpoint() {
|
|
236
|
+
let cfg = requireConfig();
|
|
237
|
+
if (!cfg.s3?.endpoint)
|
|
238
|
+
throw new Error('S3 endpoint is not configured. Run "weavix config set" to configure.');
|
|
239
|
+
return cfg.s3.endpoint;
|
|
240
|
+
}
|
|
241
|
+
function getMdsEndpoint() {
|
|
242
|
+
let cfg = requireConfig();
|
|
243
|
+
if (!cfg.mds?.endpoint)
|
|
244
|
+
throw new Error('MDS endpoint is not configured. Run "weavix config set" to configure.');
|
|
245
|
+
return cfg.mds.endpoint;
|
|
246
|
+
}
|
|
247
|
+
function getS3Region() {
|
|
248
|
+
let cfg = requireConfig();
|
|
249
|
+
if (!cfg.s3?.region)
|
|
250
|
+
throw new Error('S3 region is not configured. Run "weavix config set" to configure.');
|
|
251
|
+
return cfg.s3.region;
|
|
252
|
+
}
|
|
253
|
+
function getBuckets() {
|
|
254
|
+
let production = requireConfig().buckets?.production;
|
|
255
|
+
if (!production?.static || !production?.config)
|
|
256
|
+
throw new Error('S3 buckets are not configured. Run "weavix config set" to configure.');
|
|
257
|
+
let prod = { static: production.static, config: production.config };
|
|
258
|
+
return { testing: prod, production: prod };
|
|
259
|
+
}
|
|
260
|
+
function getPluginDownloadBase(env) {
|
|
261
|
+
if (env === "debug")
|
|
262
|
+
return "http://localhost:5173/plugins-debug";
|
|
263
|
+
let base = requireConfig().pluginDownloadBase?.production;
|
|
264
|
+
if (!base)
|
|
265
|
+
throw new Error(
|
|
266
|
+
'Plugin download base is not configured. Run "weavix config set" to configure.'
|
|
267
|
+
);
|
|
268
|
+
return base;
|
|
210
269
|
}
|
|
211
|
-
|
|
270
|
+
function getPlatformBaseUrl() {
|
|
271
|
+
let cfg = requireConfig();
|
|
272
|
+
if (!cfg.api?.platformBaseUrl)
|
|
273
|
+
throw new Error(
|
|
274
|
+
'Platform API URL is not configured. Run "weavix config set" to configure.'
|
|
275
|
+
);
|
|
276
|
+
return cfg.api.platformBaseUrl;
|
|
212
277
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
"use strict";
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// src/distributions/external/apiUrls.ts
|
|
220
|
-
var apiUrls_exports = {};
|
|
221
|
-
__export(apiUrls_exports, {
|
|
222
|
-
getPlatformApiUrl: () => getPlatformApiUrl,
|
|
223
|
-
getTrackerApiUrl: () => getTrackerApiUrl
|
|
224
|
-
});
|
|
225
|
-
async function getPlatformApiUrl() {
|
|
226
|
-
let cfg = await readConfig();
|
|
227
|
-
if (!cfg?.platformApiUrl)
|
|
228
|
-
throw new Error("Platform API URL is not configured. Run: tracker-cli config set");
|
|
229
|
-
return cfg.platformApiUrl;
|
|
278
|
+
function getTrackerBaseUrl() {
|
|
279
|
+
return TRACKER_BASE_URL;
|
|
230
280
|
}
|
|
231
|
-
|
|
232
|
-
let cfg =
|
|
233
|
-
if (!cfg?.
|
|
234
|
-
throw new Error(
|
|
235
|
-
return cfg.
|
|
281
|
+
function getOAuthTokenUrl() {
|
|
282
|
+
let cfg = requireConfig();
|
|
283
|
+
if (!cfg.auth?.oauthUrl)
|
|
284
|
+
throw new Error('OAuth URL is not configured. Run "weavix config set" to configure.');
|
|
285
|
+
return cfg.auth.oauthUrl;
|
|
236
286
|
}
|
|
237
|
-
|
|
238
|
-
|
|
287
|
+
function getUpdateCheckInfo() {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
var TRACKER_BASE_URL, init_hosts = __esm({
|
|
291
|
+
"src/distributions/external/hosts.ts"() {
|
|
239
292
|
"use strict";
|
|
240
|
-
|
|
293
|
+
init_manager();
|
|
294
|
+
TRACKER_BASE_URL = "https://tracker.yandex.ru";
|
|
241
295
|
}
|
|
242
296
|
});
|
|
243
297
|
|
|
244
|
-
// src/distributions/external/
|
|
245
|
-
var
|
|
246
|
-
__export(
|
|
247
|
-
|
|
298
|
+
// src/distributions/external/templateSubstitution.ts
|
|
299
|
+
var templateSubstitution_exports = {};
|
|
300
|
+
__export(templateSubstitution_exports, {
|
|
301
|
+
applySubstitutions: () => applySubstitutions,
|
|
302
|
+
templateDeps: () => templateDeps
|
|
248
303
|
});
|
|
249
|
-
|
|
250
|
-
|
|
304
|
+
function rewritePackageJson(content) {
|
|
305
|
+
let pkg = JSON.parse(content);
|
|
306
|
+
if (pkg.dependencies) {
|
|
307
|
+
let next = {};
|
|
308
|
+
for (let [name, version] of Object.entries(pkg.dependencies)) {
|
|
309
|
+
if (PACKAGE_DROP.has(name))
|
|
310
|
+
continue;
|
|
311
|
+
let renamed = PACKAGE_RENAME[name] ?? name;
|
|
312
|
+
next[renamed] = ADDED_DEPS[renamed] ?? version;
|
|
313
|
+
}
|
|
314
|
+
for (let [name, version] of Object.entries(ADDED_DEPS))
|
|
315
|
+
name in next || (next[name] = version);
|
|
316
|
+
pkg.dependencies = Object.fromEntries(
|
|
317
|
+
Object.entries(next).sort(([a], [b]) => a.localeCompare(b))
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
return JSON.stringify(pkg, null, 4) + `
|
|
321
|
+
`;
|
|
251
322
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
323
|
+
function rewriteImports(content) {
|
|
324
|
+
let result = content;
|
|
325
|
+
for (let [from, to] of Object.entries(PACKAGE_RENAME)) {
|
|
326
|
+
let escaped = from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
327
|
+
result = result.replace(new RegExp(escaped, "g"), to);
|
|
255
328
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
// src/distributions/external/storage.ts
|
|
259
|
-
var storage_exports = {};
|
|
260
|
-
__export(storage_exports, {
|
|
261
|
-
DEFAULT_ENVIRONMENT: () => DEFAULT_ENVIRONMENT,
|
|
262
|
-
getStorageSettings: () => getStorageSettings,
|
|
263
|
-
listEnvironments: () => listEnvironments
|
|
264
|
-
});
|
|
265
|
-
async function getStorageSettings(_environment) {
|
|
266
|
-
let cfg = await readConfig();
|
|
267
|
-
if (!cfg)
|
|
268
|
-
throw new Error("CLI is not configured. Run: tracker-cli config set");
|
|
269
|
-
return {
|
|
270
|
-
awsEndpoint: cfg.awsEndpoint,
|
|
271
|
-
awsRegion: cfg.awsRegion,
|
|
272
|
-
mdsEndpoint: cfg.mdsEndpoint ?? cfg.awsEndpoint,
|
|
273
|
-
configBucket: cfg.configBucket,
|
|
274
|
-
staticBucket: cfg.staticBucket
|
|
275
|
-
};
|
|
329
|
+
return result;
|
|
276
330
|
}
|
|
277
|
-
|
|
278
|
-
return
|
|
331
|
+
function rewriteScss(content) {
|
|
332
|
+
return content.split(`
|
|
333
|
+
`).filter((line) => {
|
|
334
|
+
let trimmed = line.trim();
|
|
335
|
+
return trimmed.startsWith("@import") ? ![...PACKAGE_DROP].some((pkg) => trimmed.includes(pkg)) : !0;
|
|
336
|
+
}).join(`
|
|
337
|
+
`);
|
|
338
|
+
}
|
|
339
|
+
function rewriteNpmrc(content) {
|
|
340
|
+
return content.split(`
|
|
341
|
+
`).filter((line) => !/^registry\s*=\s*https?:\/\/npm\.yandex-team\.ru/.test(line.trim())).join(`
|
|
342
|
+
`);
|
|
279
343
|
}
|
|
280
|
-
|
|
281
|
-
|
|
344
|
+
function applySubstitutions(filePath, content) {
|
|
345
|
+
let name = import_path2.default.basename(filePath), ext = import_path2.default.extname(filePath);
|
|
346
|
+
if (name === "package.json")
|
|
347
|
+
return Buffer.from(rewritePackageJson(content.toString("utf8")), "utf8");
|
|
348
|
+
if (name === "npmrc.template" || name === ".npmrc")
|
|
349
|
+
return Buffer.from(rewriteNpmrc(content.toString("utf8")), "utf8");
|
|
350
|
+
if (ext === ".scss" || ext === ".css")
|
|
351
|
+
return Buffer.from(rewriteScss(content.toString("utf8")), "utf8");
|
|
352
|
+
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
353
|
+
let text = content.toString("utf8"), rewritten = rewriteImports(text);
|
|
354
|
+
if (rewritten !== text)
|
|
355
|
+
return Buffer.from(rewritten, "utf8");
|
|
356
|
+
}
|
|
357
|
+
return content;
|
|
358
|
+
}
|
|
359
|
+
var import_path2, PACKAGE_RENAME, PACKAGE_DROP, ADDED_DEPS, templateDeps, init_templateSubstitution = __esm({
|
|
360
|
+
"src/distributions/external/templateSubstitution.ts"() {
|
|
282
361
|
"use strict";
|
|
283
|
-
|
|
284
|
-
|
|
362
|
+
import_path2 = __toESM(require("path")), PACKAGE_RENAME = {
|
|
363
|
+
"@yandex-data-ui/tracker-plugin-sdk-react": "@weavix/sdk-react",
|
|
364
|
+
"@yandex-data-ui/tracker-pub-api-types": "@weavix/tracker-api-types"
|
|
365
|
+
}, PACKAGE_DROP = /* @__PURE__ */ new Set(["@yandex-data-ui/gravity-themes"]), ADDED_DEPS = {
|
|
366
|
+
"@weavix/sdk-core": "latest",
|
|
367
|
+
"@weavix/sdk-react": "latest",
|
|
368
|
+
"@weavix/tracker-api-types": "latest"
|
|
369
|
+
}, templateDeps = ["@weavix/sdk-core", "@weavix/sdk-react", "@weavix/tracker-api-types"];
|
|
285
370
|
}
|
|
286
371
|
});
|
|
287
372
|
|
|
@@ -297,26 +382,35 @@ var impl2 = (init_registerCommands(), __toCommonJS(registerCommands_exports)), {
|
|
|
297
382
|
// src/utils/checkUpdate.ts
|
|
298
383
|
var import_node_fetch = __toESM(require("node-fetch"));
|
|
299
384
|
|
|
300
|
-
// src/distribution/
|
|
301
|
-
var impl3 = (
|
|
385
|
+
// src/distribution/hosts.ts
|
|
386
|
+
var impl3 = (init_hosts(), __toCommonJS(hosts_exports)), {
|
|
387
|
+
getS3Endpoint: getS3Endpoint2,
|
|
388
|
+
getMdsEndpoint: getMdsEndpoint2,
|
|
389
|
+
getS3Region: getS3Region2,
|
|
390
|
+
getBuckets: getBuckets2,
|
|
391
|
+
getPluginDownloadBase: getPluginDownloadBase2,
|
|
392
|
+
getPlatformBaseUrl: getPlatformBaseUrl2,
|
|
393
|
+
getTrackerBaseUrl: getTrackerBaseUrl2,
|
|
394
|
+
getOAuthTokenUrl: getOAuthTokenUrl2,
|
|
395
|
+
getUpdateCheckInfo: getUpdateCheckInfo2
|
|
396
|
+
} = impl3;
|
|
302
397
|
|
|
303
398
|
// src/utils/checkUpdate.ts
|
|
304
399
|
init_logger();
|
|
305
400
|
var checkUpdate = async (version) => {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
401
|
+
let info2 = getUpdateCheckInfo2();
|
|
402
|
+
if (info2)
|
|
403
|
+
try {
|
|
404
|
+
let response = await (0, import_node_fetch.default)(`${info2.registryUrl}/${info2.packageName}/latest`);
|
|
405
|
+
if (!response.ok)
|
|
406
|
+
return;
|
|
407
|
+
let latest = await response.json();
|
|
408
|
+
latest.version !== version && (logger_default.newLine(), logger_default.info(
|
|
409
|
+
`\u{1F514} Update available ${version} \u2192 ${latest.version}
|
|
410
|
+
Run: npm i -g ${info2.packageName}@latest --registry=${info2.registryUrl}`
|
|
411
|
+
));
|
|
412
|
+
} catch {
|
|
413
|
+
}
|
|
320
414
|
};
|
|
321
415
|
|
|
322
416
|
// src/utils/execCommand.ts
|
|
@@ -346,180 +440,282 @@ var build = async ({ environment = "production" } = {}) => {
|
|
|
346
440
|
);
|
|
347
441
|
};
|
|
348
442
|
|
|
349
|
-
// src/
|
|
350
|
-
var
|
|
443
|
+
// src/commands/create/index.ts
|
|
444
|
+
var path8 = __toESM(require("path")), import_prompts2 = require("@inquirer/prompts");
|
|
445
|
+
|
|
446
|
+
// src/core/manifest/constants.ts
|
|
447
|
+
var DATA_PERMISSIONS = [
|
|
448
|
+
// top 10
|
|
449
|
+
"tracker:issues:read",
|
|
450
|
+
"tracker:issues:write",
|
|
451
|
+
"tracker:issuetypes:read",
|
|
452
|
+
"tracker:statuses:read",
|
|
453
|
+
"tracker:queues:read",
|
|
454
|
+
"tracker:fields:read",
|
|
455
|
+
"tracker:entities:read",
|
|
456
|
+
"tracker:attachments:read",
|
|
457
|
+
"tracker:attachments:write",
|
|
458
|
+
// in alphabetical order
|
|
459
|
+
"tracker:applications:read",
|
|
460
|
+
"tracker:boards:read",
|
|
461
|
+
"tracker:boards:write",
|
|
462
|
+
"tracker:bulk:read",
|
|
463
|
+
"tracker:bulk:write",
|
|
464
|
+
"tracker:bulkchange:read",
|
|
465
|
+
"tracker:bulkchange:write",
|
|
466
|
+
"tracker:charts:read",
|
|
467
|
+
"tracker:commentTemplates:read",
|
|
468
|
+
"tracker:commentTemplates:write",
|
|
469
|
+
"tracker:components:read",
|
|
470
|
+
"tracker:components:write",
|
|
471
|
+
"tracker:data:read",
|
|
472
|
+
"tracker:departments:read",
|
|
473
|
+
"tracker:entities:write",
|
|
474
|
+
"tracker:externalEventTypes:write",
|
|
475
|
+
"tracker:externalEvents:write",
|
|
476
|
+
"tracker:fields:write",
|
|
477
|
+
"tracker:filterFolders:write",
|
|
478
|
+
"tracker:filters:read",
|
|
479
|
+
"tracker:filters:write",
|
|
480
|
+
"tracker:goals:read",
|
|
481
|
+
"tracker:goals:write",
|
|
482
|
+
"tracker:groups:read",
|
|
483
|
+
"tracker:issueTemplates:read",
|
|
484
|
+
"tracker:issueTemplates:write",
|
|
485
|
+
"tracker:links:read",
|
|
486
|
+
"tracker:linktypes:read",
|
|
487
|
+
"tracker:liveBoards:write",
|
|
488
|
+
"tracker:localFields:read",
|
|
489
|
+
"tracker:maillists:read",
|
|
490
|
+
"tracker:maillists:write",
|
|
491
|
+
"tracker:myself:read",
|
|
492
|
+
"tracker:myself:write",
|
|
493
|
+
"tracker:priorities:read",
|
|
494
|
+
"tracker:queues:write",
|
|
495
|
+
"tracker:reminders:read",
|
|
496
|
+
"tracker:reminders:write",
|
|
497
|
+
"tracker:remotelinks:read",
|
|
498
|
+
"tracker:reports:read",
|
|
499
|
+
"tracker:reports:write",
|
|
500
|
+
"tracker:resolutions:read",
|
|
501
|
+
"tracker:resources:read",
|
|
502
|
+
"tracker:resources:write",
|
|
503
|
+
"tracker:roles:read",
|
|
504
|
+
"tracker:screens:read",
|
|
505
|
+
"tracker:services:read",
|
|
506
|
+
"tracker:sprints:read",
|
|
507
|
+
"tracker:sprints:write",
|
|
508
|
+
"tracker:system:write",
|
|
509
|
+
"tracker:tags:read",
|
|
510
|
+
"tracker:translations:read",
|
|
511
|
+
"tracker:users:read",
|
|
512
|
+
"tracker:users:write",
|
|
513
|
+
"tracker:versions:read",
|
|
514
|
+
"tracker:versions:write",
|
|
515
|
+
"tracker:workflows:read",
|
|
516
|
+
"tracker:workflows:write",
|
|
517
|
+
"tracker:worklog:read",
|
|
518
|
+
"tracker:worklog:write"
|
|
519
|
+
], TOP_DATA_PERMISSIONS = DATA_PERMISSIONS.slice(0, 10);
|
|
520
|
+
var TEMPLATES = [
|
|
521
|
+
"default",
|
|
522
|
+
"issue.action",
|
|
523
|
+
"issue.block",
|
|
524
|
+
"issue.tab",
|
|
525
|
+
"issue.comment.action",
|
|
526
|
+
"navigation",
|
|
527
|
+
"trigger.action",
|
|
528
|
+
"project.action",
|
|
529
|
+
"portfolio.action",
|
|
530
|
+
"goal.action",
|
|
531
|
+
"attachment.viewer.action"
|
|
532
|
+
];
|
|
533
|
+
var TEMPLATE_SLOTS = {
|
|
534
|
+
default: [],
|
|
535
|
+
"issue.action": ["issue.action"],
|
|
536
|
+
"issue.block": ["issue.block"],
|
|
537
|
+
"issue.tab": ["issue.tab"],
|
|
538
|
+
"issue.comment.action": ["issue.comment.action"],
|
|
539
|
+
navigation: ["navigation"],
|
|
540
|
+
"trigger.action": ["trigger.create.action", "trigger.edit.action"],
|
|
541
|
+
"project.action": ["project.action"],
|
|
542
|
+
"portfolio.action": ["portfolio.action"],
|
|
543
|
+
"goal.action": ["goal.action"],
|
|
544
|
+
"attachment.viewer.action": ["attachment.viewer.action"]
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
// src/commands/create/index.ts
|
|
548
|
+
init_logger();
|
|
549
|
+
|
|
550
|
+
// src/commands/create/utils/getWelcomeMessage.ts
|
|
551
|
+
var import_picocolors2 = __toESM(require("picocolors")), getWelcomeMessage = (pwd) => `
|
|
552
|
+
${import_picocolors2.default.bold(import_picocolors2.default.white("\u{1F680} Create new tracker plugin"))}
|
|
351
553
|
|
|
352
|
-
|
|
353
|
-
var import_node_fetch2 = __toESM(require("node-fetch"));
|
|
554
|
+
${import_picocolors2.default.dim(`\u{1F4C1} Creating an app in your current directory: ${pwd}`)}
|
|
354
555
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}, saveAuthData = (token) => {
|
|
369
|
-
let authData = {
|
|
370
|
-
token
|
|
556
|
+
${import_picocolors2.default.dim("Press")} ${import_picocolors2.default.yellow("Ctrl+C")} ${import_picocolors2.default.dim("to cancel.")}
|
|
557
|
+
`;
|
|
558
|
+
|
|
559
|
+
// src/commands/create/utils/initManifest.ts
|
|
560
|
+
var fs = __toESM(require("fs")), path2 = __toESM(require("path"));
|
|
561
|
+
|
|
562
|
+
// src/commands/create/utils/generateManifest.ts
|
|
563
|
+
function buildSlots(template, slotTitle) {
|
|
564
|
+
let slotNames = TEMPLATE_SLOTS[template];
|
|
565
|
+
if (slotNames.length === 0) return;
|
|
566
|
+
let slotEntry = {
|
|
567
|
+
entrypoint: "index.html",
|
|
568
|
+
title: { ru: slotTitle, en: slotTitle }
|
|
371
569
|
};
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
570
|
+
return {
|
|
571
|
+
tracker: Object.fromEntries(slotNames.map((slotName) => [slotName, [slotEntry]]))
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
var generateManifest = (answers) => ({
|
|
575
|
+
$schema: "./manifest.schema.json",
|
|
576
|
+
manifest_version: 1,
|
|
577
|
+
supported_services: ["tracker"],
|
|
578
|
+
slug: answers.packageSlug,
|
|
579
|
+
version: answers.version,
|
|
580
|
+
name: {
|
|
581
|
+
ru: answers.pluginName,
|
|
582
|
+
en: answers.pluginName
|
|
380
583
|
},
|
|
381
|
-
|
|
382
|
-
|
|
584
|
+
description: {
|
|
585
|
+
ru: answers.pluginDescription,
|
|
586
|
+
en: answers.pluginDescription
|
|
383
587
|
},
|
|
384
|
-
|
|
385
|
-
|
|
588
|
+
permissions: answers.permissions,
|
|
589
|
+
support: [{ type: "email", value: answers.supportEmail }],
|
|
590
|
+
slots: buildSlots(answers.template, answers.slotTitle)
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
// src/commands/create/utils/initManifest.ts
|
|
594
|
+
var initManifest = ({ answers, targetDir }) => {
|
|
595
|
+
let generatedManifest = generateManifest(answers), manifestPath2 = path2.join(targetDir, "manifest.json");
|
|
596
|
+
fs.writeFileSync(manifestPath2, JSON.stringify(generatedManifest, null, 2), "utf-8");
|
|
386
597
|
};
|
|
387
598
|
|
|
388
|
-
// src/
|
|
389
|
-
var
|
|
599
|
+
// src/commands/create/utils/initTemplate.ts
|
|
600
|
+
var fs4 = __toESM(require("fs")), path7 = __toESM(require("path"));
|
|
390
601
|
|
|
391
|
-
// src/
|
|
392
|
-
|
|
393
|
-
if (!queryParams || Object.keys(queryParams).length === 0)
|
|
394
|
-
return "";
|
|
395
|
-
let params = new URLSearchParams();
|
|
396
|
-
return Object.entries(queryParams).forEach(([key, value]) => {
|
|
397
|
-
params.append(key, String(value));
|
|
398
|
-
}), `?${params.toString()}`;
|
|
399
|
-
}
|
|
400
|
-
async function parseResponse(response) {
|
|
401
|
-
return response.status === 204 || response.headers.get("content-length") === "0" ? void 0 : response.headers.get("content-type")?.includes("application/json") ? await response.json() : await response.text();
|
|
402
|
-
}
|
|
403
|
-
async function trackerApiRequest(endpoint, options = {}) {
|
|
404
|
-
let { method = "GET", body, headers = {}, formData, queryParams } = options, authHeader = authManager.authHeader;
|
|
405
|
-
if (!authHeader)
|
|
406
|
-
throw new Error('Not authenticated. Run "tracker-cli login" first.');
|
|
407
|
-
let requestHeaders = {
|
|
408
|
-
Authorization: authHeader,
|
|
409
|
-
Accept: "application/json",
|
|
410
|
-
...headers
|
|
411
|
-
}, requestBody;
|
|
412
|
-
if (formData) {
|
|
413
|
-
let formHeaders = formData.getHeaders?.();
|
|
414
|
-
Object.assign(requestHeaders, formHeaders), requestBody = formData;
|
|
415
|
-
} else body && method !== "GET" && (requestHeaders["Content-Type"] = "application/json", requestBody = JSON.stringify(body));
|
|
416
|
-
let queryString = buildQueryString(queryParams), url = `${await getTrackerApiUrl2()}${endpoint}${queryString}`, response = await (0, import_node_fetch2.default)(url, {
|
|
417
|
-
method,
|
|
418
|
-
headers: requestHeaders,
|
|
419
|
-
body: requestBody
|
|
420
|
-
});
|
|
421
|
-
if (!response.ok) {
|
|
422
|
-
let errorText = await response.text(), errorMessage = `Tracker API error ${response.status}: ${errorText}`;
|
|
423
|
-
try {
|
|
424
|
-
let errorJson = JSON.parse(errorText);
|
|
425
|
-
errorJson.message && (errorMessage = `Tracker API error ${response.status}: ${errorJson.message}`);
|
|
426
|
-
} catch {
|
|
427
|
-
}
|
|
428
|
-
throw new Error(errorMessage);
|
|
429
|
-
}
|
|
430
|
-
return parseResponse(response);
|
|
431
|
-
}
|
|
602
|
+
// src/utils/copyDirectory.ts
|
|
603
|
+
var fs2 = __toESM(require("fs")), import_path3 = __toESM(require("path")), import_tinyglobby = require("tinyglobby");
|
|
432
604
|
|
|
433
|
-
// src/
|
|
434
|
-
var
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
`**Version:** ${version}`
|
|
443
|
-
];
|
|
444
|
-
return catalogName && lines.push(`**Name:** ${catalogName}`), catalogDescription && lines.push(`**Description:** ${catalogDescription}`), catalogTags && catalogTags.length > 0 && lines.push(`**Tags:** ${catalogTags.join(", ")}`), lines.push("", "**Manifest:**", "```json", manifestJson, "```"), lines.join(`
|
|
445
|
-
`);
|
|
446
|
-
}
|
|
447
|
-
async function createPluginIssue(params) {
|
|
448
|
-
let { slug, pluginId, version, manifestJson } = params, body = {
|
|
449
|
-
queue: PLUGINMOD_QUEUE,
|
|
450
|
-
summary: buildIssueSummary(slug),
|
|
451
|
-
description: buildIssueDescription({ pluginId, slug, version, manifestJson }),
|
|
452
|
-
tags: ["tracker-plugin"]
|
|
453
|
-
};
|
|
454
|
-
return trackerApiRequest("/issues", {
|
|
455
|
-
method: "POST",
|
|
456
|
-
body
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
async function updatePluginIssue(issueKey, params) {
|
|
460
|
-
return trackerApiRequest(`/issues/${issueKey}`, {
|
|
461
|
-
method: "PATCH",
|
|
462
|
-
body: params
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
async function attachFileToIssue(issueKey, fileBuffer, fileName) {
|
|
466
|
-
let formData = new import_form_data.default();
|
|
467
|
-
return formData.append("file", fileBuffer, {
|
|
468
|
-
filename: fileName,
|
|
469
|
-
contentType: "application/zip"
|
|
470
|
-
}), trackerApiRequest(`/issues/${issueKey}/attachments`, {
|
|
471
|
-
method: "POST",
|
|
472
|
-
formData
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
async function getIssueAttachments(issueKey) {
|
|
476
|
-
return trackerApiRequest(`/issues/${issueKey}/attachments`, {
|
|
477
|
-
method: "GET"
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
async function getIssueTransitions(issueKey) {
|
|
481
|
-
return trackerApiRequest(`/issues/${issueKey}/transitions`, {
|
|
482
|
-
method: "GET"
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
async function executeIssueTransition(issueKey, transitionId) {
|
|
486
|
-
await trackerApiRequest(`/issues/${issueKey}/transitions/${transitionId}/_execute`, {
|
|
487
|
-
method: "POST",
|
|
488
|
-
body: {}
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
async function getIssue(issueKey) {
|
|
492
|
-
return trackerApiRequest(`/issues/${issueKey}`, {
|
|
493
|
-
method: "GET"
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
async function getMyPluginIssues() {
|
|
497
|
-
return trackerApiRequest("/issues/_search", {
|
|
498
|
-
method: "POST",
|
|
499
|
-
body: {
|
|
500
|
-
filter: {
|
|
501
|
-
queue: PLUGINMOD_QUEUE,
|
|
502
|
-
createdBy: "me()"
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
async function addIssueComment(issueKey, text) {
|
|
508
|
-
await trackerApiRequest(`/issues/${issueKey}/comments`, {
|
|
509
|
-
method: "POST",
|
|
510
|
-
body: { text }
|
|
605
|
+
// src/distribution/templateSubstitution.ts
|
|
606
|
+
var impl4 = (init_templateSubstitution(), __toCommonJS(templateSubstitution_exports)), { applySubstitutions: applySubstitutions2, templateDeps: templateDeps2 } = impl4;
|
|
607
|
+
|
|
608
|
+
// src/utils/copyDirectory.ts
|
|
609
|
+
var resolveTargetFileName = (file) => file.endsWith(".template") ? "." + file.replace(".template", "") : file, copyDirectory = async (sourceDir, targetDir) => {
|
|
610
|
+
let files = await (0, import_tinyglobby.glob)(["**/*"], {
|
|
611
|
+
cwd: sourceDir,
|
|
612
|
+
onlyFiles: !0,
|
|
613
|
+
dot: !0
|
|
511
614
|
});
|
|
512
|
-
|
|
615
|
+
await Promise.all(
|
|
616
|
+
files.map(async (file) => {
|
|
617
|
+
let sourcePath = import_path3.default.join(sourceDir, file), targetFile = resolveTargetFileName(file), targetPath = import_path3.default.join(targetDir, targetFile);
|
|
618
|
+
await fs2.promises.mkdir(import_path3.default.dirname(targetPath), { recursive: !0 });
|
|
619
|
+
let content = await fs2.promises.readFile(sourcePath), rewritten = applySubstitutions2(file, content);
|
|
620
|
+
await fs2.promises.writeFile(targetPath, rewritten);
|
|
621
|
+
})
|
|
622
|
+
);
|
|
623
|
+
};
|
|
513
624
|
|
|
514
|
-
// src/
|
|
515
|
-
var
|
|
625
|
+
// src/utils/getProjectPath.ts
|
|
626
|
+
var import_path4 = __toESM(require("path")), isDevelopment = () => __dirname.includes("/src/"), getProjectPath = (relativePath) => {
|
|
627
|
+
let levelsUp = isDevelopment() ? "../.." : "..";
|
|
628
|
+
return import_path4.default.resolve(__dirname, levelsUp, relativePath);
|
|
629
|
+
}, getTemplatesBaseDir = () => getProjectPath("templates"), getTemplatePath = (filename) => import_path4.default.join(getTemplatesBaseDir(), "_shared", filename);
|
|
516
630
|
|
|
517
|
-
// src/
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
"
|
|
631
|
+
// src/commands/create/utils/initTemplate.ts
|
|
632
|
+
init_logger();
|
|
633
|
+
|
|
634
|
+
// src/commands/create/utils/updatePackageJson.ts
|
|
635
|
+
var fs3 = __toESM(require("fs")), path6 = __toESM(require("path")), updatePackageJson = (targetDir, packageSlug) => {
|
|
636
|
+
let packageJsonPath = path6.join(targetDir, "package.json");
|
|
637
|
+
if (fs3.existsSync(packageJsonPath)) {
|
|
638
|
+
let packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
|
|
639
|
+
packageJson.name = packageSlug, fs3.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
640
|
+
`);
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
// src/commands/create/utils/initTemplate.ts
|
|
645
|
+
var initTemplate = async ({ answers, targetDir }) => {
|
|
646
|
+
fs4.existsSync(targetDir) || fs4.mkdirSync(targetDir, { recursive: !0 });
|
|
647
|
+
let templatesBaseDir = getTemplatesBaseDir(), templatesDir = path7.join(templatesBaseDir, answers.template), sharedDir = path7.join(templatesBaseDir, "_shared");
|
|
648
|
+
await copyDirectory(sharedDir, targetDir), await copyDirectory(templatesDir, targetDir), updatePackageJson(targetDir, answers.packageSlug), logger_default.info("Created template with marketplace publication requirements."), logger_default.info(
|
|
649
|
+
"Before publishing, add ./marketplace/index.md, ./marketplace/header-image.jpg (784:325), and ./public/logo.svg (square)."
|
|
650
|
+
);
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// src/commands/create/index.ts
|
|
654
|
+
var DEFAULT_VERSION = "0.0.1";
|
|
655
|
+
async function create() {
|
|
656
|
+
logger_default.info(getWelcomeMessage(process.cwd()));
|
|
657
|
+
let packageSlug = await (0, import_prompts2.input)({
|
|
658
|
+
message: "Enter app slug (e.g., my-tracker-plugin):",
|
|
659
|
+
required: !0
|
|
660
|
+
}), pluginName = await (0, import_prompts2.input)({
|
|
661
|
+
message: "Enter plugin name:",
|
|
662
|
+
required: !0
|
|
663
|
+
}), pluginDescription = await (0, import_prompts2.input)({
|
|
664
|
+
message: "Enter plugin description:",
|
|
665
|
+
required: !0
|
|
666
|
+
}), supportEmail = await (0, import_prompts2.input)({
|
|
667
|
+
message: "Enter support email:",
|
|
668
|
+
required: !0,
|
|
669
|
+
validate: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || "Please enter a valid email address"
|
|
670
|
+
}), template = await (0, import_prompts2.select)({
|
|
671
|
+
message: "Select a template:",
|
|
672
|
+
choices: TEMPLATES.map((templateName) => ({
|
|
673
|
+
name: templateName,
|
|
674
|
+
value: templateName
|
|
675
|
+
}))
|
|
676
|
+
}), dataPermissions = await (0, import_prompts2.checkbox)({
|
|
677
|
+
message: "Select data permissions (some popular options):",
|
|
678
|
+
choices: TOP_DATA_PERMISSIONS.map((permission) => ({
|
|
679
|
+
name: permission,
|
|
680
|
+
value: permission
|
|
681
|
+
}))
|
|
682
|
+
}), answers = {
|
|
683
|
+
packageSlug,
|
|
684
|
+
slotTitle: packageSlug,
|
|
685
|
+
pluginName,
|
|
686
|
+
pluginDescription,
|
|
687
|
+
supportEmail,
|
|
688
|
+
template,
|
|
689
|
+
permissions: {
|
|
690
|
+
data: dataPermissions
|
|
691
|
+
},
|
|
692
|
+
version: DEFAULT_VERSION
|
|
693
|
+
}, targetDir = path8.join(process.cwd(), answers.packageSlug);
|
|
694
|
+
await initTemplate({
|
|
695
|
+
answers,
|
|
696
|
+
targetDir
|
|
697
|
+
}), initManifest({
|
|
698
|
+
answers,
|
|
699
|
+
targetDir
|
|
700
|
+
}), logger_default.newLine(), logger_default.success("Package generated!"), logger_default.commands("To get started, run", [
|
|
701
|
+
`cd ${answers.packageSlug}`,
|
|
702
|
+
"npm install",
|
|
703
|
+
`${CLI_NAME2} debug`
|
|
704
|
+
]);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// src/commands/debug/index.ts
|
|
708
|
+
var import_fs6 = __toESM(require("fs")), import_path8 = __toESM(require("path"));
|
|
709
|
+
|
|
710
|
+
// src/core/manifest/manifestManager.ts
|
|
711
|
+
var import_fs2 = require("fs"), import_promises = require("fs/promises"), import_ajv = __toESM(require("ajv")), import_ajv_formats = __toESM(require("ajv-formats"));
|
|
712
|
+
|
|
713
|
+
// src/core/manifest/formatValidationErrors.ts
|
|
714
|
+
var priorityOrder = [
|
|
715
|
+
"required",
|
|
716
|
+
"type",
|
|
717
|
+
"minLength",
|
|
718
|
+
"format",
|
|
523
719
|
"pattern",
|
|
524
720
|
"enum",
|
|
525
721
|
"additionalProperties",
|
|
@@ -539,14 +735,14 @@ var priorityOrder = [
|
|
|
539
735
|
}, formatValidationErrors = (errors) => {
|
|
540
736
|
let errorsByPath = {};
|
|
541
737
|
for (let error2 of errors) {
|
|
542
|
-
let
|
|
543
|
-
errorsByPath[
|
|
738
|
+
let path13 = error2.instancePath || "root";
|
|
739
|
+
errorsByPath[path13] || (errorsByPath[path13] = []), errorsByPath[path13].push(error2);
|
|
544
740
|
}
|
|
545
|
-
return Object.entries(errorsByPath).map(([
|
|
741
|
+
return Object.entries(errorsByPath).map(([path13, pathErrors]) => {
|
|
546
742
|
let error2 = [...pathErrors].sort(
|
|
547
743
|
(a, b) => getPriority(a.keyword) - getPriority(b.keyword)
|
|
548
744
|
)[0], formatter = errorMessages[error2.keyword], message = formatter ? formatter(error2.params) : error2.message;
|
|
549
|
-
return ` - ${
|
|
745
|
+
return ` - ${path13}: ${message}`;
|
|
550
746
|
}).join(`
|
|
551
747
|
`);
|
|
552
748
|
};
|
|
@@ -560,7 +756,10 @@ var manifest_schema_default = {
|
|
|
560
756
|
required: [
|
|
561
757
|
"slug",
|
|
562
758
|
"version",
|
|
563
|
-
"permissions"
|
|
759
|
+
"permissions",
|
|
760
|
+
"name",
|
|
761
|
+
"description",
|
|
762
|
+
"support"
|
|
564
763
|
],
|
|
565
764
|
properties: {
|
|
566
765
|
$schema: {
|
|
@@ -573,6 +772,23 @@ var manifest_schema_default = {
|
|
|
573
772
|
maxLength: 63,
|
|
574
773
|
pattern: "^[a-z0-9-]+$"
|
|
575
774
|
},
|
|
775
|
+
manifest_version: {
|
|
776
|
+
type: "number",
|
|
777
|
+
description: "Manifest format version",
|
|
778
|
+
minimum: 1
|
|
779
|
+
},
|
|
780
|
+
supported_services: {
|
|
781
|
+
type: "array",
|
|
782
|
+
description: "Supported services for this plugin",
|
|
783
|
+
items: {
|
|
784
|
+
type: "string",
|
|
785
|
+
enum: [
|
|
786
|
+
"tracker"
|
|
787
|
+
]
|
|
788
|
+
},
|
|
789
|
+
minItems: 1,
|
|
790
|
+
uniqueItems: !0
|
|
791
|
+
},
|
|
576
792
|
slug: {
|
|
577
793
|
type: "string",
|
|
578
794
|
description: "Unique identifier for the plugin (lowercase letters, numbers, hyphen)",
|
|
@@ -621,13 +837,13 @@ var manifest_schema_default = {
|
|
|
621
837
|
type: "string",
|
|
622
838
|
description: "Russian description",
|
|
623
839
|
minLength: 1,
|
|
624
|
-
maxLength:
|
|
840
|
+
maxLength: 255
|
|
625
841
|
},
|
|
626
842
|
en: {
|
|
627
843
|
type: "string",
|
|
628
844
|
description: "English description",
|
|
629
845
|
minLength: 1,
|
|
630
|
-
maxLength:
|
|
846
|
+
maxLength: 255
|
|
631
847
|
}
|
|
632
848
|
},
|
|
633
849
|
additionalProperties: !1
|
|
@@ -901,14 +1117,6 @@ var manifest_schema_default = {
|
|
|
901
1117
|
$ref: "#/definitions/SlotConfig"
|
|
902
1118
|
}
|
|
903
1119
|
},
|
|
904
|
-
"issue.floatingbottom.action": {
|
|
905
|
-
type: "array",
|
|
906
|
-
description: "Issue Floatingbottom Action slot configurations",
|
|
907
|
-
minItems: 1,
|
|
908
|
-
items: {
|
|
909
|
-
$ref: "#/definitions/SlotConfig"
|
|
910
|
-
}
|
|
911
|
-
},
|
|
912
1120
|
"attachment.viewer.action": {
|
|
913
1121
|
type: "array",
|
|
914
1122
|
description: "Attachment Viewer Action slot configurations",
|
|
@@ -1007,7 +1215,7 @@ var validator = (() => {
|
|
|
1007
1215
|
if (!(0, import_fs2.existsSync)(manifestPath))
|
|
1008
1216
|
throw new Error(`File manifest.json not found at path: ${manifestPath}`);
|
|
1009
1217
|
try {
|
|
1010
|
-
return await (0,
|
|
1218
|
+
return await (0, import_promises.readFile)(manifestPath, "utf8");
|
|
1011
1219
|
} catch (error2) {
|
|
1012
1220
|
throw error2 instanceof Error ? new Error(`Error reading manifest.json: ${error2.message}`) : new Error("Error loading manifest");
|
|
1013
1221
|
}
|
|
@@ -1024,7 +1232,7 @@ ${errorMessages2}`);
|
|
|
1024
1232
|
}, save = async (manifest) => {
|
|
1025
1233
|
try {
|
|
1026
1234
|
let content = JSON.stringify(manifest, null, 4);
|
|
1027
|
-
await (0,
|
|
1235
|
+
await (0, import_promises.writeFile)(manifestPath, content, "utf8");
|
|
1028
1236
|
} catch (error2) {
|
|
1029
1237
|
throw error2 instanceof Error ? new Error(`Error saving manifest.json: ${error2.message}`) : new Error("Error saving manifest");
|
|
1030
1238
|
}
|
|
@@ -1039,1507 +1247,196 @@ ${errorMessages2}`);
|
|
|
1039
1247
|
update
|
|
1040
1248
|
};
|
|
1041
1249
|
|
|
1042
|
-
// src/core/
|
|
1043
|
-
var
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1250
|
+
// src/core/s3config/constants.ts
|
|
1251
|
+
var CONFIG_FILE_NAME = "config.json";
|
|
1252
|
+
|
|
1253
|
+
// src/commands/debug/index.ts
|
|
1254
|
+
init_logger();
|
|
1255
|
+
|
|
1256
|
+
// src/utils/registerCleanup.ts
|
|
1257
|
+
var registerCleanup = (cleanup) => {
|
|
1258
|
+
process.on("SIGINT", () => {
|
|
1259
|
+
cleanup(), process.exit(0);
|
|
1260
|
+
}), process.on("SIGTERM", () => {
|
|
1261
|
+
cleanup(), process.exit(0);
|
|
1262
|
+
});
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
// src/commands/debug/utils/createDebugConfig.ts
|
|
1266
|
+
var import_fs3 = __toESM(require("fs")), import_path5 = __toESM(require("path"));
|
|
1267
|
+
|
|
1268
|
+
// src/utils/convertManifestToConfig.ts
|
|
1269
|
+
function buildPluginDownloadUrl(env, id, version) {
|
|
1270
|
+
return env === "debug" ? getPluginDownloadBase2(env) : `${getPluginDownloadBase2(env)}/${id}/${version}`;
|
|
1271
|
+
}
|
|
1272
|
+
var convertManifestToConfig = (manifest, environment) => {
|
|
1273
|
+
let config = {};
|
|
1274
|
+
if (!manifest.slots)
|
|
1275
|
+
return config;
|
|
1276
|
+
for (let service in manifest.slots) {
|
|
1277
|
+
if (!Object.prototype.hasOwnProperty.call(manifest.slots, service))
|
|
1278
|
+
continue;
|
|
1279
|
+
let serviceSlots = manifest.slots[service];
|
|
1280
|
+
if (serviceSlots)
|
|
1281
|
+
for (let slotKey in serviceSlots) {
|
|
1282
|
+
if (!Object.prototype.hasOwnProperty.call(serviceSlots, slotKey))
|
|
1283
|
+
continue;
|
|
1284
|
+
let slot = slotKey, slotConfigs = serviceSlots[slot];
|
|
1285
|
+
if (!(!slotConfigs || !Array.isArray(slotConfigs))) {
|
|
1286
|
+
config[slot] || (config[slot] = []);
|
|
1287
|
+
for (let slotConfig of slotConfigs) {
|
|
1288
|
+
let pluginConfig = {
|
|
1289
|
+
slug: manifest.slug,
|
|
1290
|
+
version: manifest.version,
|
|
1291
|
+
permissions: manifest.permissions,
|
|
1292
|
+
description: slotConfig.description,
|
|
1293
|
+
entrypoint: slotConfig.entrypoint,
|
|
1294
|
+
title: slotConfig.title,
|
|
1295
|
+
downloadUrl: buildPluginDownloadUrl(
|
|
1296
|
+
environment,
|
|
1297
|
+
manifest.slug,
|
|
1298
|
+
manifest.version
|
|
1299
|
+
)
|
|
1300
|
+
};
|
|
1301
|
+
config[slot].push(pluginConfig);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1051
1305
|
}
|
|
1052
|
-
|
|
1306
|
+
return config;
|
|
1307
|
+
};
|
|
1308
|
+
|
|
1309
|
+
// src/commands/debug/utils/createDebugConfig.ts
|
|
1310
|
+
var createDebugConfig = async () => {
|
|
1311
|
+
let manifest = await manifestManager.load(), config = convertManifestToConfig(manifest, "debug"), configPath = import_path5.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
1312
|
+
import_fs3.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
1313
|
+
};
|
|
1314
|
+
|
|
1315
|
+
// src/commands/debug/utils/lockFile.ts
|
|
1316
|
+
var import_fs4 = __toESM(require("fs")), import_path6 = __toESM(require("path")), LOCK_FILE_NAME = ".tracker-cli-debug.lock", getLockFilePath = () => import_path6.default.join(process.cwd(), LOCK_FILE_NAME), getRunningDebugPid = () => {
|
|
1317
|
+
let lockPath = getLockFilePath();
|
|
1318
|
+
if (!import_fs4.default.existsSync(lockPath))
|
|
1319
|
+
return null;
|
|
1053
1320
|
try {
|
|
1054
|
-
let
|
|
1055
|
-
|
|
1056
|
-
} catch
|
|
1057
|
-
|
|
1321
|
+
let pid = JSON.parse(import_fs4.default.readFileSync(lockPath, "utf-8")).pid;
|
|
1322
|
+
return process.kill(pid, 0), pid;
|
|
1323
|
+
} catch {
|
|
1324
|
+
try {
|
|
1325
|
+
import_fs4.default.unlinkSync(lockPath);
|
|
1326
|
+
} catch {
|
|
1327
|
+
}
|
|
1328
|
+
return null;
|
|
1058
1329
|
}
|
|
1059
|
-
},
|
|
1060
|
-
let
|
|
1061
|
-
|
|
1062
|
-
},
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1330
|
+
}, createLockFile = () => {
|
|
1331
|
+
let lockPath = getLockFilePath(), lockData = {
|
|
1332
|
+
pid: process.pid
|
|
1333
|
+
}, fd = import_fs4.default.openSync(lockPath, "wx");
|
|
1334
|
+
import_fs4.default.writeSync(fd, JSON.stringify(lockData, null, 2)), import_fs4.default.closeSync(fd);
|
|
1335
|
+
}, removeLockFile = () => {
|
|
1336
|
+
let lockPath = getLockFilePath();
|
|
1337
|
+
import_fs4.default.existsSync(lockPath) && import_fs4.default.unlinkSync(lockPath);
|
|
1066
1338
|
};
|
|
1067
1339
|
|
|
1068
|
-
// src/commands/
|
|
1340
|
+
// src/commands/debug/utils/watchManifest.ts
|
|
1341
|
+
var import_fs5 = __toESM(require("fs")), import_path7 = __toESM(require("path"));
|
|
1069
1342
|
init_logger();
|
|
1343
|
+
var watchManifest = () => {
|
|
1344
|
+
let manifestPath2 = import_path7.default.join(process.cwd(), "manifest.json"), debounceTimer = null, watcher = import_fs5.default.watch(manifestPath2, async (eventType) => {
|
|
1345
|
+
eventType === "change" && (debounceTimer && clearTimeout(debounceTimer), debounceTimer = setTimeout(async () => {
|
|
1346
|
+
try {
|
|
1347
|
+
logger_default.newLine(), logger_default.info("Manifest file changed, validating..."), await manifestManager.validate(), logger_default.info("Regenerating debug config..."), await createDebugConfig(), logger_default.success("Debug config regenerated successfully");
|
|
1348
|
+
} catch (error2) {
|
|
1349
|
+
logger_default.error(`Failed to regenerate debug config: ${error2.message}`);
|
|
1350
|
+
}
|
|
1351
|
+
}, 300));
|
|
1352
|
+
}), originalClose = watcher.close.bind(watcher);
|
|
1353
|
+
return watcher.close = () => {
|
|
1354
|
+
debounceTimer && clearTimeout(debounceTimer), originalClose();
|
|
1355
|
+
}, watcher;
|
|
1356
|
+
};
|
|
1070
1357
|
|
|
1071
|
-
// src/
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1358
|
+
// src/commands/debug/index.ts
|
|
1359
|
+
async function debug(options) {
|
|
1360
|
+
let runningPid = getRunningDebugPid();
|
|
1361
|
+
runningPid && (logger_default.error(
|
|
1362
|
+
`Another instance of ${CLI_NAME2} debug is already running.
|
|
1363
|
+
Please stop the existing instance before starting a new one.
|
|
1364
|
+
|
|
1365
|
+
If you lost the terminal tab, you can kill the process with:
|
|
1366
|
+
kill ${runningPid}`
|
|
1367
|
+
), process.exit(1));
|
|
1368
|
+
let configPath = import_path8.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
1369
|
+
options.lint && await manifestManager.validate(), await createDebugConfig();
|
|
1370
|
+
let watcher = watchManifest(), cleanup = () => {
|
|
1371
|
+
watcher.close(), import_fs6.default.existsSync(configPath) && import_fs6.default.unlinkSync(configPath), removeLockFile();
|
|
1372
|
+
};
|
|
1373
|
+
registerCleanup(cleanup), createLockFile(), await execCommand(pluginCmd.dev), cleanup();
|
|
1084
1374
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
});
|
|
1375
|
+
|
|
1376
|
+
// src/commands/lint.ts
|
|
1377
|
+
init_logger();
|
|
1378
|
+
async function lint() {
|
|
1379
|
+
logger_default.info("\u{1F50D} Running manifest.json validation..."), await manifestManager.validate(), logger_default.info("\u{1F50D} Running code lint check..."), await execCommand(pluginCmd.lint);
|
|
1091
1380
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1381
|
+
|
|
1382
|
+
// src/commands/up/utils/copyTemplateFiles.ts
|
|
1383
|
+
var import_fs7 = require("fs"), import_promises2 = require("fs/promises");
|
|
1384
|
+
var copyTemplateFiles = async (filenames) => {
|
|
1385
|
+
await Promise.all(
|
|
1386
|
+
filenames.map(async (filename) => {
|
|
1387
|
+
let templatePath = getTemplatePath(filename), targetPath = `./${filename}`;
|
|
1388
|
+
if ((0, import_fs7.existsSync)(templatePath) && (0, import_fs7.existsSync)(targetPath)) {
|
|
1389
|
+
let content = await (0, import_promises2.readFile)(templatePath), rewritten = applySubstitutions2(filename, content);
|
|
1390
|
+
await (0, import_promises2.writeFile)(targetPath, rewritten);
|
|
1391
|
+
}
|
|
1392
|
+
})
|
|
1393
|
+
);
|
|
1394
|
+
};
|
|
1395
|
+
|
|
1396
|
+
// src/commands/up/utils/updateManifestCompatibility.ts
|
|
1397
|
+
async function updateManifestCompatibility() {
|
|
1398
|
+
let manifest = await manifestManager.load(), updates = {};
|
|
1399
|
+
"manifest_version" in manifest || (updates.manifest_version = 1), "supported_services" in manifest || (updates.supported_services = ["tracker"]), Object.keys(updates).length > 0 && await manifestManager.update(updates);
|
|
1096
1400
|
}
|
|
1097
1401
|
|
|
1098
|
-
// src/commands/
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1402
|
+
// src/commands/up/utils/updatePackageDependencies.ts
|
|
1403
|
+
var import_fs8 = require("fs"), import_promises3 = require("fs/promises");
|
|
1404
|
+
var updatePackageDependencies = async (dependencies) => {
|
|
1405
|
+
let packageJsonPath = "./package.json", templatePackageJsonPath = getTemplatePath("package.json");
|
|
1406
|
+
if (!(0, import_fs8.existsSync)(packageJsonPath) || !(0, import_fs8.existsSync)(templatePackageJsonPath))
|
|
1103
1407
|
return;
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
});
|
|
1119
|
-
await updatePluginIssue(state.trackerIssueKey, {
|
|
1120
|
-
description: issueDescription
|
|
1121
|
-
}), logger_default.success("Catalog entry updated successfully!");
|
|
1408
|
+
let packageJsonContent = await (0, import_promises3.readFile)(packageJsonPath, "utf-8"), templatePackageJsonRaw = await (0, import_promises3.readFile)(templatePackageJsonPath), templatePackageJsonContent = applySubstitutions2(
|
|
1409
|
+
"package.json",
|
|
1410
|
+
templatePackageJsonRaw
|
|
1411
|
+
).toString("utf8"), packageJson = JSON.parse(packageJsonContent), templatePackageJson = JSON.parse(templatePackageJsonContent), updated = !1;
|
|
1412
|
+
dependencies.forEach((dep) => {
|
|
1413
|
+
packageJson.dependencies?.[dep] && templatePackageJson.dependencies?.[dep] && packageJson.dependencies[dep] !== templatePackageJson.dependencies[dep] && (packageJson.dependencies[dep] = templatePackageJson.dependencies[dep], updated = !0);
|
|
1414
|
+
}), updated && await (0, import_promises3.writeFile)(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
1415
|
+
`, "utf-8");
|
|
1416
|
+
};
|
|
1417
|
+
|
|
1418
|
+
// src/commands/up/index.ts
|
|
1419
|
+
var templateFiles = ["manifest.schema.json", "vite.config.ts"];
|
|
1420
|
+
async function up() {
|
|
1421
|
+
await copyTemplateFiles(templateFiles), await updateManifestCompatibility(), await updatePackageDependencies(templateDeps2);
|
|
1122
1422
|
}
|
|
1123
1423
|
|
|
1124
|
-
// src/
|
|
1125
|
-
var
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
"tracker:statuses:read",
|
|
1134
|
-
"tracker:queues:read",
|
|
1135
|
-
"tracker:fields:read",
|
|
1136
|
-
"tracker:entities:read",
|
|
1137
|
-
"tracker:attachments:read",
|
|
1138
|
-
"tracker:attachments:write",
|
|
1139
|
-
// in alphabetical order
|
|
1140
|
-
"tracker:applications:read",
|
|
1141
|
-
"tracker:boards:read",
|
|
1142
|
-
"tracker:boards:write",
|
|
1143
|
-
"tracker:bulk:read",
|
|
1144
|
-
"tracker:bulk:write",
|
|
1145
|
-
"tracker:bulkchange:read",
|
|
1146
|
-
"tracker:bulkchange:write",
|
|
1147
|
-
"tracker:charts:read",
|
|
1148
|
-
"tracker:commentTemplates:read",
|
|
1149
|
-
"tracker:commentTemplates:write",
|
|
1150
|
-
"tracker:components:read",
|
|
1151
|
-
"tracker:components:write",
|
|
1152
|
-
"tracker:data:read",
|
|
1153
|
-
"tracker:departments:read",
|
|
1154
|
-
"tracker:entities:write",
|
|
1155
|
-
"tracker:externalEventTypes:write",
|
|
1156
|
-
"tracker:externalEvents:write",
|
|
1157
|
-
"tracker:fields:write",
|
|
1158
|
-
"tracker:filterFolders:write",
|
|
1159
|
-
"tracker:filters:read",
|
|
1160
|
-
"tracker:filters:write",
|
|
1161
|
-
"tracker:goals:read",
|
|
1162
|
-
"tracker:goals:write",
|
|
1163
|
-
"tracker:groups:read",
|
|
1164
|
-
"tracker:issueTemplates:read",
|
|
1165
|
-
"tracker:issueTemplates:write",
|
|
1166
|
-
"tracker:links:read",
|
|
1167
|
-
"tracker:linktypes:read",
|
|
1168
|
-
"tracker:liveBoards:write",
|
|
1169
|
-
"tracker:localFields:read",
|
|
1170
|
-
"tracker:maillists:read",
|
|
1171
|
-
"tracker:maillists:write",
|
|
1172
|
-
"tracker:myself:read",
|
|
1173
|
-
"tracker:myself:write",
|
|
1174
|
-
"tracker:priorities:read",
|
|
1175
|
-
"tracker:queues:write",
|
|
1176
|
-
"tracker:reminders:read",
|
|
1177
|
-
"tracker:reminders:write",
|
|
1178
|
-
"tracker:remotelinks:read",
|
|
1179
|
-
"tracker:reports:read",
|
|
1180
|
-
"tracker:reports:write",
|
|
1181
|
-
"tracker:resolutions:read",
|
|
1182
|
-
"tracker:resources:read",
|
|
1183
|
-
"tracker:resources:write",
|
|
1184
|
-
"tracker:roles:read",
|
|
1185
|
-
"tracker:screens:read",
|
|
1186
|
-
"tracker:services:read",
|
|
1187
|
-
"tracker:sprints:read",
|
|
1188
|
-
"tracker:sprints:write",
|
|
1189
|
-
"tracker:system:write",
|
|
1190
|
-
"tracker:tags:read",
|
|
1191
|
-
"tracker:translations:read",
|
|
1192
|
-
"tracker:users:read",
|
|
1193
|
-
"tracker:users:write",
|
|
1194
|
-
"tracker:versions:read",
|
|
1195
|
-
"tracker:versions:write",
|
|
1196
|
-
"tracker:workflows:read",
|
|
1197
|
-
"tracker:workflows:write",
|
|
1198
|
-
"tracker:worklog:read",
|
|
1199
|
-
"tracker:worklog:write"
|
|
1200
|
-
], TOP_DATA_PERMISSIONS = DATA_PERMISSIONS.slice(0, 10);
|
|
1201
|
-
var TEMPLATES = [
|
|
1202
|
-
"default",
|
|
1203
|
-
"issue.action",
|
|
1204
|
-
"issue.block",
|
|
1205
|
-
"issue.tab",
|
|
1206
|
-
"issue.comment.action",
|
|
1207
|
-
"navigation",
|
|
1208
|
-
"trigger.action",
|
|
1209
|
-
"project.action",
|
|
1210
|
-
"portfolio.action",
|
|
1211
|
-
"goal.action",
|
|
1212
|
-
"issue.floatingbottom.action",
|
|
1213
|
-
"attachment.viewer.action"
|
|
1214
|
-
];
|
|
1215
|
-
var TEMPLATE_SLOTS = {
|
|
1216
|
-
default: [],
|
|
1217
|
-
"issue.action": ["issue.action"],
|
|
1218
|
-
"issue.block": ["issue.block"],
|
|
1219
|
-
"issue.tab": ["issue.tab"],
|
|
1220
|
-
"issue.comment.action": ["issue.comment.action"],
|
|
1221
|
-
navigation: ["navigation"],
|
|
1222
|
-
"trigger.action": ["trigger.create.action", "trigger.edit.action"],
|
|
1223
|
-
"project.action": ["project.action"],
|
|
1224
|
-
"portfolio.action": ["portfolio.action"],
|
|
1225
|
-
"goal.action": ["goal.action"],
|
|
1226
|
-
"issue.floatingbottom.action": ["issue.floatingbottom.action"],
|
|
1227
|
-
"attachment.viewer.action": ["attachment.viewer.action"]
|
|
1228
|
-
};
|
|
1229
|
-
|
|
1230
|
-
// src/commands/create/index.ts
|
|
1231
|
-
init_logger();
|
|
1232
|
-
|
|
1233
|
-
// src/commands/create/utils/getWelcomeMessage.ts
|
|
1234
|
-
var import_picocolors2 = __toESM(require("picocolors")), getWelcomeMessage = (pwd) => `
|
|
1235
|
-
${import_picocolors2.default.bold(import_picocolors2.default.white("\u{1F680} Create new tracker plugin"))}
|
|
1236
|
-
|
|
1237
|
-
${import_picocolors2.default.dim(`\u{1F4C1} Creating an app in your current directory: ${pwd}`)}
|
|
1238
|
-
|
|
1239
|
-
${import_picocolors2.default.dim("Press")} ${import_picocolors2.default.yellow("Ctrl+C")} ${import_picocolors2.default.dim("to cancel.")}
|
|
1240
|
-
`;
|
|
1241
|
-
|
|
1242
|
-
// src/commands/create/utils/initManifest.ts
|
|
1243
|
-
var fs2 = __toESM(require("fs")), path3 = __toESM(require("path"));
|
|
1244
|
-
|
|
1245
|
-
// src/commands/create/utils/generateManifest.ts
|
|
1246
|
-
function buildSlots(template, slotTitle) {
|
|
1247
|
-
let slotNames = TEMPLATE_SLOTS[template];
|
|
1248
|
-
if (slotNames.length === 0) return;
|
|
1249
|
-
let slotEntry = {
|
|
1250
|
-
entrypoint: "index.html",
|
|
1251
|
-
title: { ru: slotTitle, en: slotTitle }
|
|
1252
|
-
};
|
|
1253
|
-
return {
|
|
1254
|
-
tracker: Object.fromEntries(slotNames.map((slotName) => [slotName, [slotEntry]]))
|
|
1255
|
-
};
|
|
1256
|
-
}
|
|
1257
|
-
var generateManifest = (answers) => ({
|
|
1258
|
-
$schema: "./manifest.schema.json",
|
|
1259
|
-
slug: answers.packageSlug,
|
|
1260
|
-
version: answers.version,
|
|
1261
|
-
permissions: answers.permissions,
|
|
1262
|
-
slots: buildSlots(answers.template, answers.slotTitle)
|
|
1263
|
-
});
|
|
1264
|
-
|
|
1265
|
-
// src/commands/create/utils/initManifest.ts
|
|
1266
|
-
var initManifest = ({ answers, targetDir }) => {
|
|
1267
|
-
let generatedManifest = generateManifest(answers), manifestPath2 = path3.join(targetDir, "manifest.json");
|
|
1268
|
-
fs2.writeFileSync(manifestPath2, JSON.stringify(generatedManifest, null, 2), "utf-8");
|
|
1269
|
-
};
|
|
1270
|
-
|
|
1271
|
-
// src/commands/create/utils/initTemplate.ts
|
|
1272
|
-
var fs5 = __toESM(require("fs")), path7 = __toESM(require("path"));
|
|
1273
|
-
|
|
1274
|
-
// src/utils/copyDirectory.ts
|
|
1275
|
-
var fs3 = __toESM(require("fs")), import_path2 = __toESM(require("path")), import_tinyglobby = require("tinyglobby"), resolveTargetFileName = (file) => file.endsWith(".template") ? "." + file.replace(".template", "") : file, copyDirectory = async (sourceDir, targetDir) => {
|
|
1276
|
-
let files = await (0, import_tinyglobby.glob)(["**/*"], {
|
|
1277
|
-
cwd: sourceDir,
|
|
1278
|
-
onlyFiles: !0,
|
|
1279
|
-
dot: !0
|
|
1280
|
-
});
|
|
1281
|
-
await Promise.all(
|
|
1282
|
-
files.map(async (file) => {
|
|
1283
|
-
let sourcePath = import_path2.default.join(sourceDir, file), targetFile = resolveTargetFileName(file), targetPath = import_path2.default.join(targetDir, targetFile);
|
|
1284
|
-
await fs3.promises.mkdir(import_path2.default.dirname(targetPath), { recursive: !0 }), await fs3.promises.copyFile(sourcePath, targetPath);
|
|
1285
|
-
})
|
|
1286
|
-
);
|
|
1287
|
-
};
|
|
1288
|
-
|
|
1289
|
-
// src/utils/getProjectPath.ts
|
|
1290
|
-
var import_path3 = __toESM(require("path")), isDevelopment = () => __dirname.includes("/src/"), getProjectPath = (relativePath) => {
|
|
1291
|
-
let levelsUp = isDevelopment() ? "../.." : "..";
|
|
1292
|
-
return import_path3.default.resolve(__dirname, levelsUp, relativePath);
|
|
1293
|
-
}, getTemplatesBaseDir = () => getProjectPath("templates"), getTemplatePath = (filename) => import_path3.default.join(getTemplatesBaseDir(), "_shared", filename);
|
|
1294
|
-
|
|
1295
|
-
// src/commands/create/utils/initTemplate.ts
|
|
1296
|
-
init_logger();
|
|
1297
|
-
|
|
1298
|
-
// src/commands/create/utils/updatePackageJson.ts
|
|
1299
|
-
var fs4 = __toESM(require("fs")), path6 = __toESM(require("path")), updatePackageJson = (targetDir, packageSlug) => {
|
|
1300
|
-
let packageJsonPath = path6.join(targetDir, "package.json");
|
|
1301
|
-
if (fs4.existsSync(packageJsonPath)) {
|
|
1302
|
-
let packageJson = JSON.parse(fs4.readFileSync(packageJsonPath, "utf-8"));
|
|
1303
|
-
packageJson.name = packageSlug, fs4.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
1304
|
-
`);
|
|
1305
|
-
}
|
|
1306
|
-
};
|
|
1307
|
-
|
|
1308
|
-
// src/commands/create/utils/initTemplate.ts
|
|
1309
|
-
var initTemplate = async ({ answers, targetDir }) => {
|
|
1310
|
-
fs5.existsSync(targetDir) || fs5.mkdirSync(targetDir, { recursive: !0 });
|
|
1311
|
-
let templatesBaseDir = getTemplatesBaseDir(), templatesDir = path7.join(templatesBaseDir, answers.template), sharedDir = path7.join(templatesBaseDir, "_shared");
|
|
1312
|
-
await copyDirectory(sharedDir, targetDir), await copyDirectory(templatesDir, targetDir), updatePackageJson(targetDir, answers.packageSlug), logger_default.info("Created template with marketplace publication requirements."), logger_default.info(
|
|
1313
|
-
"Before publishing, add ./marketplace/index.md, ./marketplace/header-image.jpg (784:325), and ./public/logo.svg (square)."
|
|
1314
|
-
);
|
|
1315
|
-
};
|
|
1316
|
-
|
|
1317
|
-
// src/commands/create/index.ts
|
|
1318
|
-
var DEFAULT_VERSION = "0.0.1";
|
|
1319
|
-
async function create() {
|
|
1320
|
-
logger_default.info(getWelcomeMessage(process.cwd()));
|
|
1321
|
-
let packageSlug = await (0, import_prompts3.input)({
|
|
1322
|
-
message: "Enter app slug (e.g., my-tracker-plugin):",
|
|
1323
|
-
required: !0
|
|
1324
|
-
}), template = await (0, import_prompts3.select)({
|
|
1325
|
-
message: "Select a template:",
|
|
1326
|
-
choices: TEMPLATES.map((templateName) => ({
|
|
1327
|
-
name: templateName,
|
|
1328
|
-
value: templateName
|
|
1329
|
-
}))
|
|
1330
|
-
}), dataPermissions = await (0, import_prompts3.checkbox)({
|
|
1331
|
-
message: "Select data permissions (some popular options):",
|
|
1332
|
-
choices: TOP_DATA_PERMISSIONS.map((permission) => ({
|
|
1333
|
-
name: permission,
|
|
1334
|
-
value: permission
|
|
1335
|
-
}))
|
|
1336
|
-
}), answers = {
|
|
1337
|
-
packageSlug,
|
|
1338
|
-
slotTitle: packageSlug,
|
|
1339
|
-
template,
|
|
1340
|
-
permissions: {
|
|
1341
|
-
data: dataPermissions
|
|
1342
|
-
},
|
|
1343
|
-
version: DEFAULT_VERSION
|
|
1344
|
-
}, targetDir = path8.join(process.cwd(), answers.packageSlug);
|
|
1345
|
-
await initTemplate({
|
|
1346
|
-
answers,
|
|
1347
|
-
targetDir
|
|
1348
|
-
}), initManifest({
|
|
1349
|
-
answers,
|
|
1350
|
-
targetDir
|
|
1351
|
-
}), logger_default.newLine(), logger_default.success("Package generated!"), logger_default.commands("To get started, run", [
|
|
1352
|
-
`cd ${answers.packageSlug}`,
|
|
1353
|
-
"npm install",
|
|
1354
|
-
"tracker-cli debug"
|
|
1355
|
-
]);
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
// src/commands/debug/index.ts
|
|
1359
|
-
var import_fs7 = __toESM(require("fs")), import_path7 = __toESM(require("path"));
|
|
1360
|
-
|
|
1361
|
-
// src/core/s3config/constants.ts
|
|
1362
|
-
var CONFIG_FILE_NAME = "config.json", mimeTypes = {
|
|
1363
|
-
".html": "text/html",
|
|
1364
|
-
".css": "text/css",
|
|
1365
|
-
".js": "text/javascript",
|
|
1366
|
-
".json": "application/json",
|
|
1367
|
-
".png": "image/png",
|
|
1368
|
-
".jpg": "image/jpeg",
|
|
1369
|
-
".jpeg": "image/jpeg",
|
|
1370
|
-
".gif": "image/gif",
|
|
1371
|
-
".svg": "image/svg+xml",
|
|
1372
|
-
".ico": "image/x-icon",
|
|
1373
|
-
".txt": "text/plain",
|
|
1374
|
-
".woff": "font/woff",
|
|
1375
|
-
".woff2": "font/woff2",
|
|
1376
|
-
".ttf": "font/ttf",
|
|
1377
|
-
".eot": "application/vnd.ms-fontobject"
|
|
1378
|
-
};
|
|
1379
|
-
|
|
1380
|
-
// src/commands/debug/index.ts
|
|
1381
|
-
init_logger();
|
|
1382
|
-
|
|
1383
|
-
// src/utils/registerCleanup.ts
|
|
1384
|
-
var registerCleanup = (cleanup) => {
|
|
1385
|
-
process.on("SIGINT", () => {
|
|
1386
|
-
cleanup(), process.exit(0);
|
|
1387
|
-
}), process.on("SIGTERM", () => {
|
|
1388
|
-
cleanup(), process.exit(0);
|
|
1389
|
-
});
|
|
1390
|
-
};
|
|
1391
|
-
|
|
1392
|
-
// src/commands/debug/utils/createDebugConfig.ts
|
|
1393
|
-
var import_fs4 = __toESM(require("fs")), import_path4 = __toESM(require("path"));
|
|
1394
|
-
|
|
1395
|
-
// src/utils/convertManifestToConfig.ts
|
|
1396
|
-
function buildPluginDownloadUrl(baseUrl, id, version) {
|
|
1397
|
-
return `${baseUrl.replace(/\/+$/, "")}/${id}/${version}`;
|
|
1398
|
-
}
|
|
1399
|
-
var convertManifestToConfig = (manifest, downloadBaseUrl) => {
|
|
1400
|
-
let config = {};
|
|
1401
|
-
if (!manifest.slots)
|
|
1402
|
-
return config;
|
|
1403
|
-
for (let service in manifest.slots) {
|
|
1404
|
-
if (!Object.prototype.hasOwnProperty.call(manifest.slots, service))
|
|
1405
|
-
continue;
|
|
1406
|
-
let serviceSlots = manifest.slots[service];
|
|
1407
|
-
if (serviceSlots)
|
|
1408
|
-
for (let slotKey in serviceSlots) {
|
|
1409
|
-
if (!Object.prototype.hasOwnProperty.call(serviceSlots, slotKey))
|
|
1410
|
-
continue;
|
|
1411
|
-
let slot = slotKey, slotConfigs = serviceSlots[slot];
|
|
1412
|
-
if (!(!slotConfigs || !Array.isArray(slotConfigs))) {
|
|
1413
|
-
config[slot] || (config[slot] = []);
|
|
1414
|
-
for (let slotConfig of slotConfigs) {
|
|
1415
|
-
let pluginConfig = {
|
|
1416
|
-
slug: manifest.slug,
|
|
1417
|
-
version: manifest.version,
|
|
1418
|
-
permissions: manifest.permissions,
|
|
1419
|
-
description: slotConfig.description,
|
|
1420
|
-
entrypoint: slotConfig.entrypoint,
|
|
1421
|
-
title: slotConfig.title,
|
|
1422
|
-
downloadUrl: buildPluginDownloadUrl(
|
|
1423
|
-
downloadBaseUrl,
|
|
1424
|
-
manifest.slug,
|
|
1425
|
-
manifest.version
|
|
1426
|
-
)
|
|
1427
|
-
};
|
|
1428
|
-
config[slot].push(pluginConfig);
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
return config;
|
|
1434
|
-
};
|
|
1435
|
-
|
|
1436
|
-
// src/commands/debug/utils/createDebugConfig.ts
|
|
1437
|
-
var DEBUG_DOWNLOAD_BASE = "http://localhost:5173/plugins-debug", createDebugConfig = async () => {
|
|
1438
|
-
let manifest = await manifestManager.load(), config = convertManifestToConfig(manifest, DEBUG_DOWNLOAD_BASE), configPath = import_path4.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
1439
|
-
import_fs4.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
1440
|
-
};
|
|
1441
|
-
|
|
1442
|
-
// src/commands/debug/utils/lockFile.ts
|
|
1443
|
-
var import_fs5 = __toESM(require("fs")), import_path5 = __toESM(require("path")), LOCK_FILE_NAME = ".tracker-cli-debug.lock", getLockFilePath = () => import_path5.default.join(process.cwd(), LOCK_FILE_NAME), getRunningDebugPid = () => {
|
|
1444
|
-
let lockPath = getLockFilePath();
|
|
1445
|
-
if (!import_fs5.default.existsSync(lockPath))
|
|
1446
|
-
return null;
|
|
1447
|
-
try {
|
|
1448
|
-
let pid = JSON.parse(import_fs5.default.readFileSync(lockPath, "utf-8")).pid;
|
|
1449
|
-
return process.kill(pid, 0), pid;
|
|
1450
|
-
} catch {
|
|
1451
|
-
try {
|
|
1452
|
-
import_fs5.default.unlinkSync(lockPath);
|
|
1453
|
-
} catch {
|
|
1454
|
-
}
|
|
1455
|
-
return null;
|
|
1456
|
-
}
|
|
1457
|
-
}, createLockFile = () => {
|
|
1458
|
-
let lockPath = getLockFilePath(), lockData = {
|
|
1459
|
-
pid: process.pid
|
|
1460
|
-
}, fd = import_fs5.default.openSync(lockPath, "wx");
|
|
1461
|
-
import_fs5.default.writeSync(fd, JSON.stringify(lockData, null, 2)), import_fs5.default.closeSync(fd);
|
|
1462
|
-
}, removeLockFile = () => {
|
|
1463
|
-
let lockPath = getLockFilePath();
|
|
1464
|
-
import_fs5.default.existsSync(lockPath) && import_fs5.default.unlinkSync(lockPath);
|
|
1465
|
-
};
|
|
1466
|
-
|
|
1467
|
-
// src/commands/debug/utils/watchManifest.ts
|
|
1468
|
-
var import_fs6 = __toESM(require("fs")), import_path6 = __toESM(require("path"));
|
|
1469
|
-
init_logger();
|
|
1470
|
-
var watchManifest = () => {
|
|
1471
|
-
let manifestPath2 = import_path6.default.join(process.cwd(), "manifest.json"), debounceTimer = null, watcher = import_fs6.default.watch(manifestPath2, async (eventType) => {
|
|
1472
|
-
eventType === "change" && (debounceTimer && clearTimeout(debounceTimer), debounceTimer = setTimeout(async () => {
|
|
1473
|
-
try {
|
|
1474
|
-
logger_default.newLine(), logger_default.info("Manifest file changed, validating..."), await manifestManager.validate(), logger_default.info("Regenerating debug config..."), await createDebugConfig(), logger_default.success("Debug config regenerated successfully");
|
|
1475
|
-
} catch (error2) {
|
|
1476
|
-
logger_default.error(`Failed to regenerate debug config: ${error2.message}`);
|
|
1477
|
-
}
|
|
1478
|
-
}, 300));
|
|
1479
|
-
}), originalClose = watcher.close.bind(watcher);
|
|
1480
|
-
return watcher.close = () => {
|
|
1481
|
-
debounceTimer && clearTimeout(debounceTimer), originalClose();
|
|
1482
|
-
}, watcher;
|
|
1483
|
-
};
|
|
1484
|
-
|
|
1485
|
-
// src/commands/debug/index.ts
|
|
1486
|
-
async function debug(options) {
|
|
1487
|
-
let runningPid = getRunningDebugPid();
|
|
1488
|
-
runningPid && (logger_default.error(
|
|
1489
|
-
`Another instance of tracker-cli debug is already running.
|
|
1490
|
-
Please stop the existing instance before starting a new one.
|
|
1491
|
-
|
|
1492
|
-
If you lost the terminal tab, you can kill the process with:
|
|
1493
|
-
kill ${runningPid}`
|
|
1494
|
-
), process.exit(1));
|
|
1495
|
-
let configPath = import_path7.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
1496
|
-
options.lint && await manifestManager.validate(), await createDebugConfig();
|
|
1497
|
-
let watcher = watchManifest(), cleanup = () => {
|
|
1498
|
-
watcher.close(), import_fs7.default.existsSync(configPath) && import_fs7.default.unlinkSync(configPath), removeLockFile();
|
|
1499
|
-
};
|
|
1500
|
-
registerCleanup(cleanup), createLockFile(), await execCommand(pluginCmd.dev), cleanup();
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
// src/distribution/promptEnvironment.ts
|
|
1504
|
-
var impl5 = (init_promptEnvironment(), __toCommonJS(promptEnvironment_exports)), { promptEnvironment: promptEnvironment2 } = impl5;
|
|
1505
|
-
|
|
1506
|
-
// src/core/s3config/s3Manager.ts
|
|
1507
|
-
var import_fs8 = require("fs"), import_promises4 = require("fs/promises"), os3 = __toESM(require("os")), import_path8 = __toESM(require("path")), import_client_s3 = require("@aws-sdk/client-s3"), import_lib_storage = require("@aws-sdk/lib-storage"), import_tinyglobby2 = require("tinyglobby");
|
|
1508
|
-
|
|
1509
|
-
// src/distribution/storage.ts
|
|
1510
|
-
var impl6 = (init_storage(), __toCommonJS(storage_exports)), { DEFAULT_ENVIRONMENT: DEFAULT_ENVIRONMENT2, getStorageSettings: getStorageSettings2, listEnvironments: listEnvironments2 } = impl6;
|
|
1511
|
-
|
|
1512
|
-
// src/core/s3config/s3Manager.ts
|
|
1513
|
-
init_logger();
|
|
1514
|
-
|
|
1515
|
-
// src/core/s3config/promptCredentials.ts
|
|
1516
|
-
var import_prompts4 = require("@inquirer/prompts"), promptS3Credentials = async () => {
|
|
1517
|
-
let s3AccessKeyId = await (0, import_prompts4.input)({
|
|
1518
|
-
message: "Enter S3_ACCESS_KEY_ID:",
|
|
1519
|
-
required: !0
|
|
1520
|
-
}), s3SecretAccessKey = await (0, import_prompts4.input)({
|
|
1521
|
-
message: "Enter S3_SECRET_ACCESS_KEY:",
|
|
1522
|
-
required: !0
|
|
1523
|
-
});
|
|
1524
|
-
return {
|
|
1525
|
-
s3AccessKeyId: s3AccessKeyId?.trim(),
|
|
1526
|
-
s3SecretAccessKey: s3SecretAccessKey?.trim()
|
|
1527
|
-
};
|
|
1528
|
-
}, promptMdsCredentials = async () => {
|
|
1529
|
-
let mdsAccessKeyId = await (0, import_prompts4.input)({
|
|
1530
|
-
message: "Enter MDS_ACCESS_KEY_ID:",
|
|
1531
|
-
required: !0
|
|
1532
|
-
}), mdsSecretAccessKey = await (0, import_prompts4.input)({
|
|
1533
|
-
message: "Enter MDS_SECRET_ACCESS_KEY:",
|
|
1534
|
-
required: !0
|
|
1535
|
-
});
|
|
1536
|
-
return {
|
|
1537
|
-
mdsAccessKeyId: mdsAccessKeyId?.trim(),
|
|
1538
|
-
mdsSecretAccessKey: mdsSecretAccessKey?.trim()
|
|
1539
|
-
};
|
|
1540
|
-
};
|
|
1541
|
-
|
|
1542
|
-
// src/core/s3config/s3Manager.ts
|
|
1543
|
-
var S3Manager = class {
|
|
1544
|
-
constructor() {
|
|
1545
|
-
this.credentialsDir = import_path8.default.join(os3.homedir(), ".tracker-cli");
|
|
1546
|
-
this.credentialsFile = import_path8.default.join(this.credentialsDir, "s3-credentials.json");
|
|
1547
|
-
this._environment = DEFAULT_ENVIRONMENT2;
|
|
1548
|
-
this._settings = null;
|
|
1549
|
-
}
|
|
1550
|
-
async setEnvironment(environment) {
|
|
1551
|
-
this._environment = environment, this._settings = await getStorageSettings2(environment), logger_default.info(`Environment set to: ${environment}`);
|
|
1552
|
-
}
|
|
1553
|
-
getEnvironment() {
|
|
1554
|
-
return this._environment;
|
|
1555
|
-
}
|
|
1556
|
-
getSettings() {
|
|
1557
|
-
if (!this._settings)
|
|
1558
|
-
throw new Error("Storage settings not loaded. Call s3Manager.setEnvironment() first.");
|
|
1559
|
-
return this._settings;
|
|
1560
|
-
}
|
|
1561
|
-
async checkS3Auth() {
|
|
1562
|
-
await this.checkAuth("s3");
|
|
1563
|
-
}
|
|
1564
|
-
async checkMdsAuth() {
|
|
1565
|
-
await this.checkAuth("mds");
|
|
1566
|
-
}
|
|
1567
|
-
async saveCredentials(credentials) {
|
|
1568
|
-
(0, import_fs8.existsSync)(this.credentialsDir) || (0, import_fs8.mkdirSync)(this.credentialsDir, { recursive: !0, mode: 448 }), await (0, import_promises4.writeFile)(this.credentialsFile, JSON.stringify(credentials, null, 2), {
|
|
1569
|
-
mode: 384
|
|
1570
|
-
});
|
|
1571
|
-
}
|
|
1572
|
-
get credentials() {
|
|
1573
|
-
try {
|
|
1574
|
-
if (!(0, import_fs8.existsSync)(this.credentialsFile))
|
|
1575
|
-
return null;
|
|
1576
|
-
let data = require("fs").readFileSync(this.credentialsFile, "utf-8");
|
|
1577
|
-
return JSON.parse(data);
|
|
1578
|
-
} catch {
|
|
1579
|
-
return null;
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
async getPluginsConfig() {
|
|
1583
|
-
let s3Client = this.createMdsS3Client(), bucket = this.getSettings().configBucket;
|
|
1584
|
-
try {
|
|
1585
|
-
let { Body } = await s3Client.send(
|
|
1586
|
-
new import_client_s3.GetObjectCommand({ Bucket: bucket, Key: CONFIG_FILE_NAME })
|
|
1587
|
-
);
|
|
1588
|
-
if (!Body)
|
|
1589
|
-
return logger_default.info("NO DATA"), {};
|
|
1590
|
-
let text = await Body.transformToString("utf8");
|
|
1591
|
-
return JSON.parse(text);
|
|
1592
|
-
} catch (error2) {
|
|
1593
|
-
return logger_default.error("Error getting plugins config from S3", error2), process.exit();
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
async savePluginsConfig(config) {
|
|
1597
|
-
let s3Client = this.createMdsS3Client(), bucket = this.getSettings().configBucket;
|
|
1598
|
-
try {
|
|
1599
|
-
await new import_lib_storage.Upload({
|
|
1600
|
-
client: s3Client,
|
|
1601
|
-
params: {
|
|
1602
|
-
Bucket: bucket,
|
|
1603
|
-
Key: CONFIG_FILE_NAME,
|
|
1604
|
-
Body: Buffer.from(JSON.stringify(config), "utf8"),
|
|
1605
|
-
ContentType: "application/json"
|
|
1606
|
-
}
|
|
1607
|
-
}).done();
|
|
1608
|
-
} catch (error2) {
|
|
1609
|
-
logger_default.error("Error writing plugins config to S3", error2), process.exit();
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
async uploadPluginFiles(manifest, files) {
|
|
1613
|
-
if (files.length === 0) {
|
|
1614
|
-
logger_default.warning("No files to upload in dist folder");
|
|
1615
|
-
return;
|
|
1616
|
-
}
|
|
1617
|
-
let keyPrefix = `${manifest.slug}/${manifest.version}/`, s3Client = this.createAwsS3Client(), distPath = import_path8.default.resolve("./dist"), bucket = this.getSettings().staticBucket;
|
|
1618
|
-
logger_default.info(`\u{1F4E6} Starting file upload from ${distPath} to S3 bucket: ${bucket}`);
|
|
1619
|
-
for (let filePath of files)
|
|
1620
|
-
try {
|
|
1621
|
-
let fileContent = await (0, import_promises4.readFile)(filePath), relativePath = import_path8.default.relative(distPath, filePath), s3Key = keyPrefix + relativePath.replace(/\\/g, "/"), mimeType = this.getMimeType(filePath);
|
|
1622
|
-
logger_default.info(`\u2B06\uFE0F Uploading: ${relativePath}`), await new import_lib_storage.Upload({
|
|
1623
|
-
client: s3Client,
|
|
1624
|
-
params: {
|
|
1625
|
-
Bucket: bucket,
|
|
1626
|
-
Key: s3Key,
|
|
1627
|
-
Body: fileContent,
|
|
1628
|
-
ContentType: mimeType
|
|
1629
|
-
}
|
|
1630
|
-
}).done(), logger_default.success(`Uploaded: ${s3Key}`);
|
|
1631
|
-
} catch (error2) {
|
|
1632
|
-
logger_default.error(`Error uploading file ${filePath}`, error2), process.exit();
|
|
1633
|
-
}
|
|
1634
|
-
logger_default.success("Deployment completed successfully!");
|
|
1635
|
-
}
|
|
1636
|
-
/**
|
|
1637
|
-
* Upload extra root-level files/directories to S3 under the same slug/version prefix.
|
|
1638
|
-
* @param manifest slug + version for the key prefix
|
|
1639
|
-
* @param rootPaths paths relative to cwd, e.g. ['manifest.json', 'marketplace']
|
|
1640
|
-
*/
|
|
1641
|
-
async uploadRootFiles(manifest, rootPaths) {
|
|
1642
|
-
let keyPrefix = `${manifest.slug}/${manifest.version}/`, s3Client = this.createAwsS3Client(), bucket = this.getSettings().staticBucket, cwd = process.cwd();
|
|
1643
|
-
for (let rootPath of rootPaths) {
|
|
1644
|
-
let absPath = import_path8.default.resolve(cwd, rootPath);
|
|
1645
|
-
if (!(0, import_fs8.existsSync)(absPath)) {
|
|
1646
|
-
logger_default.warning(`Skipping "${rootPath}" \u2014 not found`);
|
|
1647
|
-
continue;
|
|
1648
|
-
}
|
|
1649
|
-
if ((await import("fs")).statSync(absPath).isFile()) {
|
|
1650
|
-
let fileContent = await (0, import_promises4.readFile)(absPath), s3Key = keyPrefix + import_path8.default.basename(absPath), mimeType = this.getMimeType(absPath);
|
|
1651
|
-
logger_default.info(`\u2B06\uFE0F Uploading: ${rootPath}`), await new import_lib_storage.Upload({
|
|
1652
|
-
client: s3Client,
|
|
1653
|
-
params: {
|
|
1654
|
-
Bucket: bucket,
|
|
1655
|
-
Key: s3Key,
|
|
1656
|
-
Body: fileContent,
|
|
1657
|
-
ContentType: mimeType
|
|
1658
|
-
}
|
|
1659
|
-
}).done(), logger_default.success(`Uploaded: ${s3Key}`);
|
|
1660
|
-
} else {
|
|
1661
|
-
let files = await (0, import_tinyglobby2.glob)(["**/*"], {
|
|
1662
|
-
cwd: absPath,
|
|
1663
|
-
onlyFiles: !0,
|
|
1664
|
-
absolute: !0
|
|
1665
|
-
});
|
|
1666
|
-
for (let filePath of files)
|
|
1667
|
-
try {
|
|
1668
|
-
let fileContent = await (0, import_promises4.readFile)(filePath), relativePath = import_path8.default.relative(cwd, filePath), s3Key = keyPrefix + relativePath.replace(/\\/g, "/"), mimeType = this.getMimeType(filePath);
|
|
1669
|
-
logger_default.info(`\u2B06\uFE0F Uploading: ${relativePath}`), await new import_lib_storage.Upload({
|
|
1670
|
-
client: s3Client,
|
|
1671
|
-
params: {
|
|
1672
|
-
Bucket: bucket,
|
|
1673
|
-
Key: s3Key,
|
|
1674
|
-
Body: fileContent,
|
|
1675
|
-
ContentType: mimeType
|
|
1676
|
-
}
|
|
1677
|
-
}).done(), logger_default.success(`Uploaded: ${s3Key}`);
|
|
1678
|
-
} catch (error2) {
|
|
1679
|
-
logger_default.error(`Error uploading file ${filePath}`, error2), process.exit();
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
createAwsS3Client() {
|
|
1685
|
-
let credentials = this.credentials, settings = this.getSettings();
|
|
1686
|
-
return (!credentials?.s3AccessKeyId || !credentials?.s3SecretAccessKey) && (logger_default.error("S3 credentials not found. Please log in using: tracker-cli login"), process.exit()), new import_client_s3.S3Client({
|
|
1687
|
-
region: settings.awsRegion,
|
|
1688
|
-
endpoint: settings.awsEndpoint,
|
|
1689
|
-
credentials: {
|
|
1690
|
-
accessKeyId: credentials.s3AccessKeyId,
|
|
1691
|
-
secretAccessKey: credentials.s3SecretAccessKey
|
|
1692
|
-
}
|
|
1693
|
-
});
|
|
1694
|
-
}
|
|
1695
|
-
async checkAuth(type) {
|
|
1696
|
-
(type === "s3" ? await this.validateS3Credentials() : await this.validateMdsCredentials()) || (type === "s3" ? await this.promptS3CredentialsAndSave() : await this.promptMdsCredentialsAndSave());
|
|
1697
|
-
}
|
|
1698
|
-
async validateS3Credentials(credentials) {
|
|
1699
|
-
let creds = credentials || this.credentials;
|
|
1700
|
-
if (!creds || !creds.s3AccessKeyId || !creds.s3SecretAccessKey)
|
|
1701
|
-
return !1;
|
|
1702
|
-
try {
|
|
1703
|
-
let settings = await this.resolveSettings();
|
|
1704
|
-
return await new import_client_s3.S3Client({
|
|
1705
|
-
region: settings.awsRegion,
|
|
1706
|
-
endpoint: settings.awsEndpoint,
|
|
1707
|
-
credentials: {
|
|
1708
|
-
accessKeyId: creds.s3AccessKeyId,
|
|
1709
|
-
secretAccessKey: creds.s3SecretAccessKey
|
|
1710
|
-
}
|
|
1711
|
-
}).send(new import_client_s3.ListBucketsCommand({})), !0;
|
|
1712
|
-
} catch (error2) {
|
|
1713
|
-
return logger_default.error("AWS S3 credential validation failed:", error2), !1;
|
|
1714
|
-
}
|
|
1715
|
-
}
|
|
1716
|
-
async validateMdsCredentials(credentials) {
|
|
1717
|
-
let creds = credentials || this.credentials;
|
|
1718
|
-
if (!creds || !creds.mdsAccessKeyId || !creds.mdsSecretAccessKey)
|
|
1719
|
-
return !1;
|
|
1720
|
-
try {
|
|
1721
|
-
let settings = await this.resolveSettings();
|
|
1722
|
-
return await new import_client_s3.S3Client({
|
|
1723
|
-
region: settings.awsRegion,
|
|
1724
|
-
endpoint: settings.mdsEndpoint,
|
|
1725
|
-
forcePathStyle: !0,
|
|
1726
|
-
credentials: {
|
|
1727
|
-
accessKeyId: creds.mdsAccessKeyId,
|
|
1728
|
-
secretAccessKey: creds.mdsSecretAccessKey
|
|
1729
|
-
}
|
|
1730
|
-
}).send(
|
|
1731
|
-
new import_client_s3.GetObjectCommand({ Bucket: settings.configBucket, Key: CONFIG_FILE_NAME })
|
|
1732
|
-
), !0;
|
|
1733
|
-
} catch (error2) {
|
|
1734
|
-
return logger_default.error("MDS credential validation failed:", error2), !1;
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
async promptS3CredentialsAndSave() {
|
|
1738
|
-
await this.promptAndSaveCredentials(
|
|
1739
|
-
"s3",
|
|
1740
|
-
promptS3Credentials,
|
|
1741
|
-
(creds) => this.validateS3Credentials(creds)
|
|
1742
|
-
);
|
|
1743
|
-
}
|
|
1744
|
-
async promptMdsCredentialsAndSave() {
|
|
1745
|
-
await this.promptAndSaveCredentials(
|
|
1746
|
-
"mds",
|
|
1747
|
-
promptMdsCredentials,
|
|
1748
|
-
(creds) => this.validateMdsCredentials(creds)
|
|
1749
|
-
);
|
|
1750
|
-
}
|
|
1751
|
-
async promptAndSaveCredentials(type, promptFn, validateFn) {
|
|
1752
|
-
logger_default.info(`Please enter your ${type.toUpperCase()} credentials:`);
|
|
1753
|
-
let newCreds = await promptFn(), updatedCreds = {
|
|
1754
|
-
...this.credentials || {},
|
|
1755
|
-
...newCreds
|
|
1756
|
-
};
|
|
1757
|
-
if (logger_default.info(`Validating ${type.toUpperCase()} credentials...`), !await validateFn(updatedCreds)) {
|
|
1758
|
-
await this.promptAndSaveCredentials(type, promptFn, validateFn);
|
|
1759
|
-
return;
|
|
1760
|
-
}
|
|
1761
|
-
await this.saveCredentials(updatedCreds), logger_default.success(`${type.toUpperCase()} credentials saved successfully.`);
|
|
1762
|
-
}
|
|
1763
|
-
createMdsS3Client() {
|
|
1764
|
-
let credentials = this.credentials, settings = this.getSettings();
|
|
1765
|
-
return (!credentials?.mdsAccessKeyId || !credentials?.mdsSecretAccessKey) && (logger_default.error("MdsS3 credentials not found. Please log in using: tracker-cli login"), process.exit()), new import_client_s3.S3Client({
|
|
1766
|
-
region: settings.awsRegion,
|
|
1767
|
-
endpoint: settings.mdsEndpoint,
|
|
1768
|
-
forcePathStyle: !0,
|
|
1769
|
-
credentials: {
|
|
1770
|
-
accessKeyId: credentials.mdsAccessKeyId,
|
|
1771
|
-
secretAccessKey: credentials.mdsSecretAccessKey
|
|
1772
|
-
}
|
|
1773
|
-
});
|
|
1774
|
-
}
|
|
1775
|
-
async resolveSettings() {
|
|
1776
|
-
return this._settings ? this._settings : (this._settings = await getStorageSettings2(this._environment), this._settings);
|
|
1777
|
-
}
|
|
1778
|
-
getMimeType(filePath) {
|
|
1779
|
-
let ext = import_path8.default.extname(filePath).toLowerCase();
|
|
1780
|
-
return mimeTypes[ext] || "application/octet-stream";
|
|
1781
|
-
}
|
|
1782
|
-
}, s3Manager = new S3Manager();
|
|
1783
|
-
|
|
1784
|
-
// src/utils/getFiles.ts
|
|
1785
|
-
var import_fs9 = __toESM(require("fs")), import_path9 = __toESM(require("path")), import_tinyglobby3 = require("tinyglobby");
|
|
1786
|
-
init_logger();
|
|
1787
|
-
var getFiles = async () => {
|
|
1788
|
-
let distPath = import_path9.default.resolve("./dist");
|
|
1789
|
-
import_fs9.default.existsSync(distPath) || (logger_default.error("Dist folder not found. Build the project first"), process.exit());
|
|
1790
|
-
let files = await (0, import_tinyglobby3.glob)(["**/*"], {
|
|
1791
|
-
cwd: distPath,
|
|
1792
|
-
onlyFiles: !0,
|
|
1793
|
-
absolute: !0
|
|
1794
|
-
});
|
|
1795
|
-
return logger_default.info(`\u{1F4C1} Found ${files.length} files to upload`), files;
|
|
1796
|
-
};
|
|
1797
|
-
|
|
1798
|
-
// src/commands/deploy/index.ts
|
|
1799
|
-
async function deploy() {
|
|
1800
|
-
let environment = await promptEnvironment2();
|
|
1801
|
-
await s3Manager.setEnvironment(environment), await s3Manager.checkS3Auth();
|
|
1802
|
-
let manifest = await manifestManager.load();
|
|
1803
|
-
await build({ environment });
|
|
1804
|
-
let files = await getFiles();
|
|
1805
|
-
await s3Manager.uploadPluginFiles(manifest, files);
|
|
1806
|
-
}
|
|
1807
|
-
|
|
1808
|
-
// src/api/utils.ts
|
|
1809
|
-
init_logger();
|
|
1810
|
-
function mapTrackerStatusToPluginStatus(issue) {
|
|
1811
|
-
let statusKey = issue.status.key, resolutionKey = issue.resolution?.key, resolutionDisplay = issue.resolution?.display;
|
|
1812
|
-
switch (statusKey) {
|
|
1813
|
-
case "open":
|
|
1814
|
-
return "draft";
|
|
1815
|
-
case "inProgress":
|
|
1816
|
-
return "waiting_for_review";
|
|
1817
|
-
case "need_info":
|
|
1818
|
-
return "need_info";
|
|
1819
|
-
case "waitingForApprove":
|
|
1820
|
-
return "pending_approval";
|
|
1821
|
-
case "closed":
|
|
1822
|
-
switch (resolutionKey) {
|
|
1823
|
-
case "agreed":
|
|
1824
|
-
return "approved";
|
|
1825
|
-
case "rejected":
|
|
1826
|
-
case "declined":
|
|
1827
|
-
return "rejected";
|
|
1828
|
-
default:
|
|
1829
|
-
return logger_default.warning(
|
|
1830
|
-
`[tracker-status-debug] Unknown closed resolution for ${issue.key}: status.key=${statusKey}, status.display=${issue.status.display ?? "n/a"}, resolution.key=${resolutionKey ?? "n/a"}, resolution.display=${resolutionDisplay ?? "n/a"}`
|
|
1831
|
-
), "unknown";
|
|
1832
|
-
}
|
|
1833
|
-
default:
|
|
1834
|
-
return logger_default.warning(
|
|
1835
|
-
`[tracker-status-debug] Unknown tracker status for ${issue.key}: status.key=${statusKey}, status.display=${issue.status.display ?? "n/a"}, resolution.key=${resolutionKey ?? "n/a"}, resolution.display=${resolutionDisplay ?? "n/a"}`
|
|
1836
|
-
), "unknown";
|
|
1837
|
-
}
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
// src/commands/info/index.ts
|
|
1841
|
-
init_logger();
|
|
1842
|
-
|
|
1843
|
-
// src/utils/pluginDisplay.ts
|
|
1844
|
-
var import_picocolors3 = __toESM(require("picocolors"));
|
|
1845
|
-
init_logger();
|
|
1846
|
-
var printHeader = (title) => {
|
|
1847
|
-
console.info(import_picocolors3.default.bold(import_picocolors3.default.white(title)));
|
|
1848
|
-
}, printSuccessHeader = (title) => {
|
|
1849
|
-
console.info(import_picocolors3.default.bold(import_picocolors3.default.green(title)));
|
|
1850
|
-
}, getStatusBadge = (status) => {
|
|
1851
|
-
let normalized = status.toLowerCase();
|
|
1852
|
-
return normalized.includes("approved") ? import_picocolors3.default.black(import_picocolors3.default.bgGreen(` ${status} `)) : normalized.includes("pending") || normalized.includes("review") ? import_picocolors3.default.black(import_picocolors3.default.bgYellow(` ${status} `)) : normalized.includes("rejected") ? import_picocolors3.default.white(import_picocolors3.default.bgRed(` ${status} `)) : normalized.includes("draft") || normalized.includes("unknown") ? import_picocolors3.default.black(import_picocolors3.default.bgWhite(` ${status} `)) : import_picocolors3.default.black(import_picocolors3.default.bgBlue(` ${status} `));
|
|
1853
|
-
}, formatDate = (dateString) => dateString ? new Date(dateString).toLocaleString("ru-RU", {
|
|
1854
|
-
year: "numeric",
|
|
1855
|
-
month: "2-digit",
|
|
1856
|
-
day: "2-digit",
|
|
1857
|
-
hour: "2-digit",
|
|
1858
|
-
minute: "2-digit"
|
|
1859
|
-
}) : "-", printField = (label, value, minWidth = 12) => {
|
|
1860
|
-
console.info(` ${import_picocolors3.default.dim(label.padEnd(minWidth))} ${value}`);
|
|
1861
|
-
}, printPluginId = (pluginId) => {
|
|
1862
|
-
printField("Plugin ID", import_picocolors3.default.cyan(pluginId));
|
|
1863
|
-
}, printVersionId = (versionId) => {
|
|
1864
|
-
printField("Version ID", import_picocolors3.default.cyan(versionId));
|
|
1865
|
-
}, printStatus = (status) => {
|
|
1866
|
-
printField("Status", getStatusBadge(status.toUpperCase()));
|
|
1867
|
-
}, printCreated = (createdAt) => {
|
|
1868
|
-
printField("Created", import_picocolors3.default.white(formatDate(createdAt)));
|
|
1869
|
-
}, printUpdated = (updatedAt) => {
|
|
1870
|
-
printField("Updated", import_picocolors3.default.white(formatDate(updatedAt)));
|
|
1871
|
-
};
|
|
1872
|
-
function showPluginInfo(data) {
|
|
1873
|
-
printHeader("\u{1F4E6} Plugin"), logger_default.newLine(), printPluginId(data.id), printField("Slug", import_picocolors3.default.magenta(data.slug)), printField("Name", import_picocolors3.default.white(data.name)), printStatus(data.status), data.createdAt && printCreated(data.createdAt), data.updatedAt && printUpdated(data.updatedAt);
|
|
1874
|
-
}
|
|
1875
|
-
function showPluginVersions(versions2) {
|
|
1876
|
-
if (!versions2 || versions2.length === 0) {
|
|
1877
|
-
console.info(import_picocolors3.default.dim(" No versions found")), logger_default.newLine();
|
|
1878
|
-
return;
|
|
1879
|
-
}
|
|
1880
|
-
printHeader(`\u{1F9FE} Versions \xB7 ${versions2.length}`), logger_default.newLine(), versions2.forEach((version, index) => {
|
|
1881
|
-
console.info(` ${import_picocolors3.default.bold(String(index + 1) + ".")} ${import_picocolors3.default.cyan(version.versionId)}`), printField("Status", getStatusBadge(version.status.toUpperCase())), printField("Version", import_picocolors3.default.white(version.version)), printCreated(version.createdAt), logger_default.newLine();
|
|
1882
|
-
});
|
|
1883
|
-
}
|
|
1884
|
-
function showPluginList(plugins) {
|
|
1885
|
-
if (!plugins || plugins.length === 0) {
|
|
1886
|
-
console.info(import_picocolors3.default.dim(" No plugins found")), logger_default.newLine();
|
|
1887
|
-
return;
|
|
1888
|
-
}
|
|
1889
|
-
printHeader(`\u{1F4CB} Your Plugins \xB7 ${plugins.length}`), logger_default.newLine(), plugins.forEach((plugin) => {
|
|
1890
|
-
console.info(
|
|
1891
|
-
` ${import_picocolors3.default.magenta(plugin.slug)} ${import_picocolors3.default.dim("\xB7")} ${getStatusBadge(plugin.status.toUpperCase())} ${import_picocolors3.default.dim("\xB7")} ${import_picocolors3.default.cyan(plugin.id)}`
|
|
1892
|
-
), logger_default.newLine();
|
|
1893
|
-
});
|
|
1894
|
-
}
|
|
1895
|
-
function showPluginCreated(data) {
|
|
1896
|
-
printSuccessHeader("\u2705 Plugin Created"), logger_default.newLine(), printPluginId(data.id);
|
|
1897
|
-
}
|
|
1898
|
-
function showPluginSubmitted(data) {
|
|
1899
|
-
printSuccessHeader("\u{1F680} Plugin Submitted"), logger_default.newLine(), printPluginId(data.pluginId), printVersionId(data.versionId), printStatus(data.status);
|
|
1900
|
-
}
|
|
1901
|
-
function showTrackerPluginList(issues, mapStatus) {
|
|
1902
|
-
if (!issues || issues.length === 0) {
|
|
1903
|
-
console.info(import_picocolors3.default.dim(" No plugins found")), logger_default.newLine();
|
|
1904
|
-
return;
|
|
1905
|
-
}
|
|
1906
|
-
printHeader(`\u{1F4CB} Your Plugins \xB7 ${issues.length}`), logger_default.newLine(), issues.forEach((issue) => {
|
|
1907
|
-
let slugMatch = issue.summary.match(/^Plugin:\s*(.+)$/), slug = slugMatch ? import_picocolors3.default.magenta(slugMatch[1].trim()) : import_picocolors3.default.dim(issue.summary), lifecycleStatus = mapStatus(issue), statusBadge = getStatusBadge(lifecycleStatus.toUpperCase());
|
|
1908
|
-
console.info(
|
|
1909
|
-
` ${slug} ${import_picocolors3.default.dim("\xB7")} ${statusBadge} ${import_picocolors3.default.dim("\xB7")} ${import_picocolors3.default.dim(issue.key)}`
|
|
1910
|
-
), logger_default.newLine();
|
|
1911
|
-
});
|
|
1912
|
-
}
|
|
1913
|
-
function showTrackerPluginInfo(issue, mapStatus) {
|
|
1914
|
-
printHeader("\u{1F4E6} Plugin"), logger_default.newLine(), printField("Issue key", import_picocolors3.default.cyan(issue.key)), printField("Status", getStatusBadge(mapStatus(issue).toUpperCase())), printField("Summary", import_picocolors3.default.white(issue.summary)), issue.createdAt && printCreated(issue.createdAt), issue.updatedAt && printUpdated(issue.updatedAt);
|
|
1915
|
-
}
|
|
1916
|
-
|
|
1917
|
-
// src/commands/info/index.ts
|
|
1918
|
-
async function info2(issueKey) {
|
|
1919
|
-
let targetIssueKey = issueKey;
|
|
1920
|
-
if (targetIssueKey || (targetIssueKey = (await pluginStateManager.load()).trackerIssueKey), !targetIssueKey) {
|
|
1921
|
-
logger_default.warning(
|
|
1922
|
-
'No issue key provided and plugin is not registered. Run "tracker-cli register" first.'
|
|
1923
|
-
), logger_default.suggest("tracker-cli register");
|
|
1924
|
-
return;
|
|
1925
|
-
}
|
|
1926
|
-
logger_default.info(`\u23F3 Fetching plugin info for ${targetIssueKey}...`);
|
|
1927
|
-
try {
|
|
1928
|
-
let issue = await getIssue(targetIssueKey);
|
|
1929
|
-
showTrackerPluginInfo(issue, mapTrackerStatusToPluginStatus);
|
|
1930
|
-
} catch (error2) {
|
|
1931
|
-
throw logger_default.error(`Failed to fetch plugin info for ${targetIssueKey}`), error2;
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
|
|
1935
|
-
// src/commands/install/index.ts
|
|
1936
|
-
init_logger();
|
|
1937
|
-
|
|
1938
|
-
// src/commands/install/utils/mergeConfigs.ts
|
|
1939
|
-
var mergeConfigs = (config, newConfig) => {
|
|
1940
|
-
let result = { ...config };
|
|
1941
|
-
for (let [key, newItems] of Object.entries(newConfig)) {
|
|
1942
|
-
let slotKey = key;
|
|
1943
|
-
if (!newItems || !Array.isArray(newItems))
|
|
1944
|
-
continue;
|
|
1945
|
-
let existingItems = result[slotKey];
|
|
1946
|
-
if (!existingItems) {
|
|
1947
|
-
result[slotKey] = [...newItems];
|
|
1948
|
-
continue;
|
|
1949
|
-
}
|
|
1950
|
-
let mergedItems = [];
|
|
1951
|
-
for (let existingItem of existingItems)
|
|
1952
|
-
newItems.some(
|
|
1953
|
-
(newItem) => newItem.slug === existingItem.slug
|
|
1954
|
-
) || mergedItems.push(existingItem);
|
|
1955
|
-
mergedItems.push(...newItems), result[slotKey] = mergedItems;
|
|
1956
|
-
}
|
|
1957
|
-
return result;
|
|
1958
|
-
};
|
|
1959
|
-
|
|
1960
|
-
// src/commands/install/index.ts
|
|
1961
|
-
async function install() {
|
|
1962
|
-
let environment = await promptEnvironment2();
|
|
1963
|
-
await s3Manager.setEnvironment(environment), await s3Manager.checkMdsAuth();
|
|
1964
|
-
let [config, manifest] = await Promise.all([
|
|
1965
|
-
s3Manager.getPluginsConfig(),
|
|
1966
|
-
manifestManager.load()
|
|
1967
|
-
]), settings = s3Manager.getSettings(), downloadBaseUrl = `${settings.awsEndpoint.replace(/\/+$/, "")}/${settings.staticBucket}`, pluginConfig = convertManifestToConfig(manifest, downloadBaseUrl), mergedConfig = mergeConfigs(config, pluginConfig);
|
|
1968
|
-
await s3Manager.savePluginsConfig(mergedConfig), logger_default.info("\u{1F389} Installation completed successfully!");
|
|
1969
|
-
}
|
|
1970
|
-
|
|
1971
|
-
// src/commands/lint.ts
|
|
1972
|
-
init_logger();
|
|
1973
|
-
async function lint() {
|
|
1974
|
-
logger_default.info("\u{1F50D} Running manifest.json validation..."), await manifestManager.validate(), logger_default.info("\u{1F50D} Running code lint check..."), await execCommand(pluginCmd.lint);
|
|
1975
|
-
}
|
|
1976
|
-
|
|
1977
|
-
// src/commands/list/index.ts
|
|
1978
|
-
init_logger();
|
|
1979
|
-
async function list() {
|
|
1980
|
-
logger_default.info("\u23F3 Fetching my plugins from Tracker...");
|
|
1981
|
-
try {
|
|
1982
|
-
let issues = await getMyPluginIssues();
|
|
1983
|
-
showTrackerPluginList(issues, mapTrackerStatusToPluginStatus);
|
|
1984
|
-
} catch (error2) {
|
|
1985
|
-
throw logger_default.error("Failed to fetch plugins list"), error2;
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
// src/api/apiRequest.ts
|
|
1990
|
-
async function apiRequest(endpoint, options = {}) {
|
|
1991
|
-
let { method = "GET", body, headers = {}, token } = options, authHeader = token ? `OAuth ${token}` : authManager.authHeader;
|
|
1992
|
-
if (!authHeader)
|
|
1993
|
-
throw new Error('Not authenticated. Run "tracker-cli login" first.');
|
|
1994
|
-
let requestHeaders = {
|
|
1995
|
-
Authorization: authHeader,
|
|
1996
|
-
"Content-Type": "application/json",
|
|
1997
|
-
...headers
|
|
1998
|
-
}, requestOptions = {
|
|
1999
|
-
method,
|
|
2000
|
-
headers: requestHeaders
|
|
2001
|
-
};
|
|
2002
|
-
body && method !== "GET" && (requestOptions.body = JSON.stringify(body));
|
|
2003
|
-
let url = `${await getTrackerApiUrl2()}${endpoint}`, response = await fetch(url, requestOptions);
|
|
2004
|
-
if (!response.ok)
|
|
2005
|
-
throw new Error([response.status, response.statusText].join(" ").trim());
|
|
2006
|
-
let contentType = response.headers.get("content-type");
|
|
2007
|
-
return contentType && contentType.includes("application/json") ? await response.json() : await response.text();
|
|
2008
|
-
}
|
|
2009
|
-
|
|
2010
|
-
// src/api/user.ts
|
|
2011
|
-
async function getMyself() {
|
|
2012
|
-
return await apiRequest("/myself");
|
|
2013
|
-
}
|
|
2014
|
-
async function verifyToken(token) {
|
|
2015
|
-
return await apiRequest("/myself", { token });
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
|
-
// src/commands/login/index.ts
|
|
2019
|
-
init_logger();
|
|
2020
|
-
|
|
2021
|
-
// src/commands/login/utils/promptForCredentials.ts
|
|
2022
|
-
var import_prompts5 = require("@inquirer/prompts"), import_picocolors4 = __toESM(require("picocolors"));
|
|
2023
|
-
var OSC = "\x1B]", BEL = "\x07", promptForCredentials = async () => {
|
|
2024
|
-
let tokenUrl = await getOAuthTokenUrl2();
|
|
2025
|
-
return tokenUrl && (console.info(
|
|
2026
|
-
import_picocolors4.default.dim("Get your OAuth token at: ") + import_picocolors4.default.cyan(`${OSC}8;;${tokenUrl}${BEL}${tokenUrl}${OSC}8;;${BEL}`)
|
|
2027
|
-
), console.info("")), {
|
|
2028
|
-
token: (await (0, import_prompts5.input)({
|
|
2029
|
-
message: "Enter your OAuth token:",
|
|
2030
|
-
required: !0
|
|
2031
|
-
})).trim()
|
|
2032
|
-
};
|
|
2033
|
-
};
|
|
2034
|
-
|
|
2035
|
-
// src/commands/login/index.ts
|
|
2036
|
-
async function login() {
|
|
2037
|
-
let authToken = (await promptForCredentials()).token;
|
|
2038
|
-
try {
|
|
2039
|
-
let userInfo = await verifyToken(authToken);
|
|
2040
|
-
authManager.saveAuthData(authToken), logger_default.success(`Successfully logged in as ${userInfo.login}`);
|
|
2041
|
-
} catch (error2) {
|
|
2042
|
-
logger_default.error("Invalid token or API request failed", error2);
|
|
2043
|
-
}
|
|
2044
|
-
}
|
|
2045
|
-
|
|
2046
|
-
// src/commands/logout.ts
|
|
2047
|
-
init_logger();
|
|
2048
|
-
function logout() {
|
|
2049
|
-
try {
|
|
2050
|
-
if (!authManager.data) {
|
|
2051
|
-
logger_default.warning("You are not logged in");
|
|
2052
|
-
return;
|
|
2053
|
-
}
|
|
2054
|
-
authManager.removeAuthData(), logger_default.success("Successfully logged out");
|
|
2055
|
-
} catch (error2) {
|
|
2056
|
-
logger_default.error("Logout failed", error2);
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2060
|
-
// src/commands/register/index.ts
|
|
2061
|
-
var import_crypto = require("crypto");
|
|
2062
|
-
init_logger();
|
|
2063
|
-
async function register() {
|
|
2064
|
-
let manifest = await manifestManager.load(), state = await pluginStateManager.load();
|
|
2065
|
-
if (state.trackerIssueKey)
|
|
2066
|
-
try {
|
|
2067
|
-
let issue2 = await getIssue(state.trackerIssueKey);
|
|
2068
|
-
logger_default.error(
|
|
2069
|
-
`Plugin is already registered. Tracker issue: ${issue2.key} (${issue2.summary})`
|
|
2070
|
-
), process.exit(1);
|
|
2071
|
-
} catch {
|
|
2072
|
-
}
|
|
2073
|
-
let pluginId = manifest.id ?? (0, import_crypto.randomUUID)();
|
|
2074
|
-
logger_default.info("\u23F3 Creating plugin issue in Tracker..."), manifest.id || await manifestManager.update({ id: pluginId });
|
|
2075
|
-
let manifestJson = await manifestManager.loadRaw(), issue = await createPluginIssue({
|
|
2076
|
-
pluginId,
|
|
2077
|
-
slug: manifest.slug,
|
|
2078
|
-
version: manifest.version,
|
|
2079
|
-
manifestJson
|
|
2080
|
-
});
|
|
2081
|
-
await pluginStateManager.update({ trackerIssueKey: issue.key }), logger_default.success("Plugin registered!"), logger_default.info(` Tracker issue : ${issue.key}`), logger_default.info(` Summary : ${issue.summary}`), logger_default.info(` Plugin UUID : ${pluginId}`), logger_default.commands("\u{1F4A1} Next steps", [
|
|
2082
|
-
"tracker-cli catalog # Update catalog metadata",
|
|
2083
|
-
"tracker-cli upload # Build and upload plugin bundle",
|
|
2084
|
-
"tracker-cli submit # Submit for review"
|
|
2085
|
-
]);
|
|
2086
|
-
}
|
|
2087
|
-
|
|
2088
|
-
// src/commands/submit/index.ts
|
|
2089
|
-
init_logger();
|
|
2090
|
-
var SUBMIT_TRANSITION_DISPLAY = "waiting for approve";
|
|
2091
|
-
async function submit() {
|
|
2092
|
-
let manifest = await manifestManager.load(), state = await pluginStateManager.load();
|
|
2093
|
-
if (!state.trackerIssueKey) {
|
|
2094
|
-
logger_default.warning('Plugin is not registered yet. Run "tracker-cli register" first.'), logger_default.suggest("tracker-cli register");
|
|
2095
|
-
return;
|
|
2096
|
-
}
|
|
2097
|
-
let issueKey = state.trackerIssueKey;
|
|
2098
|
-
logger_default.info(`\u23F3 Checking for uploaded bundle on ${issueKey}...`);
|
|
2099
|
-
let attachments = await getIssueAttachments(issueKey), archiveName = `${manifest.slug}-${manifest.version}.zip`;
|
|
2100
|
-
if (!attachments.some((a) => a.name === archiveName)) {
|
|
2101
|
-
logger_default.warning(
|
|
2102
|
-
`No bundle found for version ${manifest.version}. Upload it first with "tracker-cli upload".`
|
|
2103
|
-
), logger_default.suggest("tracker-cli upload");
|
|
2104
|
-
return;
|
|
2105
|
-
}
|
|
2106
|
-
logger_default.info(`\u23F3 Fetching available transitions for ${issueKey}...`);
|
|
2107
|
-
let transitions = await getIssueTransitions(issueKey), submitTransition = transitions.find(
|
|
2108
|
-
(t) => t.display?.toLowerCase().includes(SUBMIT_TRANSITION_DISPLAY) || t.id?.toLowerCase().includes("waitingforapprove") || t.id?.toLowerCase().includes("waiting")
|
|
2109
|
-
);
|
|
2110
|
-
if (!submitTransition) {
|
|
2111
|
-
let available = transitions.map((t) => `"${t.display ?? t.id}"`).join(", ");
|
|
2112
|
-
logger_default.error(
|
|
2113
|
-
`Could not find a "Waiting for approve" transition on ${issueKey}. Available: ${available}`
|
|
2114
|
-
);
|
|
2115
|
-
return;
|
|
2116
|
-
}
|
|
2117
|
-
logger_default.info(
|
|
2118
|
-
`\u{1F680} Submitting plugin for review (transition: "${submitTransition.display ?? submitTransition.id}")...`
|
|
2119
|
-
), await executeIssueTransition(issueKey, submitTransition.id), await addIssueComment(issueKey, `Submitted version \`${manifest.version}\` for review.`), logger_default.success("Plugin submitted for review!"), logger_default.info(` Tracker issue : ${issueKey}`), logger_default.info(` Version : ${manifest.version}`);
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
// src/commands/uninstall/index.ts
|
|
2123
|
-
init_logger();
|
|
2124
|
-
|
|
2125
|
-
// src/commands/uninstall/utils/removePluginFromConfig.ts
|
|
2126
|
-
var removePluginFromConfig = (config, pluginSlug) => {
|
|
2127
|
-
let removedFromSlots = [], updatedConfig = {};
|
|
2128
|
-
return Object.keys(config).forEach((slotName) => {
|
|
2129
|
-
let slotPlugins = config[slotName];
|
|
2130
|
-
if (!slotPlugins)
|
|
2131
|
-
return;
|
|
2132
|
-
let filteredPlugins = slotPlugins.filter((plugin) => plugin.slug !== pluginSlug);
|
|
2133
|
-
filteredPlugins.length < slotPlugins.length && removedFromSlots.push(slotName), updatedConfig[slotName] = filteredPlugins;
|
|
2134
|
-
}), { updatedConfig, removedFromSlots };
|
|
2135
|
-
};
|
|
2136
|
-
|
|
2137
|
-
// src/commands/uninstall/index.ts
|
|
2138
|
-
async function uninstall() {
|
|
2139
|
-
let environment = await promptEnvironment2();
|
|
2140
|
-
await s3Manager.setEnvironment(environment), await s3Manager.checkMdsAuth();
|
|
2141
|
-
let [config, manifest] = await Promise.all([
|
|
2142
|
-
s3Manager.getPluginsConfig(),
|
|
2143
|
-
manifestManager.load()
|
|
2144
|
-
]);
|
|
2145
|
-
if (Object.keys(config).length === 0) {
|
|
2146
|
-
logger_default.info("\u{1F50D} Config is empty. Nothing to uninstall.");
|
|
2147
|
-
return;
|
|
2148
|
-
}
|
|
2149
|
-
let { updatedConfig, removedFromSlots } = removePluginFromConfig(config, manifest.slug);
|
|
2150
|
-
if (removedFromSlots.length === 0) {
|
|
2151
|
-
logger_default.info(
|
|
2152
|
-
`\u{1F50D} Plugin ${manifest.slug} not found in config. It may have already been removed.`
|
|
2153
|
-
);
|
|
2154
|
-
return;
|
|
2155
|
-
}
|
|
2156
|
-
await s3Manager.savePluginsConfig(updatedConfig), logger_default.success(
|
|
2157
|
-
`Plugin ${manifest.slug} successfully removed from slots: ${removedFromSlots.join(", ")}`
|
|
2158
|
-
);
|
|
2159
|
-
}
|
|
2160
|
-
|
|
2161
|
-
// src/commands/up/utils/copyTemplateFiles.ts
|
|
2162
|
-
var import_fs10 = require("fs"), import_promises5 = require("fs/promises");
|
|
2163
|
-
var copyTemplateFiles = async (filenames) => {
|
|
2164
|
-
await Promise.all(
|
|
2165
|
-
filenames.map(async (filename) => {
|
|
2166
|
-
let templatePath = getTemplatePath(filename), targetPath = `./${filename}`;
|
|
2167
|
-
(0, import_fs10.existsSync)(templatePath) && (0, import_fs10.existsSync)(targetPath) && await (0, import_promises5.copyFile)(templatePath, targetPath);
|
|
2168
|
-
})
|
|
2169
|
-
);
|
|
2170
|
-
};
|
|
2171
|
-
|
|
2172
|
-
// src/commands/up/utils/updatePackageDependencies.ts
|
|
2173
|
-
var import_fs11 = require("fs"), import_promises6 = require("fs/promises");
|
|
2174
|
-
var updatePackageDependencies = async (dependencies) => {
|
|
2175
|
-
let packageJsonPath = "./package.json", templatePackageJsonPath = getTemplatePath("package.json");
|
|
2176
|
-
if (!(0, import_fs11.existsSync)(packageJsonPath) || !(0, import_fs11.existsSync)(templatePackageJsonPath))
|
|
2177
|
-
return;
|
|
2178
|
-
let packageJsonContent = await (0, import_promises6.readFile)(packageJsonPath, "utf-8"), templatePackageJsonContent = await (0, import_promises6.readFile)(templatePackageJsonPath, "utf-8"), packageJson = JSON.parse(packageJsonContent), templatePackageJson = JSON.parse(templatePackageJsonContent), updated = !1;
|
|
2179
|
-
dependencies.forEach((dep) => {
|
|
2180
|
-
packageJson.dependencies?.[dep] && templatePackageJson.dependencies?.[dep] && packageJson.dependencies[dep] !== templatePackageJson.dependencies[dep] && (packageJson.dependencies[dep] = templatePackageJson.dependencies[dep], updated = !0);
|
|
2181
|
-
}), updated && await (0, import_promises6.writeFile)(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
2182
|
-
`, "utf-8");
|
|
2183
|
-
};
|
|
2184
|
-
|
|
2185
|
-
// src/commands/up/index.ts
|
|
2186
|
-
var templateFiles = ["manifest.schema.json", "vite.config.ts"], templateDeps = [
|
|
2187
|
-
"@yandex-data-ui/tracker-plugin-sdk-react",
|
|
2188
|
-
"@yandex-data-ui/tracker-pub-api-types"
|
|
2189
|
-
];
|
|
2190
|
-
async function up() {
|
|
2191
|
-
await copyTemplateFiles(templateFiles), await updatePackageDependencies(templateDeps);
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2194
|
-
// src/utils/buildArchive.ts
|
|
2195
|
-
var import_path11 = __toESM(require("path")), import_archiver = __toESM(require("archiver"));
|
|
2196
|
-
init_logger();
|
|
2197
|
-
|
|
2198
|
-
// src/utils/marketplace.ts
|
|
2199
|
-
var import_fs12 = __toESM(require("fs")), import_path10 = __toESM(require("path"));
|
|
2200
|
-
init_logger();
|
|
2201
|
-
var MARKETPLACE_DIR = "marketplace", MARKETPLACE_INDEX_FILE = "index.md", MARKETPLACE_HEADER_IMAGE_FILE = "header-image.jpg", PUBLIC_DIR = "public", PUBLIC_LOGO_FILE = "logo.svg", MANIFEST_FILE = "manifest.json", DIST_DIR = "dist", SRC_DIR = "src", ensurePathExists = (targetPath, errorMessage) => {
|
|
2202
|
-
import_fs12.default.existsSync(targetPath) || (logger_default.error(errorMessage), process.exit(1));
|
|
2203
|
-
};
|
|
2204
|
-
function validateMarketplaceAssets() {
|
|
2205
|
-
let marketplaceDir = import_path10.default.resolve(MARKETPLACE_DIR);
|
|
2206
|
-
ensurePathExists(
|
|
2207
|
-
marketplaceDir,
|
|
2208
|
-
"Marketplace folder not found. Create ./marketplace and add index.md and header-image.jpg before publishing."
|
|
2209
|
-
), ensurePathExists(
|
|
2210
|
-
import_path10.default.join(marketplaceDir, MARKETPLACE_INDEX_FILE),
|
|
2211
|
-
"Marketplace description not found. Add ./marketplace/index.md before publishing."
|
|
2212
|
-
), ensurePathExists(
|
|
2213
|
-
import_path10.default.join(marketplaceDir, MARKETPLACE_HEADER_IMAGE_FILE),
|
|
2214
|
-
"Marketplace header image not found. Add ./marketplace/header-image.jpg before publishing."
|
|
2215
|
-
), ensurePathExists(
|
|
2216
|
-
import_path10.default.resolve(PUBLIC_DIR, PUBLIC_LOGO_FILE),
|
|
2217
|
-
"Plugin logo not found. Add ./public/logo.svg before publishing."
|
|
2218
|
-
);
|
|
2219
|
-
}
|
|
2220
|
-
function validateArchiveSources() {
|
|
2221
|
-
ensurePathExists(import_path10.default.resolve(DIST_DIR), "Dist folder not found. Build the project first."), ensurePathExists(
|
|
2222
|
-
import_path10.default.resolve(SRC_DIR),
|
|
2223
|
-
"Source folder not found. Add ./src before publishing."
|
|
2224
|
-
), ensurePathExists(import_path10.default.resolve(MANIFEST_FILE), "manifest.json not found in plugin root."), validateMarketplaceAssets();
|
|
2225
|
-
}
|
|
2226
|
-
var marketplacePaths = {
|
|
2227
|
-
distDir: DIST_DIR,
|
|
2228
|
-
srcDir: SRC_DIR,
|
|
2229
|
-
marketplaceDir: MARKETPLACE_DIR,
|
|
2230
|
-
manifestFile: MANIFEST_FILE
|
|
2231
|
-
};
|
|
2232
|
-
|
|
2233
|
-
// src/utils/buildArchive.ts
|
|
2234
|
-
async function buildArchive() {
|
|
2235
|
-
return validateArchiveSources(), new Promise((resolve2, reject) => {
|
|
2236
|
-
let archive = (0, import_archiver.default)("zip", { zlib: { level: 9 } }), chunks = [];
|
|
2237
|
-
archive.on("data", (chunk) => chunks.push(chunk)), archive.on("end", () => {
|
|
2238
|
-
let buffer = Buffer.concat(chunks);
|
|
2239
|
-
logger_default.info(`\u{1F4E6} Archive created (${buffer.length} bytes)`), resolve2(buffer);
|
|
2240
|
-
}), archive.on("error", reject), archive.file(import_path11.default.resolve(marketplacePaths.manifestFile), { name: "manifest.json" }), archive.directory(import_path11.default.resolve(marketplacePaths.distDir), "dist"), archive.directory(import_path11.default.resolve(marketplacePaths.srcDir), "src"), archive.directory(import_path11.default.resolve(marketplacePaths.marketplaceDir), "marketplace"), archive.finalize();
|
|
2241
|
-
});
|
|
2242
|
-
}
|
|
2243
|
-
|
|
2244
|
-
// src/commands/upload/index.ts
|
|
2245
|
-
init_logger();
|
|
2246
|
-
async function upload() {
|
|
2247
|
-
let manifest = await manifestManager.load(), state = await pluginStateManager.load();
|
|
2248
|
-
if (!state.trackerIssueKey) {
|
|
2249
|
-
logger_default.warning('Plugin is not registered yet. Run "tracker-cli register" first.'), logger_default.suggest("tracker-cli register");
|
|
2250
|
-
return;
|
|
2251
|
-
}
|
|
2252
|
-
logger_default.info("\u{1F528} Building plugin..."), await build(), logger_default.info("\u{1F4E6} Creating archive...");
|
|
2253
|
-
let archiveBuffer = await buildArchive(), archiveName = `${manifest.slug}-${manifest.version}.zip`;
|
|
2254
|
-
logger_default.info(`\u2B06\uFE0F Attaching ${archiveName} to ${state.trackerIssueKey}...`), await attachFileToIssue(state.trackerIssueKey, archiveBuffer, archiveName), await addIssueComment(
|
|
2255
|
-
state.trackerIssueKey,
|
|
2256
|
-
`Updated bundle: \`${archiveName}\` (${archiveBuffer.length} bytes)`
|
|
2257
|
-
), logger_default.success(`Bundle updated on ${state.trackerIssueKey}: ${archiveName}`);
|
|
2258
|
-
}
|
|
2259
|
-
|
|
2260
|
-
// src/api/platform.ts
|
|
2261
|
-
var import_form_data2 = __toESM(require("form-data"));
|
|
2262
|
-
|
|
2263
|
-
// src/api/platformApiRequest.ts
|
|
2264
|
-
var import_node_fetch3 = __toESM(require("node-fetch"));
|
|
2265
|
-
function buildRequestHeaders(headers, formData) {
|
|
2266
|
-
let authHeader = authManager.authHeader, requestHeaders = {
|
|
2267
|
-
Accept: "*/*",
|
|
2268
|
-
...authHeader ? { Authorization: authHeader } : {},
|
|
2269
|
-
...headers
|
|
2270
|
-
};
|
|
2271
|
-
return formData || (requestHeaders["Content-Type"] = "application/json"), requestHeaders;
|
|
2272
|
-
}
|
|
2273
|
-
function buildRequestBody(method, body, formData) {
|
|
2274
|
-
if (formData) {
|
|
2275
|
-
let formHeaders = formData.getHeaders?.();
|
|
2276
|
-
return {
|
|
2277
|
-
body: formData,
|
|
2278
|
-
headers: formHeaders || {}
|
|
2279
|
-
};
|
|
2280
|
-
}
|
|
2281
|
-
return body && method !== "GET" ? { body: JSON.stringify(body) } : {};
|
|
2282
|
-
}
|
|
2283
|
-
function buildQueryString2(queryParams) {
|
|
2284
|
-
if (!queryParams || Object.keys(queryParams).length === 0)
|
|
2285
|
-
return "";
|
|
2286
|
-
let params = new URLSearchParams();
|
|
2287
|
-
return Object.entries(queryParams).forEach(([key, value]) => {
|
|
2288
|
-
params.append(key, String(value));
|
|
2289
|
-
}), `?${params.toString()}`;
|
|
2290
|
-
}
|
|
2291
|
-
async function parseResponse2(response) {
|
|
2292
|
-
return response.status === 204 || response.headers.get("content-length") === "0" ? void 0 : response.headers.get("content-type")?.includes("application/json") ? await response.json() : await response.text();
|
|
2293
|
-
}
|
|
2294
|
-
async function platformApiRequest(endpoint, options = {}) {
|
|
2295
|
-
let { method = "GET", body, headers = {}, formData, queryParams } = options, requestHeaders = buildRequestHeaders(headers, formData), { body: requestBody, headers: additionalHeaders } = buildRequestBody(
|
|
2296
|
-
method,
|
|
2297
|
-
body,
|
|
2298
|
-
formData
|
|
2299
|
-
), requestOptions = {
|
|
2300
|
-
method,
|
|
2301
|
-
headers: { ...requestHeaders, ...additionalHeaders },
|
|
2302
|
-
body: requestBody
|
|
2303
|
-
}, queryString = buildQueryString2(queryParams), url = `${await getPlatformApiUrl2()}${endpoint}${queryString}`, response = await (0, import_node_fetch3.default)(url, requestOptions);
|
|
2304
|
-
if (!response.ok) {
|
|
2305
|
-
let errorText = await response.text(), errorMessage = errorText;
|
|
2306
|
-
try {
|
|
2307
|
-
let errorJson = JSON.parse(errorText);
|
|
2308
|
-
errorJson.message && (errorMessage = errorJson.message);
|
|
2309
|
-
} catch {
|
|
2310
|
-
}
|
|
2311
|
-
throw new Error(errorMessage);
|
|
2312
|
-
}
|
|
2313
|
-
return parseResponse2(response);
|
|
2314
|
-
}
|
|
2315
|
-
|
|
2316
|
-
// src/api/platform.ts
|
|
2317
|
-
async function createPlugin(manifestContent) {
|
|
2318
|
-
let formData = new import_form_data2.default();
|
|
2319
|
-
return formData.append("archive", manifestContent, {
|
|
2320
|
-
filename: "manifest.json",
|
|
2321
|
-
contentType: "application/json"
|
|
2322
|
-
}), platformApiRequest("/api/v1/plugins", {
|
|
2323
|
-
method: "POST",
|
|
2324
|
-
formData
|
|
2325
|
-
});
|
|
2326
|
-
}
|
|
2327
|
-
async function updatePluginArchive(pluginId, archiveBuffer, archiveName) {
|
|
2328
|
-
let formData = new import_form_data2.default();
|
|
2329
|
-
return formData.append("archive", archiveBuffer, {
|
|
2330
|
-
filename: archiveName,
|
|
2331
|
-
contentType: "application/zip"
|
|
2332
|
-
}), platformApiRequest(`/api/v1/plugins/${pluginId}/archive`, {
|
|
2333
|
-
method: "PUT",
|
|
2334
|
-
formData
|
|
2335
|
-
});
|
|
2336
|
-
}
|
|
2337
|
-
async function updateCatalogEntry(pluginId, catalogData) {
|
|
2338
|
-
return platformApiRequest(`/api/v1/plugins/${pluginId}/catalog-entry`, {
|
|
2339
|
-
method: "PUT",
|
|
2340
|
-
body: catalogData
|
|
2341
|
-
});
|
|
2342
|
-
}
|
|
2343
|
-
async function submitPlugin(pluginId, version) {
|
|
2344
|
-
return platformApiRequest(`/api/v1/plugins/${pluginId}/submit`, {
|
|
2345
|
-
method: "POST",
|
|
2346
|
-
queryParams: {
|
|
2347
|
-
version
|
|
2348
|
-
}
|
|
2349
|
-
});
|
|
2350
|
-
}
|
|
2351
|
-
async function getPluginInfo(pluginId) {
|
|
2352
|
-
return platformApiRequest(`/api/v1/plugins/${pluginId}`, {
|
|
2353
|
-
method: "GET"
|
|
2354
|
-
});
|
|
2355
|
-
}
|
|
2356
|
-
async function getPluginVersions(pluginId) {
|
|
2357
|
-
return platformApiRequest(`/api/v1/plugins/${pluginId}/versions`, {
|
|
2358
|
-
method: "GET"
|
|
2359
|
-
});
|
|
2360
|
-
}
|
|
2361
|
-
async function getMyPlugins() {
|
|
2362
|
-
return platformApiRequest("/api/v1/plugins/my", {
|
|
2363
|
-
method: "GET"
|
|
2364
|
-
});
|
|
2365
|
-
}
|
|
2366
|
-
async function checkSlugAvailability(slug) {
|
|
2367
|
-
return platformApiRequest(`/api/v1/slugs/${slug}/available`, {
|
|
2368
|
-
method: "GET"
|
|
2369
|
-
});
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
// src/utils/getPluginId.ts
|
|
2373
|
-
async function getPluginId(pluginId) {
|
|
2374
|
-
if (pluginId)
|
|
2375
|
-
return pluginId;
|
|
2376
|
-
try {
|
|
2377
|
-
let manifest = await manifestManager.load();
|
|
2378
|
-
if (!manifest.id)
|
|
2379
|
-
throw new Error("Plugin ID not found in manifest.json");
|
|
2380
|
-
return manifest.id;
|
|
2381
|
-
} catch {
|
|
2382
|
-
throw new Error("Plugin ID must be provided as argument or present in manifest.json");
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2385
|
-
|
|
2386
|
-
// src/commands/versions/index.ts
|
|
2387
|
-
init_logger();
|
|
2388
|
-
async function versions(pluginId) {
|
|
2389
|
-
let actualPluginId = await getPluginId(pluginId);
|
|
2390
|
-
logger_default.info(`\u23F3 Fetching versions for plugin ID: ${actualPluginId}...`);
|
|
2391
|
-
try {
|
|
2392
|
-
let pluginVersions = await getPluginVersions(actualPluginId);
|
|
2393
|
-
if (!pluginVersions || pluginVersions.length === 0) {
|
|
2394
|
-
logger_default.info("No versions found for this plugin.");
|
|
2395
|
-
return;
|
|
2396
|
-
}
|
|
2397
|
-
showPluginVersions(pluginVersions), logger_default.newLine();
|
|
2398
|
-
} catch (error2) {
|
|
2399
|
-
throw logger_default.error(`Failed to fetch versions for plugin ID: ${actualPluginId}`), error2;
|
|
2400
|
-
}
|
|
2401
|
-
}
|
|
2402
|
-
|
|
2403
|
-
// src/commands/whoami.ts
|
|
2404
|
-
init_logger();
|
|
2405
|
-
async function whoami() {
|
|
2406
|
-
if (!authManager.data) {
|
|
2407
|
-
logger_default.warning("You are not logged in"), logger_default.suggest("tracker-cli login");
|
|
2408
|
-
return;
|
|
2409
|
-
}
|
|
2410
|
-
try {
|
|
2411
|
-
let userInfo = await getMyself();
|
|
2412
|
-
logger_default.info(`Current user: ${userInfo.login}`);
|
|
2413
|
-
} catch {
|
|
2414
|
-
logger_default.warning("Failed to verify token with API");
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
|
|
2418
|
-
// src/commands/catalog/platform.ts
|
|
2419
|
-
init_logger();
|
|
2420
|
-
async function catalogPlatform() {
|
|
2421
|
-
let manifest = await manifestManager.load(), pluginId = await promptPluginId(manifest);
|
|
2422
|
-
logger_default.newLine(), logger_default.info("\u{1F4DD} Catalog entry information:");
|
|
2423
|
-
let name = await promptPluginName(), description = await promptPluginDescription(), tags = await promptPluginTags();
|
|
2424
|
-
logger_default.newLine(), logger_default.info("\u{1F4E4} Updating catalog entry..."), await updateCatalogEntry(pluginId, {
|
|
2425
|
-
name,
|
|
2426
|
-
description,
|
|
2427
|
-
tags
|
|
2428
|
-
}), logger_default.success("Catalog entry updated successfully!");
|
|
2429
|
-
}
|
|
2430
|
-
|
|
2431
|
-
// src/commands/info/platform.ts
|
|
2432
|
-
init_logger();
|
|
2433
|
-
async function infoPlatform(pluginId) {
|
|
2434
|
-
let actualPluginId = await getPluginId(pluginId);
|
|
2435
|
-
logger_default.info(`\u23F3 Fetching plugin info for ID: ${actualPluginId}...`);
|
|
2436
|
-
try {
|
|
2437
|
-
let pluginInfo = await getPluginInfo(actualPluginId);
|
|
2438
|
-
showPluginInfo(pluginInfo), pluginInfo.versions && pluginInfo.versions.length > 0 && (logger_default.newLine(), showPluginVersions(pluginInfo.versions));
|
|
2439
|
-
} catch (error2) {
|
|
2440
|
-
throw logger_default.error(`Failed to fetch plugin info for ID: ${actualPluginId}`), error2;
|
|
2441
|
-
}
|
|
2442
|
-
}
|
|
2443
|
-
|
|
2444
|
-
// src/commands/list/platform.ts
|
|
2445
|
-
init_logger();
|
|
2446
|
-
async function listPlatform() {
|
|
2447
|
-
logger_default.info("\u23F3 Fetching my plugins...");
|
|
2448
|
-
try {
|
|
2449
|
-
let plugins = await getMyPlugins();
|
|
2450
|
-
showPluginList(plugins);
|
|
2451
|
-
} catch (error2) {
|
|
2452
|
-
throw logger_default.error("Failed to fetch plugins list"), error2;
|
|
2453
|
-
}
|
|
2454
|
-
}
|
|
2455
|
-
|
|
2456
|
-
// src/commands/register/platform.ts
|
|
2457
|
-
init_logger();
|
|
2458
|
-
async function registerPlatform() {
|
|
2459
|
-
let manifest = await manifestManager.load();
|
|
2460
|
-
if (manifest.id)
|
|
2461
|
-
try {
|
|
2462
|
-
let pluginInfo = await getPluginInfo(manifest.id);
|
|
2463
|
-
logger_default.error(`Plugin is already registered with ID: ${pluginInfo.id}`), process.exit(1);
|
|
2464
|
-
} catch {
|
|
2465
|
-
}
|
|
2466
|
-
await build(), logger_default.info("\u23F3 Creating plugin...");
|
|
2467
|
-
let manifestContent = await manifestManager.loadRaw(), response = await createPlugin(manifestContent);
|
|
2468
|
-
showPluginCreated(response), await manifestManager.update({ id: response.id }), logger_default.commands("\u{1F4A1} Next steps", [
|
|
2469
|
-
"tracker-cli catalog # Update catalog data",
|
|
2470
|
-
"tracker-cli submit # Submit for review"
|
|
2471
|
-
]);
|
|
2472
|
-
}
|
|
2473
|
-
|
|
2474
|
-
// src/commands/submit/platform.ts
|
|
2475
|
-
init_logger();
|
|
2476
|
-
|
|
2477
|
-
// src/commands/submit/utils/validateSlug.ts
|
|
2478
|
-
var readline = __toESM(require("readline"));
|
|
2479
|
-
init_logger();
|
|
2480
|
-
function promptForSlug() {
|
|
2481
|
-
return new Promise((resolve2) => {
|
|
2482
|
-
let rl = readline.createInterface({
|
|
2483
|
-
input: process.stdin,
|
|
2484
|
-
output: process.stdout
|
|
2485
|
-
});
|
|
2486
|
-
rl.question("Enter a new slug: ", (answer) => {
|
|
2487
|
-
rl.close(), resolve2(answer.trim());
|
|
2488
|
-
});
|
|
2489
|
-
});
|
|
2490
|
-
}
|
|
2491
|
-
async function validateAndGetUniqueSlug(currentSlug) {
|
|
2492
|
-
let slugToCheck = currentSlug, isValid = !1;
|
|
2493
|
-
for (; !isValid; )
|
|
2494
|
-
try {
|
|
2495
|
-
if ((await checkSlugAvailability(slugToCheck)).available)
|
|
2496
|
-
return isValid = !0, slugToCheck;
|
|
2497
|
-
logger_default.error(`\u274C Slug "${slugToCheck}" is already taken.`), logger_default.info("Please enter a different slug."), slugToCheck = await promptForSlug(), slugToCheck || (logger_default.error("Slug cannot be empty. Please try again."), slugToCheck = currentSlug);
|
|
2498
|
-
} catch (error2) {
|
|
2499
|
-
throw logger_default.error(`Failed to check slug availability: ${error2.message}`), error2;
|
|
2500
|
-
}
|
|
2501
|
-
return slugToCheck;
|
|
2502
|
-
}
|
|
2503
|
-
|
|
2504
|
-
// src/commands/submit/platform.ts
|
|
2505
|
-
async function submitPlatform() {
|
|
2506
|
-
let manifest = await manifestManager.load(), pluginId = manifest.id;
|
|
2507
|
-
if (!pluginId) {
|
|
2508
|
-
logger_default.warning("Please register the plugin first"), logger_default.suggest("tracker-cli register");
|
|
2509
|
-
return;
|
|
2510
|
-
}
|
|
2511
|
-
let validatedSlug = await validateAndGetUniqueSlug(manifest.slug);
|
|
2512
|
-
validatedSlug !== manifest.slug && await manifestManager.update({ slug: validatedSlug });
|
|
2513
|
-
let response = await submitPlugin(pluginId, manifest.version);
|
|
2514
|
-
showPluginSubmitted(response), logger_default.newLine();
|
|
2515
|
-
}
|
|
2516
|
-
|
|
2517
|
-
// src/commands/upload/platform.ts
|
|
2518
|
-
init_logger();
|
|
2519
|
-
async function uploadPlatform() {
|
|
2520
|
-
let manifest = await manifestManager.load(), pluginId = manifest.id;
|
|
2521
|
-
if (!pluginId) {
|
|
2522
|
-
logger_default.warning("Please register the plugin first"), logger_default.suggest("tracker-cli register");
|
|
2523
|
-
return;
|
|
2524
|
-
}
|
|
2525
|
-
await build(), logger_default.info("\u{1F4E6} Creating archive...");
|
|
2526
|
-
let archiveBuffer = await buildArchive(), archiveName = `${manifest.slug}-${manifest.version}.zip`;
|
|
2527
|
-
logger_default.info("\u{1F4E4} Updating plugin archive..."), await updatePluginArchive(pluginId, archiveBuffer, archiveName), logger_default.success("Plugin archive updated successfully!");
|
|
2528
|
-
}
|
|
2529
|
-
|
|
2530
|
-
// src/utils/getVersion.ts
|
|
2531
|
-
var import_fs13 = require("fs"), import_path12 = require("path"), UNKNOWN_VERSION = "unknown", getVersionFromPackageJson = () => {
|
|
2532
|
-
try {
|
|
2533
|
-
let packagePath = (0, import_path12.resolve)(__dirname, "../../package.json");
|
|
2534
|
-
return (0, import_fs13.existsSync)(packagePath) && JSON.parse((0, import_fs13.readFileSync)(packagePath, "utf-8")).version || null;
|
|
2535
|
-
} catch {
|
|
2536
|
-
return null;
|
|
2537
|
-
}
|
|
2538
|
-
}, getVersion = () => "0.1.0-dev";
|
|
1424
|
+
// src/utils/getVersion.ts
|
|
1425
|
+
var import_fs9 = require("fs"), import_path9 = require("path"), UNKNOWN_VERSION = "unknown", getVersionFromPackageJson = () => {
|
|
1426
|
+
try {
|
|
1427
|
+
let packagePath = (0, import_path9.resolve)(__dirname, "../../package.json");
|
|
1428
|
+
return (0, import_fs9.existsSync)(packagePath) && JSON.parse((0, import_fs9.readFileSync)(packagePath, "utf-8")).version || null;
|
|
1429
|
+
} catch {
|
|
1430
|
+
return null;
|
|
1431
|
+
}
|
|
1432
|
+
}, getVersion = () => "0.3.0";
|
|
2539
1433
|
|
|
2540
1434
|
// src/index.ts
|
|
1435
|
+
init_verbose();
|
|
1436
|
+
|
|
1437
|
+
// src/utils/withErrorHandling.ts
|
|
2541
1438
|
init_logger();
|
|
2542
|
-
function
|
|
1439
|
+
function withErrorHandling(fn) {
|
|
2543
1440
|
return async (...args) => {
|
|
2544
1441
|
try {
|
|
2545
1442
|
await fn(...args);
|
|
@@ -2548,21 +1445,14 @@ function withErrorHandling2(fn) {
|
|
|
2548
1445
|
}
|
|
2549
1446
|
};
|
|
2550
1447
|
}
|
|
1448
|
+
|
|
1449
|
+
// src/index.ts
|
|
2551
1450
|
async function main() {
|
|
2552
1451
|
let program = new import_commander.Command(), version = getVersion();
|
|
2553
|
-
await checkUpdate(version), program.name(CLI_NAME2).description(CLI_DESCRIPTION2).version(version), CLI_HELP_TEXT2 && program.addHelpText("before", CLI_HELP_TEXT2), program.
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
To report bugs or issues, go to: https://forms.yandex.ru/surveys/6767/`
|
|
2557
|
-
);
|
|
2558
|
-
}), program.command("create").description("create your app").action(withErrorHandling2(create)), program.command("up").description("update plugin from old template to latest version").action(withErrorHandling2(up)), program.command("build").description("build your app").action(withErrorHandling2(build)), program.command("debug").description(
|
|
1452
|
+
await checkUpdate(version), program.name(CLI_NAME2).description(CLI_DESCRIPTION2).version(version), CLI_HELP_TEXT2 && program.addHelpText("before", CLI_HELP_TEXT2), program.hook("preAction", (thisCommand) => {
|
|
1453
|
+
setVerboseEnabled(!!thisCommand.opts().verbose);
|
|
1454
|
+
}), program.command("create").description("create your app").action(withErrorHandling(create)), program.command("up").description("update plugin from old template to latest version").action(withErrorHandling(up)), program.command("build").description("build your app").action(withErrorHandling(build)), program.command("debug").description(
|
|
2559
1455
|
"start a tunnel to connect your local code with the app running in the development environment"
|
|
2560
|
-
).option("--no-lint", "skip lint validation").action((options) =>
|
|
2561
|
-
"get detailed information about a plugin (uses manifest.id if plugin-id not provided)"
|
|
2562
|
-
).action(withErrorHandling2(infoPlatform)), program.command("versions [plugin-id]").description(
|
|
2563
|
-
"list all versions of a plugin (uses manifest.id if plugin-id not provided)"
|
|
2564
|
-
).action(withErrorHandling2(versions))) : (program.command("register").description("register a new plugin and create a Tracker issue").action(withErrorHandling2(register)), program.command("upload").description("build and upload plugin bundle").action(withErrorHandling2(upload)), program.command("catalog").description("update plugin catalog metadata").action(withErrorHandling2(catalog)), program.command("submit").description("submit plugin for review").action(withErrorHandling2(submit)), program.command("list").description("list my plugins").action(withErrorHandling2(list)), program.command("info [issue-key]").description(
|
|
2565
|
-
"get detailed information about a plugin (uses manifest.trackerIssueKey if issue-key not provided)"
|
|
2566
|
-
).action(withErrorHandling2(info2))), process.env.TRACKER_CLI_ADMIN && (program.command("deploy").description("build and upload plugin bundle to S3 for production").action(withErrorHandling2(deploy)), program.command("install").description("manage app installations").action(withErrorHandling2(install)), program.command("uninstall").description("uninstall app from all slots").action(withErrorHandling2(uninstall))), registerDistributionCommands2(program), await program.parseAsync(), process.exit(0);
|
|
1456
|
+
).option("--no-lint", "skip lint validation").action((options) => withErrorHandling(debug)(options)), program.command("lint").description("run TypeScript and ESLint checks").action(withErrorHandling(lint)), registerDistributionCommands2(program), await program.parseAsync(), process.exit(0);
|
|
2567
1457
|
}
|
|
2568
1458
|
main();
|