@weavix/cli 0.3.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 -713
- 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,38 +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
|
|
627
|
-
let levelsUp = isDevelopment() ? "../.." : "..";
|
|
628
|
-
return import_path4.default.resolve(__dirname, levelsUp, relativePath);
|
|
629
|
-
}, getTemplatesBaseDir = () => getProjectPath("templates"), getTemplatePath = (filename) => import_path4.default.join(getTemplatesBaseDir(), "_shared", filename);
|
|
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);
|
|
630
2082
|
|
|
631
2083
|
// src/commands/create/utils/initTemplate.ts
|
|
632
2084
|
init_logger();
|
|
633
2085
|
|
|
634
2086
|
// src/commands/create/utils/updatePackageJson.ts
|
|
635
|
-
var
|
|
636
|
-
let packageJsonPath =
|
|
637
|
-
if (
|
|
638
|
-
let packageJson = JSON.parse(
|
|
639
|
-
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) + `
|
|
640
2092
|
`);
|
|
641
2093
|
}
|
|
642
2094
|
};
|
|
643
2095
|
|
|
644
2096
|
// src/commands/create/utils/initTemplate.ts
|
|
645
2097
|
var initTemplate = async ({ answers, targetDir }) => {
|
|
646
|
-
|
|
647
|
-
let templatesBaseDir = getTemplatesBaseDir(), templatesDir =
|
|
648
|
-
await copyDirectory(sharedDir, targetDir), await copyDirectory(templatesDir, targetDir), updatePackageJson(targetDir, answers.packageSlug), logger_default.info("Created template with marketplace publication requirements."), logger_default.info(
|
|
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(
|
|
649
2101
|
"Before publishing, add ./marketplace/index.md, ./marketplace/header-image.jpg (784:325), and ./public/logo.svg (square)."
|
|
650
2102
|
);
|
|
651
2103
|
};
|
|
@@ -654,26 +2106,26 @@ var initTemplate = async ({ answers, targetDir }) => {
|
|
|
654
2106
|
var DEFAULT_VERSION = "0.0.1";
|
|
655
2107
|
async function create() {
|
|
656
2108
|
logger_default.info(getWelcomeMessage(process.cwd()));
|
|
657
|
-
let packageSlug = await (0,
|
|
2109
|
+
let packageSlug = await (0, import_prompts3.input)({
|
|
658
2110
|
message: "Enter app slug (e.g., my-tracker-plugin):",
|
|
659
2111
|
required: !0
|
|
660
|
-
}), pluginName = await (0,
|
|
2112
|
+
}), pluginName = await (0, import_prompts3.input)({
|
|
661
2113
|
message: "Enter plugin name:",
|
|
662
2114
|
required: !0
|
|
663
|
-
}), pluginDescription = await (0,
|
|
2115
|
+
}), pluginDescription = await (0, import_prompts3.input)({
|
|
664
2116
|
message: "Enter plugin description:",
|
|
665
2117
|
required: !0
|
|
666
|
-
}), supportEmail = await (0,
|
|
2118
|
+
}), supportEmail = await (0, import_prompts3.input)({
|
|
667
2119
|
message: "Enter support email:",
|
|
668
2120
|
required: !0,
|
|
669
2121
|
validate: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || "Please enter a valid email address"
|
|
670
|
-
}), template = await (0,
|
|
2122
|
+
}), template = await (0, import_prompts3.select)({
|
|
671
2123
|
message: "Select a template:",
|
|
672
2124
|
choices: TEMPLATES.map((templateName) => ({
|
|
673
2125
|
name: templateName,
|
|
674
2126
|
value: templateName
|
|
675
2127
|
}))
|
|
676
|
-
}), dataPermissions = await (0,
|
|
2128
|
+
}), dataPermissions = await (0, import_prompts3.checkbox)({
|
|
677
2129
|
message: "Select data permissions (some popular options):",
|
|
678
2130
|
choices: TOP_DATA_PERMISSIONS.map((permission) => ({
|
|
679
2131
|
name: permission,
|
|
@@ -690,567 +2142,28 @@ async function create() {
|
|
|
690
2142
|
data: dataPermissions
|
|
691
2143
|
},
|
|
692
2144
|
version: DEFAULT_VERSION
|
|
693
|
-
}, targetDir =
|
|
2145
|
+
}, targetDir = path13.join(process.cwd(), answers.packageSlug);
|
|
694
2146
|
await initTemplate({
|
|
695
2147
|
answers,
|
|
696
2148
|
targetDir
|
|
697
2149
|
}), initManifest({
|
|
698
2150
|
answers,
|
|
699
2151
|
targetDir
|
|
700
|
-
}), logger_default.newLine(), logger_default.success("
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
`${CLI_NAME2} debug`
|
|
704
|
-
]);
|
|
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.");
|
|
705
2155
|
}
|
|
706
2156
|
|
|
707
2157
|
// src/commands/debug/index.ts
|
|
708
|
-
var
|
|
709
|
-
|
|
710
|
-
// src/core/manifest/manifestManager.ts
|
|
711
|
-
var import_fs2 = require("fs"), import_promises = require("fs/promises"), import_ajv = __toESM(require("ajv")), import_ajv_formats = __toESM(require("ajv-formats"));
|
|
712
|
-
|
|
713
|
-
// src/core/manifest/formatValidationErrors.ts
|
|
714
|
-
var priorityOrder = [
|
|
715
|
-
"required",
|
|
716
|
-
"type",
|
|
717
|
-
"minLength",
|
|
718
|
-
"format",
|
|
719
|
-
"pattern",
|
|
720
|
-
"enum",
|
|
721
|
-
"additionalProperties",
|
|
722
|
-
"uniqueItems"
|
|
723
|
-
], errorMessages = {
|
|
724
|
-
required: (params) => `missing required property '${params.missingProperty}'`,
|
|
725
|
-
type: (params) => `must be ${params.type}`,
|
|
726
|
-
enum: (params) => `must be one of [${params.allowedValues.join(", ")}]`,
|
|
727
|
-
pattern: (params) => `must match pattern ${params.pattern}`,
|
|
728
|
-
format: (params) => `must be a valid ${params.format}`,
|
|
729
|
-
minLength: () => "must not be empty",
|
|
730
|
-
additionalProperties: (params) => `unexpected property '${params.additionalProperty}'`,
|
|
731
|
-
uniqueItems: () => "must contain unique items"
|
|
732
|
-
}, getPriority = (keyword) => {
|
|
733
|
-
let index = priorityOrder.indexOf(keyword);
|
|
734
|
-
return index === -1 ? priorityOrder.length : index;
|
|
735
|
-
}, formatValidationErrors = (errors) => {
|
|
736
|
-
let errorsByPath = {};
|
|
737
|
-
for (let error2 of errors) {
|
|
738
|
-
let path13 = error2.instancePath || "root";
|
|
739
|
-
errorsByPath[path13] || (errorsByPath[path13] = []), errorsByPath[path13].push(error2);
|
|
740
|
-
}
|
|
741
|
-
return Object.entries(errorsByPath).map(([path13, pathErrors]) => {
|
|
742
|
-
let error2 = [...pathErrors].sort(
|
|
743
|
-
(a, b) => getPriority(a.keyword) - getPriority(b.keyword)
|
|
744
|
-
)[0], formatter = errorMessages[error2.keyword], message = formatter ? formatter(error2.params) : error2.message;
|
|
745
|
-
return ` - ${path13}: ${message}`;
|
|
746
|
-
}).join(`
|
|
747
|
-
`);
|
|
748
|
-
};
|
|
749
|
-
|
|
750
|
-
// src/core/manifest/manifest.schema.json
|
|
751
|
-
var manifest_schema_default = {
|
|
752
|
-
$schema: "http://json-schema.org/draft-07/schema#",
|
|
753
|
-
title: "Manifest",
|
|
754
|
-
description: "Schema for validating plugin manifest",
|
|
755
|
-
type: "object",
|
|
756
|
-
required: [
|
|
757
|
-
"slug",
|
|
758
|
-
"version",
|
|
759
|
-
"permissions",
|
|
760
|
-
"name",
|
|
761
|
-
"description",
|
|
762
|
-
"support"
|
|
763
|
-
],
|
|
764
|
-
properties: {
|
|
765
|
-
$schema: {
|
|
766
|
-
type: "string"
|
|
767
|
-
},
|
|
768
|
-
id: {
|
|
769
|
-
type: "string",
|
|
770
|
-
description: "Unique identifier for the plugin ()",
|
|
771
|
-
minLength: 3,
|
|
772
|
-
maxLength: 63,
|
|
773
|
-
pattern: "^[a-z0-9-]+$"
|
|
774
|
-
},
|
|
775
|
-
manifest_version: {
|
|
776
|
-
type: "number",
|
|
777
|
-
description: "Manifest format version",
|
|
778
|
-
minimum: 1
|
|
779
|
-
},
|
|
780
|
-
supported_services: {
|
|
781
|
-
type: "array",
|
|
782
|
-
description: "Supported services for this plugin",
|
|
783
|
-
items: {
|
|
784
|
-
type: "string",
|
|
785
|
-
enum: [
|
|
786
|
-
"tracker"
|
|
787
|
-
]
|
|
788
|
-
},
|
|
789
|
-
minItems: 1,
|
|
790
|
-
uniqueItems: !0
|
|
791
|
-
},
|
|
792
|
-
slug: {
|
|
793
|
-
type: "string",
|
|
794
|
-
description: "Unique identifier for the plugin (lowercase letters, numbers, hyphen)",
|
|
795
|
-
minLength: 3,
|
|
796
|
-
maxLength: 63,
|
|
797
|
-
pattern: "^[a-z0-9-]+$"
|
|
798
|
-
},
|
|
799
|
-
version: {
|
|
800
|
-
type: "string",
|
|
801
|
-
description: "Version of the plugin (semver format required)",
|
|
802
|
-
minLength: 1,
|
|
803
|
-
pattern: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$"
|
|
804
|
-
},
|
|
805
|
-
name: {
|
|
806
|
-
type: "object",
|
|
807
|
-
description: "Localized plugin name",
|
|
808
|
-
required: [
|
|
809
|
-
"ru",
|
|
810
|
-
"en"
|
|
811
|
-
],
|
|
812
|
-
properties: {
|
|
813
|
-
ru: {
|
|
814
|
-
type: "string",
|
|
815
|
-
description: "Russian name",
|
|
816
|
-
minLength: 1,
|
|
817
|
-
maxLength: 30
|
|
818
|
-
},
|
|
819
|
-
en: {
|
|
820
|
-
type: "string",
|
|
821
|
-
description: "English name",
|
|
822
|
-
minLength: 1,
|
|
823
|
-
maxLength: 30
|
|
824
|
-
}
|
|
825
|
-
},
|
|
826
|
-
additionalProperties: !1
|
|
827
|
-
},
|
|
828
|
-
description: {
|
|
829
|
-
type: "object",
|
|
830
|
-
description: "Localized plugin description",
|
|
831
|
-
required: [
|
|
832
|
-
"ru",
|
|
833
|
-
"en"
|
|
834
|
-
],
|
|
835
|
-
properties: {
|
|
836
|
-
ru: {
|
|
837
|
-
type: "string",
|
|
838
|
-
description: "Russian description",
|
|
839
|
-
minLength: 1,
|
|
840
|
-
maxLength: 255
|
|
841
|
-
},
|
|
842
|
-
en: {
|
|
843
|
-
type: "string",
|
|
844
|
-
description: "English description",
|
|
845
|
-
minLength: 1,
|
|
846
|
-
maxLength: 255
|
|
847
|
-
}
|
|
848
|
-
},
|
|
849
|
-
additionalProperties: !1
|
|
850
|
-
},
|
|
851
|
-
support: {
|
|
852
|
-
type: "array",
|
|
853
|
-
description: "Support contact information",
|
|
854
|
-
items: {
|
|
855
|
-
type: "object",
|
|
856
|
-
required: [
|
|
857
|
-
"type",
|
|
858
|
-
"value"
|
|
859
|
-
],
|
|
860
|
-
properties: {
|
|
861
|
-
type: {
|
|
862
|
-
type: "string",
|
|
863
|
-
description: "Type of support contact",
|
|
864
|
-
enum: [
|
|
865
|
-
"email"
|
|
866
|
-
]
|
|
867
|
-
},
|
|
868
|
-
value: {
|
|
869
|
-
type: "string",
|
|
870
|
-
description: "Contact value",
|
|
871
|
-
minLength: 1,
|
|
872
|
-
maxLength: 100
|
|
873
|
-
}
|
|
874
|
-
},
|
|
875
|
-
additionalProperties: !1
|
|
876
|
-
},
|
|
877
|
-
minItems: 1
|
|
878
|
-
},
|
|
879
|
-
homepage: {
|
|
880
|
-
type: "string",
|
|
881
|
-
description: "Homepage URL for the plugin (http or https)",
|
|
882
|
-
pattern: "^https?://",
|
|
883
|
-
maxLength: 1e3
|
|
884
|
-
},
|
|
885
|
-
license: {
|
|
886
|
-
type: "string",
|
|
887
|
-
description: "License identifier (e.g., MIT, Apache-2.0)",
|
|
888
|
-
minLength: 1,
|
|
889
|
-
maxLength: 32
|
|
890
|
-
},
|
|
891
|
-
keywords: {
|
|
892
|
-
type: "array",
|
|
893
|
-
description: "Keywords for plugin discovery",
|
|
894
|
-
items: {
|
|
895
|
-
type: "string",
|
|
896
|
-
minLength: 1,
|
|
897
|
-
maxLength: 30
|
|
898
|
-
},
|
|
899
|
-
uniqueItems: !0
|
|
900
|
-
},
|
|
901
|
-
whatsnew: {
|
|
902
|
-
type: "string",
|
|
903
|
-
description: "What's new in this version",
|
|
904
|
-
minLength: 1,
|
|
905
|
-
maxLength: 300
|
|
906
|
-
},
|
|
907
|
-
externalHost: {
|
|
908
|
-
type: "string",
|
|
909
|
-
description: "External host URL for the plugin (https only)",
|
|
910
|
-
format: "uri",
|
|
911
|
-
pattern: "^https://",
|
|
912
|
-
maxLength: 1e3
|
|
913
|
-
},
|
|
914
|
-
permissions: {
|
|
915
|
-
type: "object",
|
|
916
|
-
description: "Permissions required by the plugin",
|
|
917
|
-
required: [
|
|
918
|
-
"data"
|
|
919
|
-
],
|
|
920
|
-
properties: {
|
|
921
|
-
data: {
|
|
922
|
-
type: "array",
|
|
923
|
-
description: "Data access permissions",
|
|
924
|
-
items: {
|
|
925
|
-
type: "string",
|
|
926
|
-
enum: [
|
|
927
|
-
"tracker:issues:read",
|
|
928
|
-
"tracker:issues:write",
|
|
929
|
-
"tracker:issuetypes:read",
|
|
930
|
-
"tracker:statuses:read",
|
|
931
|
-
"tracker:queues:read",
|
|
932
|
-
"tracker:fields:read",
|
|
933
|
-
"tracker:entities:read",
|
|
934
|
-
"tracker:attachments:read",
|
|
935
|
-
"tracker:attachments:write",
|
|
936
|
-
"tracker:applications:read",
|
|
937
|
-
"tracker:boards:read",
|
|
938
|
-
"tracker:boards:write",
|
|
939
|
-
"tracker:bulk:read",
|
|
940
|
-
"tracker:bulk:write",
|
|
941
|
-
"tracker:bulkchange:read",
|
|
942
|
-
"tracker:bulkchange:write",
|
|
943
|
-
"tracker:charts:read",
|
|
944
|
-
"tracker:commentTemplates:read",
|
|
945
|
-
"tracker:commentTemplates:write",
|
|
946
|
-
"tracker:components:read",
|
|
947
|
-
"tracker:components:write",
|
|
948
|
-
"tracker:data:read",
|
|
949
|
-
"tracker:departments:read",
|
|
950
|
-
"tracker:entities:write",
|
|
951
|
-
"tracker:externalEventTypes:write",
|
|
952
|
-
"tracker:externalEvents:write",
|
|
953
|
-
"tracker:fields:write",
|
|
954
|
-
"tracker:filterFolders:write",
|
|
955
|
-
"tracker:filters:read",
|
|
956
|
-
"tracker:filters:write",
|
|
957
|
-
"tracker:goals:read",
|
|
958
|
-
"tracker:goals:write",
|
|
959
|
-
"tracker:groups:read",
|
|
960
|
-
"tracker:issueTemplates:read",
|
|
961
|
-
"tracker:issueTemplates:write",
|
|
962
|
-
"tracker:links:read",
|
|
963
|
-
"tracker:linktypes:read",
|
|
964
|
-
"tracker:liveBoards:write",
|
|
965
|
-
"tracker:localFields:read",
|
|
966
|
-
"tracker:maillists:read",
|
|
967
|
-
"tracker:maillists:write",
|
|
968
|
-
"tracker:myself:read",
|
|
969
|
-
"tracker:myself:write",
|
|
970
|
-
"tracker:priorities:read",
|
|
971
|
-
"tracker:queues:write",
|
|
972
|
-
"tracker:reminders:read",
|
|
973
|
-
"tracker:reminders:write",
|
|
974
|
-
"tracker:remotelinks:read",
|
|
975
|
-
"tracker:reports:read",
|
|
976
|
-
"tracker:reports:write",
|
|
977
|
-
"tracker:resolutions:read",
|
|
978
|
-
"tracker:resources:read",
|
|
979
|
-
"tracker:resources:write",
|
|
980
|
-
"tracker:roles:read",
|
|
981
|
-
"tracker:screens:read",
|
|
982
|
-
"tracker:services:read",
|
|
983
|
-
"tracker:sprints:read",
|
|
984
|
-
"tracker:sprints:write",
|
|
985
|
-
"tracker:system:write",
|
|
986
|
-
"tracker:tags:read",
|
|
987
|
-
"tracker:translations:read",
|
|
988
|
-
"tracker:users:read",
|
|
989
|
-
"tracker:users:write",
|
|
990
|
-
"tracker:versions:read",
|
|
991
|
-
"tracker:versions:write",
|
|
992
|
-
"tracker:workflows:read",
|
|
993
|
-
"tracker:workflows:write",
|
|
994
|
-
"tracker:worklog:read",
|
|
995
|
-
"tracker:worklog:write"
|
|
996
|
-
]
|
|
997
|
-
},
|
|
998
|
-
uniqueItems: !0
|
|
999
|
-
},
|
|
1000
|
-
ui: {
|
|
1001
|
-
type: "array",
|
|
1002
|
-
description: "UI permissions",
|
|
1003
|
-
items: {
|
|
1004
|
-
type: "string"
|
|
1005
|
-
},
|
|
1006
|
-
uniqueItems: !0
|
|
1007
|
-
},
|
|
1008
|
-
device: {
|
|
1009
|
-
type: "array",
|
|
1010
|
-
description: "Device permissions",
|
|
1011
|
-
items: {
|
|
1012
|
-
type: "string",
|
|
1013
|
-
enum: [
|
|
1014
|
-
"clipboard-write"
|
|
1015
|
-
]
|
|
1016
|
-
},
|
|
1017
|
-
uniqueItems: !0
|
|
1018
|
-
},
|
|
1019
|
-
external: {
|
|
1020
|
-
type: "array",
|
|
1021
|
-
description: "External permissions",
|
|
1022
|
-
items: {
|
|
1023
|
-
type: "string"
|
|
1024
|
-
},
|
|
1025
|
-
uniqueItems: !0
|
|
1026
|
-
}
|
|
1027
|
-
},
|
|
1028
|
-
additionalProperties: !1
|
|
1029
|
-
},
|
|
1030
|
-
slots: {
|
|
1031
|
-
type: "object",
|
|
1032
|
-
description: "Configuration for service slots",
|
|
1033
|
-
minProperties: 1,
|
|
1034
|
-
properties: {
|
|
1035
|
-
tracker: {
|
|
1036
|
-
type: "object",
|
|
1037
|
-
description: "Tracker service slots",
|
|
1038
|
-
minProperties: 1,
|
|
1039
|
-
properties: {
|
|
1040
|
-
"issue.action": {
|
|
1041
|
-
type: "array",
|
|
1042
|
-
description: "Issue Action slot configurations",
|
|
1043
|
-
minItems: 1,
|
|
1044
|
-
items: {
|
|
1045
|
-
$ref: "#/definitions/SlotConfig"
|
|
1046
|
-
}
|
|
1047
|
-
},
|
|
1048
|
-
"issue.block": {
|
|
1049
|
-
type: "array",
|
|
1050
|
-
description: "Issue Block slot configurations",
|
|
1051
|
-
minItems: 1,
|
|
1052
|
-
items: {
|
|
1053
|
-
$ref: "#/definitions/SlotConfig"
|
|
1054
|
-
}
|
|
1055
|
-
},
|
|
1056
|
-
"issue.tab": {
|
|
1057
|
-
type: "array",
|
|
1058
|
-
description: "Issue Tab slot configurations",
|
|
1059
|
-
minItems: 1,
|
|
1060
|
-
items: {
|
|
1061
|
-
$ref: "#/definitions/SlotConfig"
|
|
1062
|
-
}
|
|
1063
|
-
},
|
|
1064
|
-
"issue.comment.action": {
|
|
1065
|
-
type: "array",
|
|
1066
|
-
description: "Issue Comment Action slot configurations",
|
|
1067
|
-
minItems: 1,
|
|
1068
|
-
items: {
|
|
1069
|
-
$ref: "#/definitions/SlotConfig"
|
|
1070
|
-
}
|
|
1071
|
-
},
|
|
1072
|
-
navigation: {
|
|
1073
|
-
type: "array",
|
|
1074
|
-
description: "Navigation slot configurations",
|
|
1075
|
-
minItems: 1,
|
|
1076
|
-
items: {
|
|
1077
|
-
$ref: "#/definitions/SlotConfig"
|
|
1078
|
-
}
|
|
1079
|
-
},
|
|
1080
|
-
"trigger.create.action": {
|
|
1081
|
-
type: "array",
|
|
1082
|
-
description: "Trigger Create Action slot configurations",
|
|
1083
|
-
minItems: 1,
|
|
1084
|
-
items: {
|
|
1085
|
-
$ref: "#/definitions/SlotConfig"
|
|
1086
|
-
}
|
|
1087
|
-
},
|
|
1088
|
-
"trigger.edit.action": {
|
|
1089
|
-
type: "array",
|
|
1090
|
-
description: "Trigger Edit Action slot configurations",
|
|
1091
|
-
minItems: 1,
|
|
1092
|
-
items: {
|
|
1093
|
-
$ref: "#/definitions/SlotConfig"
|
|
1094
|
-
}
|
|
1095
|
-
},
|
|
1096
|
-
"project.action": {
|
|
1097
|
-
type: "array",
|
|
1098
|
-
description: "Project Action slot configurations",
|
|
1099
|
-
minItems: 1,
|
|
1100
|
-
items: {
|
|
1101
|
-
$ref: "#/definitions/SlotConfig"
|
|
1102
|
-
}
|
|
1103
|
-
},
|
|
1104
|
-
"portfolio.action": {
|
|
1105
|
-
type: "array",
|
|
1106
|
-
description: "Portfolio Action slot configurations",
|
|
1107
|
-
minItems: 1,
|
|
1108
|
-
items: {
|
|
1109
|
-
$ref: "#/definitions/SlotConfig"
|
|
1110
|
-
}
|
|
1111
|
-
},
|
|
1112
|
-
"goal.action": {
|
|
1113
|
-
type: "array",
|
|
1114
|
-
description: "Goal Action slot configurations",
|
|
1115
|
-
minItems: 1,
|
|
1116
|
-
items: {
|
|
1117
|
-
$ref: "#/definitions/SlotConfig"
|
|
1118
|
-
}
|
|
1119
|
-
},
|
|
1120
|
-
"attachment.viewer.action": {
|
|
1121
|
-
type: "array",
|
|
1122
|
-
description: "Attachment Viewer Action slot configurations",
|
|
1123
|
-
minItems: 1,
|
|
1124
|
-
items: {
|
|
1125
|
-
$ref: "#/definitions/SlotConfig"
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
},
|
|
1129
|
-
additionalProperties: !1
|
|
1130
|
-
}
|
|
1131
|
-
},
|
|
1132
|
-
additionalProperties: !1
|
|
1133
|
-
}
|
|
1134
|
-
},
|
|
1135
|
-
additionalProperties: !1,
|
|
1136
|
-
definitions: {
|
|
1137
|
-
SlotConfig: {
|
|
1138
|
-
type: "object",
|
|
1139
|
-
description: "Configuration for a specific slot",
|
|
1140
|
-
required: [
|
|
1141
|
-
"entrypoint",
|
|
1142
|
-
"title"
|
|
1143
|
-
],
|
|
1144
|
-
properties: {
|
|
1145
|
-
entrypoint: {
|
|
1146
|
-
type: "string",
|
|
1147
|
-
description: "Entry point file path for the slot",
|
|
1148
|
-
minLength: 1
|
|
1149
|
-
},
|
|
1150
|
-
title: {
|
|
1151
|
-
type: "object",
|
|
1152
|
-
description: "Localized titles for the slot",
|
|
1153
|
-
required: [
|
|
1154
|
-
"ru",
|
|
1155
|
-
"en"
|
|
1156
|
-
],
|
|
1157
|
-
properties: {
|
|
1158
|
-
ru: {
|
|
1159
|
-
type: "string",
|
|
1160
|
-
description: "Russian title",
|
|
1161
|
-
minLength: 1,
|
|
1162
|
-
maxLength: 32
|
|
1163
|
-
},
|
|
1164
|
-
en: {
|
|
1165
|
-
type: "string",
|
|
1166
|
-
description: "English title",
|
|
1167
|
-
minLength: 1,
|
|
1168
|
-
maxLength: 32
|
|
1169
|
-
}
|
|
1170
|
-
},
|
|
1171
|
-
additionalProperties: !1
|
|
1172
|
-
},
|
|
1173
|
-
description: {
|
|
1174
|
-
type: "object",
|
|
1175
|
-
description: "Localized descriptions for the slot",
|
|
1176
|
-
required: [
|
|
1177
|
-
"ru",
|
|
1178
|
-
"en"
|
|
1179
|
-
],
|
|
1180
|
-
properties: {
|
|
1181
|
-
ru: {
|
|
1182
|
-
type: "string",
|
|
1183
|
-
description: "Russian description",
|
|
1184
|
-
minLength: 1,
|
|
1185
|
-
maxLength: 300
|
|
1186
|
-
},
|
|
1187
|
-
en: {
|
|
1188
|
-
type: "string",
|
|
1189
|
-
description: "English description",
|
|
1190
|
-
minLength: 1,
|
|
1191
|
-
maxLength: 300
|
|
1192
|
-
}
|
|
1193
|
-
},
|
|
1194
|
-
additionalProperties: !1
|
|
1195
|
-
}
|
|
1196
|
-
},
|
|
1197
|
-
additionalProperties: !1
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
};
|
|
1201
|
-
|
|
1202
|
-
// src/core/manifest/manifestManager.ts
|
|
1203
|
-
var validator = (() => {
|
|
1204
|
-
let ajv = new import_ajv.default({ allErrors: !0, strict: !1 });
|
|
1205
|
-
return (0, import_ajv_formats.default)(ajv), ajv.compile(manifest_schema_default);
|
|
1206
|
-
})(), manifestPath = "./manifest.json", parseManifest = (content) => {
|
|
1207
|
-
let manifest;
|
|
1208
|
-
try {
|
|
1209
|
-
manifest = JSON.parse(content);
|
|
1210
|
-
} catch (error2) {
|
|
1211
|
-
throw error2 instanceof SyntaxError ? new Error(`File manifest.json contains invalid JSON: ${error2.message}`) : new Error(`Error reading manifest.json: ${error2.message}`);
|
|
1212
|
-
}
|
|
1213
|
-
return manifest;
|
|
1214
|
-
}, loadRaw = async () => {
|
|
1215
|
-
if (!(0, import_fs2.existsSync)(manifestPath))
|
|
1216
|
-
throw new Error(`File manifest.json not found at path: ${manifestPath}`);
|
|
1217
|
-
try {
|
|
1218
|
-
return await (0, import_promises.readFile)(manifestPath, "utf8");
|
|
1219
|
-
} catch (error2) {
|
|
1220
|
-
throw error2 instanceof Error ? new Error(`Error reading manifest.json: ${error2.message}`) : new Error("Error loading manifest");
|
|
1221
|
-
}
|
|
1222
|
-
}, load = async () => {
|
|
1223
|
-
let manifestContent = await loadRaw();
|
|
1224
|
-
return parseManifest(manifestContent);
|
|
1225
|
-
}, validate = async () => {
|
|
1226
|
-
let manifest = await load();
|
|
1227
|
-
if (!validator(manifest) && validator.errors) {
|
|
1228
|
-
let errorMessages2 = formatValidationErrors(validator.errors);
|
|
1229
|
-
throw new Error(`Manifest validation failed:
|
|
1230
|
-
${errorMessages2}`);
|
|
1231
|
-
}
|
|
1232
|
-
}, save = async (manifest) => {
|
|
1233
|
-
try {
|
|
1234
|
-
let content = JSON.stringify(manifest, null, 4);
|
|
1235
|
-
await (0, import_promises.writeFile)(manifestPath, content, "utf8");
|
|
1236
|
-
} catch (error2) {
|
|
1237
|
-
throw error2 instanceof Error ? new Error(`Error saving manifest.json: ${error2.message}`) : new Error("Error saving manifest");
|
|
1238
|
-
}
|
|
1239
|
-
}, update = async (updates) => {
|
|
1240
|
-
let updatedManifest = { ...await load(), ...updates };
|
|
1241
|
-
return await save(updatedManifest), updatedManifest;
|
|
1242
|
-
}, manifestManager = {
|
|
1243
|
-
load,
|
|
1244
|
-
loadRaw,
|
|
1245
|
-
validate,
|
|
1246
|
-
save,
|
|
1247
|
-
update
|
|
1248
|
-
};
|
|
2158
|
+
var import_fs10 = __toESM(require("fs")), import_path12 = __toESM(require("path"));
|
|
2159
|
+
init_manifestManager();
|
|
1249
2160
|
|
|
1250
2161
|
// src/core/s3config/constants.ts
|
|
1251
2162
|
var CONFIG_FILE_NAME = "config.json";
|
|
1252
2163
|
|
|
1253
2164
|
// src/commands/debug/index.ts
|
|
2165
|
+
init_meta2();
|
|
2166
|
+
init_execCommand();
|
|
1254
2167
|
init_logger();
|
|
1255
2168
|
|
|
1256
2169
|
// src/utils/registerCleanup.ts
|
|
@@ -1262,8 +2175,12 @@ var registerCleanup = (cleanup) => {
|
|
|
1262
2175
|
});
|
|
1263
2176
|
};
|
|
1264
2177
|
|
|
2178
|
+
// src/commands/debug/index.ts
|
|
2179
|
+
init_templateCommands();
|
|
2180
|
+
|
|
1265
2181
|
// src/commands/debug/utils/createDebugConfig.ts
|
|
1266
|
-
var
|
|
2182
|
+
var import_fs7 = __toESM(require("fs")), import_path9 = __toESM(require("path"));
|
|
2183
|
+
init_manifestManager();
|
|
1267
2184
|
|
|
1268
2185
|
// src/utils/convertManifestToConfig.ts
|
|
1269
2186
|
function buildPluginDownloadUrl(env, id, version) {
|
|
@@ -1292,6 +2209,7 @@ var convertManifestToConfig = (manifest, environment) => {
|
|
|
1292
2209
|
description: slotConfig.description,
|
|
1293
2210
|
entrypoint: slotConfig.entrypoint,
|
|
1294
2211
|
title: slotConfig.title,
|
|
2212
|
+
contextLevel: slotConfig.contextLevel,
|
|
1295
2213
|
downloadUrl: buildPluginDownloadUrl(
|
|
1296
2214
|
environment,
|
|
1297
2215
|
manifest.slug,
|
|
@@ -1308,21 +2226,21 @@ var convertManifestToConfig = (manifest, environment) => {
|
|
|
1308
2226
|
|
|
1309
2227
|
// src/commands/debug/utils/createDebugConfig.ts
|
|
1310
2228
|
var createDebugConfig = async () => {
|
|
1311
|
-
let manifest = await manifestManager.load(), config = convertManifestToConfig(manifest, "debug"), configPath =
|
|
1312
|
-
|
|
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");
|
|
1313
2231
|
};
|
|
1314
2232
|
|
|
1315
2233
|
// src/commands/debug/utils/lockFile.ts
|
|
1316
|
-
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 = () => {
|
|
1317
2235
|
let lockPath = getLockFilePath();
|
|
1318
|
-
if (!
|
|
2236
|
+
if (!import_fs8.default.existsSync(lockPath))
|
|
1319
2237
|
return null;
|
|
1320
2238
|
try {
|
|
1321
|
-
let pid = JSON.parse(
|
|
2239
|
+
let pid = JSON.parse(import_fs8.default.readFileSync(lockPath, "utf-8")).pid;
|
|
1322
2240
|
return process.kill(pid, 0), pid;
|
|
1323
2241
|
} catch {
|
|
1324
2242
|
try {
|
|
1325
|
-
|
|
2243
|
+
import_fs8.default.unlinkSync(lockPath);
|
|
1326
2244
|
} catch {
|
|
1327
2245
|
}
|
|
1328
2246
|
return null;
|
|
@@ -1330,18 +2248,19 @@ var import_fs4 = __toESM(require("fs")), import_path6 = __toESM(require("path"))
|
|
|
1330
2248
|
}, createLockFile = () => {
|
|
1331
2249
|
let lockPath = getLockFilePath(), lockData = {
|
|
1332
2250
|
pid: process.pid
|
|
1333
|
-
}, fd =
|
|
1334
|
-
|
|
2251
|
+
}, fd = import_fs8.default.openSync(lockPath, "wx");
|
|
2252
|
+
import_fs8.default.writeSync(fd, JSON.stringify(lockData, null, 2)), import_fs8.default.closeSync(fd);
|
|
1335
2253
|
}, removeLockFile = () => {
|
|
1336
2254
|
let lockPath = getLockFilePath();
|
|
1337
|
-
|
|
2255
|
+
import_fs8.default.existsSync(lockPath) && import_fs8.default.unlinkSync(lockPath);
|
|
1338
2256
|
};
|
|
1339
2257
|
|
|
1340
2258
|
// src/commands/debug/utils/watchManifest.ts
|
|
1341
|
-
var
|
|
2259
|
+
var import_fs9 = __toESM(require("fs")), import_path11 = __toESM(require("path"));
|
|
2260
|
+
init_manifestManager();
|
|
1342
2261
|
init_logger();
|
|
1343
2262
|
var watchManifest = () => {
|
|
1344
|
-
let manifestPath2 =
|
|
2263
|
+
let manifestPath2 = import_path11.default.join(process.cwd(), "manifest.json"), debounceTimer = null, watcher = import_fs9.default.watch(manifestPath2, async (eventType) => {
|
|
1345
2264
|
eventType === "change" && (debounceTimer && clearTimeout(debounceTimer), debounceTimer = setTimeout(async () => {
|
|
1346
2265
|
try {
|
|
1347
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");
|
|
@@ -1365,53 +2284,71 @@ Please stop the existing instance before starting a new one.
|
|
|
1365
2284
|
If you lost the terminal tab, you can kill the process with:
|
|
1366
2285
|
kill ${runningPid}`
|
|
1367
2286
|
), process.exit(1));
|
|
1368
|
-
let configPath =
|
|
2287
|
+
let configPath = import_path12.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
1369
2288
|
options.lint && await manifestManager.validate(), await createDebugConfig();
|
|
1370
2289
|
let watcher = watchManifest(), cleanup = () => {
|
|
1371
|
-
watcher.close(),
|
|
2290
|
+
watcher.close(), import_fs10.default.existsSync(configPath) && import_fs10.default.unlinkSync(configPath), removeLockFile();
|
|
1372
2291
|
};
|
|
1373
|
-
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();
|
|
1374
2293
|
}
|
|
1375
2294
|
|
|
1376
2295
|
// src/commands/lint.ts
|
|
2296
|
+
init_manifestManager();
|
|
2297
|
+
init_execCommand();
|
|
1377
2298
|
init_logger();
|
|
2299
|
+
init_templateCommands();
|
|
1378
2300
|
async function lint() {
|
|
1379
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);
|
|
1380
2302
|
}
|
|
1381
2303
|
|
|
1382
2304
|
// src/commands/up/utils/copyTemplateFiles.ts
|
|
1383
|
-
var
|
|
2305
|
+
var import_fs11 = require("fs"), import_promises3 = require("fs/promises");
|
|
1384
2306
|
var copyTemplateFiles = async (filenames) => {
|
|
1385
2307
|
await Promise.all(
|
|
1386
2308
|
filenames.map(async (filename) => {
|
|
1387
2309
|
let templatePath = getTemplatePath(filename), targetPath = `./${filename}`;
|
|
1388
|
-
if ((0,
|
|
1389
|
-
let content = await (0,
|
|
1390
|
-
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);
|
|
1391
2313
|
}
|
|
1392
2314
|
})
|
|
1393
2315
|
);
|
|
1394
2316
|
};
|
|
1395
2317
|
|
|
1396
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
|
+
}
|
|
1397
2332
|
async function updateManifestCompatibility() {
|
|
1398
2333
|
let manifest = await manifestManager.load(), updates = {};
|
|
1399
|
-
"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);
|
|
1400
2337
|
}
|
|
1401
2338
|
|
|
1402
2339
|
// src/commands/up/utils/updatePackageDependencies.ts
|
|
1403
|
-
var
|
|
2340
|
+
var import_fs12 = require("fs"), import_promises4 = require("fs/promises");
|
|
1404
2341
|
var updatePackageDependencies = async (dependencies) => {
|
|
1405
2342
|
let packageJsonPath = "./package.json", templatePackageJsonPath = getTemplatePath("package.json");
|
|
1406
|
-
if (!(0,
|
|
2343
|
+
if (!(0, import_fs12.existsSync)(packageJsonPath) || !(0, import_fs12.existsSync)(templatePackageJsonPath))
|
|
1407
2344
|
return;
|
|
1408
|
-
let packageJsonContent = await (0,
|
|
2345
|
+
let packageJsonContent = await (0, import_promises4.readFile)(packageJsonPath, "utf-8"), templatePackageJsonRaw = await (0, import_promises4.readFile)(templatePackageJsonPath), templatePackageJsonContent = applySubstitutions2(
|
|
1409
2346
|
"package.json",
|
|
1410
2347
|
templatePackageJsonRaw
|
|
1411
2348
|
).toString("utf8"), packageJson = JSON.parse(packageJsonContent), templatePackageJson = JSON.parse(templatePackageJsonContent), updated = !1;
|
|
1412
2349
|
dependencies.forEach((dep) => {
|
|
1413
2350
|
packageJson.dependencies?.[dep] && templatePackageJson.dependencies?.[dep] && packageJson.dependencies[dep] !== templatePackageJson.dependencies[dep] && (packageJson.dependencies[dep] = templatePackageJson.dependencies[dep], updated = !0);
|
|
1414
|
-
}), updated && await (0,
|
|
2351
|
+
}), updated && await (0, import_promises4.writeFile)(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
1415
2352
|
`, "utf-8");
|
|
1416
2353
|
};
|
|
1417
2354
|
|
|
@@ -1422,34 +2359,25 @@ async function up() {
|
|
|
1422
2359
|
}
|
|
1423
2360
|
|
|
1424
2361
|
// src/utils/getVersion.ts
|
|
1425
|
-
var
|
|
1426
|
-
|
|
1427
|
-
let
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
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
|
+
}
|
|
1431
2371
|
}
|
|
1432
|
-
|
|
2372
|
+
return null;
|
|
2373
|
+
}, getVersion = () => findVersionInPackageJson(__dirname) ?? UNKNOWN_VERSION;
|
|
1433
2374
|
|
|
1434
2375
|
// src/index.ts
|
|
1435
2376
|
init_verbose();
|
|
1436
|
-
|
|
1437
|
-
// src/utils/withErrorHandling.ts
|
|
1438
|
-
init_logger();
|
|
1439
|
-
function withErrorHandling(fn) {
|
|
1440
|
-
return async (...args) => {
|
|
1441
|
-
try {
|
|
1442
|
-
await fn(...args);
|
|
1443
|
-
} catch (error2) {
|
|
1444
|
-
error2 instanceof Error && error2.name === "ExitPromptError" && process.exit(0), logger_default.error(error2), process.exit(1);
|
|
1445
|
-
}
|
|
1446
|
-
};
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
// src/index.ts
|
|
2377
|
+
init_withErrorHandling();
|
|
1450
2378
|
async function main() {
|
|
1451
|
-
let program = new
|
|
1452
|
-
await checkUpdate(version), program.name(CLI_NAME2).description(CLI_DESCRIPTION2).version(version), CLI_HELP_TEXT2 && program.addHelpText("before", CLI_HELP_TEXT2), program.hook("preAction", (thisCommand) => {
|
|
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) => {
|
|
1453
2381
|
setVerboseEnabled(!!thisCommand.opts().verbose);
|
|
1454
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(
|
|
1455
2383
|
"start a tunnel to connect your local code with the app running in the development environment"
|