@weavix/cli 0.4.0 → 0.5.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/build/index.js +1641 -710
- package/build/templates/{_shared/src/styles-360.scss → _external/src/styles.scss} +2 -3
- package/build/templates/{_shared/src/styles-gravity.scss → _internal/src/styles.scss} +3 -2
- package/build/templates/_internal/src/themes/yandex-cloud/_dark-hc.scss +328 -0
- package/build/templates/_internal/src/themes/yandex-cloud/_dark.scss +329 -0
- package/build/templates/_internal/src/themes/yandex-cloud/_light-hc.scss +321 -0
- package/build/templates/_internal/src/themes/yandex-cloud/_light.scss +323 -0
- package/build/templates/_internal/src/themes/yandex-cloud.scss +168 -0
- package/build/templates/_shared/manifest.schema.json +183 -3
- package/build/templates/_shared/package.json +64 -65
- package/build/templates/_shared/src/main.tsx +1 -5
- package/build/templates/_shared/src/themes/yandex-360/_dark-hc.scss +296 -0
- package/build/templates/_shared/src/themes/yandex-360/_dark.scss +297 -0
- package/build/templates/_shared/src/themes/yandex-360/_light-hc.scss +289 -0
- package/build/templates/_shared/src/themes/yandex-360/_light.scss +291 -0
- package/build/templates/_shared/src/themes/yandex-360.scss +197 -0
- package/build/templates/_shared/src/themes/ys-text.scss +79 -0
- package/build/templates/_shared/vite.config.ts +2 -0
- package/build/templates/attachment.viewer.action/index.html +1 -1
- package/build/templates/attachment.viewer.action/src/App.tsx +13 -19
- package/build/templates/board.tab/index.html +14 -0
- package/build/templates/board.tab/src/App.tsx +27 -0
- package/build/templates/goal.action/index.html +1 -1
- package/build/templates/goal.action/src/App.tsx +4 -16
- package/build/templates/goal.block/index.html +14 -0
- package/build/templates/goal.block/src/App.tsx +27 -0
- package/build/templates/goal.tab/index.html +14 -0
- package/build/templates/goal.tab/src/App.tsx +27 -0
- package/build/templates/issue.action/index.html +1 -1
- package/build/templates/issue.action/src/App.tsx +3 -12
- package/build/templates/issue.block/index.html +1 -1
- package/build/templates/issue.block/src/App.tsx +9 -18
- package/build/templates/issue.comment.action/src/App.tsx +2 -8
- package/build/templates/issue.tab/src/App.tsx +2 -11
- package/build/templates/portfolio.action/index.html +1 -1
- package/build/templates/portfolio.action/src/App.tsx +4 -21
- package/build/templates/portfolio.block/index.html +14 -0
- package/build/templates/portfolio.block/src/App.tsx +27 -0
- package/build/templates/portfolio.tab/index.html +14 -0
- package/build/templates/portfolio.tab/src/App.tsx +27 -0
- package/build/templates/project.action/index.html +1 -1
- package/build/templates/project.action/src/App.tsx +4 -21
- package/build/templates/project.block/index.html +14 -0
- package/build/templates/project.block/src/App.tsx +27 -0
- package/build/templates/project.tab/index.html +14 -0
- package/build/templates/project.tab/src/App.tsx +27 -0
- package/build/templates/trigger.action/index.html +1 -1
- package/package.json +2 -1
package/build/index.js
CHANGED
|
@@ -26,6 +26,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
)), __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
|
|
28
28
|
|
|
29
|
+
// src/distribution/flag.ts
|
|
30
|
+
var init_flag = __esm({
|
|
31
|
+
"src/distribution/flag.ts"() {
|
|
32
|
+
"use strict";
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
29
36
|
// src/distributions/external/meta.ts
|
|
30
37
|
var meta_exports = {};
|
|
31
38
|
__export(meta_exports, {
|
|
@@ -40,6 +47,26 @@ var CLI_NAME, CLI_DESCRIPTION, CLI_HELP_TEXT, init_meta = __esm({
|
|
|
40
47
|
}
|
|
41
48
|
});
|
|
42
49
|
|
|
50
|
+
// src/distribution/meta.ts
|
|
51
|
+
var impl, CLI_NAME2, CLI_DESCRIPTION2, CLI_HELP_TEXT2, init_meta2 = __esm({
|
|
52
|
+
"src/distribution/meta.ts"() {
|
|
53
|
+
"use strict";
|
|
54
|
+
init_flag();
|
|
55
|
+
impl = (init_meta(), __toCommonJS(meta_exports)), { CLI_NAME: CLI_NAME2, CLI_DESCRIPTION: CLI_DESCRIPTION2, CLI_HELP_TEXT: CLI_HELP_TEXT2 } = impl;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// src/commands/submit/options.ts
|
|
60
|
+
var import_commander, skipChecksOption, init_options = __esm({
|
|
61
|
+
"src/commands/submit/options.ts"() {
|
|
62
|
+
"use strict";
|
|
63
|
+
import_commander = require("commander"), skipChecksOption = new import_commander.Option(
|
|
64
|
+
"--skip-checks",
|
|
65
|
+
"skip pre-submit validation (manifest, assets, lint, typecheck, tests, audit)"
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
43
70
|
// src/utils/verbose.ts
|
|
44
71
|
function setVerboseEnabled(value) {
|
|
45
72
|
verboseEnabled = value;
|
|
@@ -47,10 +74,14 @@ function setVerboseEnabled(value) {
|
|
|
47
74
|
function isVerboseEnabled() {
|
|
48
75
|
return verboseEnabled;
|
|
49
76
|
}
|
|
50
|
-
|
|
77
|
+
function writeVerboseArtifact(relativePath, content) {
|
|
78
|
+
let targetPath = import_path.default.resolve(".tracker-cli-debug", relativePath);
|
|
79
|
+
return import_fs.default.mkdirSync(import_path.default.dirname(targetPath), { recursive: !0 }), import_fs.default.writeFileSync(targetPath, content), targetPath;
|
|
80
|
+
}
|
|
81
|
+
var import_fs, import_path, verboseEnabled, init_verbose = __esm({
|
|
51
82
|
"src/utils/verbose.ts"() {
|
|
52
83
|
"use strict";
|
|
53
|
-
verboseEnabled = !1;
|
|
84
|
+
import_fs = __toESM(require("fs")), import_path = __toESM(require("path")), verboseEnabled = !1;
|
|
54
85
|
}
|
|
55
86
|
});
|
|
56
87
|
|
|
@@ -112,25 +143,25 @@ function getConfigPath() {
|
|
|
112
143
|
function readConfig() {
|
|
113
144
|
if (cached !== void 0)
|
|
114
145
|
return cached;
|
|
115
|
-
if (!(0,
|
|
146
|
+
if (!(0, import_fs2.existsSync)(CONFIG_FILE))
|
|
116
147
|
return cached = null, cached;
|
|
117
148
|
try {
|
|
118
|
-
cached = JSON.parse((0,
|
|
149
|
+
cached = JSON.parse((0, import_fs2.readFileSync)(CONFIG_FILE, "utf-8"));
|
|
119
150
|
} catch {
|
|
120
151
|
cached = null;
|
|
121
152
|
}
|
|
122
153
|
return cached;
|
|
123
154
|
}
|
|
124
155
|
function writeConfig(config) {
|
|
125
|
-
(0,
|
|
156
|
+
(0, import_fs2.existsSync)(CONFIG_DIR) || (0, import_fs2.mkdirSync)(CONFIG_DIR, { recursive: !0, mode: 448 }), (0, import_fs2.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 384 }), cached = config;
|
|
126
157
|
}
|
|
127
158
|
function clearConfig() {
|
|
128
|
-
(0,
|
|
159
|
+
(0, import_fs2.existsSync)(CONFIG_FILE) && (0, import_fs2.rmSync)(CONFIG_FILE), cached = null;
|
|
129
160
|
}
|
|
130
|
-
var
|
|
161
|
+
var import_fs2, os, import_path2, CONFIG_DIR, CONFIG_FILE, cached, init_manager = __esm({
|
|
131
162
|
"src/core/cliConfig/manager.ts"() {
|
|
132
163
|
"use strict";
|
|
133
|
-
|
|
164
|
+
import_fs2 = require("fs"), os = __toESM(require("os")), import_path2 = __toESM(require("path")), CONFIG_DIR = import_path2.default.join(os.homedir(), ".tracker-cli"), CONFIG_FILE = import_path2.default.join(CONFIG_DIR, "config.json");
|
|
134
165
|
}
|
|
135
166
|
});
|
|
136
167
|
|
|
@@ -197,19 +228,1446 @@ var import_prompts, init_registerCommand = __esm({
|
|
|
197
228
|
}
|
|
198
229
|
});
|
|
199
230
|
|
|
231
|
+
// src/utils/withErrorHandling.ts
|
|
232
|
+
function withErrorHandling(fn) {
|
|
233
|
+
return async (...args) => {
|
|
234
|
+
try {
|
|
235
|
+
await fn(...args);
|
|
236
|
+
} catch (error2) {
|
|
237
|
+
error2 instanceof Error && error2.name === "ExitPromptError" && process.exit(0), logger_default.error(error2), process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
var init_withErrorHandling = __esm({
|
|
242
|
+
"src/utils/withErrorHandling.ts"() {
|
|
243
|
+
"use strict";
|
|
244
|
+
init_logger();
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// src/core/pluginState/pluginStateManager.ts
|
|
249
|
+
var import_fs3, import_promises, STATE_FILE, load, save, update, pluginStateManager, init_pluginStateManager = __esm({
|
|
250
|
+
"src/core/pluginState/pluginStateManager.ts"() {
|
|
251
|
+
"use strict";
|
|
252
|
+
import_fs3 = require("fs"), import_promises = require("fs/promises"), STATE_FILE = ".tracker-plugin", load = async () => {
|
|
253
|
+
if (!(0, import_fs3.existsSync)(STATE_FILE))
|
|
254
|
+
return {};
|
|
255
|
+
try {
|
|
256
|
+
let content = await (0, import_promises.readFile)(STATE_FILE, "utf8");
|
|
257
|
+
return JSON.parse(content);
|
|
258
|
+
} catch {
|
|
259
|
+
return {};
|
|
260
|
+
}
|
|
261
|
+
}, save = async (state) => {
|
|
262
|
+
try {
|
|
263
|
+
let content = JSON.stringify(state, null, 4);
|
|
264
|
+
await (0, import_promises.writeFile)(STATE_FILE, content, "utf8");
|
|
265
|
+
} catch (error2) {
|
|
266
|
+
throw error2 instanceof Error ? new Error(`Error saving ${STATE_FILE}: ${error2.message}`) : new Error(`Error saving ${STATE_FILE}`);
|
|
267
|
+
}
|
|
268
|
+
}, update = async (updates) => {
|
|
269
|
+
let updated = { ...await load(), ...updates };
|
|
270
|
+
return await save(updated), updated;
|
|
271
|
+
}, pluginStateManager = {
|
|
272
|
+
load,
|
|
273
|
+
save,
|
|
274
|
+
update
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// src/api/utils.ts
|
|
280
|
+
function getIssueStatusLabel(issue) {
|
|
281
|
+
let { key: statusKey, display: statusDisplay } = issue.status;
|
|
282
|
+
return statusKey === "closed" && issue.resolution?.display ? issue.resolution.display : statusDisplay ?? statusKey;
|
|
283
|
+
}
|
|
284
|
+
function getIssueStatusCategory(issue) {
|
|
285
|
+
let statusKey = issue.status.key, resolutionKey = issue.resolution?.key;
|
|
286
|
+
if (statusKey === "closed")
|
|
287
|
+
return resolutionKey === "agreed" ? "approved" : resolutionKey === "rejected" || resolutionKey === "declined" ? "rejected" : "neutral";
|
|
288
|
+
switch (statusKey) {
|
|
289
|
+
case "waitingForApprove":
|
|
290
|
+
case "inProgress":
|
|
291
|
+
return "pending";
|
|
292
|
+
case "resultAcceptance":
|
|
293
|
+
return "acceptance";
|
|
294
|
+
case "testing":
|
|
295
|
+
return "testing";
|
|
296
|
+
case "need_info":
|
|
297
|
+
return "need_info";
|
|
298
|
+
default:
|
|
299
|
+
return "neutral";
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
var init_utils = __esm({
|
|
303
|
+
"src/api/utils.ts"() {
|
|
304
|
+
"use strict";
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// src/utils/pluginDisplay.ts
|
|
309
|
+
function showTrackerPluginList(issues) {
|
|
310
|
+
if (!issues || issues.length === 0) {
|
|
311
|
+
console.info(import_picocolors2.default.dim(" No plugins found")), logger_default.newLine();
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
printHeader(`\u{1F4CB} Your Plugins \xB7 ${issues.length}`), logger_default.newLine(), issues.forEach((issue) => {
|
|
315
|
+
let slugMatch = issue.summary.match(/^Plugin:\s*(.+)$/), slug = slugMatch ? import_picocolors2.default.magenta(slugMatch[1].trim()) : import_picocolors2.default.dim(issue.summary), statusBadge = getTrackerIssueBadge(issue);
|
|
316
|
+
console.info(
|
|
317
|
+
` ${slug} ${import_picocolors2.default.dim("\xB7")} ${statusBadge} ${import_picocolors2.default.dim("\xB7")} ${import_picocolors2.default.dim(issue.key)}`
|
|
318
|
+
), logger_default.newLine();
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
function showTrackerPluginInfo(issue) {
|
|
322
|
+
printHeader("\u{1F4E6} Plugin"), logger_default.newLine(), printField("Issue key", import_picocolors2.default.cyan(issue.key)), printField("Status", getTrackerIssueBadge(issue)), printField("Summary", import_picocolors2.default.white(issue.summary)), issue.createdAt && printCreated(issue.createdAt), issue.updatedAt && printUpdated(issue.updatedAt);
|
|
323
|
+
}
|
|
324
|
+
var import_picocolors2, printHeader, getTrackerIssueBadge, formatDate, printField, printCreated, printUpdated, init_pluginDisplay = __esm({
|
|
325
|
+
"src/utils/pluginDisplay.ts"() {
|
|
326
|
+
"use strict";
|
|
327
|
+
import_picocolors2 = __toESM(require("picocolors"));
|
|
328
|
+
init_utils();
|
|
329
|
+
init_logger();
|
|
330
|
+
printHeader = (title) => {
|
|
331
|
+
console.info(import_picocolors2.default.bold(import_picocolors2.default.white(title)));
|
|
332
|
+
}, getTrackerIssueBadge = (issue) => {
|
|
333
|
+
let label = getIssueStatusLabel(issue);
|
|
334
|
+
switch (getIssueStatusCategory(issue)) {
|
|
335
|
+
case "approved":
|
|
336
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgGreen(` ${label} `));
|
|
337
|
+
case "rejected":
|
|
338
|
+
return import_picocolors2.default.white(import_picocolors2.default.bgRed(` ${label} `));
|
|
339
|
+
case "pending":
|
|
340
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgYellow(` ${label} `));
|
|
341
|
+
case "acceptance":
|
|
342
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgCyan(` ${label} `));
|
|
343
|
+
case "testing":
|
|
344
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgMagenta(` ${label} `));
|
|
345
|
+
case "need_info":
|
|
346
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgBlue(` ${label} `));
|
|
347
|
+
default:
|
|
348
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgWhite(` ${label} `));
|
|
349
|
+
}
|
|
350
|
+
}, formatDate = (dateString) => dateString ? new Date(dateString).toLocaleString("ru-RU", {
|
|
351
|
+
year: "numeric",
|
|
352
|
+
month: "2-digit",
|
|
353
|
+
day: "2-digit",
|
|
354
|
+
hour: "2-digit",
|
|
355
|
+
minute: "2-digit"
|
|
356
|
+
}) : "-", printField = (label, value, minWidth = 12) => {
|
|
357
|
+
console.info(` ${import_picocolors2.default.dim(label.padEnd(minWidth))} ${value}`);
|
|
358
|
+
}, printCreated = (createdAt) => {
|
|
359
|
+
printField("Created", import_picocolors2.default.white(formatDate(createdAt)));
|
|
360
|
+
}, printUpdated = (updatedAt) => {
|
|
361
|
+
printField("Updated", import_picocolors2.default.white(formatDate(updatedAt)));
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// src/distributions/external/authManager.ts
|
|
367
|
+
var fs2, os2, path3, authDir, authFile, getData, getToken, saveAuthData, removeAuthData, externalAuthManager, init_authManager = __esm({
|
|
368
|
+
"src/distributions/external/authManager.ts"() {
|
|
369
|
+
"use strict";
|
|
370
|
+
fs2 = __toESM(require("fs")), os2 = __toESM(require("os")), path3 = __toESM(require("path")), authDir = path3.join(os2.homedir(), ".weavix"), authFile = path3.join(authDir, "auth.json"), getData = () => {
|
|
371
|
+
try {
|
|
372
|
+
if (!fs2.existsSync(authFile))
|
|
373
|
+
return null;
|
|
374
|
+
let data = fs2.readFileSync(authFile, "utf-8");
|
|
375
|
+
return JSON.parse(data);
|
|
376
|
+
} catch {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
}, getToken = () => getData()?.token ?? null, saveAuthData = (token) => {
|
|
380
|
+
let authData = { token };
|
|
381
|
+
fs2.existsSync(authDir) || fs2.mkdirSync(authDir, { recursive: !0, mode: 448 }), fs2.writeFileSync(authFile, JSON.stringify(authData, null, 2), {
|
|
382
|
+
mode: 384
|
|
383
|
+
});
|
|
384
|
+
}, removeAuthData = () => {
|
|
385
|
+
fs2.existsSync(authFile) && fs2.unlinkSync(authFile);
|
|
386
|
+
}, externalAuthManager = {
|
|
387
|
+
get token() {
|
|
388
|
+
return getToken();
|
|
389
|
+
},
|
|
390
|
+
get data() {
|
|
391
|
+
return getData();
|
|
392
|
+
},
|
|
393
|
+
saveAuthData,
|
|
394
|
+
removeAuthData
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// src/distributions/external/trackerApiRequest.ts
|
|
400
|
+
function buildQueryString(queryParams) {
|
|
401
|
+
if (!queryParams || Object.keys(queryParams).length === 0)
|
|
402
|
+
return "";
|
|
403
|
+
let params = new URLSearchParams();
|
|
404
|
+
return Object.entries(queryParams).forEach(([key, value]) => {
|
|
405
|
+
params.append(key, String(value));
|
|
406
|
+
}), `?${params.toString()}`;
|
|
407
|
+
}
|
|
408
|
+
async function parseResponse(response) {
|
|
409
|
+
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();
|
|
410
|
+
}
|
|
411
|
+
async function externalTrackerApiRequest(endpoint, options = {}) {
|
|
412
|
+
let { method = "GET", body, headers = {}, formData, queryParams } = options, token = externalAuthManager.token;
|
|
413
|
+
if (!token)
|
|
414
|
+
throw new Error(`Not authenticated. Run "${CLI_NAME} login" first.`);
|
|
415
|
+
let requestHeaders = {
|
|
416
|
+
Authorization: `OAuth ${token}`,
|
|
417
|
+
"X-Org-ID": ORG_ID,
|
|
418
|
+
Accept: "application/json",
|
|
419
|
+
...headers
|
|
420
|
+
}, requestBody;
|
|
421
|
+
if (formData) {
|
|
422
|
+
let formHeaders = formData.getHeaders?.();
|
|
423
|
+
Object.assign(requestHeaders, formHeaders), requestBody = formData;
|
|
424
|
+
} else body && method !== "GET" && (requestHeaders["Content-Type"] = "application/json", requestBody = JSON.stringify(body));
|
|
425
|
+
let queryString = buildQueryString(queryParams), url = `${TRACKER_BASE_URL}${endpoint}${queryString}`, response = await (0, import_node_fetch.default)(url, {
|
|
426
|
+
method,
|
|
427
|
+
headers: requestHeaders,
|
|
428
|
+
body: requestBody
|
|
429
|
+
});
|
|
430
|
+
if (!response.ok) {
|
|
431
|
+
let errorText = await response.text(), errorMessage = `Tracker API error ${response.status}: ${errorText}`;
|
|
432
|
+
try {
|
|
433
|
+
let errorJson = JSON.parse(errorText);
|
|
434
|
+
errorJson.message && (errorMessage = `Tracker API error ${response.status}: ${errorJson.message}`);
|
|
435
|
+
} catch {
|
|
436
|
+
}
|
|
437
|
+
throw new Error(errorMessage);
|
|
438
|
+
}
|
|
439
|
+
return parseResponse(response);
|
|
440
|
+
}
|
|
441
|
+
var import_node_fetch, TRACKER_BASE_URL, ORG_ID, init_trackerApiRequest = __esm({
|
|
442
|
+
"src/distributions/external/trackerApiRequest.ts"() {
|
|
443
|
+
"use strict";
|
|
444
|
+
import_node_fetch = __toESM(require("node-fetch"));
|
|
445
|
+
init_authManager();
|
|
446
|
+
init_meta();
|
|
447
|
+
TRACKER_BASE_URL = "https://api.tracker.yandex.net/v3", ORG_ID = "8470884";
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// src/distributions/external/tracker.ts
|
|
452
|
+
function buildIssueSummary(slug) {
|
|
453
|
+
return `Plugin: ${slug}`;
|
|
454
|
+
}
|
|
455
|
+
function buildIssueDescription(params) {
|
|
456
|
+
let { pluginId, slug, version, manifestJson } = params;
|
|
457
|
+
return [
|
|
458
|
+
`**Plugin UUID:** ${pluginId}`,
|
|
459
|
+
`**Slug:** ${slug}`,
|
|
460
|
+
`**Version:** ${version}`,
|
|
461
|
+
"",
|
|
462
|
+
"**Manifest:**",
|
|
463
|
+
"```json",
|
|
464
|
+
manifestJson,
|
|
465
|
+
"```"
|
|
466
|
+
].join(`
|
|
467
|
+
`);
|
|
468
|
+
}
|
|
469
|
+
async function createPluginIssue(params) {
|
|
470
|
+
let { slug, pluginId, version, manifestJson } = params, body = {
|
|
471
|
+
queue: PLUGINMOD_QUEUE,
|
|
472
|
+
summary: buildIssueSummary(slug),
|
|
473
|
+
description: buildIssueDescription({ pluginId, slug, version, manifestJson }),
|
|
474
|
+
tags: ["tracker-plugin"]
|
|
475
|
+
};
|
|
476
|
+
return externalTrackerApiRequest("/issues", {
|
|
477
|
+
method: "POST",
|
|
478
|
+
body
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
async function updatePluginIssue(issueKey, params) {
|
|
482
|
+
return externalTrackerApiRequest(`/issues/${issueKey}`, {
|
|
483
|
+
method: "PATCH",
|
|
484
|
+
body: params
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
async function attachFileToIssue(issueKey, fileBuffer, fileName) {
|
|
488
|
+
let formData = new import_form_data.default();
|
|
489
|
+
return formData.append("file", fileBuffer, {
|
|
490
|
+
filename: fileName,
|
|
491
|
+
contentType: "application/zip"
|
|
492
|
+
}), externalTrackerApiRequest(`/issues/${issueKey}/attachments`, {
|
|
493
|
+
method: "POST",
|
|
494
|
+
formData
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
async function getIssueTransitions(issueKey) {
|
|
498
|
+
return externalTrackerApiRequest(`/issues/${issueKey}/transitions`, {
|
|
499
|
+
method: "GET"
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
async function executeIssueTransition(issueKey, transitionId) {
|
|
503
|
+
await externalTrackerApiRequest(
|
|
504
|
+
`/issues/${issueKey}/transitions/${transitionId}/_execute`,
|
|
505
|
+
{
|
|
506
|
+
method: "POST",
|
|
507
|
+
body: {}
|
|
508
|
+
}
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
async function getIssue(issueKey) {
|
|
512
|
+
return externalTrackerApiRequest(`/issues/${issueKey}`, {
|
|
513
|
+
method: "GET"
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
async function addIssueComment(issueKey, text) {
|
|
517
|
+
await externalTrackerApiRequest(`/issues/${issueKey}/comments`, {
|
|
518
|
+
method: "POST",
|
|
519
|
+
body: { text }
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
async function getMyPluginIssues() {
|
|
523
|
+
return externalTrackerApiRequest("/issues/_search", {
|
|
524
|
+
method: "POST",
|
|
525
|
+
body: {
|
|
526
|
+
filter: {
|
|
527
|
+
queue: "PLUGINMOD",
|
|
528
|
+
createdBy: "me()"
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
var import_form_data, PLUGINMOD_QUEUE, init_tracker = __esm({
|
|
534
|
+
"src/distributions/external/tracker.ts"() {
|
|
535
|
+
"use strict";
|
|
536
|
+
import_form_data = __toESM(require("form-data"));
|
|
537
|
+
init_trackerApiRequest();
|
|
538
|
+
PLUGINMOD_QUEUE = "PLUGINMOD";
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
// src/distributions/external/info.ts
|
|
543
|
+
async function infoExternal(issueKey) {
|
|
544
|
+
let targetIssueKey = issueKey;
|
|
545
|
+
if (targetIssueKey || (targetIssueKey = (await pluginStateManager.load()).trackerIssueKey), !targetIssueKey) {
|
|
546
|
+
logger_default.warning(
|
|
547
|
+
`No issue key provided and plugin has not been submitted yet. Run "${CLI_NAME} submit" first.`
|
|
548
|
+
), logger_default.suggest(`${CLI_NAME} submit`);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
logger_default.info(`\u23F3 Fetching plugin info for ${targetIssueKey}...`);
|
|
552
|
+
try {
|
|
553
|
+
let issue = await getIssue(targetIssueKey);
|
|
554
|
+
showTrackerPluginInfo(issue);
|
|
555
|
+
} catch (error2) {
|
|
556
|
+
throw logger_default.error(`Failed to fetch plugin info for ${targetIssueKey}`), error2;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
var init_info = __esm({
|
|
560
|
+
"src/distributions/external/info.ts"() {
|
|
561
|
+
"use strict";
|
|
562
|
+
init_pluginStateManager();
|
|
563
|
+
init_logger();
|
|
564
|
+
init_pluginDisplay();
|
|
565
|
+
init_meta();
|
|
566
|
+
init_tracker();
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// src/distributions/external/list.ts
|
|
571
|
+
async function listExternal() {
|
|
572
|
+
logger_default.info("\u23F3 Fetching my plugins from Tracker...");
|
|
573
|
+
try {
|
|
574
|
+
let issues = await getMyPluginIssues();
|
|
575
|
+
showTrackerPluginList(issues);
|
|
576
|
+
} catch (error2) {
|
|
577
|
+
throw logger_default.error("Failed to fetch plugins list"), error2;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
var init_list = __esm({
|
|
581
|
+
"src/distributions/external/list.ts"() {
|
|
582
|
+
"use strict";
|
|
583
|
+
init_logger();
|
|
584
|
+
init_pluginDisplay();
|
|
585
|
+
init_tracker();
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
// src/distributions/external/login.ts
|
|
590
|
+
async function loginExternal() {
|
|
591
|
+
console.info(
|
|
592
|
+
import_picocolors3.default.dim(
|
|
593
|
+
"To get an OAuth token for Yandex Tracker, please contact Tracker support and request one."
|
|
594
|
+
)
|
|
595
|
+
), console.info("");
|
|
596
|
+
let trimmed = (await (0, import_prompts2.input)({
|
|
597
|
+
message: "Enter your OAuth token:",
|
|
598
|
+
required: !0
|
|
599
|
+
})).trim();
|
|
600
|
+
externalAuthManager.saveAuthData(trimmed), logger_default.success("OAuth token saved successfully."), logger_default.info('You can now use "weavix submit" to submit your plugin for review.');
|
|
601
|
+
}
|
|
602
|
+
function logoutExternal() {
|
|
603
|
+
if (!externalAuthManager.data) {
|
|
604
|
+
logger_default.warning("You are not logged in.");
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
externalAuthManager.removeAuthData(), logger_default.success("Successfully logged out.");
|
|
608
|
+
}
|
|
609
|
+
var import_prompts2, import_picocolors3, init_login = __esm({
|
|
610
|
+
"src/distributions/external/login.ts"() {
|
|
611
|
+
"use strict";
|
|
612
|
+
import_prompts2 = require("@inquirer/prompts"), import_picocolors3 = __toESM(require("picocolors"));
|
|
613
|
+
init_logger();
|
|
614
|
+
init_authManager();
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
// src/utils/execCommand.ts
|
|
619
|
+
var import_execa, execCommand, init_execCommand = __esm({
|
|
620
|
+
"src/utils/execCommand.ts"() {
|
|
621
|
+
"use strict";
|
|
622
|
+
import_execa = require("execa"), execCommand = async (command, cwd = process.cwd(), env) => {
|
|
623
|
+
await (0, import_execa.execa)(command, {
|
|
624
|
+
cwd,
|
|
625
|
+
shell: !0,
|
|
626
|
+
stdio: "inherit",
|
|
627
|
+
env: env ? { ...process.env, ...env } : void 0
|
|
628
|
+
});
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
// src/commands/constants/templateCommands.ts
|
|
634
|
+
var pluginCmd, init_templateCommands = __esm({
|
|
635
|
+
"src/commands/constants/templateCommands.ts"() {
|
|
636
|
+
"use strict";
|
|
637
|
+
pluginCmd = {
|
|
638
|
+
install: "npm install",
|
|
639
|
+
build: "npm run build",
|
|
640
|
+
dev: "npm run dev",
|
|
641
|
+
lint: "npm run lint",
|
|
642
|
+
typecheck: "npm run typecheck",
|
|
643
|
+
test: "npm test",
|
|
644
|
+
audit: "npm audit --audit-level=critical"
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
// src/commands/build.ts
|
|
650
|
+
var build, init_build = __esm({
|
|
651
|
+
"src/commands/build.ts"() {
|
|
652
|
+
"use strict";
|
|
653
|
+
init_execCommand();
|
|
654
|
+
init_logger();
|
|
655
|
+
init_templateCommands();
|
|
656
|
+
build = async ({ environment = "production" } = {}) => {
|
|
657
|
+
logger_default.info("\u{1F528} Building project..."), await execCommand(pluginCmd.install), await execCommand(
|
|
658
|
+
pluginCmd.build,
|
|
659
|
+
process.cwd(),
|
|
660
|
+
environment ? { VITE_DEPLOY_ENV: environment } : void 0
|
|
661
|
+
);
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
// src/distributions/external/manifestPermissionsSchema.ts
|
|
667
|
+
var manifestPermissionsSchema_exports = {};
|
|
668
|
+
__export(manifestPermissionsSchema_exports, {
|
|
669
|
+
permissionsSchemaExtensions: () => permissionsSchemaExtensions
|
|
670
|
+
});
|
|
671
|
+
var permissionsSchemaExtensions, init_manifestPermissionsSchema = __esm({
|
|
672
|
+
"src/distributions/external/manifestPermissionsSchema.ts"() {
|
|
673
|
+
"use strict";
|
|
674
|
+
permissionsSchemaExtensions = {};
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
// src/distribution/manifestPermissionsSchema.ts
|
|
679
|
+
var impl2, permissionsSchemaExtensions2, init_manifestPermissionsSchema2 = __esm({
|
|
680
|
+
"src/distribution/manifestPermissionsSchema.ts"() {
|
|
681
|
+
"use strict";
|
|
682
|
+
init_flag();
|
|
683
|
+
impl2 = (init_manifestPermissionsSchema(), __toCommonJS(manifestPermissionsSchema_exports)), { permissionsSchemaExtensions: permissionsSchemaExtensions2 } = impl2;
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
// src/core/manifest/formatValidationErrors.ts
|
|
688
|
+
var priorityOrder, errorMessages, getPriority, formatValidationErrors, init_formatValidationErrors = __esm({
|
|
689
|
+
"src/core/manifest/formatValidationErrors.ts"() {
|
|
690
|
+
"use strict";
|
|
691
|
+
priorityOrder = [
|
|
692
|
+
"required",
|
|
693
|
+
"type",
|
|
694
|
+
"minLength",
|
|
695
|
+
"format",
|
|
696
|
+
"pattern",
|
|
697
|
+
"enum",
|
|
698
|
+
"additionalProperties",
|
|
699
|
+
"uniqueItems"
|
|
700
|
+
], errorMessages = {
|
|
701
|
+
required: (params) => `missing required property '${params.missingProperty}'`,
|
|
702
|
+
type: (params) => `must be ${params.type}`,
|
|
703
|
+
enum: (params) => `must be one of [${params.allowedValues.join(", ")}]`,
|
|
704
|
+
pattern: (params) => `must match pattern ${params.pattern}`,
|
|
705
|
+
format: (params) => `must be a valid ${params.format}`,
|
|
706
|
+
minLength: () => "must not be empty",
|
|
707
|
+
additionalProperties: (params) => `unexpected property '${params.additionalProperty}'`,
|
|
708
|
+
uniqueItems: () => "must contain unique items"
|
|
709
|
+
}, getPriority = (keyword) => {
|
|
710
|
+
let index = priorityOrder.indexOf(keyword);
|
|
711
|
+
return index === -1 ? priorityOrder.length : index;
|
|
712
|
+
}, formatValidationErrors = (errors) => {
|
|
713
|
+
let errorsByPath = {};
|
|
714
|
+
for (let error2 of errors) {
|
|
715
|
+
let path18 = error2.instancePath || "root";
|
|
716
|
+
errorsByPath[path18] || (errorsByPath[path18] = []), errorsByPath[path18].push(error2);
|
|
717
|
+
}
|
|
718
|
+
return Object.entries(errorsByPath).map(([path18, pathErrors]) => {
|
|
719
|
+
let error2 = [...pathErrors].sort(
|
|
720
|
+
(a, b) => getPriority(a.keyword) - getPriority(b.keyword)
|
|
721
|
+
)[0], formatter = errorMessages[error2.keyword], message = formatter ? formatter(error2.params) : error2.message;
|
|
722
|
+
return ` - ${path18}: ${message}`;
|
|
723
|
+
}).join(`
|
|
724
|
+
`);
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
// src/core/manifest/manifest.schema.json
|
|
730
|
+
var manifest_schema_default, init_manifest_schema = __esm({
|
|
731
|
+
"src/core/manifest/manifest.schema.json"() {
|
|
732
|
+
manifest_schema_default = {
|
|
733
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
734
|
+
title: "Manifest",
|
|
735
|
+
description: "Schema for validating plugin manifest",
|
|
736
|
+
type: "object",
|
|
737
|
+
required: [
|
|
738
|
+
"slug",
|
|
739
|
+
"version",
|
|
740
|
+
"permissions",
|
|
741
|
+
"name",
|
|
742
|
+
"description",
|
|
743
|
+
"support"
|
|
744
|
+
],
|
|
745
|
+
properties: {
|
|
746
|
+
$schema: {
|
|
747
|
+
type: "string"
|
|
748
|
+
},
|
|
749
|
+
id: {
|
|
750
|
+
type: "string",
|
|
751
|
+
description: "Unique identifier for the plugin ()",
|
|
752
|
+
minLength: 3,
|
|
753
|
+
maxLength: 63,
|
|
754
|
+
pattern: "^[a-z0-9-]+$"
|
|
755
|
+
},
|
|
756
|
+
manifest_version: {
|
|
757
|
+
type: "number",
|
|
758
|
+
description: "Manifest format version",
|
|
759
|
+
minimum: 1
|
|
760
|
+
},
|
|
761
|
+
supported_services: {
|
|
762
|
+
type: "array",
|
|
763
|
+
description: "Supported services for this plugin",
|
|
764
|
+
items: {
|
|
765
|
+
type: "string",
|
|
766
|
+
enum: [
|
|
767
|
+
"tracker"
|
|
768
|
+
]
|
|
769
|
+
},
|
|
770
|
+
minItems: 1,
|
|
771
|
+
uniqueItems: !0
|
|
772
|
+
},
|
|
773
|
+
slug: {
|
|
774
|
+
type: "string",
|
|
775
|
+
description: "Unique identifier for the plugin (lowercase letters, numbers, hyphen)",
|
|
776
|
+
minLength: 3,
|
|
777
|
+
maxLength: 63,
|
|
778
|
+
pattern: "^[a-z0-9-]+$"
|
|
779
|
+
},
|
|
780
|
+
version: {
|
|
781
|
+
type: "string",
|
|
782
|
+
description: "Version of the plugin (semver format required)",
|
|
783
|
+
minLength: 1,
|
|
784
|
+
pattern: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$"
|
|
785
|
+
},
|
|
786
|
+
name: {
|
|
787
|
+
type: "object",
|
|
788
|
+
description: "Localized plugin name",
|
|
789
|
+
required: [
|
|
790
|
+
"ru",
|
|
791
|
+
"en"
|
|
792
|
+
],
|
|
793
|
+
properties: {
|
|
794
|
+
ru: {
|
|
795
|
+
type: "string",
|
|
796
|
+
description: "Russian name",
|
|
797
|
+
minLength: 1,
|
|
798
|
+
maxLength: 30
|
|
799
|
+
},
|
|
800
|
+
en: {
|
|
801
|
+
type: "string",
|
|
802
|
+
description: "English name",
|
|
803
|
+
minLength: 1,
|
|
804
|
+
maxLength: 30
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
additionalProperties: !1
|
|
808
|
+
},
|
|
809
|
+
description: {
|
|
810
|
+
type: "object",
|
|
811
|
+
description: "Localized plugin description",
|
|
812
|
+
required: [
|
|
813
|
+
"ru",
|
|
814
|
+
"en"
|
|
815
|
+
],
|
|
816
|
+
properties: {
|
|
817
|
+
ru: {
|
|
818
|
+
type: "string",
|
|
819
|
+
description: "Russian description",
|
|
820
|
+
minLength: 1,
|
|
821
|
+
maxLength: 255
|
|
822
|
+
},
|
|
823
|
+
en: {
|
|
824
|
+
type: "string",
|
|
825
|
+
description: "English description",
|
|
826
|
+
minLength: 1,
|
|
827
|
+
maxLength: 255
|
|
828
|
+
}
|
|
829
|
+
},
|
|
830
|
+
additionalProperties: !1
|
|
831
|
+
},
|
|
832
|
+
support: {
|
|
833
|
+
type: "array",
|
|
834
|
+
description: "Support contact information",
|
|
835
|
+
items: {
|
|
836
|
+
type: "object",
|
|
837
|
+
required: [
|
|
838
|
+
"type",
|
|
839
|
+
"value"
|
|
840
|
+
],
|
|
841
|
+
properties: {
|
|
842
|
+
type: {
|
|
843
|
+
type: "string",
|
|
844
|
+
description: "Type of support contact",
|
|
845
|
+
enum: [
|
|
846
|
+
"email"
|
|
847
|
+
]
|
|
848
|
+
},
|
|
849
|
+
value: {
|
|
850
|
+
type: "string",
|
|
851
|
+
description: "Contact value",
|
|
852
|
+
minLength: 1,
|
|
853
|
+
maxLength: 100
|
|
854
|
+
}
|
|
855
|
+
},
|
|
856
|
+
additionalProperties: !1
|
|
857
|
+
},
|
|
858
|
+
minItems: 1
|
|
859
|
+
},
|
|
860
|
+
homepage: {
|
|
861
|
+
type: "string",
|
|
862
|
+
description: "Homepage URL for the plugin (http or https)",
|
|
863
|
+
pattern: "^https?://",
|
|
864
|
+
maxLength: 1e3
|
|
865
|
+
},
|
|
866
|
+
license: {
|
|
867
|
+
type: "string",
|
|
868
|
+
description: "License identifier (e.g., MIT, Apache-2.0)",
|
|
869
|
+
minLength: 1,
|
|
870
|
+
maxLength: 32
|
|
871
|
+
},
|
|
872
|
+
keywords: {
|
|
873
|
+
type: "array",
|
|
874
|
+
description: "Keywords for plugin discovery",
|
|
875
|
+
items: {
|
|
876
|
+
type: "string",
|
|
877
|
+
minLength: 1,
|
|
878
|
+
maxLength: 30
|
|
879
|
+
},
|
|
880
|
+
uniqueItems: !0
|
|
881
|
+
},
|
|
882
|
+
whatsnew: {
|
|
883
|
+
type: "string",
|
|
884
|
+
description: "What's new in this version",
|
|
885
|
+
minLength: 1,
|
|
886
|
+
maxLength: 300
|
|
887
|
+
},
|
|
888
|
+
externalHost: {
|
|
889
|
+
type: "string",
|
|
890
|
+
description: "External host URL for the plugin (https only)",
|
|
891
|
+
format: "uri",
|
|
892
|
+
pattern: "^https://",
|
|
893
|
+
maxLength: 1e3
|
|
894
|
+
},
|
|
895
|
+
permissions: {
|
|
896
|
+
type: "object",
|
|
897
|
+
description: "Permissions required by the plugin",
|
|
898
|
+
required: [
|
|
899
|
+
"data"
|
|
900
|
+
],
|
|
901
|
+
properties: {
|
|
902
|
+
data: {
|
|
903
|
+
type: "array",
|
|
904
|
+
description: "Data access permissions",
|
|
905
|
+
items: {
|
|
906
|
+
type: "string",
|
|
907
|
+
enum: [
|
|
908
|
+
"tracker:issues:read",
|
|
909
|
+
"tracker:issues:write",
|
|
910
|
+
"tracker:issuetypes:read",
|
|
911
|
+
"tracker:statuses:read",
|
|
912
|
+
"tracker:queues:read",
|
|
913
|
+
"tracker:fields:read",
|
|
914
|
+
"tracker:entities:read",
|
|
915
|
+
"tracker:attachments:read",
|
|
916
|
+
"tracker:attachments:write",
|
|
917
|
+
"tracker:applications:read",
|
|
918
|
+
"tracker:boards:read",
|
|
919
|
+
"tracker:boards:write",
|
|
920
|
+
"tracker:bulk:read",
|
|
921
|
+
"tracker:bulk:write",
|
|
922
|
+
"tracker:bulkchange:read",
|
|
923
|
+
"tracker:bulkchange:write",
|
|
924
|
+
"tracker:charts:read",
|
|
925
|
+
"tracker:commentTemplates:read",
|
|
926
|
+
"tracker:commentTemplates:write",
|
|
927
|
+
"tracker:components:read",
|
|
928
|
+
"tracker:components:write",
|
|
929
|
+
"tracker:data:read",
|
|
930
|
+
"tracker:departments:read",
|
|
931
|
+
"tracker:entities:write",
|
|
932
|
+
"tracker:externalEventTypes:write",
|
|
933
|
+
"tracker:externalEvents:write",
|
|
934
|
+
"tracker:fields:write",
|
|
935
|
+
"tracker:filterFolders:write",
|
|
936
|
+
"tracker:filters:read",
|
|
937
|
+
"tracker:filters:write",
|
|
938
|
+
"tracker:goals:read",
|
|
939
|
+
"tracker:goals:write",
|
|
940
|
+
"tracker:groups:read",
|
|
941
|
+
"tracker:issueTemplates:read",
|
|
942
|
+
"tracker:issueTemplates:write",
|
|
943
|
+
"tracker:links:read",
|
|
944
|
+
"tracker:linktypes:read",
|
|
945
|
+
"tracker:liveBoards:write",
|
|
946
|
+
"tracker:localFields:read",
|
|
947
|
+
"tracker:maillists:read",
|
|
948
|
+
"tracker:maillists:write",
|
|
949
|
+
"tracker:myself:read",
|
|
950
|
+
"tracker:myself:write",
|
|
951
|
+
"tracker:priorities:read",
|
|
952
|
+
"tracker:queues:write",
|
|
953
|
+
"tracker:reminders:read",
|
|
954
|
+
"tracker:reminders:write",
|
|
955
|
+
"tracker:remotelinks:read",
|
|
956
|
+
"tracker:reports:read",
|
|
957
|
+
"tracker:reports:write",
|
|
958
|
+
"tracker:resolutions:read",
|
|
959
|
+
"tracker:resources:read",
|
|
960
|
+
"tracker:resources:write",
|
|
961
|
+
"tracker:roles:read",
|
|
962
|
+
"tracker:screens:read",
|
|
963
|
+
"tracker:services:read",
|
|
964
|
+
"tracker:sprints:read",
|
|
965
|
+
"tracker:sprints:write",
|
|
966
|
+
"tracker:system:write",
|
|
967
|
+
"tracker:tags:read",
|
|
968
|
+
"tracker:translations:read",
|
|
969
|
+
"tracker:users:read",
|
|
970
|
+
"tracker:users:write",
|
|
971
|
+
"tracker:versions:read",
|
|
972
|
+
"tracker:versions:write",
|
|
973
|
+
"tracker:workflows:read",
|
|
974
|
+
"tracker:workflows:write",
|
|
975
|
+
"tracker:worklog:read",
|
|
976
|
+
"tracker:worklog:write"
|
|
977
|
+
]
|
|
978
|
+
},
|
|
979
|
+
uniqueItems: !0
|
|
980
|
+
},
|
|
981
|
+
ui: {
|
|
982
|
+
type: "array",
|
|
983
|
+
description: "UI permissions",
|
|
984
|
+
items: {
|
|
985
|
+
type: "string"
|
|
986
|
+
},
|
|
987
|
+
uniqueItems: !0
|
|
988
|
+
},
|
|
989
|
+
device: {
|
|
990
|
+
type: "array",
|
|
991
|
+
description: "Device permissions",
|
|
992
|
+
items: {
|
|
993
|
+
type: "string",
|
|
994
|
+
enum: [
|
|
995
|
+
"clipboard-write"
|
|
996
|
+
]
|
|
997
|
+
},
|
|
998
|
+
uniqueItems: !0
|
|
999
|
+
},
|
|
1000
|
+
external: {
|
|
1001
|
+
type: "array",
|
|
1002
|
+
description: "External API domains the plugin may call through the platform proxy",
|
|
1003
|
+
items: {
|
|
1004
|
+
$ref: "#/definitions/ExternalDomain"
|
|
1005
|
+
},
|
|
1006
|
+
uniqueItems: !0
|
|
1007
|
+
}
|
|
1008
|
+
},
|
|
1009
|
+
additionalProperties: !1
|
|
1010
|
+
},
|
|
1011
|
+
slots: {
|
|
1012
|
+
type: "object",
|
|
1013
|
+
description: "Configuration for service slots",
|
|
1014
|
+
minProperties: 1,
|
|
1015
|
+
properties: {
|
|
1016
|
+
tracker: {
|
|
1017
|
+
type: "object",
|
|
1018
|
+
description: "Tracker service slots",
|
|
1019
|
+
minProperties: 1,
|
|
1020
|
+
properties: {
|
|
1021
|
+
"issue.action": {
|
|
1022
|
+
type: "array",
|
|
1023
|
+
description: "Issue Action slot configurations",
|
|
1024
|
+
minItems: 1,
|
|
1025
|
+
items: {
|
|
1026
|
+
$ref: "#/definitions/SlotConfig"
|
|
1027
|
+
}
|
|
1028
|
+
},
|
|
1029
|
+
"issue.block": {
|
|
1030
|
+
type: "array",
|
|
1031
|
+
description: "Issue Block slot configurations",
|
|
1032
|
+
minItems: 1,
|
|
1033
|
+
items: {
|
|
1034
|
+
$ref: "#/definitions/SlotConfig"
|
|
1035
|
+
}
|
|
1036
|
+
},
|
|
1037
|
+
"issue.tab": {
|
|
1038
|
+
type: "array",
|
|
1039
|
+
description: "Issue Tab slot configurations",
|
|
1040
|
+
minItems: 1,
|
|
1041
|
+
items: {
|
|
1042
|
+
$ref: "#/definitions/SlotConfig"
|
|
1043
|
+
}
|
|
1044
|
+
},
|
|
1045
|
+
"issue.comment.action": {
|
|
1046
|
+
type: "array",
|
|
1047
|
+
description: "Issue Comment Action slot configurations",
|
|
1048
|
+
minItems: 1,
|
|
1049
|
+
items: {
|
|
1050
|
+
$ref: "#/definitions/SlotConfig"
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1053
|
+
navigation: {
|
|
1054
|
+
type: "array",
|
|
1055
|
+
description: "Navigation slot configurations",
|
|
1056
|
+
minItems: 1,
|
|
1057
|
+
items: {
|
|
1058
|
+
$ref: "#/definitions/SlotConfig"
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
"trigger.create.action": {
|
|
1062
|
+
type: "array",
|
|
1063
|
+
description: "Trigger Create Action slot configurations",
|
|
1064
|
+
minItems: 1,
|
|
1065
|
+
items: {
|
|
1066
|
+
$ref: "#/definitions/SlotConfig"
|
|
1067
|
+
}
|
|
1068
|
+
},
|
|
1069
|
+
"trigger.edit.action": {
|
|
1070
|
+
type: "array",
|
|
1071
|
+
description: "Trigger Edit Action slot configurations",
|
|
1072
|
+
minItems: 1,
|
|
1073
|
+
items: {
|
|
1074
|
+
$ref: "#/definitions/SlotConfig"
|
|
1075
|
+
}
|
|
1076
|
+
},
|
|
1077
|
+
"project.action": {
|
|
1078
|
+
type: "array",
|
|
1079
|
+
description: "Project Action slot configurations",
|
|
1080
|
+
minItems: 1,
|
|
1081
|
+
items: {
|
|
1082
|
+
$ref: "#/definitions/SlotConfig"
|
|
1083
|
+
}
|
|
1084
|
+
},
|
|
1085
|
+
"project.block": {
|
|
1086
|
+
type: "array",
|
|
1087
|
+
description: "Project Block slot configurations",
|
|
1088
|
+
minItems: 1,
|
|
1089
|
+
items: {
|
|
1090
|
+
$ref: "#/definitions/SlotConfig"
|
|
1091
|
+
}
|
|
1092
|
+
},
|
|
1093
|
+
"project.tab": {
|
|
1094
|
+
type: "array",
|
|
1095
|
+
description: "Project Tab slot configurations",
|
|
1096
|
+
minItems: 1,
|
|
1097
|
+
items: {
|
|
1098
|
+
$ref: "#/definitions/SlotConfig"
|
|
1099
|
+
}
|
|
1100
|
+
},
|
|
1101
|
+
"portfolio.action": {
|
|
1102
|
+
type: "array",
|
|
1103
|
+
description: "Portfolio Action slot configurations",
|
|
1104
|
+
minItems: 1,
|
|
1105
|
+
items: {
|
|
1106
|
+
$ref: "#/definitions/SlotConfig"
|
|
1107
|
+
}
|
|
1108
|
+
},
|
|
1109
|
+
"portfolio.block": {
|
|
1110
|
+
type: "array",
|
|
1111
|
+
description: "Portfolio Block slot configurations",
|
|
1112
|
+
minItems: 1,
|
|
1113
|
+
items: {
|
|
1114
|
+
$ref: "#/definitions/SlotConfig"
|
|
1115
|
+
}
|
|
1116
|
+
},
|
|
1117
|
+
"portfolio.tab": {
|
|
1118
|
+
type: "array",
|
|
1119
|
+
description: "Portfolio Tab slot configurations",
|
|
1120
|
+
minItems: 1,
|
|
1121
|
+
items: {
|
|
1122
|
+
$ref: "#/definitions/SlotConfig"
|
|
1123
|
+
}
|
|
1124
|
+
},
|
|
1125
|
+
"goal.action": {
|
|
1126
|
+
type: "array",
|
|
1127
|
+
description: "Goal Action slot configurations",
|
|
1128
|
+
minItems: 1,
|
|
1129
|
+
items: {
|
|
1130
|
+
$ref: "#/definitions/SlotConfig"
|
|
1131
|
+
}
|
|
1132
|
+
},
|
|
1133
|
+
"goal.block": {
|
|
1134
|
+
type: "array",
|
|
1135
|
+
description: "Goal Block slot configurations",
|
|
1136
|
+
minItems: 1,
|
|
1137
|
+
items: {
|
|
1138
|
+
$ref: "#/definitions/SlotConfig"
|
|
1139
|
+
}
|
|
1140
|
+
},
|
|
1141
|
+
"goal.tab": {
|
|
1142
|
+
type: "array",
|
|
1143
|
+
description: "Goal Tab slot configurations",
|
|
1144
|
+
minItems: 1,
|
|
1145
|
+
items: {
|
|
1146
|
+
$ref: "#/definitions/SlotConfig"
|
|
1147
|
+
}
|
|
1148
|
+
},
|
|
1149
|
+
"attachment.viewer.action": {
|
|
1150
|
+
type: "array",
|
|
1151
|
+
description: "Attachment Viewer Action slot configurations",
|
|
1152
|
+
minItems: 1,
|
|
1153
|
+
items: {
|
|
1154
|
+
$ref: "#/definitions/SlotConfig"
|
|
1155
|
+
}
|
|
1156
|
+
},
|
|
1157
|
+
"board.tab": {
|
|
1158
|
+
type: "array",
|
|
1159
|
+
description: "Board Tab slot configurations",
|
|
1160
|
+
minItems: 1,
|
|
1161
|
+
items: {
|
|
1162
|
+
$ref: "#/definitions/SlotConfig"
|
|
1163
|
+
}
|
|
1164
|
+
},
|
|
1165
|
+
dock: {
|
|
1166
|
+
type: "array",
|
|
1167
|
+
description: "Dock slot configurations",
|
|
1168
|
+
minItems: 1,
|
|
1169
|
+
items: {
|
|
1170
|
+
$ref: "#/definitions/SlotConfig"
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
additionalProperties: !1
|
|
1175
|
+
}
|
|
1176
|
+
},
|
|
1177
|
+
additionalProperties: !1
|
|
1178
|
+
}
|
|
1179
|
+
},
|
|
1180
|
+
additionalProperties: !1,
|
|
1181
|
+
definitions: {
|
|
1182
|
+
ExternalDomain: {
|
|
1183
|
+
type: "object",
|
|
1184
|
+
description: "External API domain declaration with optional authorization config",
|
|
1185
|
+
required: [
|
|
1186
|
+
"domain"
|
|
1187
|
+
],
|
|
1188
|
+
properties: {
|
|
1189
|
+
domain: {
|
|
1190
|
+
type: "string",
|
|
1191
|
+
description: "Hostname of the external API (no scheme, no path, lowercase)",
|
|
1192
|
+
pattern: "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$",
|
|
1193
|
+
minLength: 1,
|
|
1194
|
+
maxLength: 253
|
|
1195
|
+
},
|
|
1196
|
+
authorization: {
|
|
1197
|
+
$ref: "#/definitions/ExternalAuthorization"
|
|
1198
|
+
},
|
|
1199
|
+
instructions: {
|
|
1200
|
+
type: "object",
|
|
1201
|
+
description: "Localized note shown to the end user when they need to provide a token for this domain (e.g. where to generate the PAT)",
|
|
1202
|
+
required: [
|
|
1203
|
+
"ru",
|
|
1204
|
+
"en"
|
|
1205
|
+
],
|
|
1206
|
+
properties: {
|
|
1207
|
+
ru: {
|
|
1208
|
+
type: "string",
|
|
1209
|
+
description: "Russian instructions",
|
|
1210
|
+
minLength: 1,
|
|
1211
|
+
maxLength: 500
|
|
1212
|
+
},
|
|
1213
|
+
en: {
|
|
1214
|
+
type: "string",
|
|
1215
|
+
description: "English instructions",
|
|
1216
|
+
minLength: 1,
|
|
1217
|
+
maxLength: 500
|
|
1218
|
+
}
|
|
1219
|
+
},
|
|
1220
|
+
additionalProperties: !1
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
additionalProperties: !1
|
|
1224
|
+
},
|
|
1225
|
+
ExternalAuthorization: {
|
|
1226
|
+
type: "object",
|
|
1227
|
+
description: "Authorization config for an external API domain",
|
|
1228
|
+
required: [
|
|
1229
|
+
"type"
|
|
1230
|
+
],
|
|
1231
|
+
properties: {
|
|
1232
|
+
type: {
|
|
1233
|
+
type: "string",
|
|
1234
|
+
description: "Authorization scheme: oauth (full OAuth flow or manual PAT for an OAuth provider) or token (manual non-OAuth token, e.g. API key)",
|
|
1235
|
+
enum: [
|
|
1236
|
+
"oauth",
|
|
1237
|
+
"token"
|
|
1238
|
+
]
|
|
1239
|
+
},
|
|
1240
|
+
scopes: {
|
|
1241
|
+
type: "array",
|
|
1242
|
+
description: "Scopes required by this version of the plugin for the domain",
|
|
1243
|
+
items: {
|
|
1244
|
+
type: "string",
|
|
1245
|
+
minLength: 1
|
|
1246
|
+
},
|
|
1247
|
+
uniqueItems: !0
|
|
1248
|
+
},
|
|
1249
|
+
contextTypes: {
|
|
1250
|
+
type: "array",
|
|
1251
|
+
description: "Supported token storage contexts",
|
|
1252
|
+
items: {
|
|
1253
|
+
type: "string",
|
|
1254
|
+
enum: [
|
|
1255
|
+
"user",
|
|
1256
|
+
"organization"
|
|
1257
|
+
]
|
|
1258
|
+
},
|
|
1259
|
+
minItems: 1,
|
|
1260
|
+
uniqueItems: !0
|
|
1261
|
+
},
|
|
1262
|
+
header: {
|
|
1263
|
+
type: "string",
|
|
1264
|
+
description: "Custom HTTP header name to put the token into (default: Authorization)",
|
|
1265
|
+
minLength: 1
|
|
1266
|
+
},
|
|
1267
|
+
prefix: {
|
|
1268
|
+
type: "string",
|
|
1269
|
+
description: "Custom token prefix in the Authorization header (default: Bearer; empty string for no prefix)"
|
|
1270
|
+
}
|
|
1271
|
+
},
|
|
1272
|
+
additionalProperties: !1
|
|
1273
|
+
},
|
|
1274
|
+
SlotConfig: {
|
|
1275
|
+
type: "object",
|
|
1276
|
+
description: "Configuration for a specific slot",
|
|
1277
|
+
required: [
|
|
1278
|
+
"entrypoint",
|
|
1279
|
+
"title",
|
|
1280
|
+
"contextLevel"
|
|
1281
|
+
],
|
|
1282
|
+
properties: {
|
|
1283
|
+
entrypoint: {
|
|
1284
|
+
type: "string",
|
|
1285
|
+
description: "Entry point file path for the slot",
|
|
1286
|
+
minLength: 1
|
|
1287
|
+
},
|
|
1288
|
+
title: {
|
|
1289
|
+
type: "object",
|
|
1290
|
+
description: "Localized titles for the slot",
|
|
1291
|
+
required: [
|
|
1292
|
+
"ru",
|
|
1293
|
+
"en"
|
|
1294
|
+
],
|
|
1295
|
+
properties: {
|
|
1296
|
+
ru: {
|
|
1297
|
+
type: "string",
|
|
1298
|
+
description: "Russian title",
|
|
1299
|
+
minLength: 1,
|
|
1300
|
+
maxLength: 32
|
|
1301
|
+
},
|
|
1302
|
+
en: {
|
|
1303
|
+
type: "string",
|
|
1304
|
+
description: "English title",
|
|
1305
|
+
minLength: 1,
|
|
1306
|
+
maxLength: 32
|
|
1307
|
+
}
|
|
1308
|
+
},
|
|
1309
|
+
additionalProperties: !1
|
|
1310
|
+
},
|
|
1311
|
+
contextLevel: {
|
|
1312
|
+
type: "string",
|
|
1313
|
+
description: "Level of context data provided to the slot",
|
|
1314
|
+
enum: [
|
|
1315
|
+
"basic",
|
|
1316
|
+
"full"
|
|
1317
|
+
]
|
|
1318
|
+
},
|
|
1319
|
+
icon: {
|
|
1320
|
+
type: "object",
|
|
1321
|
+
description: "Optional slot icon (used by 'dock' slot for FAB)",
|
|
1322
|
+
required: [
|
|
1323
|
+
"url"
|
|
1324
|
+
],
|
|
1325
|
+
properties: {
|
|
1326
|
+
url: {
|
|
1327
|
+
type: "string",
|
|
1328
|
+
description: "Relative path to the icon file (e.g. ./icon.svg)",
|
|
1329
|
+
minLength: 1
|
|
1330
|
+
}
|
|
1331
|
+
},
|
|
1332
|
+
additionalProperties: !1
|
|
1333
|
+
},
|
|
1334
|
+
description: {
|
|
1335
|
+
type: "object",
|
|
1336
|
+
description: "Localized descriptions for the slot",
|
|
1337
|
+
required: [
|
|
1338
|
+
"ru",
|
|
1339
|
+
"en"
|
|
1340
|
+
],
|
|
1341
|
+
properties: {
|
|
1342
|
+
ru: {
|
|
1343
|
+
type: "string",
|
|
1344
|
+
description: "Russian description",
|
|
1345
|
+
minLength: 1,
|
|
1346
|
+
maxLength: 300
|
|
1347
|
+
},
|
|
1348
|
+
en: {
|
|
1349
|
+
type: "string",
|
|
1350
|
+
description: "English description",
|
|
1351
|
+
minLength: 1,
|
|
1352
|
+
maxLength: 300
|
|
1353
|
+
}
|
|
1354
|
+
},
|
|
1355
|
+
additionalProperties: !1
|
|
1356
|
+
}
|
|
1357
|
+
},
|
|
1358
|
+
additionalProperties: !1
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
});
|
|
1364
|
+
|
|
1365
|
+
// src/core/manifest/manifestManager.ts
|
|
1366
|
+
var import_fs4, import_promises2, import_ajv, import_ajv_formats, validator, manifestPath, parseManifest, loadRaw, load2, validate, save2, update2, manifestManager, init_manifestManager = __esm({
|
|
1367
|
+
"src/core/manifest/manifestManager.ts"() {
|
|
1368
|
+
"use strict";
|
|
1369
|
+
import_fs4 = require("fs"), import_promises2 = require("fs/promises"), import_ajv = __toESM(require("ajv")), import_ajv_formats = __toESM(require("ajv-formats"));
|
|
1370
|
+
init_manifestPermissionsSchema2();
|
|
1371
|
+
init_formatValidationErrors();
|
|
1372
|
+
init_manifest_schema();
|
|
1373
|
+
validator = (() => {
|
|
1374
|
+
let schema = {
|
|
1375
|
+
...manifest_schema_default,
|
|
1376
|
+
properties: {
|
|
1377
|
+
...manifest_schema_default.properties,
|
|
1378
|
+
permissions: {
|
|
1379
|
+
...manifest_schema_default.properties.permissions,
|
|
1380
|
+
properties: {
|
|
1381
|
+
...manifest_schema_default.properties.permissions.properties,
|
|
1382
|
+
...permissionsSchemaExtensions2
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}, ajv = new import_ajv.default({ allErrors: !0, strict: !1 });
|
|
1387
|
+
return (0, import_ajv_formats.default)(ajv), ajv.compile(schema);
|
|
1388
|
+
})(), manifestPath = "./manifest.json", parseManifest = (content) => {
|
|
1389
|
+
let manifest;
|
|
1390
|
+
try {
|
|
1391
|
+
manifest = JSON.parse(content);
|
|
1392
|
+
} catch (error2) {
|
|
1393
|
+
throw error2 instanceof SyntaxError ? new Error(`File manifest.json contains invalid JSON: ${error2.message}`) : new Error(`Error reading manifest.json: ${error2.message}`);
|
|
1394
|
+
}
|
|
1395
|
+
return manifest;
|
|
1396
|
+
}, loadRaw = async () => {
|
|
1397
|
+
if (!(0, import_fs4.existsSync)(manifestPath))
|
|
1398
|
+
throw new Error(`File manifest.json not found at path: ${manifestPath}`);
|
|
1399
|
+
try {
|
|
1400
|
+
return await (0, import_promises2.readFile)(manifestPath, "utf8");
|
|
1401
|
+
} catch (error2) {
|
|
1402
|
+
throw error2 instanceof Error ? new Error(`Error reading manifest.json: ${error2.message}`) : new Error("Error loading manifest");
|
|
1403
|
+
}
|
|
1404
|
+
}, load2 = async () => {
|
|
1405
|
+
let manifestContent = await loadRaw();
|
|
1406
|
+
return parseManifest(manifestContent);
|
|
1407
|
+
}, validate = async () => {
|
|
1408
|
+
let manifest = await load2();
|
|
1409
|
+
if (!validator(manifest) && validator.errors) {
|
|
1410
|
+
let errorMessages2 = formatValidationErrors(validator.errors);
|
|
1411
|
+
throw new Error(
|
|
1412
|
+
`\u274C Manifest validation failed:
|
|
1413
|
+
${errorMessages2}
|
|
1414
|
+
|
|
1415
|
+
\u{1F4A1} Ensure all required fields are filled according to the plugin documentation.`
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1418
|
+
}, save2 = async (manifest) => {
|
|
1419
|
+
try {
|
|
1420
|
+
let content = JSON.stringify(manifest, null, 4);
|
|
1421
|
+
await (0, import_promises2.writeFile)(manifestPath, content, "utf8");
|
|
1422
|
+
} catch (error2) {
|
|
1423
|
+
throw error2 instanceof Error ? new Error(`Error saving manifest.json: ${error2.message}`) : new Error("Error saving manifest");
|
|
1424
|
+
}
|
|
1425
|
+
}, update2 = async (updates) => {
|
|
1426
|
+
let updatedManifest = { ...await load2(), ...updates };
|
|
1427
|
+
return await save2(updatedManifest), updatedManifest;
|
|
1428
|
+
}, manifestManager = {
|
|
1429
|
+
load: load2,
|
|
1430
|
+
loadRaw,
|
|
1431
|
+
validate,
|
|
1432
|
+
save: save2,
|
|
1433
|
+
update: update2
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
|
|
1438
|
+
// src/utils/marketplace.ts
|
|
1439
|
+
function validateMarketplaceAssets() {
|
|
1440
|
+
let marketplaceDir = import_path3.default.resolve(MARKETPLACE_DIR);
|
|
1441
|
+
ensurePathExists(
|
|
1442
|
+
marketplaceDir,
|
|
1443
|
+
"Marketplace folder not found. Create ./marketplace and add index.md and header-image.jpg before publishing."
|
|
1444
|
+
), ensurePathExists(
|
|
1445
|
+
import_path3.default.join(marketplaceDir, MARKETPLACE_INDEX_FILE),
|
|
1446
|
+
"Marketplace description not found. Add ./marketplace/index.md before publishing."
|
|
1447
|
+
), ensurePathExists(
|
|
1448
|
+
import_path3.default.join(marketplaceDir, MARKETPLACE_HEADER_IMAGE_FILE),
|
|
1449
|
+
"Marketplace header image not found. Add ./marketplace/header-image.jpg before publishing."
|
|
1450
|
+
), ensurePathExists(
|
|
1451
|
+
import_path3.default.resolve(PUBLIC_DIR, PUBLIC_LOGO_FILE),
|
|
1452
|
+
"Plugin logo not found. Add ./public/logo.svg before publishing."
|
|
1453
|
+
);
|
|
1454
|
+
}
|
|
1455
|
+
function validateArchiveSources() {
|
|
1456
|
+
ensurePathExists(import_path3.default.resolve(DIST_DIR), "Dist folder not found. Build the project first."), ensurePathExists(
|
|
1457
|
+
import_path3.default.resolve(SRC_DIR),
|
|
1458
|
+
"Source folder not found. Add ./src before publishing."
|
|
1459
|
+
), ensurePathExists(import_path3.default.resolve(MANIFEST_FILE), "manifest.json not found in plugin root."), validateMarketplaceAssets();
|
|
1460
|
+
}
|
|
1461
|
+
var import_fs5, import_path3, MARKETPLACE_DIR, MARKETPLACE_INDEX_FILE, MARKETPLACE_HEADER_IMAGE_FILE, PUBLIC_DIR, PUBLIC_LOGO_FILE, MANIFEST_FILE, DIST_DIR, SRC_DIR, ensurePathExists, validateManifestPublishingFields, ensureManifestCatalogFields, marketplacePaths, init_marketplace = __esm({
|
|
1462
|
+
"src/utils/marketplace.ts"() {
|
|
1463
|
+
"use strict";
|
|
1464
|
+
import_fs5 = __toESM(require("fs")), import_path3 = __toESM(require("path"));
|
|
1465
|
+
init_manifestManager();
|
|
1466
|
+
init_logger();
|
|
1467
|
+
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) => {
|
|
1468
|
+
import_fs5.default.existsSync(targetPath) || (logger_default.error(errorMessage), process.exit(1));
|
|
1469
|
+
}, validateManifestPublishingFields = async () => {
|
|
1470
|
+
let manifest = await manifestManager.load();
|
|
1471
|
+
ensureManifestCatalogFields(manifest);
|
|
1472
|
+
}, ensureManifestCatalogFields = (manifest) => {
|
|
1473
|
+
(!manifest.name?.ru || !manifest.name?.en) && (logger_default.error(
|
|
1474
|
+
'Manifest field "name" is required for publishing. Add localized "name.ru" and "name.en" to ./manifest.json.'
|
|
1475
|
+
), process.exit(1)), (!manifest.description?.ru || !manifest.description?.en) && (logger_default.error(
|
|
1476
|
+
'Manifest field "description" is required for publishing. Add localized "description.ru" and "description.en" to ./manifest.json.'
|
|
1477
|
+
), process.exit(1));
|
|
1478
|
+
};
|
|
1479
|
+
marketplacePaths = {
|
|
1480
|
+
distDir: DIST_DIR,
|
|
1481
|
+
srcDir: SRC_DIR,
|
|
1482
|
+
marketplaceDir: MARKETPLACE_DIR,
|
|
1483
|
+
manifestFile: MANIFEST_FILE
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
});
|
|
1487
|
+
|
|
1488
|
+
// src/utils/pluginPackageScripts.ts
|
|
1489
|
+
function readPluginPackageScripts(cwd = process.cwd()) {
|
|
1490
|
+
let packageJsonPath = import_path4.default.join(cwd, "package.json");
|
|
1491
|
+
return import_fs6.default.existsSync(packageJsonPath) ? JSON.parse(import_fs6.default.readFileSync(packageJsonPath, "utf-8")).scripts ?? {} : null;
|
|
1492
|
+
}
|
|
1493
|
+
function hasPluginScript(name, cwd = process.cwd()) {
|
|
1494
|
+
return !!readPluginPackageScripts(cwd)?.[name];
|
|
1495
|
+
}
|
|
1496
|
+
var import_fs6, import_path4, init_pluginPackageScripts = __esm({
|
|
1497
|
+
"src/utils/pluginPackageScripts.ts"() {
|
|
1498
|
+
"use strict";
|
|
1499
|
+
import_fs6 = __toESM(require("fs")), import_path4 = __toESM(require("path"));
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
// src/commands/submit/utils/runSubmitPrechecks.ts
|
|
1504
|
+
async function runSubmitPrechecks(options = {}) {
|
|
1505
|
+
if (options.skip) {
|
|
1506
|
+
logger_default.warning("Skipping pre-submit checks (--skip-checks).");
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
logger_default.separator(), logger_default.info("\u{1F50D} Pre-submit checks"), logger_default.separator(), await runStep("Validate manifest.json", () => manifestManager.validate()), await runStep("Check publishing metadata and assets", async () => {
|
|
1510
|
+
await validateManifestPublishingFields(), validateMarketplaceAssets();
|
|
1511
|
+
}), await runShellStep("Install dependencies", pluginCmd.install), await runShellStep("Run linter", pluginCmd.lint), hasPluginScript("typecheck") ? await runShellStep("Run typecheck", pluginCmd.typecheck) : logger_default.verbose('Skipping typecheck (no "typecheck" script in package.json).'), hasPluginScript("test") ? await runShellStep("Run tests", pluginCmd.test) : logger_default.warning(
|
|
1512
|
+
'No "test" script in package.json \u2014 add tests before publishing, or run submit with --skip-checks.'
|
|
1513
|
+
), await runShellStep("Check dependency vulnerabilities", pluginCmd.audit), logger_default.separator(), logger_default.success("Pre-submit checks passed"), logger_default.separator();
|
|
1514
|
+
}
|
|
1515
|
+
var import_picocolors4, stepStart, stepDone, runStep, runShellStep, init_runSubmitPrechecks = __esm({
|
|
1516
|
+
"src/commands/submit/utils/runSubmitPrechecks.ts"() {
|
|
1517
|
+
"use strict";
|
|
1518
|
+
import_picocolors4 = __toESM(require("picocolors"));
|
|
1519
|
+
init_manifestManager();
|
|
1520
|
+
init_execCommand();
|
|
1521
|
+
init_logger();
|
|
1522
|
+
init_marketplace();
|
|
1523
|
+
init_pluginPackageScripts();
|
|
1524
|
+
init_templateCommands();
|
|
1525
|
+
stepStart = (label) => {
|
|
1526
|
+
console.info(`${import_picocolors4.default.cyan("\u25B8")} ${label}`);
|
|
1527
|
+
}, stepDone = (label) => {
|
|
1528
|
+
console.info(`${import_picocolors4.default.green("\u2713")} ${label}`), console.info("");
|
|
1529
|
+
}, runStep = async (label, run) => {
|
|
1530
|
+
stepStart(label), await run(), stepDone(label);
|
|
1531
|
+
}, runShellStep = async (label, command) => {
|
|
1532
|
+
stepStart(label), console.info(import_picocolors4.default.dim(` $ ${command}`)), await execCommand(command), stepDone(label);
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
});
|
|
1536
|
+
|
|
1537
|
+
// src/utils/buildArchive.ts
|
|
1538
|
+
async function buildArchive() {
|
|
1539
|
+
return validateArchiveSources(), (await manifestManager.load()).manifest_version === void 0 && (logger_default.error(
|
|
1540
|
+
`manifest_version is missing in manifest.json. Run "${CLI_NAME2} up" or add "manifest_version": 1 manually before uploading.`
|
|
1541
|
+
), process.exit(1)), new Promise((resolve2, reject) => {
|
|
1542
|
+
let archive = (0, import_archiver.default)("zip", { zlib: { level: 9 } }), chunks = [];
|
|
1543
|
+
archive.on("data", (chunk) => chunks.push(chunk)), archive.on("end", () => {
|
|
1544
|
+
let buffer = Buffer.concat(chunks);
|
|
1545
|
+
if (logger_default.info(`\u{1F4E6} Archive created (${buffer.length} bytes)`), isVerboseEnabled()) {
|
|
1546
|
+
let debugPath = writeVerboseArtifact("archive/latest-upload.zip", buffer);
|
|
1547
|
+
logger_default.info(`[platform-api-debug] Saved archive copy to ${debugPath}`);
|
|
1548
|
+
}
|
|
1549
|
+
resolve2(buffer);
|
|
1550
|
+
}), archive.on("error", reject), archive.glob("**/*", {
|
|
1551
|
+
cwd: process.cwd(),
|
|
1552
|
+
ignore: ["node_modules/**", "dist/**", "**/.DS_Store"],
|
|
1553
|
+
dot: !0
|
|
1554
|
+
}), archive.file(import_path5.default.resolve(marketplacePaths.manifestFile), { name: "src/manifest.json" }), archive.glob(
|
|
1555
|
+
"**/*",
|
|
1556
|
+
{
|
|
1557
|
+
cwd: import_path5.default.resolve(marketplacePaths.distDir),
|
|
1558
|
+
ignore: ["**/.DS_Store"]
|
|
1559
|
+
},
|
|
1560
|
+
{ prefix: "dist/" }
|
|
1561
|
+
), archive.finalize();
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1564
|
+
var import_path5, import_archiver, init_buildArchive = __esm({
|
|
1565
|
+
"src/utils/buildArchive.ts"() {
|
|
1566
|
+
"use strict";
|
|
1567
|
+
import_path5 = __toESM(require("path")), import_archiver = __toESM(require("archiver"));
|
|
1568
|
+
init_manifestManager();
|
|
1569
|
+
init_meta2();
|
|
1570
|
+
init_logger();
|
|
1571
|
+
init_marketplace();
|
|
1572
|
+
init_verbose();
|
|
1573
|
+
}
|
|
1574
|
+
});
|
|
1575
|
+
|
|
1576
|
+
// src/distributions/external/submit.ts
|
|
1577
|
+
async function submitExternal(options = {}) {
|
|
1578
|
+
await runSubmitPrechecks({ skip: options.skipChecks });
|
|
1579
|
+
let manifest = await manifestManager.load(), issueKey = (await pluginStateManager.load()).trackerIssueKey;
|
|
1580
|
+
if (issueKey)
|
|
1581
|
+
try {
|
|
1582
|
+
await getIssue(issueKey);
|
|
1583
|
+
} catch {
|
|
1584
|
+
issueKey = void 0;
|
|
1585
|
+
}
|
|
1586
|
+
let pluginId = manifest.id ?? (0, import_crypto.randomUUID)();
|
|
1587
|
+
manifest.id || await manifestManager.update({ id: pluginId });
|
|
1588
|
+
let manifestJson = await manifestManager.loadRaw();
|
|
1589
|
+
if (issueKey) {
|
|
1590
|
+
logger_default.verbose(`\u23F3 Updating issue ${issueKey} with latest manifest...`);
|
|
1591
|
+
let issueDescription = buildIssueDescription({
|
|
1592
|
+
pluginId,
|
|
1593
|
+
slug: manifest.slug,
|
|
1594
|
+
version: manifest.version,
|
|
1595
|
+
manifestJson
|
|
1596
|
+
});
|
|
1597
|
+
await updatePluginIssue(issueKey, { description: issueDescription });
|
|
1598
|
+
} else if (options.ticket === !1) {
|
|
1599
|
+
logger_default.warning(
|
|
1600
|
+
"Tracker issue is required for tracker-backed submit. Skipping ticket creation."
|
|
1601
|
+
);
|
|
1602
|
+
return;
|
|
1603
|
+
} else {
|
|
1604
|
+
logger_default.info("\u23F3 Creating plugin issue in Tracker...");
|
|
1605
|
+
let issue = await createPluginIssue({
|
|
1606
|
+
pluginId,
|
|
1607
|
+
slug: manifest.slug,
|
|
1608
|
+
version: manifest.version,
|
|
1609
|
+
manifestJson
|
|
1610
|
+
});
|
|
1611
|
+
await pluginStateManager.update({ trackerIssueKey: issue.key }), issueKey = issue.key, logger_default.info(` Tracker issue : ${issueKey}`);
|
|
1612
|
+
}
|
|
1613
|
+
logger_default.info("\u{1F528} Building plugin..."), await build(), logger_default.info("\u{1F4E6} Creating archive...");
|
|
1614
|
+
let archiveBuffer = await buildArchive(), archiveName = `${manifest.slug}-${manifest.version}.zip`;
|
|
1615
|
+
logger_default.verbose(`\u2B06\uFE0F Attaching ${archiveName} to ${issueKey}...`), await attachFileToIssue(issueKey, archiveBuffer, archiveName), await addIssueComment(
|
|
1616
|
+
issueKey,
|
|
1617
|
+
`Updated bundle: \`${archiveName}\` (${archiveBuffer.length} bytes)`
|
|
1618
|
+
), logger_default.verbose(`\u23F3 Fetching available transitions for ${issueKey}...`);
|
|
1619
|
+
let transitions = await getIssueTransitions(issueKey), submitTransition = transitions.find(
|
|
1620
|
+
(t) => t.display?.toLowerCase().includes(SUBMIT_TRANSITION_DISPLAY) || t.id?.toLowerCase().includes("waitingforapprove") || t.id?.toLowerCase().includes("waiting")
|
|
1621
|
+
);
|
|
1622
|
+
if (!submitTransition) {
|
|
1623
|
+
let available = transitions.map((t) => `"${t.display ?? t.id}"`).join(", ");
|
|
1624
|
+
logger_default.error(
|
|
1625
|
+
`Could not find a "Waiting for approve" transition on ${issueKey}. Available: ${available}`
|
|
1626
|
+
);
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
1629
|
+
logger_default.info("\u{1F680} Submitting plugin for review..."), 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}`), logger_default.newLine();
|
|
1630
|
+
}
|
|
1631
|
+
var import_crypto, SUBMIT_TRANSITION_DISPLAY, init_submit = __esm({
|
|
1632
|
+
"src/distributions/external/submit.ts"() {
|
|
1633
|
+
"use strict";
|
|
1634
|
+
import_crypto = require("crypto");
|
|
1635
|
+
init_build();
|
|
1636
|
+
init_runSubmitPrechecks();
|
|
1637
|
+
init_manifestManager();
|
|
1638
|
+
init_pluginStateManager();
|
|
1639
|
+
init_buildArchive();
|
|
1640
|
+
init_logger();
|
|
1641
|
+
init_tracker();
|
|
1642
|
+
SUBMIT_TRANSITION_DISPLAY = "waiting for approve";
|
|
1643
|
+
}
|
|
1644
|
+
});
|
|
1645
|
+
|
|
200
1646
|
// src/distributions/external/registerCommands.ts
|
|
201
1647
|
var registerCommands_exports = {};
|
|
202
1648
|
__export(registerCommands_exports, {
|
|
203
1649
|
registerDistributionCommands: () => registerDistributionCommands
|
|
204
1650
|
});
|
|
205
1651
|
function registerDistributionCommands(program) {
|
|
206
|
-
registerConfigCommand(program, CLI_NAME)
|
|
1652
|
+
registerConfigCommand(program, CLI_NAME), program.command("login").description("save your Yandex Tracker OAuth token (request it via Tracker support)").action(withErrorHandling(loginExternal)), program.command("logout").description("remove saved OAuth token").action(
|
|
1653
|
+
withErrorHandling(async () => {
|
|
1654
|
+
logoutExternal();
|
|
1655
|
+
})
|
|
1656
|
+
), program.command("submit").description("build plugin, create a Tracker issue in PLUGINMOD, and submit for review").addOption(skipChecksOption).action(withErrorHandling(submitExternal)), program.command("list").description("list all your plugins and their moderation status").action(withErrorHandling(listExternal)), program.command("info [issue-key]").description(
|
|
1657
|
+
"show moderation status of a plugin (uses .tracker-plugin issue key if not provided)"
|
|
1658
|
+
).action(withErrorHandling(infoExternal));
|
|
207
1659
|
}
|
|
208
1660
|
var init_registerCommands = __esm({
|
|
209
1661
|
"src/distributions/external/registerCommands.ts"() {
|
|
210
1662
|
"use strict";
|
|
1663
|
+
init_options();
|
|
211
1664
|
init_registerCommand();
|
|
1665
|
+
init_withErrorHandling();
|
|
1666
|
+
init_info();
|
|
1667
|
+
init_list();
|
|
1668
|
+
init_login();
|
|
212
1669
|
init_meta();
|
|
1670
|
+
init_submit();
|
|
213
1671
|
}
|
|
214
1672
|
});
|
|
215
1673
|
|
|
@@ -276,7 +1734,7 @@ function getPlatformBaseUrl() {
|
|
|
276
1734
|
return cfg.api.platformBaseUrl;
|
|
277
1735
|
}
|
|
278
1736
|
function getTrackerBaseUrl() {
|
|
279
|
-
return
|
|
1737
|
+
return TRACKER_BASE_URL2;
|
|
280
1738
|
}
|
|
281
1739
|
function getOAuthTokenUrl() {
|
|
282
1740
|
let cfg = requireConfig();
|
|
@@ -287,11 +1745,11 @@ function getOAuthTokenUrl() {
|
|
|
287
1745
|
function getUpdateCheckInfo() {
|
|
288
1746
|
return null;
|
|
289
1747
|
}
|
|
290
|
-
var
|
|
1748
|
+
var TRACKER_BASE_URL2, init_hosts = __esm({
|
|
291
1749
|
"src/distributions/external/hosts.ts"() {
|
|
292
1750
|
"use strict";
|
|
293
1751
|
init_manager();
|
|
294
|
-
|
|
1752
|
+
TRACKER_BASE_URL2 = "https://api.tracker.yandex.net/v3";
|
|
295
1753
|
}
|
|
296
1754
|
});
|
|
297
1755
|
|
|
@@ -299,6 +1757,7 @@ var TRACKER_BASE_URL, init_hosts = __esm({
|
|
|
299
1757
|
var templateSubstitution_exports = {};
|
|
300
1758
|
__export(templateSubstitution_exports, {
|
|
301
1759
|
applySubstitutions: () => applySubstitutions,
|
|
1760
|
+
overlayDirName: () => overlayDirName,
|
|
302
1761
|
templateDeps: () => templateDeps
|
|
303
1762
|
});
|
|
304
1763
|
function rewritePackageJson(content) {
|
|
@@ -306,8 +1765,6 @@ function rewritePackageJson(content) {
|
|
|
306
1765
|
if (pkg.dependencies) {
|
|
307
1766
|
let next = {};
|
|
308
1767
|
for (let [name, version] of Object.entries(pkg.dependencies)) {
|
|
309
|
-
if (PACKAGE_DROP.has(name))
|
|
310
|
-
continue;
|
|
311
1768
|
let renamed = PACKAGE_RENAME[name] ?? name;
|
|
312
1769
|
next[renamed] = ADDED_DEPS[renamed] ?? version;
|
|
313
1770
|
}
|
|
@@ -328,62 +1785,52 @@ function rewriteImports(content) {
|
|
|
328
1785
|
}
|
|
329
1786
|
return result;
|
|
330
1787
|
}
|
|
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
1788
|
function rewriteNpmrc(content) {
|
|
340
1789
|
return content.split(`
|
|
341
1790
|
`).filter((line) => !/^registry\s*=\s*https?:\/\/npm\.yandex-team\.ru/.test(line.trim())).join(`
|
|
342
1791
|
`);
|
|
343
1792
|
}
|
|
344
1793
|
function applySubstitutions(filePath, content) {
|
|
345
|
-
let name =
|
|
1794
|
+
let name = import_path6.default.basename(filePath), ext = import_path6.default.extname(filePath);
|
|
346
1795
|
if (name === "package.json")
|
|
347
1796
|
return Buffer.from(rewritePackageJson(content.toString("utf8")), "utf8");
|
|
348
1797
|
if (name === "npmrc.template" || name === ".npmrc")
|
|
349
1798
|
return Buffer.from(rewriteNpmrc(content.toString("utf8")), "utf8");
|
|
350
|
-
if (ext === ".scss" || ext === ".css")
|
|
351
|
-
return Buffer.from(rewriteScss(content.toString("utf8")), "utf8");
|
|
352
1799
|
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
353
|
-
let
|
|
354
|
-
if (rewritten !==
|
|
1800
|
+
let original = content.toString("utf8"), rewritten = rewriteImports(original);
|
|
1801
|
+
if (rewritten !== original)
|
|
355
1802
|
return Buffer.from(rewritten, "utf8");
|
|
356
1803
|
}
|
|
357
1804
|
return content;
|
|
358
1805
|
}
|
|
359
|
-
var
|
|
1806
|
+
var import_path6, PACKAGE_RENAME, ADDED_DEPS, templateDeps, overlayDirName, init_templateSubstitution = __esm({
|
|
360
1807
|
"src/distributions/external/templateSubstitution.ts"() {
|
|
361
1808
|
"use strict";
|
|
362
|
-
|
|
1809
|
+
import_path6 = __toESM(require("path")), PACKAGE_RENAME = {
|
|
363
1810
|
"@yandex-data-ui/tracker-plugin-sdk-react": "@weavix/sdk-react",
|
|
364
1811
|
"@yandex-data-ui/tracker-pub-api-types": "@weavix/tracker-api-types"
|
|
365
|
-
},
|
|
1812
|
+
}, ADDED_DEPS = {
|
|
366
1813
|
"@weavix/sdk-core": "latest",
|
|
367
1814
|
"@weavix/sdk-react": "latest",
|
|
368
1815
|
"@weavix/tracker-api-types": "latest"
|
|
369
|
-
}, templateDeps = ["@weavix/sdk-core", "@weavix/sdk-react", "@weavix/tracker-api-types"];
|
|
1816
|
+
}, templateDeps = ["@weavix/sdk-core", "@weavix/sdk-react", "@weavix/tracker-api-types"], overlayDirName = "_external";
|
|
370
1817
|
}
|
|
371
1818
|
});
|
|
372
1819
|
|
|
373
1820
|
// src/index.ts
|
|
374
|
-
var
|
|
375
|
-
|
|
376
|
-
// src/distribution/meta.ts
|
|
377
|
-
var impl = (init_meta(), __toCommonJS(meta_exports)), { CLI_NAME: CLI_NAME2, CLI_DESCRIPTION: CLI_DESCRIPTION2, CLI_HELP_TEXT: CLI_HELP_TEXT2 } = impl;
|
|
1821
|
+
var import_commander2 = require("commander");
|
|
1822
|
+
init_meta2();
|
|
378
1823
|
|
|
379
1824
|
// src/distribution/registerCommands.ts
|
|
380
|
-
|
|
1825
|
+
init_flag();
|
|
1826
|
+
var impl3 = (init_registerCommands(), __toCommonJS(registerCommands_exports)), { registerDistributionCommands: registerDistributionCommands2 } = impl3;
|
|
381
1827
|
|
|
382
1828
|
// src/utils/checkUpdate.ts
|
|
383
|
-
var
|
|
1829
|
+
var import_node_fetch2 = __toESM(require("node-fetch"));
|
|
384
1830
|
|
|
385
1831
|
// src/distribution/hosts.ts
|
|
386
|
-
|
|
1832
|
+
init_flag();
|
|
1833
|
+
var impl4 = (init_hosts(), __toCommonJS(hosts_exports)), {
|
|
387
1834
|
getS3Endpoint: getS3Endpoint2,
|
|
388
1835
|
getMdsEndpoint: getMdsEndpoint2,
|
|
389
1836
|
getS3Region: getS3Region2,
|
|
@@ -393,55 +1840,48 @@ var impl3 = (init_hosts(), __toCommonJS(hosts_exports)), {
|
|
|
393
1840
|
getTrackerBaseUrl: getTrackerBaseUrl2,
|
|
394
1841
|
getOAuthTokenUrl: getOAuthTokenUrl2,
|
|
395
1842
|
getUpdateCheckInfo: getUpdateCheckInfo2
|
|
396
|
-
} =
|
|
397
|
-
|
|
398
|
-
// src/utils/checkUpdate.ts
|
|
399
|
-
init_logger();
|
|
400
|
-
var checkUpdate = async (version) => {
|
|
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
|
-
}
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
// src/utils/execCommand.ts
|
|
417
|
-
var import_execa = require("execa"), execCommand = async (command, cwd = process.cwd()) => {
|
|
418
|
-
await (0, import_execa.execa)(command, {
|
|
419
|
-
cwd,
|
|
420
|
-
shell: !0,
|
|
421
|
-
stdio: "inherit"
|
|
422
|
-
});
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
// src/commands/build.ts
|
|
426
|
-
init_logger();
|
|
1843
|
+
} = impl4;
|
|
427
1844
|
|
|
428
|
-
// src/
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
1845
|
+
// src/utils/checkUpdate.ts
|
|
1846
|
+
init_logger();
|
|
1847
|
+
var SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/, DIAGNOSTIC_FLAGS = /* @__PURE__ */ new Set(["--version", "-V", "--help", "-h", "help"]), parse = (v) => {
|
|
1848
|
+
let m = SEMVER_RE.exec(v);
|
|
1849
|
+
return m ? { major: +m[1], minor: +m[2], patch: +m[3] } : null;
|
|
1850
|
+
}, isDiagnosticInvocation = () => {
|
|
1851
|
+
let args = process.argv.slice(2);
|
|
1852
|
+
return args.length === 0 ? !0 : args.some((a) => DIAGNOSTIC_FLAGS.has(a));
|
|
1853
|
+
}, classify = (current, latest) => latest.major > current.major ? "minorOrMajor" : latest.major < current.major ? "none" : latest.minor > current.minor ? "minorOrMajor" : latest.minor < current.minor ? "none" : latest.patch > current.patch ? "patch" : "none", checkUpdate = async (version) => {
|
|
1854
|
+
if (version === "unknown" || isDiagnosticInvocation() || process.env.TRACKER_CLI_SKIP_UPDATE_CHECK) return;
|
|
1855
|
+
let info2 = getUpdateCheckInfo2();
|
|
1856
|
+
if (!info2) return;
|
|
1857
|
+
let current = parse(version);
|
|
1858
|
+
if (current)
|
|
1859
|
+
try {
|
|
1860
|
+
let response = await (0, import_node_fetch2.default)(`${info2.registryUrl}/${info2.packageName}/latest`);
|
|
1861
|
+
if (!response.ok) return;
|
|
1862
|
+
let json = await response.json(), latest = parse(json.version);
|
|
1863
|
+
if (!latest) return;
|
|
1864
|
+
let kind = classify(current, latest);
|
|
1865
|
+
if (kind === "none") return;
|
|
1866
|
+
let installCmd = `npm i -g ${info2.packageName}@latest --registry=${info2.registryUrl}`;
|
|
1867
|
+
if (kind === "minorOrMajor") {
|
|
1868
|
+
logger_default.newLine(), logger_default.error(
|
|
1869
|
+
`Update required ${version} \u2192 ${json.version}
|
|
1870
|
+
This release is not backward-compatible with your installed version.`
|
|
1871
|
+
), logger_default.suggest(installCmd), process.exit(1);
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1874
|
+
logger_default.newLine(), logger_default.info(`\u{1F514} Update available ${version} \u2192 ${json.version}
|
|
1875
|
+
Run: ${installCmd}`);
|
|
1876
|
+
} catch {
|
|
1877
|
+
}
|
|
434
1878
|
};
|
|
435
1879
|
|
|
436
|
-
// src/
|
|
437
|
-
|
|
438
|
-
logger_default.info("\u{1F528} Building project..."), await execCommand(pluginCmd.install), await execCommand(
|
|
439
|
-
environment ? `VITE_DEPLOY_ENV=${environment} ${pluginCmd.build}` : pluginCmd.build
|
|
440
|
-
);
|
|
441
|
-
};
|
|
1880
|
+
// src/index.ts
|
|
1881
|
+
init_build();
|
|
442
1882
|
|
|
443
1883
|
// src/commands/create/index.ts
|
|
444
|
-
var
|
|
1884
|
+
var path13 = __toESM(require("path")), import_prompts3 = require("@inquirer/prompts");
|
|
445
1885
|
|
|
446
1886
|
// src/core/manifest/constants.ts
|
|
447
1887
|
var DATA_PERMISSIONS = [
|
|
@@ -526,9 +1966,16 @@ var TEMPLATES = [
|
|
|
526
1966
|
"navigation",
|
|
527
1967
|
"trigger.action",
|
|
528
1968
|
"project.action",
|
|
1969
|
+
"project.block",
|
|
1970
|
+
"project.tab",
|
|
529
1971
|
"portfolio.action",
|
|
1972
|
+
"portfolio.block",
|
|
1973
|
+
"portfolio.tab",
|
|
530
1974
|
"goal.action",
|
|
531
|
-
"
|
|
1975
|
+
"goal.block",
|
|
1976
|
+
"goal.tab",
|
|
1977
|
+
"attachment.viewer.action",
|
|
1978
|
+
"board.tab"
|
|
532
1979
|
];
|
|
533
1980
|
var TEMPLATE_SLOTS = {
|
|
534
1981
|
default: [],
|
|
@@ -539,25 +1986,33 @@ var TEMPLATE_SLOTS = {
|
|
|
539
1986
|
navigation: ["navigation"],
|
|
540
1987
|
"trigger.action": ["trigger.create.action", "trigger.edit.action"],
|
|
541
1988
|
"project.action": ["project.action"],
|
|
1989
|
+
"project.block": ["project.block"],
|
|
1990
|
+
"project.tab": ["project.tab"],
|
|
542
1991
|
"portfolio.action": ["portfolio.action"],
|
|
1992
|
+
"portfolio.block": ["portfolio.block"],
|
|
1993
|
+
"portfolio.tab": ["portfolio.tab"],
|
|
543
1994
|
"goal.action": ["goal.action"],
|
|
544
|
-
"
|
|
1995
|
+
"goal.block": ["goal.block"],
|
|
1996
|
+
"goal.tab": ["goal.tab"],
|
|
1997
|
+
"attachment.viewer.action": ["attachment.viewer.action"],
|
|
1998
|
+
"board.tab": ["board.tab"]
|
|
545
1999
|
};
|
|
546
2000
|
|
|
547
2001
|
// src/commands/create/index.ts
|
|
2002
|
+
init_meta2();
|
|
548
2003
|
init_logger();
|
|
549
2004
|
|
|
550
2005
|
// src/commands/create/utils/getWelcomeMessage.ts
|
|
551
|
-
var
|
|
552
|
-
${
|
|
2006
|
+
var import_picocolors5 = __toESM(require("picocolors")), getWelcomeMessage = (pwd) => `
|
|
2007
|
+
${import_picocolors5.default.bold(import_picocolors5.default.white("\u{1F680} Create new tracker plugin"))}
|
|
553
2008
|
|
|
554
|
-
${
|
|
2009
|
+
${import_picocolors5.default.dim(`\u{1F4C1} Creating an app in your current directory: ${pwd}`)}
|
|
555
2010
|
|
|
556
|
-
${
|
|
2011
|
+
${import_picocolors5.default.dim("Press")} ${import_picocolors5.default.yellow("Ctrl+C")} ${import_picocolors5.default.dim("to cancel.")}
|
|
557
2012
|
`;
|
|
558
2013
|
|
|
559
2014
|
// src/commands/create/utils/initManifest.ts
|
|
560
|
-
var
|
|
2015
|
+
var fs5 = __toESM(require("fs")), path7 = __toESM(require("path"));
|
|
561
2016
|
|
|
562
2017
|
// src/commands/create/utils/generateManifest.ts
|
|
563
2018
|
function buildSlots(template, slotTitle) {
|
|
@@ -565,7 +2020,8 @@ function buildSlots(template, slotTitle) {
|
|
|
565
2020
|
if (slotNames.length === 0) return;
|
|
566
2021
|
let slotEntry = {
|
|
567
2022
|
entrypoint: "index.html",
|
|
568
|
-
title: { ru: slotTitle, en: slotTitle }
|
|
2023
|
+
title: { ru: slotTitle, en: slotTitle },
|
|
2024
|
+
contextLevel: "basic"
|
|
569
2025
|
};
|
|
570
2026
|
return {
|
|
571
2027
|
tracker: Object.fromEntries(slotNames.map((slotName) => [slotName, [slotEntry]]))
|
|
@@ -592,20 +2048,19 @@ var generateManifest = (answers) => ({
|
|
|
592
2048
|
|
|
593
2049
|
// src/commands/create/utils/initManifest.ts
|
|
594
2050
|
var initManifest = ({ answers, targetDir }) => {
|
|
595
|
-
let generatedManifest = generateManifest(answers), manifestPath2 =
|
|
596
|
-
|
|
2051
|
+
let generatedManifest = generateManifest(answers), manifestPath2 = path7.join(targetDir, "manifest.json");
|
|
2052
|
+
fs5.writeFileSync(manifestPath2, JSON.stringify(generatedManifest, null, 2), "utf-8");
|
|
597
2053
|
};
|
|
598
2054
|
|
|
599
2055
|
// src/commands/create/utils/initTemplate.ts
|
|
600
|
-
var
|
|
601
|
-
|
|
602
|
-
// src/utils/copyDirectory.ts
|
|
603
|
-
var fs2 = __toESM(require("fs")), import_path3 = __toESM(require("path")), import_tinyglobby = require("tinyglobby");
|
|
2056
|
+
var fs8 = __toESM(require("fs")), path12 = __toESM(require("path"));
|
|
604
2057
|
|
|
605
2058
|
// src/distribution/templateSubstitution.ts
|
|
606
|
-
|
|
2059
|
+
init_flag();
|
|
2060
|
+
var impl5 = (init_templateSubstitution(), __toCommonJS(templateSubstitution_exports)), { applySubstitutions: applySubstitutions2, overlayDirName: overlayDirName2, templateDeps: templateDeps2 } = impl5;
|
|
607
2061
|
|
|
608
2062
|
// src/utils/copyDirectory.ts
|
|
2063
|
+
var fs6 = __toESM(require("fs")), import_path7 = __toESM(require("path")), import_tinyglobby = require("tinyglobby");
|
|
609
2064
|
var resolveTargetFileName = (file) => file.endsWith(".template") ? "." + file.replace(".template", "") : file, copyDirectory = async (sourceDir, targetDir) => {
|
|
610
2065
|
let files = await (0, import_tinyglobby.glob)(["**/*"], {
|
|
611
2066
|
cwd: sourceDir,
|
|
@@ -614,35 +2069,35 @@ var resolveTargetFileName = (file) => file.endsWith(".template") ? "." + file.re
|
|
|
614
2069
|
});
|
|
615
2070
|
await Promise.all(
|
|
616
2071
|
files.map(async (file) => {
|
|
617
|
-
let sourcePath =
|
|
618
|
-
await
|
|
619
|
-
let content = await
|
|
620
|
-
await
|
|
2072
|
+
let sourcePath = import_path7.default.join(sourceDir, file), targetFile = resolveTargetFileName(file), targetPath = import_path7.default.join(targetDir, targetFile);
|
|
2073
|
+
await fs6.promises.mkdir(import_path7.default.dirname(targetPath), { recursive: !0 });
|
|
2074
|
+
let content = await fs6.promises.readFile(sourcePath), rewritten = applySubstitutions2(file, content);
|
|
2075
|
+
await fs6.promises.writeFile(targetPath, rewritten);
|
|
621
2076
|
})
|
|
622
2077
|
);
|
|
623
2078
|
};
|
|
624
2079
|
|
|
625
2080
|
// src/utils/getProjectPath.ts
|
|
626
|
-
var
|
|
2081
|
+
var import_path8 = __toESM(require("path")), isDevelopment = () => __dirname.includes("/src/"), getProjectPath = (relativePath) => isDevelopment() ? import_path8.default.resolve(__dirname, "..", "..", relativePath) : import_path8.default.resolve(__dirname, relativePath), getTemplatesBaseDir = () => getProjectPath("templates"), getTemplatePath = (filename) => import_path8.default.join(getTemplatesBaseDir(), "_shared", filename);
|
|
627
2082
|
|
|
628
2083
|
// src/commands/create/utils/initTemplate.ts
|
|
629
2084
|
init_logger();
|
|
630
2085
|
|
|
631
2086
|
// src/commands/create/utils/updatePackageJson.ts
|
|
632
|
-
var
|
|
633
|
-
let packageJsonPath =
|
|
634
|
-
if (
|
|
635
|
-
let packageJson = JSON.parse(
|
|
636
|
-
packageJson.name = packageSlug,
|
|
2087
|
+
var fs7 = __toESM(require("fs")), path11 = __toESM(require("path")), updatePackageJson = (targetDir, packageSlug) => {
|
|
2088
|
+
let packageJsonPath = path11.join(targetDir, "package.json");
|
|
2089
|
+
if (fs7.existsSync(packageJsonPath)) {
|
|
2090
|
+
let packageJson = JSON.parse(fs7.readFileSync(packageJsonPath, "utf-8"));
|
|
2091
|
+
packageJson.name = packageSlug, fs7.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
637
2092
|
`);
|
|
638
2093
|
}
|
|
639
2094
|
};
|
|
640
2095
|
|
|
641
2096
|
// src/commands/create/utils/initTemplate.ts
|
|
642
2097
|
var initTemplate = async ({ answers, targetDir }) => {
|
|
643
|
-
|
|
644
|
-
let templatesBaseDir = getTemplatesBaseDir(), templatesDir =
|
|
645
|
-
await copyDirectory(sharedDir, targetDir), await copyDirectory(templatesDir, targetDir), updatePackageJson(targetDir, answers.packageSlug), logger_default.info("Created template with marketplace publication requirements."), logger_default.info(
|
|
2098
|
+
fs8.existsSync(targetDir) || fs8.mkdirSync(targetDir, { recursive: !0 });
|
|
2099
|
+
let templatesBaseDir = getTemplatesBaseDir(), templatesDir = path12.join(templatesBaseDir, answers.template), sharedDir = path12.join(templatesBaseDir, "_shared"), overlayDir = path12.join(templatesBaseDir, overlayDirName2);
|
|
2100
|
+
await copyDirectory(sharedDir, targetDir), await copyDirectory(overlayDir, targetDir), await copyDirectory(templatesDir, targetDir), updatePackageJson(targetDir, answers.packageSlug), logger_default.info("Created template with marketplace publication requirements."), logger_default.info(
|
|
646
2101
|
"Before publishing, add ./marketplace/index.md, ./marketplace/header-image.jpg (784:325), and ./public/logo.svg (square)."
|
|
647
2102
|
);
|
|
648
2103
|
};
|
|
@@ -651,26 +2106,26 @@ var initTemplate = async ({ answers, targetDir }) => {
|
|
|
651
2106
|
var DEFAULT_VERSION = "0.0.1";
|
|
652
2107
|
async function create() {
|
|
653
2108
|
logger_default.info(getWelcomeMessage(process.cwd()));
|
|
654
|
-
let packageSlug = await (0,
|
|
2109
|
+
let packageSlug = await (0, import_prompts3.input)({
|
|
655
2110
|
message: "Enter app slug (e.g., my-tracker-plugin):",
|
|
656
2111
|
required: !0
|
|
657
|
-
}), pluginName = await (0,
|
|
2112
|
+
}), pluginName = await (0, import_prompts3.input)({
|
|
658
2113
|
message: "Enter plugin name:",
|
|
659
2114
|
required: !0
|
|
660
|
-
}), pluginDescription = await (0,
|
|
2115
|
+
}), pluginDescription = await (0, import_prompts3.input)({
|
|
661
2116
|
message: "Enter plugin description:",
|
|
662
2117
|
required: !0
|
|
663
|
-
}), supportEmail = await (0,
|
|
2118
|
+
}), supportEmail = await (0, import_prompts3.input)({
|
|
664
2119
|
message: "Enter support email:",
|
|
665
2120
|
required: !0,
|
|
666
2121
|
validate: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || "Please enter a valid email address"
|
|
667
|
-
}), template = await (0,
|
|
2122
|
+
}), template = await (0, import_prompts3.select)({
|
|
668
2123
|
message: "Select a template:",
|
|
669
2124
|
choices: TEMPLATES.map((templateName) => ({
|
|
670
2125
|
name: templateName,
|
|
671
2126
|
value: templateName
|
|
672
2127
|
}))
|
|
673
|
-
}), dataPermissions = await (0,
|
|
2128
|
+
}), dataPermissions = await (0, import_prompts3.checkbox)({
|
|
674
2129
|
message: "Select data permissions (some popular options):",
|
|
675
2130
|
choices: TOP_DATA_PERMISSIONS.map((permission) => ({
|
|
676
2131
|
name: permission,
|
|
@@ -687,567 +2142,28 @@ async function create() {
|
|
|
687
2142
|
data: dataPermissions
|
|
688
2143
|
},
|
|
689
2144
|
version: DEFAULT_VERSION
|
|
690
|
-
}, targetDir =
|
|
2145
|
+
}, targetDir = path13.join(process.cwd(), answers.packageSlug);
|
|
691
2146
|
await initTemplate({
|
|
692
2147
|
answers,
|
|
693
2148
|
targetDir
|
|
694
2149
|
}), initManifest({
|
|
695
2150
|
answers,
|
|
696
2151
|
targetDir
|
|
697
|
-
}), logger_default.newLine(), logger_default.success("
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
`${CLI_NAME2} debug`
|
|
701
|
-
]);
|
|
2152
|
+
}), logger_default.newLine(), logger_default.success("\u2705 Plugin created successfully!"), logger_default.newLine(), logger_default.info("\u{1F680} To start development:"), logger_default.commands("", [`cd ${answers.packageSlug}`, "npm install", `${CLI_NAME2} debug`]), logger_default.newLine(), logger_default.info(
|
|
2153
|
+
"\u{1F4CC} Important: After running debug, the plugin will be available in the Tracker interface,"
|
|
2154
|
+
), logger_default.info("not at localhost. Open Tracker and check the plugin in the appropriate context.");
|
|
702
2155
|
}
|
|
703
2156
|
|
|
704
2157
|
// src/commands/debug/index.ts
|
|
705
|
-
var
|
|
706
|
-
|
|
707
|
-
// src/core/manifest/manifestManager.ts
|
|
708
|
-
var import_fs2 = require("fs"), import_promises = require("fs/promises"), import_ajv = __toESM(require("ajv")), import_ajv_formats = __toESM(require("ajv-formats"));
|
|
709
|
-
|
|
710
|
-
// src/core/manifest/formatValidationErrors.ts
|
|
711
|
-
var priorityOrder = [
|
|
712
|
-
"required",
|
|
713
|
-
"type",
|
|
714
|
-
"minLength",
|
|
715
|
-
"format",
|
|
716
|
-
"pattern",
|
|
717
|
-
"enum",
|
|
718
|
-
"additionalProperties",
|
|
719
|
-
"uniqueItems"
|
|
720
|
-
], errorMessages = {
|
|
721
|
-
required: (params) => `missing required property '${params.missingProperty}'`,
|
|
722
|
-
type: (params) => `must be ${params.type}`,
|
|
723
|
-
enum: (params) => `must be one of [${params.allowedValues.join(", ")}]`,
|
|
724
|
-
pattern: (params) => `must match pattern ${params.pattern}`,
|
|
725
|
-
format: (params) => `must be a valid ${params.format}`,
|
|
726
|
-
minLength: () => "must not be empty",
|
|
727
|
-
additionalProperties: (params) => `unexpected property '${params.additionalProperty}'`,
|
|
728
|
-
uniqueItems: () => "must contain unique items"
|
|
729
|
-
}, getPriority = (keyword) => {
|
|
730
|
-
let index = priorityOrder.indexOf(keyword);
|
|
731
|
-
return index === -1 ? priorityOrder.length : index;
|
|
732
|
-
}, formatValidationErrors = (errors) => {
|
|
733
|
-
let errorsByPath = {};
|
|
734
|
-
for (let error2 of errors) {
|
|
735
|
-
let path13 = error2.instancePath || "root";
|
|
736
|
-
errorsByPath[path13] || (errorsByPath[path13] = []), errorsByPath[path13].push(error2);
|
|
737
|
-
}
|
|
738
|
-
return Object.entries(errorsByPath).map(([path13, pathErrors]) => {
|
|
739
|
-
let error2 = [...pathErrors].sort(
|
|
740
|
-
(a, b) => getPriority(a.keyword) - getPriority(b.keyword)
|
|
741
|
-
)[0], formatter = errorMessages[error2.keyword], message = formatter ? formatter(error2.params) : error2.message;
|
|
742
|
-
return ` - ${path13}: ${message}`;
|
|
743
|
-
}).join(`
|
|
744
|
-
`);
|
|
745
|
-
};
|
|
746
|
-
|
|
747
|
-
// src/core/manifest/manifest.schema.json
|
|
748
|
-
var manifest_schema_default = {
|
|
749
|
-
$schema: "http://json-schema.org/draft-07/schema#",
|
|
750
|
-
title: "Manifest",
|
|
751
|
-
description: "Schema for validating plugin manifest",
|
|
752
|
-
type: "object",
|
|
753
|
-
required: [
|
|
754
|
-
"slug",
|
|
755
|
-
"version",
|
|
756
|
-
"permissions",
|
|
757
|
-
"name",
|
|
758
|
-
"description",
|
|
759
|
-
"support"
|
|
760
|
-
],
|
|
761
|
-
properties: {
|
|
762
|
-
$schema: {
|
|
763
|
-
type: "string"
|
|
764
|
-
},
|
|
765
|
-
id: {
|
|
766
|
-
type: "string",
|
|
767
|
-
description: "Unique identifier for the plugin ()",
|
|
768
|
-
minLength: 3,
|
|
769
|
-
maxLength: 63,
|
|
770
|
-
pattern: "^[a-z0-9-]+$"
|
|
771
|
-
},
|
|
772
|
-
manifest_version: {
|
|
773
|
-
type: "number",
|
|
774
|
-
description: "Manifest format version",
|
|
775
|
-
minimum: 1
|
|
776
|
-
},
|
|
777
|
-
supported_services: {
|
|
778
|
-
type: "array",
|
|
779
|
-
description: "Supported services for this plugin",
|
|
780
|
-
items: {
|
|
781
|
-
type: "string",
|
|
782
|
-
enum: [
|
|
783
|
-
"tracker"
|
|
784
|
-
]
|
|
785
|
-
},
|
|
786
|
-
minItems: 1,
|
|
787
|
-
uniqueItems: !0
|
|
788
|
-
},
|
|
789
|
-
slug: {
|
|
790
|
-
type: "string",
|
|
791
|
-
description: "Unique identifier for the plugin (lowercase letters, numbers, hyphen)",
|
|
792
|
-
minLength: 3,
|
|
793
|
-
maxLength: 63,
|
|
794
|
-
pattern: "^[a-z0-9-]+$"
|
|
795
|
-
},
|
|
796
|
-
version: {
|
|
797
|
-
type: "string",
|
|
798
|
-
description: "Version of the plugin (semver format required)",
|
|
799
|
-
minLength: 1,
|
|
800
|
-
pattern: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$"
|
|
801
|
-
},
|
|
802
|
-
name: {
|
|
803
|
-
type: "object",
|
|
804
|
-
description: "Localized plugin name",
|
|
805
|
-
required: [
|
|
806
|
-
"ru",
|
|
807
|
-
"en"
|
|
808
|
-
],
|
|
809
|
-
properties: {
|
|
810
|
-
ru: {
|
|
811
|
-
type: "string",
|
|
812
|
-
description: "Russian name",
|
|
813
|
-
minLength: 1,
|
|
814
|
-
maxLength: 30
|
|
815
|
-
},
|
|
816
|
-
en: {
|
|
817
|
-
type: "string",
|
|
818
|
-
description: "English name",
|
|
819
|
-
minLength: 1,
|
|
820
|
-
maxLength: 30
|
|
821
|
-
}
|
|
822
|
-
},
|
|
823
|
-
additionalProperties: !1
|
|
824
|
-
},
|
|
825
|
-
description: {
|
|
826
|
-
type: "object",
|
|
827
|
-
description: "Localized plugin description",
|
|
828
|
-
required: [
|
|
829
|
-
"ru",
|
|
830
|
-
"en"
|
|
831
|
-
],
|
|
832
|
-
properties: {
|
|
833
|
-
ru: {
|
|
834
|
-
type: "string",
|
|
835
|
-
description: "Russian description",
|
|
836
|
-
minLength: 1,
|
|
837
|
-
maxLength: 255
|
|
838
|
-
},
|
|
839
|
-
en: {
|
|
840
|
-
type: "string",
|
|
841
|
-
description: "English description",
|
|
842
|
-
minLength: 1,
|
|
843
|
-
maxLength: 255
|
|
844
|
-
}
|
|
845
|
-
},
|
|
846
|
-
additionalProperties: !1
|
|
847
|
-
},
|
|
848
|
-
support: {
|
|
849
|
-
type: "array",
|
|
850
|
-
description: "Support contact information",
|
|
851
|
-
items: {
|
|
852
|
-
type: "object",
|
|
853
|
-
required: [
|
|
854
|
-
"type",
|
|
855
|
-
"value"
|
|
856
|
-
],
|
|
857
|
-
properties: {
|
|
858
|
-
type: {
|
|
859
|
-
type: "string",
|
|
860
|
-
description: "Type of support contact",
|
|
861
|
-
enum: [
|
|
862
|
-
"email"
|
|
863
|
-
]
|
|
864
|
-
},
|
|
865
|
-
value: {
|
|
866
|
-
type: "string",
|
|
867
|
-
description: "Contact value",
|
|
868
|
-
minLength: 1,
|
|
869
|
-
maxLength: 100
|
|
870
|
-
}
|
|
871
|
-
},
|
|
872
|
-
additionalProperties: !1
|
|
873
|
-
},
|
|
874
|
-
minItems: 1
|
|
875
|
-
},
|
|
876
|
-
homepage: {
|
|
877
|
-
type: "string",
|
|
878
|
-
description: "Homepage URL for the plugin (http or https)",
|
|
879
|
-
pattern: "^https?://",
|
|
880
|
-
maxLength: 1e3
|
|
881
|
-
},
|
|
882
|
-
license: {
|
|
883
|
-
type: "string",
|
|
884
|
-
description: "License identifier (e.g., MIT, Apache-2.0)",
|
|
885
|
-
minLength: 1,
|
|
886
|
-
maxLength: 32
|
|
887
|
-
},
|
|
888
|
-
keywords: {
|
|
889
|
-
type: "array",
|
|
890
|
-
description: "Keywords for plugin discovery",
|
|
891
|
-
items: {
|
|
892
|
-
type: "string",
|
|
893
|
-
minLength: 1,
|
|
894
|
-
maxLength: 30
|
|
895
|
-
},
|
|
896
|
-
uniqueItems: !0
|
|
897
|
-
},
|
|
898
|
-
whatsnew: {
|
|
899
|
-
type: "string",
|
|
900
|
-
description: "What's new in this version",
|
|
901
|
-
minLength: 1,
|
|
902
|
-
maxLength: 300
|
|
903
|
-
},
|
|
904
|
-
externalHost: {
|
|
905
|
-
type: "string",
|
|
906
|
-
description: "External host URL for the plugin (https only)",
|
|
907
|
-
format: "uri",
|
|
908
|
-
pattern: "^https://",
|
|
909
|
-
maxLength: 1e3
|
|
910
|
-
},
|
|
911
|
-
permissions: {
|
|
912
|
-
type: "object",
|
|
913
|
-
description: "Permissions required by the plugin",
|
|
914
|
-
required: [
|
|
915
|
-
"data"
|
|
916
|
-
],
|
|
917
|
-
properties: {
|
|
918
|
-
data: {
|
|
919
|
-
type: "array",
|
|
920
|
-
description: "Data access permissions",
|
|
921
|
-
items: {
|
|
922
|
-
type: "string",
|
|
923
|
-
enum: [
|
|
924
|
-
"tracker:issues:read",
|
|
925
|
-
"tracker:issues:write",
|
|
926
|
-
"tracker:issuetypes:read",
|
|
927
|
-
"tracker:statuses:read",
|
|
928
|
-
"tracker:queues:read",
|
|
929
|
-
"tracker:fields:read",
|
|
930
|
-
"tracker:entities:read",
|
|
931
|
-
"tracker:attachments:read",
|
|
932
|
-
"tracker:attachments:write",
|
|
933
|
-
"tracker:applications:read",
|
|
934
|
-
"tracker:boards:read",
|
|
935
|
-
"tracker:boards:write",
|
|
936
|
-
"tracker:bulk:read",
|
|
937
|
-
"tracker:bulk:write",
|
|
938
|
-
"tracker:bulkchange:read",
|
|
939
|
-
"tracker:bulkchange:write",
|
|
940
|
-
"tracker:charts:read",
|
|
941
|
-
"tracker:commentTemplates:read",
|
|
942
|
-
"tracker:commentTemplates:write",
|
|
943
|
-
"tracker:components:read",
|
|
944
|
-
"tracker:components:write",
|
|
945
|
-
"tracker:data:read",
|
|
946
|
-
"tracker:departments:read",
|
|
947
|
-
"tracker:entities:write",
|
|
948
|
-
"tracker:externalEventTypes:write",
|
|
949
|
-
"tracker:externalEvents:write",
|
|
950
|
-
"tracker:fields:write",
|
|
951
|
-
"tracker:filterFolders:write",
|
|
952
|
-
"tracker:filters:read",
|
|
953
|
-
"tracker:filters:write",
|
|
954
|
-
"tracker:goals:read",
|
|
955
|
-
"tracker:goals:write",
|
|
956
|
-
"tracker:groups:read",
|
|
957
|
-
"tracker:issueTemplates:read",
|
|
958
|
-
"tracker:issueTemplates:write",
|
|
959
|
-
"tracker:links:read",
|
|
960
|
-
"tracker:linktypes:read",
|
|
961
|
-
"tracker:liveBoards:write",
|
|
962
|
-
"tracker:localFields:read",
|
|
963
|
-
"tracker:maillists:read",
|
|
964
|
-
"tracker:maillists:write",
|
|
965
|
-
"tracker:myself:read",
|
|
966
|
-
"tracker:myself:write",
|
|
967
|
-
"tracker:priorities:read",
|
|
968
|
-
"tracker:queues:write",
|
|
969
|
-
"tracker:reminders:read",
|
|
970
|
-
"tracker:reminders:write",
|
|
971
|
-
"tracker:remotelinks:read",
|
|
972
|
-
"tracker:reports:read",
|
|
973
|
-
"tracker:reports:write",
|
|
974
|
-
"tracker:resolutions:read",
|
|
975
|
-
"tracker:resources:read",
|
|
976
|
-
"tracker:resources:write",
|
|
977
|
-
"tracker:roles:read",
|
|
978
|
-
"tracker:screens:read",
|
|
979
|
-
"tracker:services:read",
|
|
980
|
-
"tracker:sprints:read",
|
|
981
|
-
"tracker:sprints:write",
|
|
982
|
-
"tracker:system:write",
|
|
983
|
-
"tracker:tags:read",
|
|
984
|
-
"tracker:translations:read",
|
|
985
|
-
"tracker:users:read",
|
|
986
|
-
"tracker:users:write",
|
|
987
|
-
"tracker:versions:read",
|
|
988
|
-
"tracker:versions:write",
|
|
989
|
-
"tracker:workflows:read",
|
|
990
|
-
"tracker:workflows:write",
|
|
991
|
-
"tracker:worklog:read",
|
|
992
|
-
"tracker:worklog:write"
|
|
993
|
-
]
|
|
994
|
-
},
|
|
995
|
-
uniqueItems: !0
|
|
996
|
-
},
|
|
997
|
-
ui: {
|
|
998
|
-
type: "array",
|
|
999
|
-
description: "UI permissions",
|
|
1000
|
-
items: {
|
|
1001
|
-
type: "string"
|
|
1002
|
-
},
|
|
1003
|
-
uniqueItems: !0
|
|
1004
|
-
},
|
|
1005
|
-
device: {
|
|
1006
|
-
type: "array",
|
|
1007
|
-
description: "Device permissions",
|
|
1008
|
-
items: {
|
|
1009
|
-
type: "string",
|
|
1010
|
-
enum: [
|
|
1011
|
-
"clipboard-write"
|
|
1012
|
-
]
|
|
1013
|
-
},
|
|
1014
|
-
uniqueItems: !0
|
|
1015
|
-
},
|
|
1016
|
-
external: {
|
|
1017
|
-
type: "array",
|
|
1018
|
-
description: "External permissions",
|
|
1019
|
-
items: {
|
|
1020
|
-
type: "string"
|
|
1021
|
-
},
|
|
1022
|
-
uniqueItems: !0
|
|
1023
|
-
}
|
|
1024
|
-
},
|
|
1025
|
-
additionalProperties: !1
|
|
1026
|
-
},
|
|
1027
|
-
slots: {
|
|
1028
|
-
type: "object",
|
|
1029
|
-
description: "Configuration for service slots",
|
|
1030
|
-
minProperties: 1,
|
|
1031
|
-
properties: {
|
|
1032
|
-
tracker: {
|
|
1033
|
-
type: "object",
|
|
1034
|
-
description: "Tracker service slots",
|
|
1035
|
-
minProperties: 1,
|
|
1036
|
-
properties: {
|
|
1037
|
-
"issue.action": {
|
|
1038
|
-
type: "array",
|
|
1039
|
-
description: "Issue Action slot configurations",
|
|
1040
|
-
minItems: 1,
|
|
1041
|
-
items: {
|
|
1042
|
-
$ref: "#/definitions/SlotConfig"
|
|
1043
|
-
}
|
|
1044
|
-
},
|
|
1045
|
-
"issue.block": {
|
|
1046
|
-
type: "array",
|
|
1047
|
-
description: "Issue Block slot configurations",
|
|
1048
|
-
minItems: 1,
|
|
1049
|
-
items: {
|
|
1050
|
-
$ref: "#/definitions/SlotConfig"
|
|
1051
|
-
}
|
|
1052
|
-
},
|
|
1053
|
-
"issue.tab": {
|
|
1054
|
-
type: "array",
|
|
1055
|
-
description: "Issue Tab slot configurations",
|
|
1056
|
-
minItems: 1,
|
|
1057
|
-
items: {
|
|
1058
|
-
$ref: "#/definitions/SlotConfig"
|
|
1059
|
-
}
|
|
1060
|
-
},
|
|
1061
|
-
"issue.comment.action": {
|
|
1062
|
-
type: "array",
|
|
1063
|
-
description: "Issue Comment Action slot configurations",
|
|
1064
|
-
minItems: 1,
|
|
1065
|
-
items: {
|
|
1066
|
-
$ref: "#/definitions/SlotConfig"
|
|
1067
|
-
}
|
|
1068
|
-
},
|
|
1069
|
-
navigation: {
|
|
1070
|
-
type: "array",
|
|
1071
|
-
description: "Navigation slot configurations",
|
|
1072
|
-
minItems: 1,
|
|
1073
|
-
items: {
|
|
1074
|
-
$ref: "#/definitions/SlotConfig"
|
|
1075
|
-
}
|
|
1076
|
-
},
|
|
1077
|
-
"trigger.create.action": {
|
|
1078
|
-
type: "array",
|
|
1079
|
-
description: "Trigger Create Action slot configurations",
|
|
1080
|
-
minItems: 1,
|
|
1081
|
-
items: {
|
|
1082
|
-
$ref: "#/definitions/SlotConfig"
|
|
1083
|
-
}
|
|
1084
|
-
},
|
|
1085
|
-
"trigger.edit.action": {
|
|
1086
|
-
type: "array",
|
|
1087
|
-
description: "Trigger Edit Action slot configurations",
|
|
1088
|
-
minItems: 1,
|
|
1089
|
-
items: {
|
|
1090
|
-
$ref: "#/definitions/SlotConfig"
|
|
1091
|
-
}
|
|
1092
|
-
},
|
|
1093
|
-
"project.action": {
|
|
1094
|
-
type: "array",
|
|
1095
|
-
description: "Project Action slot configurations",
|
|
1096
|
-
minItems: 1,
|
|
1097
|
-
items: {
|
|
1098
|
-
$ref: "#/definitions/SlotConfig"
|
|
1099
|
-
}
|
|
1100
|
-
},
|
|
1101
|
-
"portfolio.action": {
|
|
1102
|
-
type: "array",
|
|
1103
|
-
description: "Portfolio Action slot configurations",
|
|
1104
|
-
minItems: 1,
|
|
1105
|
-
items: {
|
|
1106
|
-
$ref: "#/definitions/SlotConfig"
|
|
1107
|
-
}
|
|
1108
|
-
},
|
|
1109
|
-
"goal.action": {
|
|
1110
|
-
type: "array",
|
|
1111
|
-
description: "Goal Action slot configurations",
|
|
1112
|
-
minItems: 1,
|
|
1113
|
-
items: {
|
|
1114
|
-
$ref: "#/definitions/SlotConfig"
|
|
1115
|
-
}
|
|
1116
|
-
},
|
|
1117
|
-
"attachment.viewer.action": {
|
|
1118
|
-
type: "array",
|
|
1119
|
-
description: "Attachment Viewer Action slot configurations",
|
|
1120
|
-
minItems: 1,
|
|
1121
|
-
items: {
|
|
1122
|
-
$ref: "#/definitions/SlotConfig"
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
},
|
|
1126
|
-
additionalProperties: !1
|
|
1127
|
-
}
|
|
1128
|
-
},
|
|
1129
|
-
additionalProperties: !1
|
|
1130
|
-
}
|
|
1131
|
-
},
|
|
1132
|
-
additionalProperties: !1,
|
|
1133
|
-
definitions: {
|
|
1134
|
-
SlotConfig: {
|
|
1135
|
-
type: "object",
|
|
1136
|
-
description: "Configuration for a specific slot",
|
|
1137
|
-
required: [
|
|
1138
|
-
"entrypoint",
|
|
1139
|
-
"title"
|
|
1140
|
-
],
|
|
1141
|
-
properties: {
|
|
1142
|
-
entrypoint: {
|
|
1143
|
-
type: "string",
|
|
1144
|
-
description: "Entry point file path for the slot",
|
|
1145
|
-
minLength: 1
|
|
1146
|
-
},
|
|
1147
|
-
title: {
|
|
1148
|
-
type: "object",
|
|
1149
|
-
description: "Localized titles for the slot",
|
|
1150
|
-
required: [
|
|
1151
|
-
"ru",
|
|
1152
|
-
"en"
|
|
1153
|
-
],
|
|
1154
|
-
properties: {
|
|
1155
|
-
ru: {
|
|
1156
|
-
type: "string",
|
|
1157
|
-
description: "Russian title",
|
|
1158
|
-
minLength: 1,
|
|
1159
|
-
maxLength: 32
|
|
1160
|
-
},
|
|
1161
|
-
en: {
|
|
1162
|
-
type: "string",
|
|
1163
|
-
description: "English title",
|
|
1164
|
-
minLength: 1,
|
|
1165
|
-
maxLength: 32
|
|
1166
|
-
}
|
|
1167
|
-
},
|
|
1168
|
-
additionalProperties: !1
|
|
1169
|
-
},
|
|
1170
|
-
description: {
|
|
1171
|
-
type: "object",
|
|
1172
|
-
description: "Localized descriptions for the slot",
|
|
1173
|
-
required: [
|
|
1174
|
-
"ru",
|
|
1175
|
-
"en"
|
|
1176
|
-
],
|
|
1177
|
-
properties: {
|
|
1178
|
-
ru: {
|
|
1179
|
-
type: "string",
|
|
1180
|
-
description: "Russian description",
|
|
1181
|
-
minLength: 1,
|
|
1182
|
-
maxLength: 300
|
|
1183
|
-
},
|
|
1184
|
-
en: {
|
|
1185
|
-
type: "string",
|
|
1186
|
-
description: "English description",
|
|
1187
|
-
minLength: 1,
|
|
1188
|
-
maxLength: 300
|
|
1189
|
-
}
|
|
1190
|
-
},
|
|
1191
|
-
additionalProperties: !1
|
|
1192
|
-
}
|
|
1193
|
-
},
|
|
1194
|
-
additionalProperties: !1
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
};
|
|
1198
|
-
|
|
1199
|
-
// src/core/manifest/manifestManager.ts
|
|
1200
|
-
var validator = (() => {
|
|
1201
|
-
let ajv = new import_ajv.default({ allErrors: !0, strict: !1 });
|
|
1202
|
-
return (0, import_ajv_formats.default)(ajv), ajv.compile(manifest_schema_default);
|
|
1203
|
-
})(), manifestPath = "./manifest.json", parseManifest = (content) => {
|
|
1204
|
-
let manifest;
|
|
1205
|
-
try {
|
|
1206
|
-
manifest = JSON.parse(content);
|
|
1207
|
-
} catch (error2) {
|
|
1208
|
-
throw error2 instanceof SyntaxError ? new Error(`File manifest.json contains invalid JSON: ${error2.message}`) : new Error(`Error reading manifest.json: ${error2.message}`);
|
|
1209
|
-
}
|
|
1210
|
-
return manifest;
|
|
1211
|
-
}, loadRaw = async () => {
|
|
1212
|
-
if (!(0, import_fs2.existsSync)(manifestPath))
|
|
1213
|
-
throw new Error(`File manifest.json not found at path: ${manifestPath}`);
|
|
1214
|
-
try {
|
|
1215
|
-
return await (0, import_promises.readFile)(manifestPath, "utf8");
|
|
1216
|
-
} catch (error2) {
|
|
1217
|
-
throw error2 instanceof Error ? new Error(`Error reading manifest.json: ${error2.message}`) : new Error("Error loading manifest");
|
|
1218
|
-
}
|
|
1219
|
-
}, load = async () => {
|
|
1220
|
-
let manifestContent = await loadRaw();
|
|
1221
|
-
return parseManifest(manifestContent);
|
|
1222
|
-
}, validate = async () => {
|
|
1223
|
-
let manifest = await load();
|
|
1224
|
-
if (!validator(manifest) && validator.errors) {
|
|
1225
|
-
let errorMessages2 = formatValidationErrors(validator.errors);
|
|
1226
|
-
throw new Error(`Manifest validation failed:
|
|
1227
|
-
${errorMessages2}`);
|
|
1228
|
-
}
|
|
1229
|
-
}, save = async (manifest) => {
|
|
1230
|
-
try {
|
|
1231
|
-
let content = JSON.stringify(manifest, null, 4);
|
|
1232
|
-
await (0, import_promises.writeFile)(manifestPath, content, "utf8");
|
|
1233
|
-
} catch (error2) {
|
|
1234
|
-
throw error2 instanceof Error ? new Error(`Error saving manifest.json: ${error2.message}`) : new Error("Error saving manifest");
|
|
1235
|
-
}
|
|
1236
|
-
}, update = async (updates) => {
|
|
1237
|
-
let updatedManifest = { ...await load(), ...updates };
|
|
1238
|
-
return await save(updatedManifest), updatedManifest;
|
|
1239
|
-
}, manifestManager = {
|
|
1240
|
-
load,
|
|
1241
|
-
loadRaw,
|
|
1242
|
-
validate,
|
|
1243
|
-
save,
|
|
1244
|
-
update
|
|
1245
|
-
};
|
|
2158
|
+
var import_fs10 = __toESM(require("fs")), import_path12 = __toESM(require("path"));
|
|
2159
|
+
init_manifestManager();
|
|
1246
2160
|
|
|
1247
2161
|
// src/core/s3config/constants.ts
|
|
1248
2162
|
var CONFIG_FILE_NAME = "config.json";
|
|
1249
2163
|
|
|
1250
2164
|
// src/commands/debug/index.ts
|
|
2165
|
+
init_meta2();
|
|
2166
|
+
init_execCommand();
|
|
1251
2167
|
init_logger();
|
|
1252
2168
|
|
|
1253
2169
|
// src/utils/registerCleanup.ts
|
|
@@ -1259,8 +2175,12 @@ var registerCleanup = (cleanup) => {
|
|
|
1259
2175
|
});
|
|
1260
2176
|
};
|
|
1261
2177
|
|
|
2178
|
+
// src/commands/debug/index.ts
|
|
2179
|
+
init_templateCommands();
|
|
2180
|
+
|
|
1262
2181
|
// src/commands/debug/utils/createDebugConfig.ts
|
|
1263
|
-
var
|
|
2182
|
+
var import_fs7 = __toESM(require("fs")), import_path9 = __toESM(require("path"));
|
|
2183
|
+
init_manifestManager();
|
|
1264
2184
|
|
|
1265
2185
|
// src/utils/convertManifestToConfig.ts
|
|
1266
2186
|
function buildPluginDownloadUrl(env, id, version) {
|
|
@@ -1289,6 +2209,7 @@ var convertManifestToConfig = (manifest, environment) => {
|
|
|
1289
2209
|
description: slotConfig.description,
|
|
1290
2210
|
entrypoint: slotConfig.entrypoint,
|
|
1291
2211
|
title: slotConfig.title,
|
|
2212
|
+
contextLevel: slotConfig.contextLevel,
|
|
1292
2213
|
downloadUrl: buildPluginDownloadUrl(
|
|
1293
2214
|
environment,
|
|
1294
2215
|
manifest.slug,
|
|
@@ -1305,21 +2226,21 @@ var convertManifestToConfig = (manifest, environment) => {
|
|
|
1305
2226
|
|
|
1306
2227
|
// src/commands/debug/utils/createDebugConfig.ts
|
|
1307
2228
|
var createDebugConfig = async () => {
|
|
1308
|
-
let manifest = await manifestManager.load(), config = convertManifestToConfig(manifest, "debug"), configPath =
|
|
1309
|
-
|
|
2229
|
+
let manifest = await manifestManager.load(), config = convertManifestToConfig(manifest, "debug"), configPath = import_path9.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
2230
|
+
import_fs7.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
1310
2231
|
};
|
|
1311
2232
|
|
|
1312
2233
|
// src/commands/debug/utils/lockFile.ts
|
|
1313
|
-
var
|
|
2234
|
+
var import_fs8 = __toESM(require("fs")), import_path10 = __toESM(require("path")), LOCK_FILE_NAME = ".tracker-cli-debug.lock", getLockFilePath = () => import_path10.default.join(process.cwd(), LOCK_FILE_NAME), getRunningDebugPid = () => {
|
|
1314
2235
|
let lockPath = getLockFilePath();
|
|
1315
|
-
if (!
|
|
2236
|
+
if (!import_fs8.default.existsSync(lockPath))
|
|
1316
2237
|
return null;
|
|
1317
2238
|
try {
|
|
1318
|
-
let pid = JSON.parse(
|
|
2239
|
+
let pid = JSON.parse(import_fs8.default.readFileSync(lockPath, "utf-8")).pid;
|
|
1319
2240
|
return process.kill(pid, 0), pid;
|
|
1320
2241
|
} catch {
|
|
1321
2242
|
try {
|
|
1322
|
-
|
|
2243
|
+
import_fs8.default.unlinkSync(lockPath);
|
|
1323
2244
|
} catch {
|
|
1324
2245
|
}
|
|
1325
2246
|
return null;
|
|
@@ -1327,18 +2248,19 @@ var import_fs4 = __toESM(require("fs")), import_path6 = __toESM(require("path"))
|
|
|
1327
2248
|
}, createLockFile = () => {
|
|
1328
2249
|
let lockPath = getLockFilePath(), lockData = {
|
|
1329
2250
|
pid: process.pid
|
|
1330
|
-
}, fd =
|
|
1331
|
-
|
|
2251
|
+
}, fd = import_fs8.default.openSync(lockPath, "wx");
|
|
2252
|
+
import_fs8.default.writeSync(fd, JSON.stringify(lockData, null, 2)), import_fs8.default.closeSync(fd);
|
|
1332
2253
|
}, removeLockFile = () => {
|
|
1333
2254
|
let lockPath = getLockFilePath();
|
|
1334
|
-
|
|
2255
|
+
import_fs8.default.existsSync(lockPath) && import_fs8.default.unlinkSync(lockPath);
|
|
1335
2256
|
};
|
|
1336
2257
|
|
|
1337
2258
|
// src/commands/debug/utils/watchManifest.ts
|
|
1338
|
-
var
|
|
2259
|
+
var import_fs9 = __toESM(require("fs")), import_path11 = __toESM(require("path"));
|
|
2260
|
+
init_manifestManager();
|
|
1339
2261
|
init_logger();
|
|
1340
2262
|
var watchManifest = () => {
|
|
1341
|
-
let manifestPath2 =
|
|
2263
|
+
let manifestPath2 = import_path11.default.join(process.cwd(), "manifest.json"), debounceTimer = null, watcher = import_fs9.default.watch(manifestPath2, async (eventType) => {
|
|
1342
2264
|
eventType === "change" && (debounceTimer && clearTimeout(debounceTimer), debounceTimer = setTimeout(async () => {
|
|
1343
2265
|
try {
|
|
1344
2266
|
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");
|
|
@@ -1362,53 +2284,71 @@ Please stop the existing instance before starting a new one.
|
|
|
1362
2284
|
If you lost the terminal tab, you can kill the process with:
|
|
1363
2285
|
kill ${runningPid}`
|
|
1364
2286
|
), process.exit(1));
|
|
1365
|
-
let configPath =
|
|
2287
|
+
let configPath = import_path12.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
1366
2288
|
options.lint && await manifestManager.validate(), await createDebugConfig();
|
|
1367
2289
|
let watcher = watchManifest(), cleanup = () => {
|
|
1368
|
-
watcher.close(),
|
|
2290
|
+
watcher.close(), import_fs10.default.existsSync(configPath) && import_fs10.default.unlinkSync(configPath), removeLockFile();
|
|
1369
2291
|
};
|
|
1370
|
-
registerCleanup(cleanup), createLockFile(), await execCommand(pluginCmd.dev), cleanup();
|
|
2292
|
+
registerCleanup(cleanup), createLockFile(), logger_default.newLine(), logger_default.info("\u{1F527} Debug mode started!"), logger_default.newLine(), logger_default.info("\u{1F4CC} The plugin is now available in the Tracker interface."), logger_default.info("Open Tracker and check the plugin functionality in the appropriate context."), logger_default.newLine(), logger_default.info("\u26A0\uFE0F Do not try to open localhost in the browser - the plugin works"), logger_default.info("only inside Tracker through a special loading mechanism."), logger_default.newLine(), logger_default.info("\u{1F504} Code changes will be automatically reloaded."), logger_default.info("Press Ctrl+C to stop."), logger_default.newLine(), await execCommand(pluginCmd.dev), cleanup();
|
|
1371
2293
|
}
|
|
1372
2294
|
|
|
1373
2295
|
// src/commands/lint.ts
|
|
2296
|
+
init_manifestManager();
|
|
2297
|
+
init_execCommand();
|
|
1374
2298
|
init_logger();
|
|
2299
|
+
init_templateCommands();
|
|
1375
2300
|
async function lint() {
|
|
1376
2301
|
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);
|
|
1377
2302
|
}
|
|
1378
2303
|
|
|
1379
2304
|
// src/commands/up/utils/copyTemplateFiles.ts
|
|
1380
|
-
var
|
|
2305
|
+
var import_fs11 = require("fs"), import_promises3 = require("fs/promises");
|
|
1381
2306
|
var copyTemplateFiles = async (filenames) => {
|
|
1382
2307
|
await Promise.all(
|
|
1383
2308
|
filenames.map(async (filename) => {
|
|
1384
2309
|
let templatePath = getTemplatePath(filename), targetPath = `./${filename}`;
|
|
1385
|
-
if ((0,
|
|
1386
|
-
let content = await (0,
|
|
1387
|
-
await (0,
|
|
2310
|
+
if ((0, import_fs11.existsSync)(templatePath) && (0, import_fs11.existsSync)(targetPath)) {
|
|
2311
|
+
let content = await (0, import_promises3.readFile)(templatePath), rewritten = applySubstitutions2(filename, content);
|
|
2312
|
+
await (0, import_promises3.writeFile)(targetPath, rewritten);
|
|
1388
2313
|
}
|
|
1389
2314
|
})
|
|
1390
2315
|
);
|
|
1391
2316
|
};
|
|
1392
2317
|
|
|
1393
2318
|
// src/commands/up/utils/updateManifestCompatibility.ts
|
|
2319
|
+
init_manifestManager();
|
|
2320
|
+
function addDefaultContextLevel(slots) {
|
|
2321
|
+
if (!slots)
|
|
2322
|
+
return;
|
|
2323
|
+
let updatedSlots = {}, updates = [];
|
|
2324
|
+
for (let [service, serviceSlots] of Object.entries(slots))
|
|
2325
|
+
if (serviceSlots) {
|
|
2326
|
+
updatedSlots[service] = {};
|
|
2327
|
+
for (let [slot, slotConfigs] of Object.entries(serviceSlots))
|
|
2328
|
+
slotConfigs && (updatedSlots[service][slot] = slotConfigs.map((slotConfig) => "contextLevel" in slotConfig ? slotConfig : (updates.push(slotConfig), Object.assign({}, slotConfig, { contextLevel: "basic" }))));
|
|
2329
|
+
}
|
|
2330
|
+
return updates.length > 0 ? updatedSlots : void 0;
|
|
2331
|
+
}
|
|
1394
2332
|
async function updateManifestCompatibility() {
|
|
1395
2333
|
let manifest = await manifestManager.load(), updates = {};
|
|
1396
|
-
"manifest_version" in manifest || (updates.manifest_version = 1), "supported_services" in manifest || (updates.supported_services = ["tracker"])
|
|
2334
|
+
"manifest_version" in manifest || (updates.manifest_version = 1), "supported_services" in manifest || (updates.supported_services = ["tracker"]);
|
|
2335
|
+
let updatedSlots = addDefaultContextLevel(manifest.slots);
|
|
2336
|
+
updatedSlots && (updates.slots = updatedSlots), Object.keys(updates).length > 0 && await manifestManager.update(updates);
|
|
1397
2337
|
}
|
|
1398
2338
|
|
|
1399
2339
|
// src/commands/up/utils/updatePackageDependencies.ts
|
|
1400
|
-
var
|
|
2340
|
+
var import_fs12 = require("fs"), import_promises4 = require("fs/promises");
|
|
1401
2341
|
var updatePackageDependencies = async (dependencies) => {
|
|
1402
2342
|
let packageJsonPath = "./package.json", templatePackageJsonPath = getTemplatePath("package.json");
|
|
1403
|
-
if (!(0,
|
|
2343
|
+
if (!(0, import_fs12.existsSync)(packageJsonPath) || !(0, import_fs12.existsSync)(templatePackageJsonPath))
|
|
1404
2344
|
return;
|
|
1405
|
-
let packageJsonContent = await (0,
|
|
2345
|
+
let packageJsonContent = await (0, import_promises4.readFile)(packageJsonPath, "utf-8"), templatePackageJsonRaw = await (0, import_promises4.readFile)(templatePackageJsonPath), templatePackageJsonContent = applySubstitutions2(
|
|
1406
2346
|
"package.json",
|
|
1407
2347
|
templatePackageJsonRaw
|
|
1408
2348
|
).toString("utf8"), packageJson = JSON.parse(packageJsonContent), templatePackageJson = JSON.parse(templatePackageJsonContent), updated = !1;
|
|
1409
2349
|
dependencies.forEach((dep) => {
|
|
1410
2350
|
packageJson.dependencies?.[dep] && templatePackageJson.dependencies?.[dep] && packageJson.dependencies[dep] !== templatePackageJson.dependencies[dep] && (packageJson.dependencies[dep] = templatePackageJson.dependencies[dep], updated = !0);
|
|
1411
|
-
}), updated && await (0,
|
|
2351
|
+
}), updated && await (0, import_promises4.writeFile)(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
1412
2352
|
`, "utf-8");
|
|
1413
2353
|
};
|
|
1414
2354
|
|
|
@@ -1419,34 +2359,25 @@ async function up() {
|
|
|
1419
2359
|
}
|
|
1420
2360
|
|
|
1421
2361
|
// src/utils/getVersion.ts
|
|
1422
|
-
var
|
|
1423
|
-
|
|
1424
|
-
let
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
2362
|
+
var import_fs13 = require("fs"), import_path13 = require("path"), UNKNOWN_VERSION = "unknown", CANDIDATES = ["..", "../.."], findVersionInPackageJson = (startDir) => {
|
|
2363
|
+
for (let rel of CANDIDATES) {
|
|
2364
|
+
let path18 = (0, import_path13.resolve)(startDir, rel, "package.json");
|
|
2365
|
+
if ((0, import_fs13.existsSync)(path18))
|
|
2366
|
+
try {
|
|
2367
|
+
let pkg = JSON.parse((0, import_fs13.readFileSync)(path18, "utf-8"));
|
|
2368
|
+
if (typeof pkg.version == "string") return pkg.version;
|
|
2369
|
+
} catch {
|
|
2370
|
+
}
|
|
1428
2371
|
}
|
|
1429
|
-
|
|
2372
|
+
return null;
|
|
2373
|
+
}, getVersion = () => findVersionInPackageJson(__dirname) ?? UNKNOWN_VERSION;
|
|
1430
2374
|
|
|
1431
2375
|
// src/index.ts
|
|
1432
2376
|
init_verbose();
|
|
1433
|
-
|
|
1434
|
-
// src/utils/withErrorHandling.ts
|
|
1435
|
-
init_logger();
|
|
1436
|
-
function withErrorHandling(fn) {
|
|
1437
|
-
return async (...args) => {
|
|
1438
|
-
try {
|
|
1439
|
-
await fn(...args);
|
|
1440
|
-
} catch (error2) {
|
|
1441
|
-
error2 instanceof Error && error2.name === "ExitPromptError" && process.exit(0), logger_default.error(error2), process.exit(1);
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
// src/index.ts
|
|
2377
|
+
init_withErrorHandling();
|
|
1447
2378
|
async function main() {
|
|
1448
|
-
let program = new
|
|
1449
|
-
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) => {
|
|
2379
|
+
let program = new import_commander2.Command(), version = getVersion();
|
|
2380
|
+
await checkUpdate(version), program.name(CLI_NAME2).description(CLI_DESCRIPTION2).version(version).option("--verbose", "enable verbose output"), CLI_HELP_TEXT2 && program.addHelpText("before", CLI_HELP_TEXT2), program.hook("preAction", (thisCommand) => {
|
|
1450
2381
|
setVerboseEnabled(!!thisCommand.opts().verbose);
|
|
1451
2382
|
}), 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(
|
|
1452
2383
|
"start a tunnel to connect your local code with the app running in the development environment"
|