@weavix/cli 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/build/index.js +3113 -1006
- package/build/templates/_external/npmrc.template +1 -0
- package/build/templates/{_shared/src/styles-360.scss → _external/src/styles.scss} +14 -16
- package/build/templates/_internal/npmrc.template +3 -0
- package/build/templates/{_shared/src/styles-gravity.scss → _internal/src/styles.scss} +32 -11
- 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/AGENTS.md +53 -0
- package/build/templates/_shared/manifest.schema.json +255 -5
- package/build/templates/_shared/package.json +63 -65
- package/build/templates/_shared/proxy.ts +111 -0
- package/build/templates/_shared/src/main.tsx +2 -6
- 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 +5 -1
- package/build/templates/attachment.viewer.action/index.html +1 -1
- package/build/templates/attachment.viewer.action/src/App.tsx +14 -24
- package/build/templates/board.tab/index.html +14 -0
- package/build/templates/board.tab/src/App.tsx +27 -0
- package/build/templates/default/src/App.tsx +1 -1
- 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.editor.action/index.html +14 -0
- package/build/templates/goal.editor.action/src/App.tsx +56 -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 +6 -13
- 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 +5 -11
- package/build/templates/issue.editor.action/index.html +14 -0
- package/build/templates/issue.editor.action/src/App.tsx +56 -0
- package/build/templates/issue.tab/src/App.tsx +5 -12
- package/build/templates/navigation/src/App.tsx +2 -7
- 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.editor.action/index.html +14 -0
- package/build/templates/portfolio.editor.action/src/App.tsx +56 -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.editor.action/index.html +14 -0
- package/build/templates/project.editor.action/src/App.tsx +56 -0
- package/build/templates/project.tab/index.html +14 -0
- package/build/templates/project.tab/src/App.tsx +27 -0
- package/build/templates/queue.action/index.html +14 -0
- package/build/templates/queue.action/src/App.tsx +29 -0
- package/build/templates/queue.tab/index.html +14 -0
- package/build/templates/queue.tab/src/App.tsx +29 -0
- package/build/templates/trigger.action/index.html +1 -1
- package/build/templates/trigger.action/src/App.tsx +15 -21
- package/package.json +3 -1
- package/build/templates/_shared/npmrc.template +0 -2
package/build/index.js
CHANGED
|
@@ -26,82 +26,34 @@ 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, {
|
|
32
39
|
CLI_DESCRIPTION: () => CLI_DESCRIPTION,
|
|
33
40
|
CLI_HELP_TEXT: () => CLI_HELP_TEXT,
|
|
34
|
-
CLI_NAME: () => CLI_NAME
|
|
41
|
+
CLI_NAME: () => CLI_NAME,
|
|
42
|
+
CREATE_SERVICES: () => CREATE_SERVICES
|
|
35
43
|
});
|
|
36
|
-
var CLI_NAME, CLI_DESCRIPTION, CLI_HELP_TEXT, init_meta = __esm({
|
|
44
|
+
var CLI_NAME, CLI_DESCRIPTION, CLI_HELP_TEXT, CREATE_SERVICES, init_meta = __esm({
|
|
37
45
|
"src/distributions/external/meta.ts"() {
|
|
38
46
|
"use strict";
|
|
39
|
-
CLI_NAME = "weavix", CLI_DESCRIPTION = "Weavix CLI", CLI_HELP_TEXT = "";
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// src/utils/verbose.ts
|
|
44
|
-
function setVerboseEnabled(value) {
|
|
45
|
-
verboseEnabled = value;
|
|
46
|
-
}
|
|
47
|
-
function isVerboseEnabled() {
|
|
48
|
-
return verboseEnabled;
|
|
49
|
-
}
|
|
50
|
-
var verboseEnabled, init_verbose = __esm({
|
|
51
|
-
"src/utils/verbose.ts"() {
|
|
52
|
-
"use strict";
|
|
53
|
-
verboseEnabled = !1;
|
|
47
|
+
CLI_NAME = "weavix", CLI_DESCRIPTION = "Weavix CLI", CLI_HELP_TEXT = "", CREATE_SERVICES = ["tracker"];
|
|
54
48
|
}
|
|
55
49
|
});
|
|
56
50
|
|
|
57
|
-
// src/
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
function error(messageOrErr, err) {
|
|
62
|
-
let message = messageOrErr instanceof Error ? messageOrErr.message : messageOrErr;
|
|
63
|
-
console.error(import_picocolors.default.red(`\u274C ${message}`)), err instanceof Error && console.error(import_picocolors.default.red(err.message)), newLine();
|
|
64
|
-
}
|
|
65
|
-
function warning(message) {
|
|
66
|
-
console.warn(import_picocolors.default.yellow(`\u26A0\uFE0F ${message}`)), newLine();
|
|
67
|
-
}
|
|
68
|
-
function info(message) {
|
|
69
|
-
console.info(message), newLine();
|
|
70
|
-
}
|
|
71
|
-
function verbose(message) {
|
|
72
|
-
isVerboseEnabled() && (console.info(import_picocolors.default.dim(message)), newLine());
|
|
73
|
-
}
|
|
74
|
-
function suggest(command) {
|
|
75
|
-
console.info(`Run: ${command}`), newLine();
|
|
76
|
-
}
|
|
77
|
-
function newLine(count = 1) {
|
|
78
|
-
console.info(`
|
|
79
|
-
`.repeat(count - 1));
|
|
80
|
-
}
|
|
81
|
-
function separator(char = "\u2500", length = 60) {
|
|
82
|
-
console.info(import_picocolors.default.dim(char.repeat(length))), newLine();
|
|
83
|
-
}
|
|
84
|
-
function commands(title, data) {
|
|
85
|
-
newLine(), console.info(import_picocolors.default.bold(import_picocolors.default.cyan(`${title}:`))), newLine(), data.forEach((cmd) => {
|
|
86
|
-
console.info(import_picocolors.default.dim(" $ ") + import_picocolors.default.white(cmd));
|
|
87
|
-
}), newLine();
|
|
88
|
-
}
|
|
89
|
-
var import_picocolors, logger, logger_default, init_logger = __esm({
|
|
90
|
-
"src/utils/logger.ts"() {
|
|
51
|
+
// src/distribution/meta.ts
|
|
52
|
+
var impl, CLI_NAME2, CLI_DESCRIPTION2, CLI_HELP_TEXT2, CREATE_SERVICES2, init_meta2 = __esm({
|
|
53
|
+
"src/distribution/meta.ts"() {
|
|
91
54
|
"use strict";
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
logger = {
|
|
95
|
-
success,
|
|
96
|
-
error,
|
|
97
|
-
warning,
|
|
98
|
-
info,
|
|
99
|
-
verbose,
|
|
100
|
-
suggest,
|
|
101
|
-
newLine,
|
|
102
|
-
separator,
|
|
103
|
-
commands
|
|
104
|
-
}, logger_default = logger;
|
|
55
|
+
init_flag();
|
|
56
|
+
impl = (init_meta(), __toCommonJS(meta_exports)), { CLI_NAME: CLI_NAME2, CLI_DESCRIPTION: CLI_DESCRIPTION2, CLI_HELP_TEXT: CLI_HELP_TEXT2, CREATE_SERVICES: CREATE_SERVICES2 } = impl;
|
|
105
57
|
}
|
|
106
58
|
});
|
|
107
59
|
|
|
@@ -130,86 +82,178 @@ function clearConfig() {
|
|
|
130
82
|
var import_fs, os, import_path, CONFIG_DIR, CONFIG_FILE, cached, init_manager = __esm({
|
|
131
83
|
"src/core/cliConfig/manager.ts"() {
|
|
132
84
|
"use strict";
|
|
133
|
-
import_fs = require("fs"), os = __toESM(require("os")), import_path = __toESM(require("path")), CONFIG_DIR = import_path.default.join(os.homedir(), ".
|
|
85
|
+
import_fs = require("fs"), os = __toESM(require("os")), import_path = __toESM(require("path")), CONFIG_DIR = import_path.default.join(os.homedir(), ".yaweavix"), CONFIG_FILE = import_path.default.join(CONFIG_DIR, "config.json");
|
|
134
86
|
}
|
|
135
87
|
});
|
|
136
88
|
|
|
137
|
-
// src/core/
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
89
|
+
// src/core/doctor/policy.ts
|
|
90
|
+
function createDoctorPolicy(options) {
|
|
91
|
+
let publish = !!options.publish, publishOnlyStatus = publish ? "fail" : "warn";
|
|
92
|
+
return {
|
|
93
|
+
mode: publish ? "publish" : "debug",
|
|
94
|
+
marketplaceAssetsStatus: publishOnlyStatus,
|
|
95
|
+
manifestPermissionsStatus: publishOnlyStatus,
|
|
96
|
+
manifestSupportStatus: publishOnlyStatus,
|
|
97
|
+
distMissingStatus: publishOnlyStatus,
|
|
98
|
+
authMissingStatus: publishOnlyStatus
|
|
99
|
+
};
|
|
144
100
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
), platformBaseUrl = await promptString(
|
|
160
|
-
"Platform API base URL",
|
|
161
|
-
existing.api?.platformBaseUrl
|
|
162
|
-
), oauthUrl = await promptString("OAuth token URL", existing.auth?.oauthUrl);
|
|
163
|
-
writeConfig({
|
|
164
|
-
s3: { endpoint: s3Endpoint, region: s3Region },
|
|
165
|
-
mds: { endpoint: mdsEndpoint },
|
|
166
|
-
buckets: {
|
|
167
|
-
production: { static: productionStatic, config: productionConfig }
|
|
101
|
+
var init_policy = __esm({
|
|
102
|
+
"src/core/doctor/policy.ts"() {
|
|
103
|
+
"use strict";
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// src/core/doctor/report.ts
|
|
108
|
+
function createDoctorReport() {
|
|
109
|
+
return {
|
|
110
|
+
ok: !1,
|
|
111
|
+
summary: {
|
|
112
|
+
passed: 0,
|
|
113
|
+
warnings: 0,
|
|
114
|
+
failures: 0
|
|
168
115
|
},
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
auth: { oauthUrl }
|
|
172
|
-
}), logger_default.success(`Configuration saved \u2192 ${getConfigPath()}`), logger_default.info(`Inspect with "${cliName} config show" or revert with "${cliName} config clear".`);
|
|
116
|
+
checks: []
|
|
117
|
+
};
|
|
173
118
|
}
|
|
174
|
-
function
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
);
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
logger_default.info(`Configuration at ${getConfigPath()}:`), logger_default.info(JSON.stringify(cfg, null, 2));
|
|
119
|
+
function addCheck(report, check) {
|
|
120
|
+
report.checks.push({
|
|
121
|
+
...check,
|
|
122
|
+
status: check.status || "pass"
|
|
123
|
+
});
|
|
183
124
|
}
|
|
184
|
-
function
|
|
185
|
-
|
|
125
|
+
function updateSummary(report) {
|
|
126
|
+
let passed = report.checks.filter((check) => check.status === "pass").length, warnings = report.checks.filter((check) => check.status === "warn").length, failures = report.checks.filter((check) => check.status === "fail").length;
|
|
127
|
+
report.summary = {
|
|
128
|
+
passed,
|
|
129
|
+
warnings,
|
|
130
|
+
failures
|
|
131
|
+
}, report.ok = failures === 0;
|
|
186
132
|
}
|
|
187
|
-
function
|
|
188
|
-
let
|
|
189
|
-
|
|
133
|
+
function statusBadge(status) {
|
|
134
|
+
let display = STATUS_DISPLAY[status];
|
|
135
|
+
return `${display.icon} [${display.label}]`;
|
|
190
136
|
}
|
|
191
|
-
|
|
192
|
-
"
|
|
137
|
+
function formatReport(report) {
|
|
138
|
+
let lines = ["Tracker Plugin Doctor", ""];
|
|
139
|
+
report.distribution && lines.push(`Distribution: ${report.distribution}`), report.mode && lines.push(`Mode: ${report.mode}`), report.projectRoot && lines.push(`Project root: ${report.projectRoot}`), report.manifestPath && lines.push(`Manifest path: ${report.manifestPath}`), report.manifest && lines.push(`Manifest: ${report.manifest.slug}@${report.manifest.version}`), report.packageManager && lines.push(`Package manager: ${report.packageManager}`), lines.push("", "Checks:");
|
|
140
|
+
for (let check of report.checks)
|
|
141
|
+
lines.push(` ${statusBadge(check.status)} ${check.title}: ${check.message}`), check.action && lines.push(` Action: ${check.action}`);
|
|
142
|
+
return lines.push(
|
|
143
|
+
"",
|
|
144
|
+
`Summary: \u2713 ${report.summary.passed} passed, \u26A0 ${report.summary.warnings} warning(s), \u2717 ${report.summary.failures} failure(s).`
|
|
145
|
+
), lines.push(
|
|
146
|
+
report.ok ? report.summary.warnings > 0 ? "\u26A0 Doctor finished with warnings." : "\u2713 Doctor finished successfully." : report.mode === "publish" ? "\u2717 Doctor failed. Fix failed checks before publishing." : "\u2717 Doctor failed. Fix failed checks before local debug or build."
|
|
147
|
+
), `${lines.join(`
|
|
148
|
+
`)}
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
function writeStdout(content) {
|
|
152
|
+
return new Promise((resolve2, reject) => {
|
|
153
|
+
process.stdout.write(content, (error2) => {
|
|
154
|
+
if (error2) {
|
|
155
|
+
reject(error2);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
resolve2();
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async function finishDoctor(report, options) {
|
|
163
|
+
updateSummary(report), await writeStdout(options.json ? `${JSON.stringify(report, null, 4)}
|
|
164
|
+
` : formatReport(report)), report.ok || (process.exitCode = 1);
|
|
165
|
+
}
|
|
166
|
+
var STATUS_DISPLAY, init_report = __esm({
|
|
167
|
+
"src/core/doctor/report.ts"() {
|
|
193
168
|
"use strict";
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
169
|
+
STATUS_DISPLAY = {
|
|
170
|
+
pass: { icon: "\u2713", label: "PASS" },
|
|
171
|
+
warn: { icon: "\u26A0", label: "WARN" },
|
|
172
|
+
fail: { icon: "\u2717", label: "FAIL" }
|
|
173
|
+
};
|
|
197
174
|
}
|
|
198
175
|
});
|
|
199
176
|
|
|
200
|
-
// src/
|
|
201
|
-
var
|
|
202
|
-
|
|
203
|
-
|
|
177
|
+
// src/core/auth/keyringAuthStorage.ts
|
|
178
|
+
var fs, import_keyring, parseAuthData, readLegacyAuthData, removeLegacyAuthData, createKeyringAuthStorage, init_keyringAuthStorage = __esm({
|
|
179
|
+
"src/core/auth/keyringAuthStorage.ts"() {
|
|
180
|
+
"use strict";
|
|
181
|
+
fs = __toESM(require("fs")), import_keyring = require("@napi-rs/keyring"), parseAuthData = (value) => !value || typeof value != "object" || !("token" in value) || typeof value.token != "string" || !value.token ? null : {
|
|
182
|
+
token: value.token
|
|
183
|
+
}, readLegacyAuthData = (legacyAuthFile) => {
|
|
184
|
+
try {
|
|
185
|
+
if (!fs.existsSync(legacyAuthFile))
|
|
186
|
+
return null;
|
|
187
|
+
let data = fs.readFileSync(legacyAuthFile, "utf-8");
|
|
188
|
+
return parseAuthData(JSON.parse(data));
|
|
189
|
+
} catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
}, removeLegacyAuthData = (legacyAuthFile) => {
|
|
193
|
+
try {
|
|
194
|
+
fs.existsSync(legacyAuthFile) && fs.unlinkSync(legacyAuthFile);
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
}, createKeyringAuthStorage = ({
|
|
198
|
+
service,
|
|
199
|
+
account,
|
|
200
|
+
legacyAuthFile
|
|
201
|
+
}) => {
|
|
202
|
+
let createEntry = () => new import_keyring.Entry(service, account);
|
|
203
|
+
return {
|
|
204
|
+
getData: () => {
|
|
205
|
+
try {
|
|
206
|
+
let token = createEntry().getPassword();
|
|
207
|
+
if (token)
|
|
208
|
+
return { token };
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
let legacyAuthData = readLegacyAuthData(legacyAuthFile);
|
|
213
|
+
if (!legacyAuthData)
|
|
214
|
+
return null;
|
|
215
|
+
try {
|
|
216
|
+
createEntry().setPassword(legacyAuthData.token), removeLegacyAuthData(legacyAuthFile);
|
|
217
|
+
} catch {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
return legacyAuthData;
|
|
221
|
+
},
|
|
222
|
+
saveAuthData: (token) => {
|
|
223
|
+
createEntry().setPassword(token), removeLegacyAuthData(legacyAuthFile);
|
|
224
|
+
},
|
|
225
|
+
removeAuthData: () => {
|
|
226
|
+
try {
|
|
227
|
+
createEntry().deletePassword();
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
removeLegacyAuthData(legacyAuthFile);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
}
|
|
204
235
|
});
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
"src/distributions/external/registerCommands.ts"() {
|
|
236
|
+
|
|
237
|
+
// src/distributions/external/authManager.ts
|
|
238
|
+
var os2, path2, authFile, authStorage, getToken, externalAuthManager, init_authManager = __esm({
|
|
239
|
+
"src/distributions/external/authManager.ts"() {
|
|
210
240
|
"use strict";
|
|
211
|
-
|
|
212
|
-
|
|
241
|
+
os2 = __toESM(require("os")), path2 = __toESM(require("path"));
|
|
242
|
+
init_keyringAuthStorage();
|
|
243
|
+
authFile = path2.join(os2.homedir(), ".weavix", "auth.json"), authStorage = createKeyringAuthStorage({
|
|
244
|
+
service: "weavix",
|
|
245
|
+
account: "oauth-token",
|
|
246
|
+
legacyAuthFile: authFile
|
|
247
|
+
}), getToken = () => authStorage.getData()?.token ?? null, externalAuthManager = {
|
|
248
|
+
get token() {
|
|
249
|
+
return getToken();
|
|
250
|
+
},
|
|
251
|
+
get data() {
|
|
252
|
+
return authStorage.getData();
|
|
253
|
+
},
|
|
254
|
+
saveAuthData: authStorage.saveAuthData,
|
|
255
|
+
removeAuthData: authStorage.removeAuthData
|
|
256
|
+
};
|
|
213
257
|
}
|
|
214
258
|
});
|
|
215
259
|
|
|
@@ -291,290 +335,2844 @@ var TRACKER_BASE_URL, init_hosts = __esm({
|
|
|
291
335
|
"src/distributions/external/hosts.ts"() {
|
|
292
336
|
"use strict";
|
|
293
337
|
init_manager();
|
|
294
|
-
TRACKER_BASE_URL = "https://tracker.yandex.
|
|
338
|
+
TRACKER_BASE_URL = "https://api.tracker.yandex.net/v3";
|
|
295
339
|
}
|
|
296
340
|
});
|
|
297
341
|
|
|
298
|
-
// src/distributions/external/
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
342
|
+
// src/distributions/external/trackerApiRequest.ts
|
|
343
|
+
function buildQueryString(queryParams) {
|
|
344
|
+
if (!queryParams || Object.keys(queryParams).length === 0)
|
|
345
|
+
return "";
|
|
346
|
+
let params = new URLSearchParams();
|
|
347
|
+
return Object.entries(queryParams).forEach(([key, value]) => {
|
|
348
|
+
params.append(key, String(value));
|
|
349
|
+
}), `?${params.toString()}`;
|
|
350
|
+
}
|
|
351
|
+
async function parseResponse(response) {
|
|
352
|
+
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();
|
|
353
|
+
}
|
|
354
|
+
async function externalTrackerApiRequest(endpoint, options = {}) {
|
|
355
|
+
let { method = "GET", body, headers = {}, formData, queryParams } = options, token = externalAuthManager.token;
|
|
356
|
+
if (!token)
|
|
357
|
+
throw new Error(`Not authenticated. Run "${CLI_NAME} login" first.`);
|
|
358
|
+
let requestHeaders = {
|
|
359
|
+
Authorization: `OAuth ${token}`,
|
|
360
|
+
"X-Org-ID": ORG_ID,
|
|
361
|
+
Accept: "application/json",
|
|
362
|
+
...headers
|
|
363
|
+
}, requestBody;
|
|
364
|
+
if (formData) {
|
|
365
|
+
let formHeaders = formData.getHeaders?.();
|
|
366
|
+
Object.assign(requestHeaders, formHeaders), requestBody = formData;
|
|
367
|
+
} else body && method !== "GET" && (requestHeaders["Content-Type"] = "application/json", requestBody = JSON.stringify(body));
|
|
368
|
+
let queryString = buildQueryString(queryParams), url = `${TRACKER_BASE_URL2}${endpoint}${queryString}`, response = await (0, import_node_fetch.default)(url, {
|
|
369
|
+
method,
|
|
370
|
+
headers: requestHeaders,
|
|
371
|
+
body: requestBody
|
|
372
|
+
});
|
|
373
|
+
if (!response.ok) {
|
|
374
|
+
let errorText = await response.text(), errorMessage = `Tracker API error ${response.status}: ${errorText}`;
|
|
375
|
+
try {
|
|
376
|
+
let errorJson = JSON.parse(errorText);
|
|
377
|
+
errorJson.message && (errorMessage = `Tracker API error ${response.status}: ${errorJson.message}`);
|
|
378
|
+
} catch {
|
|
313
379
|
}
|
|
314
|
-
|
|
315
|
-
name in next || (next[name] = version);
|
|
316
|
-
pkg.dependencies = Object.fromEntries(
|
|
317
|
-
Object.entries(next).sort(([a], [b]) => a.localeCompare(b))
|
|
318
|
-
);
|
|
380
|
+
throw new Error(errorMessage);
|
|
319
381
|
}
|
|
320
|
-
return
|
|
321
|
-
`;
|
|
382
|
+
return parseResponse(response);
|
|
322
383
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
384
|
+
var import_node_fetch, TRACKER_BASE_URL2, ORG_ID, init_trackerApiRequest = __esm({
|
|
385
|
+
"src/distributions/external/trackerApiRequest.ts"() {
|
|
386
|
+
"use strict";
|
|
387
|
+
import_node_fetch = __toESM(require("node-fetch"));
|
|
388
|
+
init_authManager();
|
|
389
|
+
init_meta();
|
|
390
|
+
TRACKER_BASE_URL2 = "https://api.tracker.yandex.net/v3", ORG_ID = "8470884";
|
|
328
391
|
}
|
|
329
|
-
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// src/distributions/external/doctorChecks.ts
|
|
395
|
+
var doctorChecks_exports = {};
|
|
396
|
+
__export(doctorChecks_exports, {
|
|
397
|
+
checkDistribution: () => checkDistribution
|
|
398
|
+
});
|
|
399
|
+
function checkCliConfig(report) {
|
|
400
|
+
let config = readConfig(), configPath = getConfigPath();
|
|
401
|
+
if (config) {
|
|
402
|
+
addCheck(report, {
|
|
403
|
+
id: "distribution.config",
|
|
404
|
+
title: "CLI config",
|
|
405
|
+
message: `External CLI config is readable at ${configPath}.`,
|
|
406
|
+
data: {
|
|
407
|
+
configPath
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
addCheck(report, {
|
|
413
|
+
id: "distribution.config",
|
|
414
|
+
title: "CLI config",
|
|
415
|
+
status: "fail",
|
|
416
|
+
message: `External CLI config is missing at ${configPath}.`,
|
|
417
|
+
action: "Run weavix config set before using external distribution commands.",
|
|
418
|
+
data: {
|
|
419
|
+
configPath
|
|
420
|
+
}
|
|
421
|
+
});
|
|
330
422
|
}
|
|
331
|
-
function
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
423
|
+
function checkHostResolution(report) {
|
|
424
|
+
try {
|
|
425
|
+
let data = {
|
|
426
|
+
trackerBaseUrl: getTrackerBaseUrl(),
|
|
427
|
+
platformBaseUrl: getPlatformBaseUrl(),
|
|
428
|
+
s3Endpoint: getS3Endpoint(),
|
|
429
|
+
mdsEndpoint: getMdsEndpoint(),
|
|
430
|
+
s3Region: getS3Region(),
|
|
431
|
+
buckets: getBuckets(),
|
|
432
|
+
pluginDownloadBase: getPluginDownloadBase("production")
|
|
433
|
+
};
|
|
434
|
+
addCheck(report, {
|
|
435
|
+
id: "distribution.hosts",
|
|
436
|
+
title: "External host configuration",
|
|
437
|
+
message: "External host configuration resolved.",
|
|
438
|
+
data
|
|
439
|
+
});
|
|
440
|
+
} catch (error2) {
|
|
441
|
+
addCheck(report, {
|
|
442
|
+
id: "distribution.hosts",
|
|
443
|
+
title: "External host configuration",
|
|
444
|
+
status: "fail",
|
|
445
|
+
message: error2 instanceof Error ? error2.message : String(error2),
|
|
446
|
+
action: "Run weavix config set and fill required endpoints."
|
|
447
|
+
});
|
|
448
|
+
}
|
|
338
449
|
}
|
|
339
|
-
function
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
450
|
+
async function checkExternalAuth(report, {
|
|
451
|
+
required,
|
|
452
|
+
useNetwork
|
|
453
|
+
}) {
|
|
454
|
+
let authData = externalAuthManager.data, authStatus = required || useNetwork ? "fail" : "warn";
|
|
455
|
+
if (!authData) {
|
|
456
|
+
addCheck(report, {
|
|
457
|
+
id: "auth.tracker",
|
|
458
|
+
title: "Tracker auth",
|
|
459
|
+
status: authStatus,
|
|
460
|
+
message: "External Tracker auth token is missing in the system credential store.",
|
|
461
|
+
action: "Run weavix login before submit or network diagnostics.",
|
|
462
|
+
data: {
|
|
463
|
+
storage: "system credential store"
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
if (addCheck(report, {
|
|
469
|
+
id: "auth.tracker",
|
|
470
|
+
title: "Tracker auth",
|
|
471
|
+
message: "External Tracker auth token is available in the system credential store.",
|
|
472
|
+
data: {
|
|
473
|
+
storage: "system credential store"
|
|
474
|
+
}
|
|
475
|
+
}), !!useNetwork)
|
|
476
|
+
try {
|
|
477
|
+
await externalTrackerApiRequest("/myself"), addCheck(report, {
|
|
478
|
+
id: "auth.tracker.network",
|
|
479
|
+
title: "Tracker auth network",
|
|
480
|
+
message: "Verified external Tracker auth with /myself."
|
|
481
|
+
});
|
|
482
|
+
} catch (error2) {
|
|
483
|
+
addCheck(report, {
|
|
484
|
+
id: "auth.tracker.network",
|
|
485
|
+
title: "Tracker auth network",
|
|
486
|
+
status: "fail",
|
|
487
|
+
message: error2 instanceof Error ? error2.message : String(error2),
|
|
488
|
+
action: "Check network access, org access, and rerun weavix login."
|
|
489
|
+
});
|
|
490
|
+
}
|
|
343
491
|
}
|
|
344
|
-
function
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
|
|
353
|
-
let text = content.toString("utf8"), rewritten = rewriteImports(text);
|
|
354
|
-
if (rewritten !== text)
|
|
355
|
-
return Buffer.from(rewritten, "utf8");
|
|
356
|
-
}
|
|
357
|
-
return content;
|
|
358
|
-
}
|
|
359
|
-
var import_path2, PACKAGE_RENAME, PACKAGE_DROP, ADDED_DEPS, templateDeps, init_templateSubstitution = __esm({
|
|
360
|
-
"src/distributions/external/templateSubstitution.ts"() {
|
|
492
|
+
async function checkDistribution(report, _projectRoot, options, policy = createDoctorPolicy(options)) {
|
|
493
|
+
report.distribution = DISTRIBUTION, checkCliConfig(report), checkHostResolution(report), await checkExternalAuth(report, {
|
|
494
|
+
required: policy.authMissingStatus === "fail",
|
|
495
|
+
useNetwork: !!options.network
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
var DISTRIBUTION, init_doctorChecks = __esm({
|
|
499
|
+
"src/distributions/external/doctorChecks.ts"() {
|
|
361
500
|
"use strict";
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}, templateDeps = ["@weavix/sdk-core", "@weavix/sdk-react", "@weavix/tracker-api-types"];
|
|
501
|
+
init_manager();
|
|
502
|
+
init_policy();
|
|
503
|
+
init_report();
|
|
504
|
+
init_authManager();
|
|
505
|
+
init_hosts();
|
|
506
|
+
init_trackerApiRequest();
|
|
507
|
+
DISTRIBUTION = "external";
|
|
370
508
|
}
|
|
371
509
|
});
|
|
372
510
|
|
|
373
|
-
// src/
|
|
374
|
-
var
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
// src/utils/checkUpdate.ts
|
|
383
|
-
var import_node_fetch = __toESM(require("node-fetch"));
|
|
384
|
-
|
|
385
|
-
// src/distribution/hosts.ts
|
|
386
|
-
var impl3 = (init_hosts(), __toCommonJS(hosts_exports)), {
|
|
387
|
-
getS3Endpoint: getS3Endpoint2,
|
|
388
|
-
getMdsEndpoint: getMdsEndpoint2,
|
|
389
|
-
getS3Region: getS3Region2,
|
|
390
|
-
getBuckets: getBuckets2,
|
|
391
|
-
getPluginDownloadBase: getPluginDownloadBase2,
|
|
392
|
-
getPlatformBaseUrl: getPlatformBaseUrl2,
|
|
393
|
-
getTrackerBaseUrl: getTrackerBaseUrl2,
|
|
394
|
-
getOAuthTokenUrl: getOAuthTokenUrl2,
|
|
395
|
-
getUpdateCheckInfo: getUpdateCheckInfo2
|
|
396
|
-
} = impl3;
|
|
511
|
+
// src/distribution/doctorChecks.ts
|
|
512
|
+
var impl2, checkDistribution2, init_doctorChecks2 = __esm({
|
|
513
|
+
"src/distribution/doctorChecks.ts"() {
|
|
514
|
+
"use strict";
|
|
515
|
+
init_flag();
|
|
516
|
+
impl2 = (init_doctorChecks(), __toCommonJS(doctorChecks_exports)), { checkDistribution: checkDistribution2 } = impl2;
|
|
517
|
+
}
|
|
518
|
+
});
|
|
397
519
|
|
|
398
|
-
// src/
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
520
|
+
// src/core/doctor/distChecks.ts
|
|
521
|
+
function resolveDistEntrypoint(distDir, entrypoint) {
|
|
522
|
+
if (import_path2.default.isAbsolute(entrypoint))
|
|
523
|
+
return {
|
|
524
|
+
error: `${entrypoint} is absolute`
|
|
525
|
+
};
|
|
526
|
+
let filePath = import_path2.default.resolve(distDir, import_path2.default.normalize(entrypoint)), relative = import_path2.default.relative(distDir, filePath);
|
|
527
|
+
return relative.startsWith("..") || import_path2.default.isAbsolute(relative) ? {
|
|
528
|
+
error: `${entrypoint} escapes dist`
|
|
529
|
+
} : {
|
|
530
|
+
filePath
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
async function checkDist(report, projectRoot, entries, policy) {
|
|
534
|
+
let distDir = import_path2.default.join(projectRoot, "dist");
|
|
535
|
+
if (!import_fs2.default.existsSync(distDir)) {
|
|
536
|
+
addCheck(report, {
|
|
537
|
+
id: "dist.exists",
|
|
538
|
+
title: "dist directory",
|
|
539
|
+
status: policy.distMissingStatus,
|
|
540
|
+
message: "dist directory is missing.",
|
|
541
|
+
action: "Run the plugin build before publishing."
|
|
542
|
+
});
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
if (!import_fs2.default.statSync(distDir).isDirectory()) {
|
|
546
|
+
addCheck(report, {
|
|
547
|
+
id: "dist.exists",
|
|
548
|
+
title: "dist directory",
|
|
549
|
+
status: "fail",
|
|
550
|
+
message: `${distDir} exists but is not a directory.`,
|
|
551
|
+
action: "Remove it and run the plugin build."
|
|
552
|
+
});
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
let files = await (0, import_tinyglobby.glob)(["**/*"], {
|
|
556
|
+
cwd: distDir,
|
|
557
|
+
onlyFiles: !0,
|
|
558
|
+
absolute: !0
|
|
559
|
+
});
|
|
560
|
+
files.length === 0 ? addCheck(report, {
|
|
561
|
+
id: "dist.files",
|
|
562
|
+
title: "dist files",
|
|
563
|
+
status: "fail",
|
|
564
|
+
message: "dist directory is empty.",
|
|
565
|
+
action: "Run the plugin build and verify generated files."
|
|
566
|
+
}) : addCheck(report, {
|
|
567
|
+
id: "dist.files",
|
|
568
|
+
title: "dist files",
|
|
569
|
+
message: `dist contains ${files.length} file(s).`
|
|
570
|
+
});
|
|
571
|
+
let entrypoints = [...new Set(entries.map((entry) => entry.entrypoint))], invalidEntrypoints = [], missingEntrypoints = [];
|
|
572
|
+
for (let entrypoint of entrypoints) {
|
|
573
|
+
let resolved = resolveDistEntrypoint(distDir, entrypoint);
|
|
574
|
+
if (resolved.error || !resolved.filePath) {
|
|
575
|
+
invalidEntrypoints.push(
|
|
576
|
+
resolved.error ? `${entrypoint} (${resolved.error})` : entrypoint
|
|
577
|
+
);
|
|
578
|
+
continue;
|
|
413
579
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
580
|
+
(!import_fs2.default.existsSync(resolved.filePath) || !import_fs2.default.statSync(resolved.filePath).isFile()) && missingEntrypoints.push(entrypoint);
|
|
581
|
+
}
|
|
582
|
+
invalidEntrypoints.length > 0 ? addCheck(report, {
|
|
583
|
+
id: "dist.entrypoints.valid",
|
|
584
|
+
title: "Built entrypoint paths",
|
|
585
|
+
status: "fail",
|
|
586
|
+
message: `Invalid entrypoint path(s): ${invalidEntrypoints.join(", ")}.`,
|
|
587
|
+
action: "Use relative entrypoint paths inside dist, for example index.html."
|
|
588
|
+
}) : entrypoints.length > 0 && addCheck(report, {
|
|
589
|
+
id: "dist.entrypoints.valid",
|
|
590
|
+
title: "Built entrypoint paths",
|
|
591
|
+
message: "Manifest entrypoint paths stay inside dist."
|
|
592
|
+
}), missingEntrypoints.length > 0 ? addCheck(report, {
|
|
593
|
+
id: "dist.entrypoints.exist",
|
|
594
|
+
title: "Built entrypoints",
|
|
595
|
+
status: "fail",
|
|
596
|
+
message: `Missing built entrypoint file(s): ${missingEntrypoints.join(", ")}.`,
|
|
597
|
+
action: "Run the plugin build and keep manifest entrypoint values in sync."
|
|
598
|
+
}) : entrypoints.length > 0 && invalidEntrypoints.length === 0 && addCheck(report, {
|
|
599
|
+
id: "dist.entrypoints.exist",
|
|
600
|
+
title: "Built entrypoints",
|
|
601
|
+
message: "All manifest entrypoints exist in dist."
|
|
422
602
|
});
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
build: "npm run build",
|
|
432
|
-
dev: "npm run dev",
|
|
433
|
-
lint: "npm run lint"
|
|
434
|
-
};
|
|
603
|
+
}
|
|
604
|
+
var import_fs2, import_path2, import_tinyglobby, init_distChecks = __esm({
|
|
605
|
+
"src/core/doctor/distChecks.ts"() {
|
|
606
|
+
"use strict";
|
|
607
|
+
import_fs2 = __toESM(require("fs")), import_path2 = __toESM(require("path")), import_tinyglobby = require("tinyglobby");
|
|
608
|
+
init_report();
|
|
609
|
+
}
|
|
610
|
+
});
|
|
435
611
|
|
|
436
|
-
// src/
|
|
437
|
-
var
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
612
|
+
// ../tracker-core/src/types/slots.ts
|
|
613
|
+
var TRACKER_SLOTS, init_slots = __esm({
|
|
614
|
+
"../tracker-core/src/types/slots.ts"() {
|
|
615
|
+
"use strict";
|
|
616
|
+
TRACKER_SLOTS = [
|
|
617
|
+
"issue.action",
|
|
618
|
+
"issue.block",
|
|
619
|
+
"issue.tab",
|
|
620
|
+
"issue.comment.action",
|
|
621
|
+
"issue.editor.action",
|
|
622
|
+
"queue.action",
|
|
623
|
+
"queue.tab",
|
|
624
|
+
"navigation",
|
|
625
|
+
"trigger.create.action",
|
|
626
|
+
"trigger.edit.action",
|
|
627
|
+
"project.action",
|
|
628
|
+
"project.block",
|
|
629
|
+
"project.tab",
|
|
630
|
+
"project.editor.action",
|
|
631
|
+
"portfolio.action",
|
|
632
|
+
"portfolio.block",
|
|
633
|
+
"portfolio.tab",
|
|
634
|
+
"portfolio.editor.action",
|
|
635
|
+
"goal.action",
|
|
636
|
+
"goal.block",
|
|
637
|
+
"goal.tab",
|
|
638
|
+
"goal.editor.action",
|
|
639
|
+
"attachment.viewer.action",
|
|
640
|
+
"board.tab"
|
|
641
|
+
];
|
|
642
|
+
}
|
|
643
|
+
});
|
|
442
644
|
|
|
443
|
-
// src/
|
|
444
|
-
var
|
|
645
|
+
// ../tracker-core/src/index.ts
|
|
646
|
+
var init_src = __esm({
|
|
647
|
+
"../tracker-core/src/index.ts"() {
|
|
648
|
+
"use strict";
|
|
649
|
+
init_slots();
|
|
650
|
+
}
|
|
651
|
+
});
|
|
445
652
|
|
|
446
653
|
// src/core/manifest/constants.ts
|
|
447
|
-
var DATA_PERMISSIONS =
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
654
|
+
var DATA_PERMISSIONS, TOP_DATA_PERMISSIONS, SERVICES, TEMPLATES, CLI_ONLY_TRACKER_SLOTS, TRACKER_SERVICE_SLOTS, MESSENGER_SERVICE_SLOTS, SERVICE_SLOTS, TEMPLATE_SLOTS, TEMPLATE_SERVICE, init_constants = __esm({
|
|
655
|
+
"src/core/manifest/constants.ts"() {
|
|
656
|
+
"use strict";
|
|
657
|
+
init_src();
|
|
658
|
+
DATA_PERMISSIONS = [
|
|
659
|
+
// top 10
|
|
660
|
+
"tracker:issues:read",
|
|
661
|
+
"tracker:issues:write",
|
|
662
|
+
"tracker:issuetypes:read",
|
|
663
|
+
"tracker:statuses:read",
|
|
664
|
+
"tracker:queues:read",
|
|
665
|
+
"tracker:fields:read",
|
|
666
|
+
"tracker:entities:read",
|
|
667
|
+
"tracker:attachments:read",
|
|
668
|
+
"tracker:attachments:write",
|
|
669
|
+
// in alphabetical order
|
|
670
|
+
"tracker:applications:read",
|
|
671
|
+
"tracker:boards:read",
|
|
672
|
+
"tracker:boards:write",
|
|
673
|
+
"tracker:bulk:read",
|
|
674
|
+
"tracker:bulk:write",
|
|
675
|
+
"tracker:bulkchange:read",
|
|
676
|
+
"tracker:bulkchange:write",
|
|
677
|
+
"tracker:charts:read",
|
|
678
|
+
"tracker:commentTemplates:read",
|
|
679
|
+
"tracker:commentTemplates:write",
|
|
680
|
+
"tracker:components:read",
|
|
681
|
+
"tracker:components:write",
|
|
682
|
+
"tracker:data:read",
|
|
683
|
+
"tracker:departments:read",
|
|
684
|
+
"tracker:entities:write",
|
|
685
|
+
"tracker:externalEventTypes:write",
|
|
686
|
+
"tracker:externalEvents:write",
|
|
687
|
+
"tracker:fields:write",
|
|
688
|
+
"tracker:filterFolders:write",
|
|
689
|
+
"tracker:filters:read",
|
|
690
|
+
"tracker:filters:write",
|
|
691
|
+
"tracker:goals:read",
|
|
692
|
+
"tracker:goals:write",
|
|
693
|
+
"tracker:groups:read",
|
|
694
|
+
"tracker:issueTemplates:read",
|
|
695
|
+
"tracker:issueTemplates:write",
|
|
696
|
+
"tracker:links:read",
|
|
697
|
+
"tracker:linktypes:read",
|
|
698
|
+
"tracker:liveBoards:write",
|
|
699
|
+
"tracker:localFields:read",
|
|
700
|
+
"tracker:maillists:read",
|
|
701
|
+
"tracker:maillists:write",
|
|
702
|
+
"tracker:myself:read",
|
|
703
|
+
"tracker:myself:write",
|
|
704
|
+
"tracker:priorities:read",
|
|
705
|
+
"tracker:queues:write",
|
|
706
|
+
"tracker:reminders:read",
|
|
707
|
+
"tracker:reminders:write",
|
|
708
|
+
"tracker:remotelinks:read",
|
|
709
|
+
"tracker:reports:read",
|
|
710
|
+
"tracker:reports:write",
|
|
711
|
+
"tracker:resolutions:read",
|
|
712
|
+
"tracker:resources:read",
|
|
713
|
+
"tracker:resources:write",
|
|
714
|
+
"tracker:roles:read",
|
|
715
|
+
"tracker:screens:read",
|
|
716
|
+
"tracker:services:read",
|
|
717
|
+
"tracker:sprints:read",
|
|
718
|
+
"tracker:sprints:write",
|
|
719
|
+
"tracker:system:write",
|
|
720
|
+
"tracker:tags:read",
|
|
721
|
+
"tracker:translations:read",
|
|
722
|
+
"tracker:users:read",
|
|
723
|
+
"tracker:users:write",
|
|
724
|
+
"tracker:versions:read",
|
|
725
|
+
"tracker:versions:write",
|
|
726
|
+
"tracker:workflows:read",
|
|
727
|
+
"tracker:workflows:write",
|
|
728
|
+
"tracker:worklog:read",
|
|
729
|
+
"tracker:worklog:write"
|
|
730
|
+
], TOP_DATA_PERMISSIONS = DATA_PERMISSIONS.slice(0, 10), SERVICES = ["tracker", "messenger"], TEMPLATES = [
|
|
731
|
+
"default",
|
|
732
|
+
"issue.action",
|
|
733
|
+
"issue.block",
|
|
734
|
+
"issue.tab",
|
|
735
|
+
"issue.comment.action",
|
|
736
|
+
"issue.editor.action",
|
|
737
|
+
"queue.action",
|
|
738
|
+
"queue.tab",
|
|
739
|
+
"navigation",
|
|
740
|
+
"trigger.action",
|
|
741
|
+
"project.action",
|
|
742
|
+
"project.block",
|
|
743
|
+
"project.tab",
|
|
744
|
+
"project.editor.action",
|
|
745
|
+
"portfolio.action",
|
|
746
|
+
"portfolio.block",
|
|
747
|
+
"portfolio.tab",
|
|
748
|
+
"portfolio.editor.action",
|
|
749
|
+
"goal.action",
|
|
750
|
+
"goal.block",
|
|
751
|
+
"goal.tab",
|
|
752
|
+
"goal.editor.action",
|
|
753
|
+
"attachment.viewer.action",
|
|
754
|
+
"board.tab",
|
|
755
|
+
"user-card-info",
|
|
756
|
+
"user-card-calendar"
|
|
757
|
+
], CLI_ONLY_TRACKER_SLOTS = ["dock"], TRACKER_SERVICE_SLOTS = [...TRACKER_SLOTS, ...CLI_ONLY_TRACKER_SLOTS], MESSENGER_SERVICE_SLOTS = ["user.card.info"], SERVICE_SLOTS = [...TRACKER_SERVICE_SLOTS, ...MESSENGER_SERVICE_SLOTS], TEMPLATE_SLOTS = {
|
|
758
|
+
default: [],
|
|
759
|
+
"issue.action": ["issue.action"],
|
|
760
|
+
"issue.block": ["issue.block"],
|
|
761
|
+
"issue.tab": ["issue.tab"],
|
|
762
|
+
"issue.comment.action": ["issue.comment.action"],
|
|
763
|
+
"issue.editor.action": ["issue.editor.action"],
|
|
764
|
+
"queue.action": ["queue.action"],
|
|
765
|
+
"queue.tab": ["queue.tab"],
|
|
766
|
+
navigation: ["navigation"],
|
|
767
|
+
"trigger.action": ["trigger.create.action", "trigger.edit.action"],
|
|
768
|
+
"project.action": ["project.action"],
|
|
769
|
+
"project.block": ["project.block"],
|
|
770
|
+
"project.tab": ["project.tab"],
|
|
771
|
+
"project.editor.action": ["project.editor.action"],
|
|
772
|
+
"portfolio.action": ["portfolio.action"],
|
|
773
|
+
"portfolio.block": ["portfolio.block"],
|
|
774
|
+
"portfolio.tab": ["portfolio.tab"],
|
|
775
|
+
"portfolio.editor.action": ["portfolio.editor.action"],
|
|
776
|
+
"goal.action": ["goal.action"],
|
|
777
|
+
"goal.block": ["goal.block"],
|
|
778
|
+
"goal.tab": ["goal.tab"],
|
|
779
|
+
"goal.editor.action": ["goal.editor.action"],
|
|
780
|
+
"attachment.viewer.action": ["attachment.viewer.action"],
|
|
781
|
+
"board.tab": ["board.tab"],
|
|
782
|
+
"user-card-info": ["user.card.info"],
|
|
783
|
+
"user-card-calendar": ["user.card.info"]
|
|
784
|
+
}, TEMPLATE_SERVICE = {
|
|
785
|
+
default: "tracker",
|
|
786
|
+
"issue.action": "tracker",
|
|
787
|
+
"issue.block": "tracker",
|
|
788
|
+
"issue.tab": "tracker",
|
|
789
|
+
"issue.comment.action": "tracker",
|
|
790
|
+
"issue.editor.action": "tracker",
|
|
791
|
+
"queue.action": "tracker",
|
|
792
|
+
"queue.tab": "tracker",
|
|
793
|
+
navigation: "tracker",
|
|
794
|
+
"trigger.action": "tracker",
|
|
795
|
+
"project.action": "tracker",
|
|
796
|
+
"project.block": "tracker",
|
|
797
|
+
"project.tab": "tracker",
|
|
798
|
+
"project.editor.action": "tracker",
|
|
799
|
+
"portfolio.action": "tracker",
|
|
800
|
+
"portfolio.block": "tracker",
|
|
801
|
+
"portfolio.tab": "tracker",
|
|
802
|
+
"portfolio.editor.action": "tracker",
|
|
803
|
+
"goal.action": "tracker",
|
|
804
|
+
"goal.block": "tracker",
|
|
805
|
+
"goal.tab": "tracker",
|
|
806
|
+
"goal.editor.action": "tracker",
|
|
807
|
+
"attachment.viewer.action": "tracker",
|
|
808
|
+
"board.tab": "tracker",
|
|
809
|
+
"user-card-info": "messenger",
|
|
810
|
+
"user-card-calendar": "messenger"
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
// src/distributions/external/manifestPermissionsSchema.ts
|
|
816
|
+
var manifestPermissionsSchema_exports = {};
|
|
817
|
+
__export(manifestPermissionsSchema_exports, {
|
|
818
|
+
permissionsSchemaExtensions: () => permissionsSchemaExtensions
|
|
819
|
+
});
|
|
820
|
+
var permissionsSchemaExtensions, init_manifestPermissionsSchema = __esm({
|
|
821
|
+
"src/distributions/external/manifestPermissionsSchema.ts"() {
|
|
822
|
+
"use strict";
|
|
823
|
+
permissionsSchemaExtensions = {};
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
// src/distribution/manifestPermissionsSchema.ts
|
|
828
|
+
var impl3, permissionsSchemaExtensions2, init_manifestPermissionsSchema2 = __esm({
|
|
829
|
+
"src/distribution/manifestPermissionsSchema.ts"() {
|
|
830
|
+
"use strict";
|
|
831
|
+
init_flag();
|
|
832
|
+
impl3 = (init_manifestPermissionsSchema(), __toCommonJS(manifestPermissionsSchema_exports)), { permissionsSchemaExtensions: permissionsSchemaExtensions2 } = impl3;
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
// src/core/manifest/formatValidationErrors.ts
|
|
837
|
+
var priorityOrder, errorMessages, getPriority, formatValidationErrors, init_formatValidationErrors = __esm({
|
|
838
|
+
"src/core/manifest/formatValidationErrors.ts"() {
|
|
839
|
+
"use strict";
|
|
840
|
+
priorityOrder = [
|
|
841
|
+
"required",
|
|
842
|
+
"type",
|
|
843
|
+
"minLength",
|
|
844
|
+
"format",
|
|
845
|
+
"pattern",
|
|
846
|
+
"enum",
|
|
847
|
+
"additionalProperties",
|
|
848
|
+
"uniqueItems"
|
|
849
|
+
], errorMessages = {
|
|
850
|
+
required: (params) => `missing required property '${params.missingProperty}'`,
|
|
851
|
+
type: (params) => `must be ${params.type}`,
|
|
852
|
+
enum: (params) => `must be one of [${params.allowedValues.join(", ")}]`,
|
|
853
|
+
pattern: (params) => `must match pattern ${params.pattern}`,
|
|
854
|
+
format: (params) => `must be a valid ${params.format}`,
|
|
855
|
+
minLength: () => "must not be empty",
|
|
856
|
+
additionalProperties: (params) => `unexpected property '${params.additionalProperty}'`,
|
|
857
|
+
uniqueItems: () => "must contain unique items"
|
|
858
|
+
}, getPriority = (keyword) => {
|
|
859
|
+
let index = priorityOrder.indexOf(keyword);
|
|
860
|
+
return index === -1 ? priorityOrder.length : index;
|
|
861
|
+
}, formatValidationErrors = (errors) => {
|
|
862
|
+
let errorsByPath = {};
|
|
863
|
+
for (let error2 of errors) {
|
|
864
|
+
let path24 = error2.instancePath || "root";
|
|
865
|
+
errorsByPath[path24] || (errorsByPath[path24] = []), errorsByPath[path24].push(error2);
|
|
866
|
+
}
|
|
867
|
+
return Object.entries(errorsByPath).map(([path24, pathErrors]) => {
|
|
868
|
+
let error2 = [...pathErrors].sort(
|
|
869
|
+
(a, b) => getPriority(a.keyword) - getPriority(b.keyword)
|
|
870
|
+
)[0], formatter = errorMessages[error2.keyword], message = formatter ? formatter(error2.params) : error2.message;
|
|
871
|
+
return ` - ${path24}: ${message}`;
|
|
872
|
+
}).join(`
|
|
873
|
+
`);
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
// src/core/manifest/manifest.schema.json
|
|
879
|
+
var manifest_schema_default, init_manifest_schema = __esm({
|
|
880
|
+
"src/core/manifest/manifest.schema.json"() {
|
|
881
|
+
manifest_schema_default = {
|
|
882
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
883
|
+
title: "Manifest",
|
|
884
|
+
description: "Schema for validating plugin manifest",
|
|
885
|
+
type: "object",
|
|
886
|
+
required: [
|
|
887
|
+
"slug",
|
|
888
|
+
"version",
|
|
889
|
+
"permissions",
|
|
890
|
+
"name",
|
|
891
|
+
"description",
|
|
892
|
+
"support"
|
|
893
|
+
],
|
|
894
|
+
properties: {
|
|
895
|
+
$schema: {
|
|
896
|
+
type: "string"
|
|
897
|
+
},
|
|
898
|
+
id: {
|
|
899
|
+
type: "string",
|
|
900
|
+
description: "Unique identifier for the plugin ()",
|
|
901
|
+
minLength: 3,
|
|
902
|
+
maxLength: 63,
|
|
903
|
+
pattern: "^[a-z0-9-]+$"
|
|
904
|
+
},
|
|
905
|
+
manifest_version: {
|
|
906
|
+
type: "number",
|
|
907
|
+
description: "Manifest format version",
|
|
908
|
+
minimum: 1
|
|
909
|
+
},
|
|
910
|
+
supported_services: {
|
|
911
|
+
type: "array",
|
|
912
|
+
description: "Supported services for this plugin",
|
|
913
|
+
items: {
|
|
914
|
+
type: "string",
|
|
915
|
+
enum: [
|
|
916
|
+
"tracker",
|
|
917
|
+
"messenger"
|
|
918
|
+
]
|
|
919
|
+
},
|
|
920
|
+
minItems: 1,
|
|
921
|
+
uniqueItems: !0
|
|
922
|
+
},
|
|
923
|
+
slug: {
|
|
924
|
+
type: "string",
|
|
925
|
+
description: "Unique identifier for the plugin (lowercase letters, numbers, hyphen)",
|
|
926
|
+
minLength: 3,
|
|
927
|
+
maxLength: 63,
|
|
928
|
+
pattern: "^[a-z0-9-]+$"
|
|
929
|
+
},
|
|
930
|
+
version: {
|
|
931
|
+
type: "string",
|
|
932
|
+
description: "Version of the plugin (semver format required)",
|
|
933
|
+
minLength: 1,
|
|
934
|
+
pattern: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$"
|
|
935
|
+
},
|
|
936
|
+
name: {
|
|
937
|
+
type: "object",
|
|
938
|
+
description: "Localized plugin name",
|
|
939
|
+
required: [
|
|
940
|
+
"ru",
|
|
941
|
+
"en"
|
|
942
|
+
],
|
|
943
|
+
properties: {
|
|
944
|
+
ru: {
|
|
945
|
+
type: "string",
|
|
946
|
+
description: "Russian name",
|
|
947
|
+
minLength: 1,
|
|
948
|
+
maxLength: 30
|
|
949
|
+
},
|
|
950
|
+
en: {
|
|
951
|
+
type: "string",
|
|
952
|
+
description: "English name",
|
|
953
|
+
minLength: 1,
|
|
954
|
+
maxLength: 30
|
|
955
|
+
}
|
|
956
|
+
},
|
|
957
|
+
additionalProperties: !1
|
|
958
|
+
},
|
|
959
|
+
description: {
|
|
960
|
+
type: "object",
|
|
961
|
+
description: "Localized plugin description",
|
|
962
|
+
required: [
|
|
963
|
+
"ru",
|
|
964
|
+
"en"
|
|
965
|
+
],
|
|
966
|
+
properties: {
|
|
967
|
+
ru: {
|
|
968
|
+
type: "string",
|
|
969
|
+
description: "Russian description",
|
|
970
|
+
minLength: 1,
|
|
971
|
+
maxLength: 255
|
|
972
|
+
},
|
|
973
|
+
en: {
|
|
974
|
+
type: "string",
|
|
975
|
+
description: "English description",
|
|
976
|
+
minLength: 1,
|
|
977
|
+
maxLength: 255
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
additionalProperties: !1
|
|
981
|
+
},
|
|
982
|
+
support: {
|
|
983
|
+
type: "array",
|
|
984
|
+
description: "Support contact information",
|
|
985
|
+
items: {
|
|
986
|
+
type: "object",
|
|
987
|
+
required: [
|
|
988
|
+
"type",
|
|
989
|
+
"value"
|
|
990
|
+
],
|
|
991
|
+
properties: {
|
|
992
|
+
type: {
|
|
993
|
+
type: "string",
|
|
994
|
+
description: "Type of support contact",
|
|
995
|
+
enum: [
|
|
996
|
+
"email"
|
|
997
|
+
]
|
|
998
|
+
},
|
|
999
|
+
value: {
|
|
1000
|
+
type: "string",
|
|
1001
|
+
description: "Contact value",
|
|
1002
|
+
minLength: 1,
|
|
1003
|
+
maxLength: 100
|
|
1004
|
+
}
|
|
1005
|
+
},
|
|
1006
|
+
additionalProperties: !1
|
|
1007
|
+
},
|
|
1008
|
+
minItems: 1
|
|
1009
|
+
},
|
|
1010
|
+
homepage: {
|
|
1011
|
+
type: "string",
|
|
1012
|
+
description: "Homepage URL for the plugin (http or https)",
|
|
1013
|
+
pattern: "^https?://",
|
|
1014
|
+
maxLength: 1e3
|
|
1015
|
+
},
|
|
1016
|
+
license: {
|
|
1017
|
+
type: "string",
|
|
1018
|
+
description: "License identifier (e.g., MIT, Apache-2.0)",
|
|
1019
|
+
minLength: 1,
|
|
1020
|
+
maxLength: 32
|
|
1021
|
+
},
|
|
1022
|
+
keywords: {
|
|
1023
|
+
type: "array",
|
|
1024
|
+
description: "Keywords for plugin discovery",
|
|
1025
|
+
items: {
|
|
1026
|
+
type: "string",
|
|
1027
|
+
minLength: 1,
|
|
1028
|
+
maxLength: 30
|
|
1029
|
+
},
|
|
1030
|
+
uniqueItems: !0
|
|
1031
|
+
},
|
|
1032
|
+
whatsnew: {
|
|
1033
|
+
type: "string",
|
|
1034
|
+
description: "What's new in this version",
|
|
1035
|
+
minLength: 1,
|
|
1036
|
+
maxLength: 300
|
|
1037
|
+
},
|
|
1038
|
+
externalHost: {
|
|
1039
|
+
type: "string",
|
|
1040
|
+
description: "External host URL for the plugin (https only)",
|
|
1041
|
+
format: "uri",
|
|
1042
|
+
pattern: "^https://",
|
|
1043
|
+
maxLength: 1e3
|
|
1044
|
+
},
|
|
1045
|
+
permissions: {
|
|
1046
|
+
type: "object",
|
|
1047
|
+
description: "Permissions required by the plugin",
|
|
1048
|
+
required: [
|
|
1049
|
+
"data"
|
|
1050
|
+
],
|
|
1051
|
+
properties: {
|
|
1052
|
+
data: {
|
|
1053
|
+
type: "array",
|
|
1054
|
+
description: "Data access permissions",
|
|
1055
|
+
items: {
|
|
1056
|
+
type: "string",
|
|
1057
|
+
enum: [
|
|
1058
|
+
"tracker:issues:read",
|
|
1059
|
+
"tracker:issues:write",
|
|
1060
|
+
"tracker:issuetypes:read",
|
|
1061
|
+
"tracker:statuses:read",
|
|
1062
|
+
"tracker:queues:read",
|
|
1063
|
+
"tracker:fields:read",
|
|
1064
|
+
"tracker:entities:read",
|
|
1065
|
+
"tracker:attachments:read",
|
|
1066
|
+
"tracker:attachments:write",
|
|
1067
|
+
"tracker:applications:read",
|
|
1068
|
+
"tracker:boards:read",
|
|
1069
|
+
"tracker:boards:write",
|
|
1070
|
+
"tracker:bulk:read",
|
|
1071
|
+
"tracker:bulk:write",
|
|
1072
|
+
"tracker:bulkchange:read",
|
|
1073
|
+
"tracker:bulkchange:write",
|
|
1074
|
+
"tracker:charts:read",
|
|
1075
|
+
"tracker:commentTemplates:read",
|
|
1076
|
+
"tracker:commentTemplates:write",
|
|
1077
|
+
"tracker:components:read",
|
|
1078
|
+
"tracker:components:write",
|
|
1079
|
+
"tracker:data:read",
|
|
1080
|
+
"tracker:departments:read",
|
|
1081
|
+
"tracker:entities:write",
|
|
1082
|
+
"tracker:externalEventTypes:write",
|
|
1083
|
+
"tracker:externalEvents:write",
|
|
1084
|
+
"tracker:fields:write",
|
|
1085
|
+
"tracker:filterFolders:write",
|
|
1086
|
+
"tracker:filters:read",
|
|
1087
|
+
"tracker:filters:write",
|
|
1088
|
+
"tracker:goals:read",
|
|
1089
|
+
"tracker:goals:write",
|
|
1090
|
+
"tracker:groups:read",
|
|
1091
|
+
"tracker:issueTemplates:read",
|
|
1092
|
+
"tracker:issueTemplates:write",
|
|
1093
|
+
"tracker:links:read",
|
|
1094
|
+
"tracker:linktypes:read",
|
|
1095
|
+
"tracker:liveBoards:write",
|
|
1096
|
+
"tracker:localFields:read",
|
|
1097
|
+
"tracker:maillists:read",
|
|
1098
|
+
"tracker:maillists:write",
|
|
1099
|
+
"tracker:myself:read",
|
|
1100
|
+
"tracker:myself:write",
|
|
1101
|
+
"tracker:priorities:read",
|
|
1102
|
+
"tracker:queues:write",
|
|
1103
|
+
"tracker:reminders:read",
|
|
1104
|
+
"tracker:reminders:write",
|
|
1105
|
+
"tracker:remotelinks:read",
|
|
1106
|
+
"tracker:reports:read",
|
|
1107
|
+
"tracker:reports:write",
|
|
1108
|
+
"tracker:resolutions:read",
|
|
1109
|
+
"tracker:resources:read",
|
|
1110
|
+
"tracker:resources:write",
|
|
1111
|
+
"tracker:roles:read",
|
|
1112
|
+
"tracker:screens:read",
|
|
1113
|
+
"tracker:services:read",
|
|
1114
|
+
"tracker:sprints:read",
|
|
1115
|
+
"tracker:sprints:write",
|
|
1116
|
+
"tracker:system:write",
|
|
1117
|
+
"tracker:tags:read",
|
|
1118
|
+
"tracker:translations:read",
|
|
1119
|
+
"tracker:users:read",
|
|
1120
|
+
"tracker:users:write",
|
|
1121
|
+
"tracker:versions:read",
|
|
1122
|
+
"tracker:versions:write",
|
|
1123
|
+
"tracker:workflows:read",
|
|
1124
|
+
"tracker:workflows:write",
|
|
1125
|
+
"tracker:worklog:read",
|
|
1126
|
+
"tracker:worklog:write"
|
|
1127
|
+
]
|
|
1128
|
+
},
|
|
1129
|
+
uniqueItems: !0
|
|
1130
|
+
},
|
|
1131
|
+
ui: {
|
|
1132
|
+
type: "array",
|
|
1133
|
+
description: "UI permissions",
|
|
1134
|
+
items: {
|
|
1135
|
+
type: "string"
|
|
1136
|
+
},
|
|
1137
|
+
uniqueItems: !0
|
|
1138
|
+
},
|
|
1139
|
+
device: {
|
|
1140
|
+
type: "array",
|
|
1141
|
+
description: "Device permissions",
|
|
1142
|
+
items: {
|
|
1143
|
+
type: "string",
|
|
1144
|
+
enum: [
|
|
1145
|
+
"clipboard-write",
|
|
1146
|
+
"microphone",
|
|
1147
|
+
"camera",
|
|
1148
|
+
"geolocation",
|
|
1149
|
+
"web-share",
|
|
1150
|
+
"allow-downloads"
|
|
1151
|
+
]
|
|
1152
|
+
},
|
|
1153
|
+
uniqueItems: !0
|
|
1154
|
+
},
|
|
1155
|
+
external: {
|
|
1156
|
+
type: "array",
|
|
1157
|
+
description: "External API domains the plugin may call through the platform proxy",
|
|
1158
|
+
items: {
|
|
1159
|
+
$ref: "#/definitions/ExternalDomain"
|
|
1160
|
+
},
|
|
1161
|
+
uniqueItems: !0
|
|
1162
|
+
}
|
|
1163
|
+
},
|
|
1164
|
+
additionalProperties: !1
|
|
1165
|
+
},
|
|
1166
|
+
slots: {
|
|
1167
|
+
type: "object",
|
|
1168
|
+
description: "Configuration for service slots",
|
|
1169
|
+
minProperties: 1,
|
|
1170
|
+
properties: {
|
|
1171
|
+
tracker: {
|
|
1172
|
+
type: "object",
|
|
1173
|
+
description: "Tracker service slots",
|
|
1174
|
+
minProperties: 1,
|
|
1175
|
+
properties: {
|
|
1176
|
+
"issue.action": {
|
|
1177
|
+
type: "array",
|
|
1178
|
+
description: "Issue Action slot configurations",
|
|
1179
|
+
minItems: 1,
|
|
1180
|
+
items: {
|
|
1181
|
+
$ref: "#/definitions/SlotConfig"
|
|
1182
|
+
}
|
|
1183
|
+
},
|
|
1184
|
+
"issue.block": {
|
|
1185
|
+
type: "array",
|
|
1186
|
+
description: "Issue Block slot configurations",
|
|
1187
|
+
minItems: 1,
|
|
1188
|
+
items: {
|
|
1189
|
+
$ref: "#/definitions/SlotConfig"
|
|
1190
|
+
}
|
|
1191
|
+
},
|
|
1192
|
+
"issue.tab": {
|
|
1193
|
+
type: "array",
|
|
1194
|
+
description: "Issue Tab slot configurations",
|
|
1195
|
+
minItems: 1,
|
|
1196
|
+
items: {
|
|
1197
|
+
$ref: "#/definitions/SlotConfig"
|
|
1198
|
+
}
|
|
1199
|
+
},
|
|
1200
|
+
"issue.comment.action": {
|
|
1201
|
+
type: "array",
|
|
1202
|
+
description: "Issue Comment Action slot configurations",
|
|
1203
|
+
minItems: 1,
|
|
1204
|
+
items: {
|
|
1205
|
+
$ref: "#/definitions/SlotConfig"
|
|
1206
|
+
}
|
|
1207
|
+
},
|
|
1208
|
+
"issue.editor.action": {
|
|
1209
|
+
type: "array",
|
|
1210
|
+
description: "Issue Editor Action slot configurations",
|
|
1211
|
+
minItems: 1,
|
|
1212
|
+
items: {
|
|
1213
|
+
$ref: "#/definitions/SlotConfig"
|
|
1214
|
+
}
|
|
1215
|
+
},
|
|
1216
|
+
"queue.action": {
|
|
1217
|
+
type: "array",
|
|
1218
|
+
description: "Queue Action slot configurations",
|
|
1219
|
+
minItems: 1,
|
|
1220
|
+
items: {
|
|
1221
|
+
$ref: "#/definitions/SlotConfig"
|
|
1222
|
+
}
|
|
1223
|
+
},
|
|
1224
|
+
"queue.tab": {
|
|
1225
|
+
type: "array",
|
|
1226
|
+
description: "Queue Tab slot configurations",
|
|
1227
|
+
minItems: 1,
|
|
1228
|
+
items: {
|
|
1229
|
+
$ref: "#/definitions/SlotConfig"
|
|
1230
|
+
}
|
|
1231
|
+
},
|
|
1232
|
+
navigation: {
|
|
1233
|
+
type: "array",
|
|
1234
|
+
description: "Navigation slot configurations",
|
|
1235
|
+
minItems: 1,
|
|
1236
|
+
items: {
|
|
1237
|
+
$ref: "#/definitions/SlotConfig"
|
|
1238
|
+
}
|
|
1239
|
+
},
|
|
1240
|
+
"trigger.create.action": {
|
|
1241
|
+
type: "array",
|
|
1242
|
+
description: "Trigger Create Action slot configurations",
|
|
1243
|
+
minItems: 1,
|
|
1244
|
+
items: {
|
|
1245
|
+
$ref: "#/definitions/SlotConfig"
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
"trigger.edit.action": {
|
|
1249
|
+
type: "array",
|
|
1250
|
+
description: "Trigger Edit Action slot configurations",
|
|
1251
|
+
minItems: 1,
|
|
1252
|
+
items: {
|
|
1253
|
+
$ref: "#/definitions/SlotConfig"
|
|
1254
|
+
}
|
|
1255
|
+
},
|
|
1256
|
+
"project.action": {
|
|
1257
|
+
type: "array",
|
|
1258
|
+
description: "Project Action slot configurations",
|
|
1259
|
+
minItems: 1,
|
|
1260
|
+
items: {
|
|
1261
|
+
$ref: "#/definitions/SlotConfig"
|
|
1262
|
+
}
|
|
1263
|
+
},
|
|
1264
|
+
"project.block": {
|
|
1265
|
+
type: "array",
|
|
1266
|
+
description: "Project Block slot configurations",
|
|
1267
|
+
minItems: 1,
|
|
1268
|
+
items: {
|
|
1269
|
+
$ref: "#/definitions/SlotConfig"
|
|
1270
|
+
}
|
|
1271
|
+
},
|
|
1272
|
+
"project.tab": {
|
|
1273
|
+
type: "array",
|
|
1274
|
+
description: "Project Tab slot configurations",
|
|
1275
|
+
minItems: 1,
|
|
1276
|
+
items: {
|
|
1277
|
+
$ref: "#/definitions/SlotConfig"
|
|
1278
|
+
}
|
|
1279
|
+
},
|
|
1280
|
+
"project.editor.action": {
|
|
1281
|
+
type: "array",
|
|
1282
|
+
description: "Project Editor Action slot configurations",
|
|
1283
|
+
minItems: 1,
|
|
1284
|
+
items: {
|
|
1285
|
+
$ref: "#/definitions/SlotConfig"
|
|
1286
|
+
}
|
|
1287
|
+
},
|
|
1288
|
+
"portfolio.action": {
|
|
1289
|
+
type: "array",
|
|
1290
|
+
description: "Portfolio Action slot configurations",
|
|
1291
|
+
minItems: 1,
|
|
1292
|
+
items: {
|
|
1293
|
+
$ref: "#/definitions/SlotConfig"
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
1296
|
+
"portfolio.block": {
|
|
1297
|
+
type: "array",
|
|
1298
|
+
description: "Portfolio Block slot configurations",
|
|
1299
|
+
minItems: 1,
|
|
1300
|
+
items: {
|
|
1301
|
+
$ref: "#/definitions/SlotConfig"
|
|
1302
|
+
}
|
|
1303
|
+
},
|
|
1304
|
+
"portfolio.tab": {
|
|
1305
|
+
type: "array",
|
|
1306
|
+
description: "Portfolio Tab slot configurations",
|
|
1307
|
+
minItems: 1,
|
|
1308
|
+
items: {
|
|
1309
|
+
$ref: "#/definitions/SlotConfig"
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1312
|
+
"portfolio.editor.action": {
|
|
1313
|
+
type: "array",
|
|
1314
|
+
description: "Portfolio Editor Action slot configurations",
|
|
1315
|
+
minItems: 1,
|
|
1316
|
+
items: {
|
|
1317
|
+
$ref: "#/definitions/SlotConfig"
|
|
1318
|
+
}
|
|
1319
|
+
},
|
|
1320
|
+
"goal.action": {
|
|
1321
|
+
type: "array",
|
|
1322
|
+
description: "Goal Action slot configurations",
|
|
1323
|
+
minItems: 1,
|
|
1324
|
+
items: {
|
|
1325
|
+
$ref: "#/definitions/SlotConfig"
|
|
1326
|
+
}
|
|
1327
|
+
},
|
|
1328
|
+
"goal.block": {
|
|
1329
|
+
type: "array",
|
|
1330
|
+
description: "Goal Block slot configurations",
|
|
1331
|
+
minItems: 1,
|
|
1332
|
+
items: {
|
|
1333
|
+
$ref: "#/definitions/SlotConfig"
|
|
1334
|
+
}
|
|
1335
|
+
},
|
|
1336
|
+
"goal.tab": {
|
|
1337
|
+
type: "array",
|
|
1338
|
+
description: "Goal Tab slot configurations",
|
|
1339
|
+
minItems: 1,
|
|
1340
|
+
items: {
|
|
1341
|
+
$ref: "#/definitions/SlotConfig"
|
|
1342
|
+
}
|
|
1343
|
+
},
|
|
1344
|
+
"goal.editor.action": {
|
|
1345
|
+
type: "array",
|
|
1346
|
+
description: "Goal Editor Action slot configurations",
|
|
1347
|
+
minItems: 1,
|
|
1348
|
+
items: {
|
|
1349
|
+
$ref: "#/definitions/SlotConfig"
|
|
1350
|
+
}
|
|
1351
|
+
},
|
|
1352
|
+
"attachment.viewer.action": {
|
|
1353
|
+
type: "array",
|
|
1354
|
+
description: "Attachment Viewer Action slot configurations",
|
|
1355
|
+
minItems: 1,
|
|
1356
|
+
items: {
|
|
1357
|
+
$ref: "#/definitions/SlotConfig"
|
|
1358
|
+
}
|
|
1359
|
+
},
|
|
1360
|
+
"board.tab": {
|
|
1361
|
+
type: "array",
|
|
1362
|
+
description: "Board Tab slot configurations",
|
|
1363
|
+
minItems: 1,
|
|
1364
|
+
items: {
|
|
1365
|
+
$ref: "#/definitions/SlotConfig"
|
|
1366
|
+
}
|
|
1367
|
+
},
|
|
1368
|
+
dock: {
|
|
1369
|
+
type: "array",
|
|
1370
|
+
description: "Dock slot configurations",
|
|
1371
|
+
minItems: 1,
|
|
1372
|
+
items: {
|
|
1373
|
+
$ref: "#/definitions/SlotConfig"
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
},
|
|
1377
|
+
additionalProperties: !1
|
|
1378
|
+
},
|
|
1379
|
+
messenger: {
|
|
1380
|
+
type: "object",
|
|
1381
|
+
description: "Messenger service slots",
|
|
1382
|
+
minProperties: 1,
|
|
1383
|
+
properties: {
|
|
1384
|
+
"user.card.info": {
|
|
1385
|
+
type: "array",
|
|
1386
|
+
description: "User Card Info slot configurations",
|
|
1387
|
+
minItems: 1,
|
|
1388
|
+
items: {
|
|
1389
|
+
$ref: "#/definitions/SlotConfig"
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
},
|
|
1393
|
+
additionalProperties: !1
|
|
1394
|
+
}
|
|
1395
|
+
},
|
|
1396
|
+
additionalProperties: !1
|
|
1397
|
+
}
|
|
1398
|
+
},
|
|
1399
|
+
additionalProperties: !1,
|
|
1400
|
+
definitions: {
|
|
1401
|
+
ExternalDomain: {
|
|
1402
|
+
type: "object",
|
|
1403
|
+
description: "External API domain declaration with optional authorization config",
|
|
1404
|
+
required: [
|
|
1405
|
+
"domain"
|
|
1406
|
+
],
|
|
1407
|
+
properties: {
|
|
1408
|
+
domain: {
|
|
1409
|
+
type: "string",
|
|
1410
|
+
description: "Hostname of the external API (no scheme, no path, lowercase)",
|
|
1411
|
+
pattern: "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$",
|
|
1412
|
+
minLength: 1,
|
|
1413
|
+
maxLength: 253
|
|
1414
|
+
},
|
|
1415
|
+
authorization: {
|
|
1416
|
+
$ref: "#/definitions/ExternalAuthorization"
|
|
1417
|
+
},
|
|
1418
|
+
instructions: {
|
|
1419
|
+
type: "object",
|
|
1420
|
+
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)",
|
|
1421
|
+
required: [
|
|
1422
|
+
"ru",
|
|
1423
|
+
"en"
|
|
1424
|
+
],
|
|
1425
|
+
properties: {
|
|
1426
|
+
ru: {
|
|
1427
|
+
type: "string",
|
|
1428
|
+
description: "Russian instructions",
|
|
1429
|
+
minLength: 1,
|
|
1430
|
+
maxLength: 500
|
|
1431
|
+
},
|
|
1432
|
+
en: {
|
|
1433
|
+
type: "string",
|
|
1434
|
+
description: "English instructions",
|
|
1435
|
+
minLength: 1,
|
|
1436
|
+
maxLength: 500
|
|
1437
|
+
}
|
|
1438
|
+
},
|
|
1439
|
+
additionalProperties: !1
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1442
|
+
additionalProperties: !1
|
|
1443
|
+
},
|
|
1444
|
+
ExternalAuthorization: {
|
|
1445
|
+
type: "object",
|
|
1446
|
+
description: "Authorization config for an external API domain",
|
|
1447
|
+
required: [
|
|
1448
|
+
"type"
|
|
1449
|
+
],
|
|
1450
|
+
properties: {
|
|
1451
|
+
type: {
|
|
1452
|
+
type: "string",
|
|
1453
|
+
description: "Authorization scheme: oauth (full OAuth flow or manual PAT for an OAuth provider) or token (manual non-OAuth token, e.g. API key)",
|
|
1454
|
+
enum: [
|
|
1455
|
+
"oauth",
|
|
1456
|
+
"token"
|
|
1457
|
+
]
|
|
1458
|
+
},
|
|
1459
|
+
scopes: {
|
|
1460
|
+
type: "array",
|
|
1461
|
+
description: "Scopes required by this version of the plugin for the domain",
|
|
1462
|
+
items: {
|
|
1463
|
+
type: "string",
|
|
1464
|
+
minLength: 1
|
|
1465
|
+
},
|
|
1466
|
+
uniqueItems: !0
|
|
1467
|
+
},
|
|
1468
|
+
contextTypes: {
|
|
1469
|
+
type: "array",
|
|
1470
|
+
description: "Supported token storage contexts",
|
|
1471
|
+
items: {
|
|
1472
|
+
type: "string",
|
|
1473
|
+
enum: [
|
|
1474
|
+
"user",
|
|
1475
|
+
"organization"
|
|
1476
|
+
]
|
|
1477
|
+
},
|
|
1478
|
+
minItems: 1,
|
|
1479
|
+
uniqueItems: !0
|
|
1480
|
+
},
|
|
1481
|
+
header: {
|
|
1482
|
+
type: "string",
|
|
1483
|
+
description: "Custom HTTP header name to put the token into (default: Authorization)",
|
|
1484
|
+
minLength: 1
|
|
1485
|
+
},
|
|
1486
|
+
prefix: {
|
|
1487
|
+
type: "string",
|
|
1488
|
+
description: "Custom token prefix in the Authorization header (default: Bearer; empty string for no prefix)"
|
|
1489
|
+
}
|
|
1490
|
+
},
|
|
1491
|
+
additionalProperties: !1
|
|
1492
|
+
},
|
|
1493
|
+
SlotConfig: {
|
|
1494
|
+
type: "object",
|
|
1495
|
+
description: "Configuration for a specific slot",
|
|
1496
|
+
required: [
|
|
1497
|
+
"entrypoint",
|
|
1498
|
+
"title",
|
|
1499
|
+
"contextLevel"
|
|
1500
|
+
],
|
|
1501
|
+
properties: {
|
|
1502
|
+
entrypoint: {
|
|
1503
|
+
type: "string",
|
|
1504
|
+
description: "Entry point file path for the slot",
|
|
1505
|
+
minLength: 1
|
|
1506
|
+
},
|
|
1507
|
+
title: {
|
|
1508
|
+
type: "object",
|
|
1509
|
+
description: "Localized titles for the slot",
|
|
1510
|
+
required: [
|
|
1511
|
+
"ru",
|
|
1512
|
+
"en"
|
|
1513
|
+
],
|
|
1514
|
+
properties: {
|
|
1515
|
+
ru: {
|
|
1516
|
+
type: "string",
|
|
1517
|
+
description: "Russian title",
|
|
1518
|
+
minLength: 1,
|
|
1519
|
+
maxLength: 32
|
|
1520
|
+
},
|
|
1521
|
+
en: {
|
|
1522
|
+
type: "string",
|
|
1523
|
+
description: "English title",
|
|
1524
|
+
minLength: 1,
|
|
1525
|
+
maxLength: 32
|
|
1526
|
+
}
|
|
1527
|
+
},
|
|
1528
|
+
additionalProperties: !1
|
|
1529
|
+
},
|
|
1530
|
+
contextLevel: {
|
|
1531
|
+
type: "string",
|
|
1532
|
+
description: "Level of context data provided to the slot",
|
|
1533
|
+
enum: [
|
|
1534
|
+
"basic",
|
|
1535
|
+
"full"
|
|
1536
|
+
]
|
|
1537
|
+
},
|
|
1538
|
+
icon: {
|
|
1539
|
+
type: "object",
|
|
1540
|
+
description: "Optional slot icon (used by 'dock' slot for FAB)",
|
|
1541
|
+
required: [
|
|
1542
|
+
"url"
|
|
1543
|
+
],
|
|
1544
|
+
properties: {
|
|
1545
|
+
url: {
|
|
1546
|
+
type: "string",
|
|
1547
|
+
description: "Relative path to the icon file (e.g. ./icon.svg)",
|
|
1548
|
+
minLength: 1
|
|
1549
|
+
}
|
|
1550
|
+
},
|
|
1551
|
+
additionalProperties: !1
|
|
1552
|
+
},
|
|
1553
|
+
description: {
|
|
1554
|
+
type: "object",
|
|
1555
|
+
description: "Localized descriptions for the slot",
|
|
1556
|
+
required: [
|
|
1557
|
+
"ru",
|
|
1558
|
+
"en"
|
|
1559
|
+
],
|
|
1560
|
+
properties: {
|
|
1561
|
+
ru: {
|
|
1562
|
+
type: "string",
|
|
1563
|
+
description: "Russian description",
|
|
1564
|
+
minLength: 1,
|
|
1565
|
+
maxLength: 300
|
|
1566
|
+
},
|
|
1567
|
+
en: {
|
|
1568
|
+
type: "string",
|
|
1569
|
+
description: "English description",
|
|
1570
|
+
minLength: 1,
|
|
1571
|
+
maxLength: 300
|
|
1572
|
+
}
|
|
1573
|
+
},
|
|
1574
|
+
additionalProperties: !1
|
|
1575
|
+
}
|
|
1576
|
+
},
|
|
1577
|
+
additionalProperties: !1
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
});
|
|
1583
|
+
|
|
1584
|
+
// src/core/manifest/manifestManager.ts
|
|
1585
|
+
var import_fs3, import_promises, import_ajv, import_ajv_formats, validator, defaultManifestPath, parseManifest, loadRaw, load, validate, save, update, manifestManager, init_manifestManager = __esm({
|
|
1586
|
+
"src/core/manifest/manifestManager.ts"() {
|
|
1587
|
+
"use strict";
|
|
1588
|
+
import_fs3 = require("fs"), import_promises = require("fs/promises"), import_ajv = __toESM(require("ajv")), import_ajv_formats = __toESM(require("ajv-formats"));
|
|
1589
|
+
init_manifestPermissionsSchema2();
|
|
1590
|
+
init_formatValidationErrors();
|
|
1591
|
+
init_manifest_schema();
|
|
1592
|
+
validator = (() => {
|
|
1593
|
+
let schema = {
|
|
1594
|
+
...manifest_schema_default,
|
|
1595
|
+
properties: {
|
|
1596
|
+
...manifest_schema_default.properties,
|
|
1597
|
+
permissions: {
|
|
1598
|
+
...manifest_schema_default.properties.permissions,
|
|
1599
|
+
properties: {
|
|
1600
|
+
...manifest_schema_default.properties.permissions.properties,
|
|
1601
|
+
...permissionsSchemaExtensions2
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
}, ajv = new import_ajv.default({ allErrors: !0, strict: !1 });
|
|
1606
|
+
return (0, import_ajv_formats.default)(ajv), ajv.compile(schema);
|
|
1607
|
+
})(), defaultManifestPath = "./manifest.json", parseManifest = (content) => {
|
|
1608
|
+
let manifest;
|
|
1609
|
+
try {
|
|
1610
|
+
manifest = JSON.parse(content);
|
|
1611
|
+
} catch (error2) {
|
|
1612
|
+
throw error2 instanceof SyntaxError ? new Error(`File manifest.json contains invalid JSON: ${error2.message}`) : new Error(`Error reading manifest.json: ${error2.message}`);
|
|
1613
|
+
}
|
|
1614
|
+
return manifest;
|
|
1615
|
+
}, loadRaw = async (manifestPath = defaultManifestPath) => {
|
|
1616
|
+
if (!(0, import_fs3.existsSync)(manifestPath))
|
|
1617
|
+
throw new Error(`File manifest.json not found at path: ${manifestPath}`);
|
|
1618
|
+
try {
|
|
1619
|
+
return await (0, import_promises.readFile)(manifestPath, "utf8");
|
|
1620
|
+
} catch (error2) {
|
|
1621
|
+
throw error2 instanceof Error ? new Error(`Error reading manifest.json: ${error2.message}`) : new Error("Error loading manifest");
|
|
1622
|
+
}
|
|
1623
|
+
}, load = async (manifestPath = defaultManifestPath) => {
|
|
1624
|
+
let manifestContent = await loadRaw(manifestPath);
|
|
1625
|
+
return parseManifest(manifestContent);
|
|
1626
|
+
}, validate = async (manifestPath = defaultManifestPath) => {
|
|
1627
|
+
let manifest = await load(manifestPath);
|
|
1628
|
+
if (!validator(manifest) && validator.errors) {
|
|
1629
|
+
let errorMessages2 = formatValidationErrors(validator.errors);
|
|
1630
|
+
throw new Error(
|
|
1631
|
+
`\u274C Manifest validation failed:
|
|
1632
|
+
${errorMessages2}
|
|
1633
|
+
|
|
1634
|
+
\u{1F4A1} Ensure all required fields are filled according to the plugin documentation.`
|
|
1635
|
+
);
|
|
1636
|
+
}
|
|
1637
|
+
}, save = async (manifest, manifestPath = defaultManifestPath) => {
|
|
1638
|
+
try {
|
|
1639
|
+
let content = JSON.stringify(manifest, null, 4);
|
|
1640
|
+
await (0, import_promises.writeFile)(manifestPath, content, "utf8");
|
|
1641
|
+
} catch (error2) {
|
|
1642
|
+
throw error2 instanceof Error ? new Error(`Error saving manifest.json: ${error2.message}`) : new Error("Error saving manifest");
|
|
1643
|
+
}
|
|
1644
|
+
}, update = async (updates, manifestPath = defaultManifestPath) => {
|
|
1645
|
+
let updatedManifest = { ...await load(manifestPath), ...updates };
|
|
1646
|
+
return await save(updatedManifest, manifestPath), updatedManifest;
|
|
1647
|
+
}, manifestManager = {
|
|
1648
|
+
load,
|
|
1649
|
+
loadRaw,
|
|
1650
|
+
validate,
|
|
1651
|
+
save,
|
|
1652
|
+
update
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
});
|
|
1656
|
+
|
|
1657
|
+
// src/core/doctor/helpers.ts
|
|
1658
|
+
function getErrorMessage(error2) {
|
|
1659
|
+
return error2 instanceof Error ? error2.message : String(error2);
|
|
1660
|
+
}
|
|
1661
|
+
var init_helpers = __esm({
|
|
1662
|
+
"src/core/doctor/helpers.ts"() {
|
|
1663
|
+
"use strict";
|
|
1664
|
+
}
|
|
1665
|
+
});
|
|
1666
|
+
|
|
1667
|
+
// src/core/doctor/manifestChecks.ts
|
|
1668
|
+
function isNonEmptyString(value) {
|
|
1669
|
+
return typeof value == "string" && !!value.trim();
|
|
1670
|
+
}
|
|
1671
|
+
function isSafeRelativePath(value) {
|
|
1672
|
+
if (import_path3.default.isAbsolute(value))
|
|
1673
|
+
return !1;
|
|
1674
|
+
let normalized = import_path3.default.normalize(value);
|
|
1675
|
+
return normalized !== ".." && !normalized.startsWith(`..${import_path3.default.sep}`);
|
|
1676
|
+
}
|
|
1677
|
+
function getManifestEntries(manifest) {
|
|
1678
|
+
let result = [];
|
|
1679
|
+
for (let service of SERVICES) {
|
|
1680
|
+
let serviceSlots = manifest.slots?.[service];
|
|
1681
|
+
if (serviceSlots) {
|
|
1682
|
+
for (let [slot, slotConfigs] of Object.entries(serviceSlots))
|
|
1683
|
+
if (!(!SERVICE_SLOTS.includes(slot) || !Array.isArray(slotConfigs)))
|
|
1684
|
+
for (let slotConfig of slotConfigs) {
|
|
1685
|
+
let slotRecord = slotConfig;
|
|
1686
|
+
result.push({
|
|
1687
|
+
service,
|
|
1688
|
+
slot,
|
|
1689
|
+
entrypoint: slotConfig.entrypoint,
|
|
1690
|
+
title: slotConfig.title,
|
|
1691
|
+
description: slotConfig.description,
|
|
1692
|
+
contextLevel: slotConfig.contextLevel,
|
|
1693
|
+
iconUrl: slotRecord.icon?.url
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return result;
|
|
1699
|
+
}
|
|
1700
|
+
function checkLocalizedString(missingValues, name, value) {
|
|
1701
|
+
isNonEmptyString(value?.ru) || missingValues.push(`${name}.ru`), isNonEmptyString(value?.en) || missingValues.push(`${name}.en`);
|
|
1702
|
+
}
|
|
1703
|
+
function checkManifestDetails(report, manifest, policy) {
|
|
1704
|
+
let entries = getManifestEntries(manifest);
|
|
1705
|
+
entries.length > 0 ? addCheck(report, {
|
|
1706
|
+
id: "manifest.entries",
|
|
1707
|
+
title: "Manifest slot entries",
|
|
1708
|
+
message: `Found ${entries.length} plugin slot entry(s).`,
|
|
1709
|
+
data: entries.map((entry) => ({
|
|
1710
|
+
service: entry.service,
|
|
1711
|
+
slot: entry.slot,
|
|
1712
|
+
entrypoint: entry.entrypoint,
|
|
1713
|
+
contextLevel: entry.contextLevel
|
|
1714
|
+
}))
|
|
1715
|
+
}) : addCheck(report, {
|
|
1716
|
+
id: "manifest.entries",
|
|
1717
|
+
title: "Manifest slot entries",
|
|
1718
|
+
status: "fail",
|
|
1719
|
+
message: "Manifest does not define any supported service slot entries.",
|
|
1720
|
+
action: `Add at least one slots.${SERVICES[0]} entry to manifest.json.`
|
|
1721
|
+
});
|
|
1722
|
+
let missingLocalizedStrings = [];
|
|
1723
|
+
checkLocalizedString(missingLocalizedStrings, "name", manifest.name), checkLocalizedString(missingLocalizedStrings, "description", manifest.description);
|
|
1724
|
+
for (let entry of entries)
|
|
1725
|
+
checkLocalizedString(
|
|
1726
|
+
missingLocalizedStrings,
|
|
1727
|
+
`slots.${entry.service}.${entry.slot}.title`,
|
|
1728
|
+
entry.title
|
|
1729
|
+
), entry.description && checkLocalizedString(
|
|
1730
|
+
missingLocalizedStrings,
|
|
1731
|
+
`slots.${entry.service}.${entry.slot}.description`,
|
|
1732
|
+
entry.description
|
|
1733
|
+
);
|
|
1734
|
+
missingLocalizedStrings.length === 0 ? addCheck(report, {
|
|
1735
|
+
id: "manifest.localized-strings",
|
|
1736
|
+
title: "Localized strings",
|
|
1737
|
+
message: "Manifest localized strings are non-empty."
|
|
1738
|
+
}) : addCheck(report, {
|
|
1739
|
+
id: "manifest.localized-strings",
|
|
1740
|
+
title: "Localized strings",
|
|
1741
|
+
status: "fail",
|
|
1742
|
+
message: `Empty localized value(s): ${missingLocalizedStrings.join(", ")}.`,
|
|
1743
|
+
action: "Fill ru and en values before publishing."
|
|
1744
|
+
});
|
|
1745
|
+
let invalidEntrypoints = entries.map((entry) => entry.entrypoint).filter((entrypoint) => !isSafeRelativePath(entrypoint));
|
|
1746
|
+
return invalidEntrypoints.length > 0 ? addCheck(report, {
|
|
1747
|
+
id: "manifest.entrypoints.valid",
|
|
1748
|
+
title: "Manifest entrypoint paths",
|
|
1749
|
+
status: "fail",
|
|
1750
|
+
message: `Invalid entrypoint path(s): ${invalidEntrypoints.join(", ")}.`,
|
|
1751
|
+
action: "Use relative entrypoint paths inside dist, for example index.html."
|
|
1752
|
+
}) : entries.length > 0 && addCheck(report, {
|
|
1753
|
+
id: "manifest.entrypoints.valid",
|
|
1754
|
+
title: "Manifest entrypoint paths",
|
|
1755
|
+
message: "All manifest entrypoint paths are relative."
|
|
1756
|
+
}), manifest.permissions?.data?.length ? addCheck(report, {
|
|
1757
|
+
id: "manifest.permissions",
|
|
1758
|
+
title: "Manifest permissions",
|
|
1759
|
+
message: `Manifest declares ${manifest.permissions.data.length} data permission(s).`,
|
|
1760
|
+
data: manifest.permissions
|
|
1761
|
+
}) : addCheck(report, {
|
|
1762
|
+
id: "manifest.permissions",
|
|
1763
|
+
title: "Manifest permissions",
|
|
1764
|
+
status: policy.manifestPermissionsStatus,
|
|
1765
|
+
message: "Manifest permissions.data is empty.",
|
|
1766
|
+
action: "Add the data permissions required by the plugin before publishing."
|
|
1767
|
+
}), manifest.support?.length ? addCheck(report, {
|
|
1768
|
+
id: "manifest.support",
|
|
1769
|
+
title: "Support contacts",
|
|
1770
|
+
message: `Manifest declares ${manifest.support.length} support contact(s).`
|
|
1771
|
+
}) : addCheck(report, {
|
|
1772
|
+
id: "manifest.support",
|
|
1773
|
+
title: "Support contacts",
|
|
1774
|
+
status: policy.manifestSupportStatus,
|
|
1775
|
+
message: "Manifest support contacts are missing.",
|
|
1776
|
+
action: "Add at least one support contact to manifest.json before publishing."
|
|
1777
|
+
}), entries;
|
|
1778
|
+
}
|
|
1779
|
+
async function checkManifest(report, manifestPath, policy) {
|
|
1780
|
+
try {
|
|
1781
|
+
await manifestManager.validate(manifestPath);
|
|
1782
|
+
let manifest = await manifestManager.load(manifestPath);
|
|
1783
|
+
return report.manifest = {
|
|
1784
|
+
slug: manifest.slug,
|
|
1785
|
+
version: manifest.version
|
|
1786
|
+
}, addCheck(report, {
|
|
1787
|
+
id: "manifest.valid",
|
|
1788
|
+
title: "Manifest schema",
|
|
1789
|
+
message: "manifest.json is valid."
|
|
1790
|
+
}), {
|
|
1791
|
+
manifest,
|
|
1792
|
+
entries: checkManifestDetails(report, manifest, policy)
|
|
1793
|
+
};
|
|
1794
|
+
} catch (error2) {
|
|
1795
|
+
return addCheck(report, {
|
|
1796
|
+
id: "manifest.valid",
|
|
1797
|
+
title: "Manifest schema",
|
|
1798
|
+
status: "fail",
|
|
1799
|
+
message: getErrorMessage(error2),
|
|
1800
|
+
action: "Fix manifest.json before running build, debug, or submit."
|
|
1801
|
+
}), {
|
|
1802
|
+
entries: []
|
|
1803
|
+
};
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
var import_path3, init_manifestChecks = __esm({
|
|
1807
|
+
"src/core/doctor/manifestChecks.ts"() {
|
|
1808
|
+
"use strict";
|
|
1809
|
+
import_path3 = __toESM(require("path"));
|
|
1810
|
+
init_constants();
|
|
1811
|
+
init_manifestManager();
|
|
1812
|
+
init_helpers();
|
|
1813
|
+
init_report();
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1816
|
+
|
|
1817
|
+
// src/core/doctor/marketplaceChecks.ts
|
|
1818
|
+
function getMissingOrInvalidStatus(requiredPath, policy) {
|
|
1819
|
+
return requiredPath.path === "src" ? "fail" : policy.marketplaceAssetsStatus;
|
|
1820
|
+
}
|
|
1821
|
+
function checkMarketplaceAssets(report, projectRoot, policy) {
|
|
1822
|
+
for (let requiredPath of REQUIRED_PATHS) {
|
|
1823
|
+
let fullPath = import_path4.default.join(projectRoot, requiredPath.path), status = getMissingOrInvalidStatus(requiredPath, policy);
|
|
1824
|
+
if (!import_fs4.default.existsSync(fullPath)) {
|
|
1825
|
+
addCheck(report, {
|
|
1826
|
+
id: `marketplace.${requiredPath.path}`,
|
|
1827
|
+
title: requiredPath.title,
|
|
1828
|
+
status,
|
|
1829
|
+
message: `${requiredPath.path} is missing.`,
|
|
1830
|
+
action: `Add ${requiredPath.path} before publishing.`
|
|
1831
|
+
});
|
|
1832
|
+
continue;
|
|
1833
|
+
}
|
|
1834
|
+
let stat = import_fs4.default.statSync(fullPath), validKind = requiredPath.kind === "directory" ? stat.isDirectory() : stat.isFile();
|
|
1835
|
+
addCheck(report, {
|
|
1836
|
+
id: `marketplace.${requiredPath.path}`,
|
|
1837
|
+
title: requiredPath.title,
|
|
1838
|
+
status: validKind ? "pass" : status,
|
|
1839
|
+
message: validKind ? `Found ${requiredPath.path}.` : `${requiredPath.path} exists but is not a ${requiredPath.kind}.`,
|
|
1840
|
+
action: validKind ? void 0 : `Replace ${requiredPath.path} with a ${requiredPath.kind}.`
|
|
1841
|
+
});
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
var import_fs4, import_path4, REQUIRED_PATHS, init_marketplaceChecks = __esm({
|
|
1845
|
+
"src/core/doctor/marketplaceChecks.ts"() {
|
|
1846
|
+
"use strict";
|
|
1847
|
+
import_fs4 = __toESM(require("fs")), import_path4 = __toESM(require("path"));
|
|
1848
|
+
init_report();
|
|
1849
|
+
REQUIRED_PATHS = [
|
|
1850
|
+
{ path: "src", title: "Source directory", kind: "directory" },
|
|
1851
|
+
{ path: "marketplace", title: "Marketplace directory", kind: "directory" },
|
|
1852
|
+
{ path: "marketplace/index.md", title: "Marketplace description", kind: "file" },
|
|
1853
|
+
{ path: "marketplace/header-image.jpg", title: "Marketplace header image", kind: "file" },
|
|
1854
|
+
{ path: "public/logo.svg", title: "Plugin logo", kind: "file" }
|
|
1855
|
+
];
|
|
1856
|
+
}
|
|
1857
|
+
});
|
|
1858
|
+
|
|
1859
|
+
// src/core/doctor/nodeChecks.ts
|
|
1860
|
+
function checkNodeVersion(report) {
|
|
1861
|
+
let version = process.versions.node, major = Number(version.split(".")[0]);
|
|
1862
|
+
if (Number.isInteger(major) && major >= REQUIRED_NODE_MAJOR) {
|
|
1863
|
+
addCheck(report, {
|
|
1864
|
+
id: "node.version",
|
|
1865
|
+
title: "Node.js version",
|
|
1866
|
+
message: `Node.js ${version} satisfies >=${REQUIRED_NODE_MAJOR}.`,
|
|
1867
|
+
data: {
|
|
1868
|
+
version,
|
|
1869
|
+
requiredMajor: REQUIRED_NODE_MAJOR
|
|
1870
|
+
}
|
|
1871
|
+
});
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1874
|
+
addCheck(report, {
|
|
1875
|
+
id: "node.version",
|
|
1876
|
+
title: "Node.js version",
|
|
1877
|
+
status: "fail",
|
|
1878
|
+
message: `Node.js ${version} does not satisfy >=${REQUIRED_NODE_MAJOR}.`,
|
|
1879
|
+
action: `Switch to Node.js ${REQUIRED_NODE_MAJOR} or newer.`,
|
|
1880
|
+
data: {
|
|
1881
|
+
version,
|
|
1882
|
+
requiredMajor: REQUIRED_NODE_MAJOR
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
var REQUIRED_NODE_MAJOR, init_nodeChecks = __esm({
|
|
1887
|
+
"src/core/doctor/nodeChecks.ts"() {
|
|
1888
|
+
"use strict";
|
|
1889
|
+
init_report();
|
|
1890
|
+
REQUIRED_NODE_MAJOR = 22;
|
|
1891
|
+
}
|
|
1892
|
+
});
|
|
1893
|
+
|
|
1894
|
+
// src/utils/packageManager.ts
|
|
1895
|
+
function defaultCommandExists(command) {
|
|
1896
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(command))
|
|
1897
|
+
return !1;
|
|
1898
|
+
let result = (0, import_child_process.spawnSync)("sh", ["-c", `command -v ${command}`], {
|
|
1899
|
+
stdio: "ignore"
|
|
1900
|
+
});
|
|
1901
|
+
return !result.error && result.status === 0;
|
|
1902
|
+
}
|
|
1903
|
+
function detectFromPackageJson(projectRoot) {
|
|
1904
|
+
let packageJsonPath = import_path5.default.join(projectRoot, "package.json");
|
|
1905
|
+
if (import_fs5.default.existsSync(packageJsonPath))
|
|
1906
|
+
try {
|
|
1907
|
+
let raw = import_fs5.default.readFileSync(packageJsonPath, "utf8"), packageManager = JSON.parse(raw).packageManager;
|
|
1908
|
+
if (typeof packageManager != "string")
|
|
1909
|
+
return;
|
|
1910
|
+
if (packageManager.startsWith("pnpm@"))
|
|
1911
|
+
return "pnpm";
|
|
1912
|
+
if (packageManager.startsWith("npm@"))
|
|
1913
|
+
return "npm";
|
|
1914
|
+
} catch {
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
function detectPackageManager(projectRoot = process.cwd()) {
|
|
1919
|
+
return import_fs5.default.existsSync(import_path5.default.join(projectRoot, "pnpm-lock.yaml")) ? "pnpm" : detectFromPackageJson(projectRoot) || "npm";
|
|
1920
|
+
}
|
|
1921
|
+
function resolvePackageManagerExecutable(packageManager, options = {}) {
|
|
1922
|
+
let commandExists = options.commandExists || defaultCommandExists;
|
|
1923
|
+
if (commandExists(packageManager))
|
|
1924
|
+
return {
|
|
1925
|
+
command: packageManager,
|
|
1926
|
+
argsPrefix: []
|
|
1927
|
+
};
|
|
1928
|
+
if (packageManager !== "npm" && commandExists("corepack"))
|
|
1929
|
+
return {
|
|
1930
|
+
command: "corepack",
|
|
1931
|
+
argsPrefix: [packageManager]
|
|
1932
|
+
};
|
|
1933
|
+
throw packageManager === "npm" ? new Error(
|
|
1934
|
+
"npm is not available in PATH. Install Node.js and npm, then rerun this command."
|
|
1935
|
+
) : new Error(
|
|
1936
|
+
`${packageManager} is not available in PATH, and Corepack is not available either. Install Node.js >= 22 with Corepack, or run npm install -g corepack@latest && corepack enable once, then rerun this command.`
|
|
1937
|
+
);
|
|
1938
|
+
}
|
|
1939
|
+
function truncateOutput(value) {
|
|
1940
|
+
let normalized = value.trim();
|
|
1941
|
+
return normalized.length <= MAX_RUNTIME_OUTPUT_LENGTH ? normalized : `${normalized.slice(0, MAX_RUNTIME_OUTPUT_LENGTH)}...`;
|
|
1942
|
+
}
|
|
1943
|
+
function getRuntimeOutput(result) {
|
|
1944
|
+
return truncateOutput(
|
|
1945
|
+
[result.stdout?.toString(), result.stderr?.toString()].filter(Boolean).join(`
|
|
1946
|
+
`)
|
|
1947
|
+
);
|
|
1948
|
+
}
|
|
1949
|
+
function isCorepackKeyIdError(output) {
|
|
1950
|
+
return /Cannot find matching keyid/i.test(output);
|
|
1951
|
+
}
|
|
1952
|
+
function getPackageManagerRuntimeAction(output, packageManager) {
|
|
1953
|
+
return isCorepackKeyIdError(output) ? `Corepack cannot verify the pinned package manager signature. Update Corepack from the same registry used for global CLI installs: npm install -g corepack@latest && corepack enable. Then rerun: ${packageManager === "npm" ? "npm install" : `corepack ${packageManager} install`}. Do not use COREPACK_INTEGRITY_KEYS=0 because it disables signature checks.` : packageManager === "npm" ? "Fix the npm runtime, then rerun doctor. For freshly generated plugins, install Node.js >= 22 and run npm install from the plugin directory." : `Fix the ${packageManager} runtime, then rerun doctor. For Corepack-managed package managers, try: npm install -g corepack@latest && corepack enable.`;
|
|
1954
|
+
}
|
|
1955
|
+
function runPackageManagerRuntimeCheck(projectRoot, packageManager, executable) {
|
|
1956
|
+
let args = [...executable.argsPrefix, "--version"], commandLabel = [executable.command, ...args].join(" "), result = (0, import_child_process.spawnSync)(executable.command, args, {
|
|
1957
|
+
cwd: projectRoot,
|
|
1958
|
+
encoding: "utf8",
|
|
1959
|
+
timeout: PACKAGE_MANAGER_RUNTIME_TIMEOUT_MS
|
|
1960
|
+
}), output = getRuntimeOutput(result);
|
|
1961
|
+
if (!result.error && result.status === 0)
|
|
1962
|
+
return {
|
|
1963
|
+
ok: !0,
|
|
1964
|
+
packageManager,
|
|
1965
|
+
command: executable.command,
|
|
1966
|
+
args,
|
|
1967
|
+
commandLabel,
|
|
1968
|
+
message: `${commandLabel} returned ${output || "success"}.`,
|
|
1969
|
+
version: output || void 0,
|
|
1970
|
+
status: result.status,
|
|
1971
|
+
signal: result.signal,
|
|
1972
|
+
output: output || null
|
|
1973
|
+
};
|
|
1974
|
+
let message = result.error ? result.error.message : output || `${commandLabel} exited with code ${result.status}.`;
|
|
1975
|
+
return {
|
|
1976
|
+
ok: !1,
|
|
1977
|
+
packageManager,
|
|
1978
|
+
command: executable.command,
|
|
1979
|
+
args,
|
|
1980
|
+
commandLabel,
|
|
1981
|
+
message,
|
|
1982
|
+
action: getPackageManagerRuntimeAction(output || message, packageManager),
|
|
1983
|
+
status: result.status,
|
|
1984
|
+
signal: result.signal,
|
|
1985
|
+
output: output || null
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
var import_child_process, import_fs5, import_path5, PACKAGE_MANAGER_RUNTIME_TIMEOUT_MS, MAX_RUNTIME_OUTPUT_LENGTH, PackageManagerRuntimeError, init_packageManager = __esm({
|
|
1989
|
+
"src/utils/packageManager.ts"() {
|
|
1990
|
+
"use strict";
|
|
1991
|
+
import_child_process = require("child_process"), import_fs5 = __toESM(require("fs")), import_path5 = __toESM(require("path")), PACKAGE_MANAGER_RUNTIME_TIMEOUT_MS = 15e3, MAX_RUNTIME_OUTPUT_LENGTH = 1e3, PackageManagerRuntimeError = class extends Error {
|
|
1992
|
+
constructor(check) {
|
|
1993
|
+
super(check.message), this.name = "PackageManagerRuntimeError", this.action = check.action, this.check = check;
|
|
1994
|
+
}
|
|
1995
|
+
};
|
|
1996
|
+
}
|
|
1997
|
+
});
|
|
1998
|
+
|
|
1999
|
+
// src/core/doctor/packageChecks.ts
|
|
2000
|
+
function readPackageJson(projectRoot) {
|
|
2001
|
+
let packageJsonPath = import_path6.default.join(projectRoot, "package.json");
|
|
2002
|
+
if (!import_fs6.default.existsSync(packageJsonPath))
|
|
2003
|
+
return {
|
|
2004
|
+
path: packageJsonPath,
|
|
2005
|
+
error: "package.json not found"
|
|
2006
|
+
};
|
|
2007
|
+
try {
|
|
2008
|
+
let raw = import_fs6.default.readFileSync(packageJsonPath, "utf8");
|
|
2009
|
+
return {
|
|
2010
|
+
path: packageJsonPath,
|
|
2011
|
+
packageJson: JSON.parse(raw)
|
|
2012
|
+
};
|
|
2013
|
+
} catch (error2) {
|
|
2014
|
+
return {
|
|
2015
|
+
path: packageJsonPath,
|
|
2016
|
+
error: getErrorMessage(error2)
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
function getScript(packageJson, name) {
|
|
2021
|
+
if (typeof packageJson.scripts != "object" || packageJson.scripts === null)
|
|
2022
|
+
return;
|
|
2023
|
+
let value = packageJson.scripts[name];
|
|
2024
|
+
return typeof value == "string" && value.trim() ? value : void 0;
|
|
2025
|
+
}
|
|
2026
|
+
function getDependencyVersion(packageJson, name) {
|
|
2027
|
+
let dependencySources = [packageJson.dependencies, packageJson.devDependencies];
|
|
2028
|
+
for (let source of dependencySources) {
|
|
2029
|
+
if (typeof source != "object" || source === null)
|
|
2030
|
+
continue;
|
|
2031
|
+
let value = source[name];
|
|
2032
|
+
if (typeof value == "string" && value.trim())
|
|
2033
|
+
return value;
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
function addPackageManagerRuntimeCheck(report, runtimeCheck) {
|
|
2037
|
+
if (runtimeCheck.ok) {
|
|
2038
|
+
addCheck(report, {
|
|
2039
|
+
id: "package-manager.runtime",
|
|
2040
|
+
title: "Package manager runtime",
|
|
2041
|
+
message: runtimeCheck.message,
|
|
2042
|
+
data: {
|
|
2043
|
+
packageManager: runtimeCheck.packageManager,
|
|
2044
|
+
command: runtimeCheck.command,
|
|
2045
|
+
args: runtimeCheck.args,
|
|
2046
|
+
version: runtimeCheck.version || null
|
|
2047
|
+
}
|
|
2048
|
+
});
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
addCheck(report, {
|
|
2052
|
+
id: "package-manager.runtime",
|
|
2053
|
+
title: "Package manager runtime",
|
|
2054
|
+
status: "fail",
|
|
2055
|
+
message: runtimeCheck.message,
|
|
2056
|
+
action: runtimeCheck.action,
|
|
2057
|
+
data: {
|
|
2058
|
+
packageManager: runtimeCheck.packageManager,
|
|
2059
|
+
command: runtimeCheck.command,
|
|
2060
|
+
args: runtimeCheck.args,
|
|
2061
|
+
status: runtimeCheck.status,
|
|
2062
|
+
signal: runtimeCheck.signal,
|
|
2063
|
+
output: runtimeCheck.output
|
|
2064
|
+
}
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2067
|
+
function getPackageManagerInstallAction(packageManager) {
|
|
2068
|
+
return packageManager === "npm" ? "Install Node.js >= 22 with npm, then rerun npm install." : `Install and enable Corepack once: npm install -g corepack@latest && corepack enable. Then rerun corepack ${packageManager} install.`;
|
|
2069
|
+
}
|
|
2070
|
+
function checkScript(report, packageJson, script, required) {
|
|
2071
|
+
let value = getScript(packageJson, script);
|
|
2072
|
+
if (value) {
|
|
2073
|
+
addCheck(report, {
|
|
2074
|
+
id: `package-json.script.${script}`,
|
|
2075
|
+
title: `${script} script`,
|
|
2076
|
+
message: `${script} script is "${value}".`
|
|
2077
|
+
});
|
|
2078
|
+
return;
|
|
2079
|
+
}
|
|
2080
|
+
addCheck(report, {
|
|
2081
|
+
id: `package-json.script.${script}`,
|
|
2082
|
+
title: `${script} script`,
|
|
2083
|
+
status: required ? "fail" : "warn",
|
|
2084
|
+
message: `Missing package.json scripts.${script}.`,
|
|
2085
|
+
action: required ? `Add scripts.${script}; CLI commands expect it.` : `Add scripts.${script} if this plugin should support this check.`
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
function checkPluginSdkDependency(report, packageJson) {
|
|
2089
|
+
let detectedPackages = COMMON_SDK_PACKAGES.filter(
|
|
2090
|
+
(packageName) => getDependencyVersion(packageJson, packageName)
|
|
2091
|
+
), detectedGenericPackages = GENERIC_SDK_PACKAGES.filter(
|
|
2092
|
+
(packageName) => getDependencyVersion(packageJson, packageName)
|
|
2093
|
+
), missingGenericPackages = GENERIC_SDK_PACKAGES.filter(
|
|
2094
|
+
(packageName) => !getDependencyVersion(packageJson, packageName)
|
|
2095
|
+
);
|
|
2096
|
+
if (detectedPackages.length > 0) {
|
|
2097
|
+
addCheck(report, {
|
|
2098
|
+
id: "package-json.sdk-dependency",
|
|
2099
|
+
title: "Plugin SDK dependency",
|
|
2100
|
+
message: `Uses common plugin SDK package(s): ${detectedPackages.join(", ")}.`,
|
|
2101
|
+
data: detectedPackages
|
|
2102
|
+
}), detectedGenericPackages.length > 0 && missingGenericPackages.length > 0 && addCheck(report, {
|
|
2103
|
+
id: "package-json.sdk-generic-pair",
|
|
2104
|
+
title: "Generic SDK dependency pair",
|
|
2105
|
+
status: "warn",
|
|
2106
|
+
message: `Generic SDK dependency set is incomplete. Missing: ${missingGenericPackages.join(", ")}.`,
|
|
2107
|
+
action: "Generated generic React templates depend on both @weavix/sdk-core and @weavix/sdk-react.",
|
|
2108
|
+
data: {
|
|
2109
|
+
detected: detectedGenericPackages,
|
|
2110
|
+
missing: missingGenericPackages
|
|
2111
|
+
}
|
|
2112
|
+
});
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
addCheck(report, {
|
|
2116
|
+
id: "package-json.sdk-dependency",
|
|
2117
|
+
title: "Plugin SDK dependency",
|
|
2118
|
+
status: "warn",
|
|
2119
|
+
message: "No common plugin SDK package was found in dependencies.",
|
|
2120
|
+
action: "Add @weavix/sdk-core + @weavix/sdk-react for generic plugins, or @weavix/tracker-plugin-sdk-react for Tracker plugins."
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
function checkPackageJson(report, projectRoot) {
|
|
2124
|
+
let result = readPackageJson(projectRoot);
|
|
2125
|
+
if (!result.packageJson) {
|
|
2126
|
+
addCheck(report, {
|
|
2127
|
+
id: "package-json.valid",
|
|
2128
|
+
title: "package.json",
|
|
2129
|
+
status: "fail",
|
|
2130
|
+
message: result.error || "package.json cannot be read.",
|
|
2131
|
+
action: `Create a valid package.json at ${result.path}.`
|
|
2132
|
+
});
|
|
2133
|
+
return;
|
|
2134
|
+
}
|
|
2135
|
+
return addCheck(report, {
|
|
2136
|
+
id: "package-json.valid",
|
|
2137
|
+
title: "package.json",
|
|
2138
|
+
message: `Found valid package.json at ${result.path}.`
|
|
2139
|
+
}), typeof result.packageJson.packageManager == "string" ? addCheck(report, {
|
|
2140
|
+
id: "package-json.package-manager",
|
|
2141
|
+
title: "Pinned package manager",
|
|
2142
|
+
message: `packageManager is ${result.packageJson.packageManager}.`
|
|
2143
|
+
}) : addCheck(report, {
|
|
2144
|
+
id: "package-json.package-manager",
|
|
2145
|
+
title: "Pinned package manager",
|
|
2146
|
+
status: "warn",
|
|
2147
|
+
message: "packageManager is missing. CLI will fall back to lockfiles or npm.",
|
|
2148
|
+
action: 'Add packageManager, for example "npm@11.6.4".'
|
|
2149
|
+
}), checkScript(report, result.packageJson, "build", !0), checkScript(report, result.packageJson, "lint", !0), checkScript(report, result.packageJson, "dev", !1), checkScript(report, result.packageJson, "typecheck", !1), checkScript(report, result.packageJson, "test", !1), checkPluginSdkDependency(report, result.packageJson), result.packageJson;
|
|
2150
|
+
}
|
|
2151
|
+
function checkPackageManager(report, projectRoot) {
|
|
2152
|
+
let projectPackageManager = detectPackageManager(projectRoot);
|
|
2153
|
+
report.packageManager = projectPackageManager, projectPackageManager !== CLI_PACKAGE_MANAGER && addCheck(report, {
|
|
2154
|
+
id: "package-manager.cli-compat",
|
|
2155
|
+
title: "CLI package manager compatibility",
|
|
2156
|
+
status: "warn",
|
|
2157
|
+
message: `Detected ${projectPackageManager}, but existing CLI build/debug/submit commands run ${CLI_PACKAGE_MANAGER}.`,
|
|
2158
|
+
action: "Use npm for generated plugins until CLI command execution is made package-manager aware.",
|
|
2159
|
+
data: {
|
|
2160
|
+
packageManager: projectPackageManager,
|
|
2161
|
+
cliPackageManager: CLI_PACKAGE_MANAGER
|
|
2162
|
+
}
|
|
2163
|
+
});
|
|
2164
|
+
try {
|
|
2165
|
+
let executable = resolvePackageManagerExecutable(CLI_PACKAGE_MANAGER);
|
|
2166
|
+
addCheck(report, {
|
|
2167
|
+
id: "package-manager.executable",
|
|
2168
|
+
title: "CLI package manager executable",
|
|
2169
|
+
message: `CLI commands run ${[executable.command, ...executable.argsPrefix].join(
|
|
2170
|
+
" "
|
|
2171
|
+
)}.`,
|
|
2172
|
+
data: {
|
|
2173
|
+
packageManager: projectPackageManager,
|
|
2174
|
+
cliPackageManager: CLI_PACKAGE_MANAGER,
|
|
2175
|
+
executable
|
|
2176
|
+
}
|
|
2177
|
+
}), addPackageManagerRuntimeCheck(
|
|
2178
|
+
report,
|
|
2179
|
+
runPackageManagerRuntimeCheck(projectRoot, CLI_PACKAGE_MANAGER, executable)
|
|
2180
|
+
);
|
|
2181
|
+
} catch (error2) {
|
|
2182
|
+
addCheck(report, {
|
|
2183
|
+
id: "package-manager.executable",
|
|
2184
|
+
title: "CLI package manager executable",
|
|
2185
|
+
status: "fail",
|
|
2186
|
+
message: getErrorMessage(error2),
|
|
2187
|
+
action: getPackageManagerInstallAction(CLI_PACKAGE_MANAGER),
|
|
2188
|
+
data: {
|
|
2189
|
+
packageManager: projectPackageManager,
|
|
2190
|
+
cliPackageManager: CLI_PACKAGE_MANAGER
|
|
2191
|
+
}
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
var import_fs6, import_path6, CLI_PACKAGE_MANAGER, COMMON_SDK_PACKAGES, GENERIC_SDK_PACKAGES, init_packageChecks = __esm({
|
|
2196
|
+
"src/core/doctor/packageChecks.ts"() {
|
|
2197
|
+
"use strict";
|
|
2198
|
+
import_fs6 = __toESM(require("fs")), import_path6 = __toESM(require("path"));
|
|
2199
|
+
init_packageManager();
|
|
2200
|
+
init_helpers();
|
|
2201
|
+
init_report();
|
|
2202
|
+
CLI_PACKAGE_MANAGER = "npm", COMMON_SDK_PACKAGES = [
|
|
2203
|
+
"@weavix/sdk-core",
|
|
2204
|
+
"@weavix/sdk-react",
|
|
2205
|
+
"@weavix/tracker-plugin-sdk",
|
|
2206
|
+
"@weavix/tracker-plugin-sdk-react",
|
|
2207
|
+
"@yandex-weavix/tracker-plugin-sdk-core",
|
|
2208
|
+
"@yandex-weavix/tracker-plugin-sdk-react"
|
|
2209
|
+
], GENERIC_SDK_PACKAGES = ["@weavix/sdk-core", "@weavix/sdk-react"];
|
|
2210
|
+
}
|
|
2211
|
+
});
|
|
2212
|
+
|
|
2213
|
+
// src/utils/project.ts
|
|
2214
|
+
function resolveProjectRoot(startDir = process.cwd()) {
|
|
2215
|
+
let current = import_path7.default.resolve(startDir);
|
|
2216
|
+
for (; ; ) {
|
|
2217
|
+
if (import_fs7.default.existsSync(import_path7.default.join(current, MANIFEST_FILE)))
|
|
2218
|
+
return current;
|
|
2219
|
+
let parent = import_path7.default.dirname(current);
|
|
2220
|
+
if (parent === current)
|
|
2221
|
+
throw new Error(
|
|
2222
|
+
`Could not find ${MANIFEST_FILE}. Run this command inside a plugin project.`
|
|
2223
|
+
);
|
|
2224
|
+
current = parent;
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
function getManifestPath(projectRoot = process.cwd()) {
|
|
2228
|
+
return import_path7.default.join(resolveProjectRoot(projectRoot), MANIFEST_FILE);
|
|
2229
|
+
}
|
|
2230
|
+
var import_fs7, import_path7, MANIFEST_FILE, init_project = __esm({
|
|
2231
|
+
"src/utils/project.ts"() {
|
|
2232
|
+
"use strict";
|
|
2233
|
+
import_fs7 = __toESM(require("fs")), import_path7 = __toESM(require("path")), MANIFEST_FILE = "manifest.json";
|
|
2234
|
+
}
|
|
2235
|
+
});
|
|
2236
|
+
|
|
2237
|
+
// src/core/doctor/projectChecks.ts
|
|
2238
|
+
function checkProjectRoot(report) {
|
|
2239
|
+
try {
|
|
2240
|
+
let projectRoot = resolveProjectRoot();
|
|
2241
|
+
return report.projectRoot = projectRoot, report.manifestPath = getManifestPath(projectRoot), addCheck(report, {
|
|
2242
|
+
id: "project-root.resolved",
|
|
2243
|
+
title: "Project root",
|
|
2244
|
+
message: `Found plugin project root at ${projectRoot}.`
|
|
2245
|
+
}), projectRoot;
|
|
2246
|
+
} catch (error2) {
|
|
2247
|
+
addCheck(report, {
|
|
2248
|
+
id: "project-root.resolved",
|
|
2249
|
+
title: "Project root",
|
|
2250
|
+
status: "fail",
|
|
2251
|
+
message: getErrorMessage(error2),
|
|
2252
|
+
action: "Run doctor inside a generated plugin project."
|
|
2253
|
+
});
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
var init_projectChecks = __esm({
|
|
2258
|
+
"src/core/doctor/projectChecks.ts"() {
|
|
2259
|
+
"use strict";
|
|
2260
|
+
init_project();
|
|
2261
|
+
init_helpers();
|
|
2262
|
+
init_report();
|
|
2263
|
+
}
|
|
2264
|
+
});
|
|
2265
|
+
|
|
2266
|
+
// src/core/doctor/checks.ts
|
|
2267
|
+
async function runDoctorChecks(options) {
|
|
2268
|
+
let report = createDoctorReport(), policy = createDoctorPolicy(options);
|
|
2269
|
+
report.mode = policy.mode, checkNodeVersion(report);
|
|
2270
|
+
let projectRoot = checkProjectRoot(report);
|
|
2271
|
+
if (!projectRoot)
|
|
2272
|
+
return await checkDistribution2(report, void 0, options, policy), report;
|
|
2273
|
+
let { manifest, entries } = await checkManifest(report, report.manifestPath, policy);
|
|
2274
|
+
return checkPackageJson(report, projectRoot) && checkPackageManager(report, projectRoot), manifest && await checkDist(report, projectRoot, entries, policy), checkMarketplaceAssets(report, projectRoot, policy), await checkDistribution2(report, projectRoot, options, policy), report;
|
|
2275
|
+
}
|
|
2276
|
+
var init_checks = __esm({
|
|
2277
|
+
"src/core/doctor/checks.ts"() {
|
|
2278
|
+
"use strict";
|
|
2279
|
+
init_doctorChecks2();
|
|
2280
|
+
init_distChecks();
|
|
2281
|
+
init_manifestChecks();
|
|
2282
|
+
init_marketplaceChecks();
|
|
2283
|
+
init_nodeChecks();
|
|
2284
|
+
init_packageChecks();
|
|
2285
|
+
init_policy();
|
|
2286
|
+
init_projectChecks();
|
|
2287
|
+
init_report();
|
|
2288
|
+
}
|
|
2289
|
+
});
|
|
2290
|
+
|
|
2291
|
+
// src/commands/doctor/index.ts
|
|
2292
|
+
async function doctor(options = {}) {
|
|
2293
|
+
let report = await runDoctorChecks(options);
|
|
2294
|
+
await finishDoctor(report, options);
|
|
2295
|
+
}
|
|
2296
|
+
var init_doctor = __esm({
|
|
2297
|
+
"src/commands/doctor/index.ts"() {
|
|
2298
|
+
"use strict";
|
|
2299
|
+
init_checks();
|
|
2300
|
+
init_report();
|
|
2301
|
+
}
|
|
2302
|
+
});
|
|
2303
|
+
|
|
2304
|
+
// src/commands/submit/options.ts
|
|
2305
|
+
var import_commander, skipChecksOption, init_options = __esm({
|
|
2306
|
+
"src/commands/submit/options.ts"() {
|
|
2307
|
+
"use strict";
|
|
2308
|
+
import_commander = require("commander"), skipChecksOption = new import_commander.Option(
|
|
2309
|
+
"--skip-checks",
|
|
2310
|
+
"skip pre-submit validation (manifest, assets, lint, typecheck, tests, audit)"
|
|
2311
|
+
);
|
|
2312
|
+
}
|
|
2313
|
+
});
|
|
2314
|
+
|
|
2315
|
+
// src/utils/verbose.ts
|
|
2316
|
+
function setVerboseEnabled(value) {
|
|
2317
|
+
verboseEnabled = value;
|
|
2318
|
+
}
|
|
2319
|
+
function isVerboseEnabled() {
|
|
2320
|
+
return verboseEnabled;
|
|
2321
|
+
}
|
|
2322
|
+
function writeVerboseArtifact(relativePath, content) {
|
|
2323
|
+
let targetPath = import_path8.default.resolve(".yaweavix-debug", relativePath);
|
|
2324
|
+
return import_fs8.default.mkdirSync(import_path8.default.dirname(targetPath), { recursive: !0 }), import_fs8.default.writeFileSync(targetPath, content), targetPath;
|
|
2325
|
+
}
|
|
2326
|
+
var import_fs8, import_path8, verboseEnabled, init_verbose = __esm({
|
|
2327
|
+
"src/utils/verbose.ts"() {
|
|
2328
|
+
"use strict";
|
|
2329
|
+
import_fs8 = __toESM(require("fs")), import_path8 = __toESM(require("path")), verboseEnabled = !1;
|
|
2330
|
+
}
|
|
2331
|
+
});
|
|
2332
|
+
|
|
2333
|
+
// src/utils/logger.ts
|
|
2334
|
+
function success(message) {
|
|
2335
|
+
console.info(import_picocolors.default.green(`\u2705 ${message}`)), newLine();
|
|
2336
|
+
}
|
|
2337
|
+
function error(messageOrErr, err) {
|
|
2338
|
+
let message = messageOrErr instanceof Error ? messageOrErr.message : messageOrErr;
|
|
2339
|
+
console.error(import_picocolors.default.red(`\u274C ${message}`)), err instanceof Error && console.error(import_picocolors.default.red(err.message)), newLine();
|
|
2340
|
+
}
|
|
2341
|
+
function warning(message) {
|
|
2342
|
+
console.warn(import_picocolors.default.yellow(`\u26A0\uFE0F ${message}`)), newLine();
|
|
2343
|
+
}
|
|
2344
|
+
function info(message) {
|
|
2345
|
+
console.info(message), newLine();
|
|
2346
|
+
}
|
|
2347
|
+
function verbose(message) {
|
|
2348
|
+
isVerboseEnabled() && (console.info(import_picocolors.default.dim(message)), newLine());
|
|
2349
|
+
}
|
|
2350
|
+
function suggest(command) {
|
|
2351
|
+
console.info(`Run: ${command}`), newLine();
|
|
2352
|
+
}
|
|
2353
|
+
function newLine(count = 1) {
|
|
2354
|
+
console.info(`
|
|
2355
|
+
`.repeat(count - 1));
|
|
2356
|
+
}
|
|
2357
|
+
function separator(char = "\u2500", length = 60) {
|
|
2358
|
+
console.info(import_picocolors.default.dim(char.repeat(length))), newLine();
|
|
2359
|
+
}
|
|
2360
|
+
function commands(title, data) {
|
|
2361
|
+
newLine(), title && (console.info(import_picocolors.default.bold(import_picocolors.default.cyan(`${title}:`))), newLine()), data.forEach((cmd) => {
|
|
2362
|
+
console.info(import_picocolors.default.dim(" $ ") + import_picocolors.default.white(cmd));
|
|
2363
|
+
}), newLine();
|
|
2364
|
+
}
|
|
2365
|
+
var import_picocolors, logger, logger_default, init_logger = __esm({
|
|
2366
|
+
"src/utils/logger.ts"() {
|
|
2367
|
+
"use strict";
|
|
2368
|
+
import_picocolors = __toESM(require("picocolors"));
|
|
2369
|
+
init_verbose();
|
|
2370
|
+
logger = {
|
|
2371
|
+
success,
|
|
2372
|
+
error,
|
|
2373
|
+
warning,
|
|
2374
|
+
info,
|
|
2375
|
+
verbose,
|
|
2376
|
+
suggest,
|
|
2377
|
+
newLine,
|
|
2378
|
+
separator,
|
|
2379
|
+
commands
|
|
2380
|
+
}, logger_default = logger;
|
|
2381
|
+
}
|
|
2382
|
+
});
|
|
2383
|
+
|
|
2384
|
+
// src/core/cliConfig/registerCommand.ts
|
|
2385
|
+
async function promptString(message, current) {
|
|
2386
|
+
return (await (0, import_prompts.input)({
|
|
2387
|
+
message: current ? `${message} (current: ${current})` : `${message} (optional)`,
|
|
2388
|
+
default: current,
|
|
2389
|
+
required: !1
|
|
2390
|
+
}))?.trim() || void 0;
|
|
2391
|
+
}
|
|
2392
|
+
async function runConfigSet(cliName) {
|
|
2393
|
+
let existing = readConfig() ?? {};
|
|
2394
|
+
logger_default.info(
|
|
2395
|
+
"Configure CLI overrides. Empty input clears the value (and falls back to defaults where applicable)."
|
|
2396
|
+
);
|
|
2397
|
+
let s3Endpoint = await promptString("S3 endpoint", existing.s3?.endpoint), s3Region = await promptString("S3 region", existing.s3?.region), mdsEndpoint = await promptString("MDS endpoint", existing.mds?.endpoint), productionStatic = await promptString(
|
|
2398
|
+
"Production bucket (static)",
|
|
2399
|
+
existing.buckets?.production?.static
|
|
2400
|
+
), productionConfig = await promptString(
|
|
2401
|
+
"Production bucket (config)",
|
|
2402
|
+
existing.buckets?.production?.config
|
|
2403
|
+
), pluginDownloadProduction = await promptString(
|
|
2404
|
+
"Plugin download base URL",
|
|
2405
|
+
existing.pluginDownloadBase?.production
|
|
2406
|
+
), platformBaseUrl = await promptString(
|
|
2407
|
+
"Platform API base URL",
|
|
2408
|
+
existing.api?.platformBaseUrl
|
|
2409
|
+
), oauthUrl = await promptString("OAuth token URL", existing.auth?.oauthUrl);
|
|
2410
|
+
writeConfig({
|
|
2411
|
+
s3: { endpoint: s3Endpoint, region: s3Region },
|
|
2412
|
+
mds: { endpoint: mdsEndpoint },
|
|
2413
|
+
buckets: {
|
|
2414
|
+
production: { static: productionStatic, config: productionConfig }
|
|
2415
|
+
},
|
|
2416
|
+
pluginDownloadBase: { production: pluginDownloadProduction },
|
|
2417
|
+
api: { platformBaseUrl },
|
|
2418
|
+
auth: { oauthUrl }
|
|
2419
|
+
}), logger_default.success(`Configuration saved \u2192 ${getConfigPath()}`), logger_default.info(`Inspect with "${cliName} config show" or revert with "${cliName} config clear".`);
|
|
2420
|
+
}
|
|
2421
|
+
function runConfigShow(cliName) {
|
|
2422
|
+
let cfg = readConfig();
|
|
2423
|
+
if (!cfg) {
|
|
2424
|
+
logger_default.info(
|
|
2425
|
+
`No configuration found at ${getConfigPath()}. Run "${cliName} config set" to create one.`
|
|
2426
|
+
);
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
logger_default.info(`Configuration at ${getConfigPath()}:`), logger_default.info(JSON.stringify(cfg, null, 2));
|
|
2430
|
+
}
|
|
2431
|
+
function runConfigClear() {
|
|
2432
|
+
clearConfig(), logger_default.success(`Configuration removed (${getConfigPath()})`);
|
|
2433
|
+
}
|
|
2434
|
+
function registerConfigCommand(program, cliName) {
|
|
2435
|
+
let config = program.command("config").description("manage CLI configuration");
|
|
2436
|
+
config.command("set").description("set CLI configuration values interactively").action(() => runConfigSet(cliName)), config.command("show").description("display current CLI configuration").action(() => runConfigShow(cliName)), config.command("clear").description("remove stored CLI configuration").action(runConfigClear);
|
|
2437
|
+
}
|
|
2438
|
+
var import_prompts, init_registerCommand = __esm({
|
|
2439
|
+
"src/core/cliConfig/registerCommand.ts"() {
|
|
2440
|
+
"use strict";
|
|
2441
|
+
import_prompts = require("@inquirer/prompts");
|
|
2442
|
+
init_logger();
|
|
2443
|
+
init_manager();
|
|
2444
|
+
}
|
|
2445
|
+
});
|
|
2446
|
+
|
|
2447
|
+
// src/utils/withErrorHandling.ts
|
|
2448
|
+
function withErrorHandling(fn) {
|
|
2449
|
+
return async (...args) => {
|
|
2450
|
+
try {
|
|
2451
|
+
await fn(...args);
|
|
2452
|
+
} catch (error2) {
|
|
2453
|
+
error2 instanceof Error && error2.name === "ExitPromptError" && process.exit(0), logger_default.error(error2), printErrorHints(error2), process.exit(1);
|
|
2454
|
+
}
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
function getErrorMessage2(error2) {
|
|
2458
|
+
return error2 instanceof Error ? error2.message : String(error2);
|
|
2459
|
+
}
|
|
2460
|
+
function printErrorHints(error2) {
|
|
2461
|
+
if (error2 instanceof PackageManagerRuntimeError) {
|
|
2462
|
+
error2.action && logger_default.info(`Action: ${error2.action}`), logger_default.info(`Run ${CLI_NAME2} doctor from the plugin directory for full local diagnostics.`);
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
let message = getErrorMessage2(error2);
|
|
2466
|
+
if (isCorepackKeyIdError(message)) {
|
|
2467
|
+
logger_default.info(`Action: ${getPackageManagerRuntimeAction(message, "pnpm")}`);
|
|
2468
|
+
return;
|
|
2469
|
+
}
|
|
2470
|
+
/\b(manifest\.json|manifest validation|package manager|corepack|pnpm|npm|build|dist)\b/i.test(
|
|
2471
|
+
message
|
|
2472
|
+
) && logger_default.info(`Run ${CLI_NAME2} doctor from the plugin directory for local diagnostics.`);
|
|
2473
|
+
}
|
|
2474
|
+
var init_withErrorHandling = __esm({
|
|
2475
|
+
"src/utils/withErrorHandling.ts"() {
|
|
2476
|
+
"use strict";
|
|
2477
|
+
init_meta2();
|
|
2478
|
+
init_logger();
|
|
2479
|
+
init_packageManager();
|
|
2480
|
+
}
|
|
2481
|
+
});
|
|
2482
|
+
|
|
2483
|
+
// src/core/pluginState/pluginStateManager.ts
|
|
2484
|
+
var import_fs9, import_promises2, STATE_FILE, load2, save2, update2, pluginStateManager, init_pluginStateManager = __esm({
|
|
2485
|
+
"src/core/pluginState/pluginStateManager.ts"() {
|
|
2486
|
+
"use strict";
|
|
2487
|
+
import_fs9 = require("fs"), import_promises2 = require("fs/promises"), STATE_FILE = ".tracker-plugin", load2 = async () => {
|
|
2488
|
+
if (!(0, import_fs9.existsSync)(STATE_FILE))
|
|
2489
|
+
return {};
|
|
2490
|
+
try {
|
|
2491
|
+
let content = await (0, import_promises2.readFile)(STATE_FILE, "utf8");
|
|
2492
|
+
return JSON.parse(content);
|
|
2493
|
+
} catch {
|
|
2494
|
+
return {};
|
|
2495
|
+
}
|
|
2496
|
+
}, save2 = async (state) => {
|
|
2497
|
+
try {
|
|
2498
|
+
let content = JSON.stringify(state, null, 4);
|
|
2499
|
+
await (0, import_promises2.writeFile)(STATE_FILE, content, "utf8");
|
|
2500
|
+
} catch (error2) {
|
|
2501
|
+
throw error2 instanceof Error ? new Error(`Error saving ${STATE_FILE}: ${error2.message}`) : new Error(`Error saving ${STATE_FILE}`);
|
|
2502
|
+
}
|
|
2503
|
+
}, update2 = async (updates) => {
|
|
2504
|
+
let updated = { ...await load2(), ...updates };
|
|
2505
|
+
return await save2(updated), updated;
|
|
2506
|
+
}, pluginStateManager = {
|
|
2507
|
+
load: load2,
|
|
2508
|
+
save: save2,
|
|
2509
|
+
update: update2
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
});
|
|
2513
|
+
|
|
2514
|
+
// src/api/utils.ts
|
|
2515
|
+
function getIssueStatusLabel(issue) {
|
|
2516
|
+
let { key: statusKey, display: statusDisplay } = issue.status;
|
|
2517
|
+
return statusKey === "closed" && issue.resolution?.display ? issue.resolution.display : statusDisplay ?? statusKey;
|
|
2518
|
+
}
|
|
2519
|
+
function getIssueStatusCategory(issue) {
|
|
2520
|
+
let statusKey = issue.status.key, resolutionKey = issue.resolution?.key;
|
|
2521
|
+
if (statusKey === "closed")
|
|
2522
|
+
return resolutionKey === "agreed" ? "approved" : resolutionKey === "rejected" || resolutionKey === "declined" ? "rejected" : "neutral";
|
|
2523
|
+
switch (statusKey) {
|
|
2524
|
+
case "waitingForApprove":
|
|
2525
|
+
case "inProgress":
|
|
2526
|
+
return "pending";
|
|
2527
|
+
case "resultAcceptance":
|
|
2528
|
+
return "acceptance";
|
|
2529
|
+
case "testing":
|
|
2530
|
+
return "testing";
|
|
2531
|
+
case "need_info":
|
|
2532
|
+
return "need_info";
|
|
2533
|
+
default:
|
|
2534
|
+
return "neutral";
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
var init_utils = __esm({
|
|
2538
|
+
"src/api/utils.ts"() {
|
|
2539
|
+
"use strict";
|
|
2540
|
+
}
|
|
2541
|
+
});
|
|
2542
|
+
|
|
2543
|
+
// src/utils/pluginDisplay.ts
|
|
2544
|
+
function showTrackerPluginList(issues) {
|
|
2545
|
+
if (!issues || issues.length === 0) {
|
|
2546
|
+
console.info(import_picocolors2.default.dim(" No plugins found")), logger_default.newLine();
|
|
2547
|
+
return;
|
|
2548
|
+
}
|
|
2549
|
+
printHeader(`\u{1F4CB} Your Plugins \xB7 ${issues.length}`), logger_default.newLine(), issues.forEach((issue) => {
|
|
2550
|
+
let slugMatch = issue.summary.match(/^Plugin:\s*(.+)$/), slug = slugMatch ? import_picocolors2.default.magenta(slugMatch[1].trim()) : import_picocolors2.default.dim(issue.summary), statusBadge2 = getTrackerIssueBadge(issue);
|
|
2551
|
+
console.info(
|
|
2552
|
+
` ${slug} ${import_picocolors2.default.dim("\xB7")} ${statusBadge2} ${import_picocolors2.default.dim("\xB7")} ${import_picocolors2.default.dim(issue.key)}`
|
|
2553
|
+
), logger_default.newLine();
|
|
2554
|
+
});
|
|
2555
|
+
}
|
|
2556
|
+
function showTrackerPluginInfo(issue) {
|
|
2557
|
+
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);
|
|
2558
|
+
}
|
|
2559
|
+
var import_picocolors2, printHeader, getTrackerIssueBadge, formatDate, printField, printCreated, printUpdated, init_pluginDisplay = __esm({
|
|
2560
|
+
"src/utils/pluginDisplay.ts"() {
|
|
2561
|
+
"use strict";
|
|
2562
|
+
import_picocolors2 = __toESM(require("picocolors"));
|
|
2563
|
+
init_utils();
|
|
2564
|
+
init_logger();
|
|
2565
|
+
printHeader = (title) => {
|
|
2566
|
+
console.info(import_picocolors2.default.bold(import_picocolors2.default.white(title)));
|
|
2567
|
+
}, getTrackerIssueBadge = (issue) => {
|
|
2568
|
+
let label = getIssueStatusLabel(issue);
|
|
2569
|
+
switch (getIssueStatusCategory(issue)) {
|
|
2570
|
+
case "approved":
|
|
2571
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgGreen(` ${label} `));
|
|
2572
|
+
case "rejected":
|
|
2573
|
+
return import_picocolors2.default.white(import_picocolors2.default.bgRed(` ${label} `));
|
|
2574
|
+
case "pending":
|
|
2575
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgYellow(` ${label} `));
|
|
2576
|
+
case "acceptance":
|
|
2577
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgCyan(` ${label} `));
|
|
2578
|
+
case "testing":
|
|
2579
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgMagenta(` ${label} `));
|
|
2580
|
+
case "need_info":
|
|
2581
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgBlue(` ${label} `));
|
|
2582
|
+
default:
|
|
2583
|
+
return import_picocolors2.default.black(import_picocolors2.default.bgWhite(` ${label} `));
|
|
2584
|
+
}
|
|
2585
|
+
}, formatDate = (dateString) => dateString ? new Date(dateString).toLocaleString("ru-RU", {
|
|
2586
|
+
year: "numeric",
|
|
2587
|
+
month: "2-digit",
|
|
2588
|
+
day: "2-digit",
|
|
2589
|
+
hour: "2-digit",
|
|
2590
|
+
minute: "2-digit"
|
|
2591
|
+
}) : "-", printField = (label, value, minWidth = 12) => {
|
|
2592
|
+
console.info(` ${import_picocolors2.default.dim(label.padEnd(minWidth))} ${value}`);
|
|
2593
|
+
}, printCreated = (createdAt) => {
|
|
2594
|
+
printField("Created", import_picocolors2.default.white(formatDate(createdAt)));
|
|
2595
|
+
}, printUpdated = (updatedAt) => {
|
|
2596
|
+
printField("Updated", import_picocolors2.default.white(formatDate(updatedAt)));
|
|
2597
|
+
};
|
|
2598
|
+
}
|
|
2599
|
+
});
|
|
2600
|
+
|
|
2601
|
+
// src/distributions/external/tracker.ts
|
|
2602
|
+
function buildIssueSummary(slug) {
|
|
2603
|
+
return `Plugin: ${slug}`;
|
|
2604
|
+
}
|
|
2605
|
+
function buildIssueDescription(params) {
|
|
2606
|
+
let { pluginId, slug, version, manifestJson } = params;
|
|
2607
|
+
return [
|
|
2608
|
+
`**Plugin UUID:** ${pluginId}`,
|
|
2609
|
+
`**Slug:** ${slug}`,
|
|
2610
|
+
`**Version:** ${version}`,
|
|
2611
|
+
"",
|
|
2612
|
+
"**Manifest:**",
|
|
2613
|
+
"```json",
|
|
2614
|
+
manifestJson,
|
|
2615
|
+
"```"
|
|
2616
|
+
].join(`
|
|
2617
|
+
`);
|
|
2618
|
+
}
|
|
2619
|
+
async function createPluginIssue(params) {
|
|
2620
|
+
let { slug, pluginId, version, manifestJson } = params, body = {
|
|
2621
|
+
queue: PLUGINMOD_QUEUE,
|
|
2622
|
+
summary: buildIssueSummary(slug),
|
|
2623
|
+
description: buildIssueDescription({ pluginId, slug, version, manifestJson }),
|
|
2624
|
+
tags: ["tracker-plugin"]
|
|
2625
|
+
};
|
|
2626
|
+
return externalTrackerApiRequest("/issues", {
|
|
2627
|
+
method: "POST",
|
|
2628
|
+
body
|
|
2629
|
+
});
|
|
2630
|
+
}
|
|
2631
|
+
async function updatePluginIssue(issueKey, params) {
|
|
2632
|
+
return externalTrackerApiRequest(`/issues/${issueKey}`, {
|
|
2633
|
+
method: "PATCH",
|
|
2634
|
+
body: params
|
|
2635
|
+
});
|
|
2636
|
+
}
|
|
2637
|
+
async function attachFileToIssue(issueKey, fileBuffer, fileName) {
|
|
2638
|
+
let formData = new import_form_data.default();
|
|
2639
|
+
return formData.append("file", fileBuffer, {
|
|
2640
|
+
filename: fileName,
|
|
2641
|
+
contentType: "application/zip"
|
|
2642
|
+
}), externalTrackerApiRequest(`/issues/${issueKey}/attachments`, {
|
|
2643
|
+
method: "POST",
|
|
2644
|
+
formData
|
|
2645
|
+
});
|
|
2646
|
+
}
|
|
2647
|
+
async function getIssueTransitions(issueKey) {
|
|
2648
|
+
return externalTrackerApiRequest(`/issues/${issueKey}/transitions`, {
|
|
2649
|
+
method: "GET"
|
|
2650
|
+
});
|
|
2651
|
+
}
|
|
2652
|
+
async function executeIssueTransition(issueKey, transitionId) {
|
|
2653
|
+
await externalTrackerApiRequest(
|
|
2654
|
+
`/issues/${issueKey}/transitions/${transitionId}/_execute`,
|
|
2655
|
+
{
|
|
2656
|
+
method: "POST",
|
|
2657
|
+
body: {}
|
|
2658
|
+
}
|
|
2659
|
+
);
|
|
2660
|
+
}
|
|
2661
|
+
async function getIssue(issueKey) {
|
|
2662
|
+
return externalTrackerApiRequest(`/issues/${issueKey}`, {
|
|
2663
|
+
method: "GET"
|
|
2664
|
+
});
|
|
2665
|
+
}
|
|
2666
|
+
async function addIssueComment(issueKey, text) {
|
|
2667
|
+
await externalTrackerApiRequest(`/issues/${issueKey}/comments`, {
|
|
2668
|
+
method: "POST",
|
|
2669
|
+
body: { text }
|
|
2670
|
+
});
|
|
2671
|
+
}
|
|
2672
|
+
async function getMyPluginIssues() {
|
|
2673
|
+
return externalTrackerApiRequest("/issues/_search", {
|
|
2674
|
+
method: "POST",
|
|
2675
|
+
body: {
|
|
2676
|
+
filter: {
|
|
2677
|
+
queue: "PLUGINMOD",
|
|
2678
|
+
createdBy: "me()"
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
});
|
|
2682
|
+
}
|
|
2683
|
+
var import_form_data, PLUGINMOD_QUEUE, init_tracker = __esm({
|
|
2684
|
+
"src/distributions/external/tracker.ts"() {
|
|
2685
|
+
"use strict";
|
|
2686
|
+
import_form_data = __toESM(require("form-data"));
|
|
2687
|
+
init_trackerApiRequest();
|
|
2688
|
+
PLUGINMOD_QUEUE = "PLUGINMOD";
|
|
2689
|
+
}
|
|
2690
|
+
});
|
|
2691
|
+
|
|
2692
|
+
// src/distributions/external/info.ts
|
|
2693
|
+
async function infoExternal(issueKey) {
|
|
2694
|
+
let targetIssueKey = issueKey;
|
|
2695
|
+
if (targetIssueKey || (targetIssueKey = (await pluginStateManager.load()).trackerIssueKey), !targetIssueKey) {
|
|
2696
|
+
logger_default.warning(
|
|
2697
|
+
`No issue key provided and plugin has not been submitted yet. Run "${CLI_NAME} submit" first.`
|
|
2698
|
+
), logger_default.suggest(`${CLI_NAME} submit`);
|
|
2699
|
+
return;
|
|
2700
|
+
}
|
|
2701
|
+
logger_default.info(`\u23F3 Fetching plugin info for ${targetIssueKey}...`);
|
|
2702
|
+
try {
|
|
2703
|
+
let issue = await getIssue(targetIssueKey);
|
|
2704
|
+
showTrackerPluginInfo(issue);
|
|
2705
|
+
} catch (error2) {
|
|
2706
|
+
throw logger_default.error(`Failed to fetch plugin info for ${targetIssueKey}`), error2;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
var init_info = __esm({
|
|
2710
|
+
"src/distributions/external/info.ts"() {
|
|
2711
|
+
"use strict";
|
|
2712
|
+
init_pluginStateManager();
|
|
2713
|
+
init_logger();
|
|
2714
|
+
init_pluginDisplay();
|
|
2715
|
+
init_meta();
|
|
2716
|
+
init_tracker();
|
|
2717
|
+
}
|
|
2718
|
+
});
|
|
2719
|
+
|
|
2720
|
+
// src/distributions/external/list.ts
|
|
2721
|
+
async function listExternal() {
|
|
2722
|
+
logger_default.info("\u23F3 Fetching my plugins from Tracker...");
|
|
2723
|
+
try {
|
|
2724
|
+
let issues = await getMyPluginIssues();
|
|
2725
|
+
showTrackerPluginList(issues);
|
|
2726
|
+
} catch (error2) {
|
|
2727
|
+
throw logger_default.error("Failed to fetch plugins list"), error2;
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
var init_list = __esm({
|
|
2731
|
+
"src/distributions/external/list.ts"() {
|
|
2732
|
+
"use strict";
|
|
2733
|
+
init_logger();
|
|
2734
|
+
init_pluginDisplay();
|
|
2735
|
+
init_tracker();
|
|
2736
|
+
}
|
|
2737
|
+
});
|
|
2738
|
+
|
|
2739
|
+
// src/distributions/external/login.ts
|
|
2740
|
+
async function loginExternal() {
|
|
2741
|
+
console.info(
|
|
2742
|
+
import_picocolors3.default.dim(
|
|
2743
|
+
"To get an OAuth token for Yandex Tracker, please contact Tracker support and request one."
|
|
2744
|
+
)
|
|
2745
|
+
), console.info("");
|
|
2746
|
+
let trimmed = (await (0, import_prompts2.input)({
|
|
2747
|
+
message: "Enter your OAuth token:",
|
|
2748
|
+
required: !0
|
|
2749
|
+
})).trim();
|
|
2750
|
+
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.');
|
|
2751
|
+
}
|
|
2752
|
+
function logoutExternal() {
|
|
2753
|
+
if (!externalAuthManager.data) {
|
|
2754
|
+
logger_default.warning("You are not logged in.");
|
|
2755
|
+
return;
|
|
2756
|
+
}
|
|
2757
|
+
externalAuthManager.removeAuthData(), logger_default.success("Successfully logged out.");
|
|
2758
|
+
}
|
|
2759
|
+
var import_prompts2, import_picocolors3, init_login = __esm({
|
|
2760
|
+
"src/distributions/external/login.ts"() {
|
|
2761
|
+
"use strict";
|
|
2762
|
+
import_prompts2 = require("@inquirer/prompts"), import_picocolors3 = __toESM(require("picocolors"));
|
|
2763
|
+
init_logger();
|
|
2764
|
+
init_authManager();
|
|
2765
|
+
}
|
|
2766
|
+
});
|
|
2767
|
+
|
|
2768
|
+
// src/utils/execCommand.ts
|
|
2769
|
+
var import_execa, execCommand, init_execCommand = __esm({
|
|
2770
|
+
"src/utils/execCommand.ts"() {
|
|
2771
|
+
"use strict";
|
|
2772
|
+
import_execa = require("execa"), execCommand = async (command, cwd = process.cwd(), env) => {
|
|
2773
|
+
await (0, import_execa.execa)(command, {
|
|
2774
|
+
cwd,
|
|
2775
|
+
shell: !0,
|
|
2776
|
+
stdio: "inherit",
|
|
2777
|
+
env: env ? { ...process.env, ...env } : void 0
|
|
2778
|
+
});
|
|
2779
|
+
};
|
|
2780
|
+
}
|
|
2781
|
+
});
|
|
2782
|
+
|
|
2783
|
+
// src/commands/constants/templateCommands.ts
|
|
2784
|
+
var pluginCmd, init_templateCommands = __esm({
|
|
2785
|
+
"src/commands/constants/templateCommands.ts"() {
|
|
2786
|
+
"use strict";
|
|
2787
|
+
pluginCmd = {
|
|
2788
|
+
install: "npm install",
|
|
2789
|
+
build: "npm run build",
|
|
2790
|
+
dev: "npm run dev",
|
|
2791
|
+
lint: "npm run lint",
|
|
2792
|
+
typecheck: "npm run typecheck",
|
|
2793
|
+
test: "npm test",
|
|
2794
|
+
audit: "npm audit --audit-level=critical"
|
|
2795
|
+
};
|
|
2796
|
+
}
|
|
2797
|
+
});
|
|
2798
|
+
|
|
2799
|
+
// src/commands/build.ts
|
|
2800
|
+
var build, init_build = __esm({
|
|
2801
|
+
"src/commands/build.ts"() {
|
|
2802
|
+
"use strict";
|
|
2803
|
+
init_execCommand();
|
|
2804
|
+
init_logger();
|
|
2805
|
+
init_templateCommands();
|
|
2806
|
+
build = async ({ environment = "production" } = {}) => {
|
|
2807
|
+
logger_default.info("\u{1F528} Building project..."), await execCommand(pluginCmd.install), await execCommand(
|
|
2808
|
+
pluginCmd.build,
|
|
2809
|
+
process.cwd(),
|
|
2810
|
+
environment ? { VITE_DEPLOY_ENV: environment } : void 0
|
|
2811
|
+
);
|
|
2812
|
+
};
|
|
2813
|
+
}
|
|
2814
|
+
});
|
|
2815
|
+
|
|
2816
|
+
// src/utils/marketplace.ts
|
|
2817
|
+
function validateMarketplaceAssets() {
|
|
2818
|
+
let marketplaceDir = import_path9.default.resolve(MARKETPLACE_DIR);
|
|
2819
|
+
ensurePathExists(
|
|
2820
|
+
marketplaceDir,
|
|
2821
|
+
"Marketplace folder not found. Create ./marketplace and add index.md and header-image.jpg before publishing."
|
|
2822
|
+
), ensurePathExists(
|
|
2823
|
+
import_path9.default.join(marketplaceDir, MARKETPLACE_INDEX_FILE),
|
|
2824
|
+
"Marketplace description not found. Add ./marketplace/index.md before publishing."
|
|
2825
|
+
), ensurePathExists(
|
|
2826
|
+
import_path9.default.join(marketplaceDir, MARKETPLACE_HEADER_IMAGE_FILE),
|
|
2827
|
+
"Marketplace header image not found. Add ./marketplace/header-image.jpg before publishing."
|
|
2828
|
+
), ensurePathExists(
|
|
2829
|
+
import_path9.default.resolve(PUBLIC_DIR, PUBLIC_LOGO_FILE),
|
|
2830
|
+
"Plugin logo not found. Add ./public/logo.svg before publishing."
|
|
2831
|
+
);
|
|
2832
|
+
}
|
|
2833
|
+
function validateArchiveSources() {
|
|
2834
|
+
ensurePathExists(import_path9.default.resolve(DIST_DIR), "Dist folder not found. Build the project first."), ensurePathExists(
|
|
2835
|
+
import_path9.default.resolve(SRC_DIR),
|
|
2836
|
+
"Source folder not found. Add ./src before publishing."
|
|
2837
|
+
), ensurePathExists(import_path9.default.resolve(MANIFEST_FILE2), "manifest.json not found in plugin root."), validateMarketplaceAssets();
|
|
2838
|
+
}
|
|
2839
|
+
var import_fs10, import_path9, MARKETPLACE_DIR, MARKETPLACE_INDEX_FILE, MARKETPLACE_HEADER_IMAGE_FILE, PUBLIC_DIR, PUBLIC_LOGO_FILE, MANIFEST_FILE2, DIST_DIR, SRC_DIR, ensurePathExists, validateManifestPublishingFields, ensureManifestCatalogFields, marketplacePaths, init_marketplace = __esm({
|
|
2840
|
+
"src/utils/marketplace.ts"() {
|
|
2841
|
+
"use strict";
|
|
2842
|
+
import_fs10 = __toESM(require("fs")), import_path9 = __toESM(require("path"));
|
|
2843
|
+
init_manifestManager();
|
|
2844
|
+
init_logger();
|
|
2845
|
+
MARKETPLACE_DIR = "marketplace", MARKETPLACE_INDEX_FILE = "index.md", MARKETPLACE_HEADER_IMAGE_FILE = "header-image.jpg", PUBLIC_DIR = "public", PUBLIC_LOGO_FILE = "logo.svg", MANIFEST_FILE2 = "manifest.json", DIST_DIR = "dist", SRC_DIR = "src", ensurePathExists = (targetPath, errorMessage) => {
|
|
2846
|
+
import_fs10.default.existsSync(targetPath) || (logger_default.error(errorMessage), process.exit(1));
|
|
2847
|
+
}, validateManifestPublishingFields = async () => {
|
|
2848
|
+
let manifest = await manifestManager.load();
|
|
2849
|
+
ensureManifestCatalogFields(manifest);
|
|
2850
|
+
}, ensureManifestCatalogFields = (manifest) => {
|
|
2851
|
+
(!manifest.name?.ru || !manifest.name?.en) && (logger_default.error(
|
|
2852
|
+
'Manifest field "name" is required for publishing. Add localized "name.ru" and "name.en" to ./manifest.json.'
|
|
2853
|
+
), process.exit(1)), (!manifest.description?.ru || !manifest.description?.en) && (logger_default.error(
|
|
2854
|
+
'Manifest field "description" is required for publishing. Add localized "description.ru" and "description.en" to ./manifest.json.'
|
|
2855
|
+
), process.exit(1));
|
|
2856
|
+
};
|
|
2857
|
+
marketplacePaths = {
|
|
2858
|
+
distDir: DIST_DIR,
|
|
2859
|
+
srcDir: SRC_DIR,
|
|
2860
|
+
marketplaceDir: MARKETPLACE_DIR,
|
|
2861
|
+
manifestFile: MANIFEST_FILE2
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
|
|
2866
|
+
// src/utils/pluginPackageScripts.ts
|
|
2867
|
+
function readPluginPackageScripts(cwd = process.cwd()) {
|
|
2868
|
+
let packageJsonPath = import_path10.default.join(cwd, "package.json");
|
|
2869
|
+
return import_fs11.default.existsSync(packageJsonPath) ? JSON.parse(import_fs11.default.readFileSync(packageJsonPath, "utf-8")).scripts ?? {} : null;
|
|
2870
|
+
}
|
|
2871
|
+
function hasPluginScript(name, cwd = process.cwd()) {
|
|
2872
|
+
return !!readPluginPackageScripts(cwd)?.[name];
|
|
2873
|
+
}
|
|
2874
|
+
var import_fs11, import_path10, init_pluginPackageScripts = __esm({
|
|
2875
|
+
"src/utils/pluginPackageScripts.ts"() {
|
|
2876
|
+
"use strict";
|
|
2877
|
+
import_fs11 = __toESM(require("fs")), import_path10 = __toESM(require("path"));
|
|
2878
|
+
}
|
|
2879
|
+
});
|
|
2880
|
+
|
|
2881
|
+
// src/commands/submit/utils/runSubmitPrechecks.ts
|
|
2882
|
+
async function runSubmitPrechecks(options = {}) {
|
|
2883
|
+
if (options.skip) {
|
|
2884
|
+
logger_default.warning("Skipping pre-submit checks (--skip-checks).");
|
|
2885
|
+
return;
|
|
2886
|
+
}
|
|
2887
|
+
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 () => {
|
|
2888
|
+
await validateManifestPublishingFields(), validateMarketplaceAssets();
|
|
2889
|
+
}), 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(
|
|
2890
|
+
'No "test" script in package.json \u2014 add tests before publishing, or run submit with --skip-checks.'
|
|
2891
|
+
), await runShellStep("Check dependency vulnerabilities", pluginCmd.audit), logger_default.separator(), logger_default.success("Pre-submit checks passed"), logger_default.separator();
|
|
2892
|
+
}
|
|
2893
|
+
var import_picocolors4, stepStart, stepDone, runStep, runShellStep, init_runSubmitPrechecks = __esm({
|
|
2894
|
+
"src/commands/submit/utils/runSubmitPrechecks.ts"() {
|
|
2895
|
+
"use strict";
|
|
2896
|
+
import_picocolors4 = __toESM(require("picocolors"));
|
|
2897
|
+
init_manifestManager();
|
|
2898
|
+
init_execCommand();
|
|
2899
|
+
init_logger();
|
|
2900
|
+
init_marketplace();
|
|
2901
|
+
init_pluginPackageScripts();
|
|
2902
|
+
init_templateCommands();
|
|
2903
|
+
stepStart = (label) => {
|
|
2904
|
+
console.info(`${import_picocolors4.default.cyan("\u25B8")} ${label}`);
|
|
2905
|
+
}, stepDone = (label) => {
|
|
2906
|
+
console.info(`${import_picocolors4.default.green("\u2713")} ${label}`), console.info("");
|
|
2907
|
+
}, runStep = async (label, run) => {
|
|
2908
|
+
stepStart(label), await run(), stepDone(label);
|
|
2909
|
+
}, runShellStep = async (label, command) => {
|
|
2910
|
+
stepStart(label), console.info(import_picocolors4.default.dim(` $ ${command}`)), await execCommand(command), stepDone(label);
|
|
2911
|
+
};
|
|
2912
|
+
}
|
|
2913
|
+
});
|
|
2914
|
+
|
|
2915
|
+
// src/utils/buildArchive.ts
|
|
2916
|
+
async function buildArchive() {
|
|
2917
|
+
return validateArchiveSources(), (await manifestManager.load()).manifest_version === void 0 && (logger_default.error(
|
|
2918
|
+
`manifest_version is missing in manifest.json. Run "${CLI_NAME2} up" or add "manifest_version": 1 manually before uploading.`
|
|
2919
|
+
), process.exit(1)), new Promise((resolve2, reject) => {
|
|
2920
|
+
let archive = (0, import_archiver.default)("zip", { zlib: { level: 9 } }), chunks = [];
|
|
2921
|
+
archive.on("data", (chunk) => chunks.push(chunk)), archive.on("end", () => {
|
|
2922
|
+
let buffer = Buffer.concat(chunks);
|
|
2923
|
+
if (logger_default.info(`\u{1F4E6} Archive created (${buffer.length} bytes)`), isVerboseEnabled()) {
|
|
2924
|
+
let debugPath = writeVerboseArtifact("archive/latest-upload.zip", buffer);
|
|
2925
|
+
logger_default.info(`[platform-api-debug] Saved archive copy to ${debugPath}`);
|
|
2926
|
+
}
|
|
2927
|
+
resolve2(buffer);
|
|
2928
|
+
}), archive.on("error", reject), archive.glob("**/*", {
|
|
2929
|
+
cwd: process.cwd(),
|
|
2930
|
+
ignore: ["node_modules/**", "dist/**"],
|
|
2931
|
+
dot: !1
|
|
2932
|
+
});
|
|
2933
|
+
for (let dotfile of [".npmrc", ".nvmrc"]) {
|
|
2934
|
+
let dotfilePath = import_path11.default.resolve(dotfile);
|
|
2935
|
+
import_fs12.default.existsSync(dotfilePath) && archive.file(dotfilePath, { name: dotfile });
|
|
2936
|
+
}
|
|
2937
|
+
archive.file(import_path11.default.resolve(marketplacePaths.manifestFile), { name: "src/manifest.json" }), archive.glob(
|
|
2938
|
+
"**/*",
|
|
2939
|
+
{
|
|
2940
|
+
cwd: import_path11.default.resolve(marketplacePaths.distDir),
|
|
2941
|
+
dot: !1
|
|
2942
|
+
},
|
|
2943
|
+
{ prefix: "dist/" }
|
|
2944
|
+
), archive.finalize();
|
|
2945
|
+
});
|
|
2946
|
+
}
|
|
2947
|
+
var import_fs12, import_path11, import_archiver, init_buildArchive = __esm({
|
|
2948
|
+
"src/utils/buildArchive.ts"() {
|
|
2949
|
+
"use strict";
|
|
2950
|
+
import_fs12 = __toESM(require("fs")), import_path11 = __toESM(require("path")), import_archiver = __toESM(require("archiver"));
|
|
2951
|
+
init_manifestManager();
|
|
2952
|
+
init_meta2();
|
|
2953
|
+
init_logger();
|
|
2954
|
+
init_marketplace();
|
|
2955
|
+
init_verbose();
|
|
2956
|
+
}
|
|
2957
|
+
});
|
|
2958
|
+
|
|
2959
|
+
// src/distributions/external/submit.ts
|
|
2960
|
+
async function submitExternal(options = {}) {
|
|
2961
|
+
await runSubmitPrechecks({ skip: options.skipChecks });
|
|
2962
|
+
let manifest = await manifestManager.load(), issueKey = (await pluginStateManager.load()).trackerIssueKey;
|
|
2963
|
+
if (issueKey)
|
|
2964
|
+
try {
|
|
2965
|
+
await getIssue(issueKey);
|
|
2966
|
+
} catch {
|
|
2967
|
+
issueKey = void 0;
|
|
2968
|
+
}
|
|
2969
|
+
let pluginId = manifest.id ?? (0, import_crypto.randomUUID)();
|
|
2970
|
+
manifest.id || await manifestManager.update({ id: pluginId });
|
|
2971
|
+
let manifestJson = await manifestManager.loadRaw();
|
|
2972
|
+
if (issueKey) {
|
|
2973
|
+
logger_default.verbose(`\u23F3 Updating issue ${issueKey} with latest manifest...`);
|
|
2974
|
+
let issueDescription = buildIssueDescription({
|
|
2975
|
+
pluginId,
|
|
2976
|
+
slug: manifest.slug,
|
|
2977
|
+
version: manifest.version,
|
|
2978
|
+
manifestJson
|
|
2979
|
+
});
|
|
2980
|
+
await updatePluginIssue(issueKey, { description: issueDescription });
|
|
2981
|
+
} else if (options.ticket === !1) {
|
|
2982
|
+
logger_default.warning(
|
|
2983
|
+
"Tracker issue is required for tracker-backed submit. Skipping ticket creation."
|
|
2984
|
+
);
|
|
2985
|
+
return;
|
|
2986
|
+
} else {
|
|
2987
|
+
logger_default.info("\u23F3 Creating plugin issue in Tracker...");
|
|
2988
|
+
let issue = await createPluginIssue({
|
|
2989
|
+
pluginId,
|
|
2990
|
+
slug: manifest.slug,
|
|
2991
|
+
version: manifest.version,
|
|
2992
|
+
manifestJson
|
|
2993
|
+
});
|
|
2994
|
+
await pluginStateManager.update({ trackerIssueKey: issue.key }), issueKey = issue.key, logger_default.info(` Tracker issue : ${issueKey}`);
|
|
2995
|
+
}
|
|
2996
|
+
logger_default.info("\u{1F528} Building plugin..."), await build(), logger_default.info("\u{1F4E6} Creating archive...");
|
|
2997
|
+
let archiveBuffer = await buildArchive(), archiveName = `${manifest.slug}-${manifest.version}.zip`;
|
|
2998
|
+
logger_default.verbose(`\u2B06\uFE0F Attaching ${archiveName} to ${issueKey}...`), await attachFileToIssue(issueKey, archiveBuffer, archiveName), await addIssueComment(
|
|
2999
|
+
issueKey,
|
|
3000
|
+
`Updated bundle: \`${archiveName}\` (${archiveBuffer.length} bytes)`
|
|
3001
|
+
), logger_default.verbose(`\u23F3 Fetching available transitions for ${issueKey}...`);
|
|
3002
|
+
let transitions = await getIssueTransitions(issueKey), submitTransition = transitions.find(
|
|
3003
|
+
(t) => t.display?.toLowerCase().includes(SUBMIT_TRANSITION_DISPLAY) || t.id?.toLowerCase().includes("waitingforapprove") || t.id?.toLowerCase().includes("waiting")
|
|
3004
|
+
);
|
|
3005
|
+
if (!submitTransition) {
|
|
3006
|
+
let available = transitions.map((t) => `"${t.display ?? t.id}"`).join(", ");
|
|
3007
|
+
logger_default.error(
|
|
3008
|
+
`Could not find a "Waiting for approve" transition on ${issueKey}. Available: ${available}`
|
|
3009
|
+
);
|
|
3010
|
+
return;
|
|
3011
|
+
}
|
|
3012
|
+
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();
|
|
3013
|
+
}
|
|
3014
|
+
var import_crypto, SUBMIT_TRANSITION_DISPLAY, init_submit = __esm({
|
|
3015
|
+
"src/distributions/external/submit.ts"() {
|
|
3016
|
+
"use strict";
|
|
3017
|
+
import_crypto = require("crypto");
|
|
3018
|
+
init_build();
|
|
3019
|
+
init_runSubmitPrechecks();
|
|
3020
|
+
init_manifestManager();
|
|
3021
|
+
init_pluginStateManager();
|
|
3022
|
+
init_buildArchive();
|
|
3023
|
+
init_logger();
|
|
3024
|
+
init_tracker();
|
|
3025
|
+
SUBMIT_TRANSITION_DISPLAY = "waiting for approve";
|
|
3026
|
+
}
|
|
3027
|
+
});
|
|
3028
|
+
|
|
3029
|
+
// src/distributions/external/registerCommands.ts
|
|
3030
|
+
var registerCommands_exports = {};
|
|
3031
|
+
__export(registerCommands_exports, {
|
|
3032
|
+
registerDistributionCommands: () => registerDistributionCommands
|
|
3033
|
+
});
|
|
3034
|
+
function registerDistributionCommands(program) {
|
|
3035
|
+
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(
|
|
3036
|
+
withErrorHandling(async () => {
|
|
3037
|
+
logoutExternal();
|
|
3038
|
+
})
|
|
3039
|
+
), program.command("submit").description("build plugin, create a Tracker issue in PLUGINMOD, and submit for review").addOption(skipChecksOption).action(withErrorHandling(submitExternal)), program.command("doctor").description("validate local plugin project, external config and auth").option("--network", "verify OAuth token with Tracker /myself", !1).option("--publish", "treat publish-readiness checks as failures", !1).option("--json", "machine-readable output", !1).action((options) => withErrorHandling(doctor)(options)), program.command("list").description("list all your plugins and their moderation status").action(withErrorHandling(listExternal)), program.command("info [issue-key]").description(
|
|
3040
|
+
"show moderation status of a plugin (uses .tracker-plugin issue key if not provided)"
|
|
3041
|
+
).action(withErrorHandling(infoExternal));
|
|
3042
|
+
}
|
|
3043
|
+
var init_registerCommands = __esm({
|
|
3044
|
+
"src/distributions/external/registerCommands.ts"() {
|
|
3045
|
+
"use strict";
|
|
3046
|
+
init_doctor();
|
|
3047
|
+
init_options();
|
|
3048
|
+
init_registerCommand();
|
|
3049
|
+
init_withErrorHandling();
|
|
3050
|
+
init_info();
|
|
3051
|
+
init_list();
|
|
3052
|
+
init_login();
|
|
3053
|
+
init_meta();
|
|
3054
|
+
init_submit();
|
|
3055
|
+
}
|
|
3056
|
+
});
|
|
3057
|
+
|
|
3058
|
+
// src/index.ts
|
|
3059
|
+
var import_commander2 = require("commander");
|
|
3060
|
+
init_meta2();
|
|
3061
|
+
|
|
3062
|
+
// src/distribution/registerCommands.ts
|
|
3063
|
+
init_flag();
|
|
3064
|
+
var impl4 = (init_registerCommands(), __toCommonJS(registerCommands_exports)), { registerDistributionCommands: registerDistributionCommands2 } = impl4;
|
|
3065
|
+
|
|
3066
|
+
// src/utils/checkUpdate.ts
|
|
3067
|
+
var import_node_fetch2 = __toESM(require("node-fetch"));
|
|
3068
|
+
|
|
3069
|
+
// src/distribution/hosts.ts
|
|
3070
|
+
init_flag();
|
|
3071
|
+
var impl5 = (init_hosts(), __toCommonJS(hosts_exports)), {
|
|
3072
|
+
getS3Endpoint: getS3Endpoint2,
|
|
3073
|
+
getMdsEndpoint: getMdsEndpoint2,
|
|
3074
|
+
getS3Region: getS3Region2,
|
|
3075
|
+
getBuckets: getBuckets2,
|
|
3076
|
+
getPluginDownloadBase: getPluginDownloadBase2,
|
|
3077
|
+
getPlatformBaseUrl: getPlatformBaseUrl2,
|
|
3078
|
+
getTrackerBaseUrl: getTrackerBaseUrl2,
|
|
3079
|
+
getOAuthTokenUrl: getOAuthTokenUrl2,
|
|
3080
|
+
getUpdateCheckInfo: getUpdateCheckInfo2
|
|
3081
|
+
} = impl5;
|
|
3082
|
+
|
|
3083
|
+
// src/utils/checkUpdate.ts
|
|
3084
|
+
init_logger();
|
|
3085
|
+
var SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/, DIAGNOSTIC_FLAGS = /* @__PURE__ */ new Set(["--version", "-V", "--help", "-h", "help"]), parse = (v) => {
|
|
3086
|
+
let m = SEMVER_RE.exec(v);
|
|
3087
|
+
return m ? { major: +m[1], minor: +m[2], patch: +m[3] } : null;
|
|
3088
|
+
}, isDiagnosticInvocation = () => {
|
|
3089
|
+
let args = process.argv.slice(2);
|
|
3090
|
+
return args.length === 0 ? !0 : args.some((a) => DIAGNOSTIC_FLAGS.has(a));
|
|
3091
|
+
}, 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) => {
|
|
3092
|
+
if (version === "unknown" || isDiagnosticInvocation() || process.env.TRACKER_CLI_SKIP_UPDATE_CHECK) return;
|
|
3093
|
+
let info2 = getUpdateCheckInfo2();
|
|
3094
|
+
if (!info2) return;
|
|
3095
|
+
let current = parse(version);
|
|
3096
|
+
if (current)
|
|
3097
|
+
try {
|
|
3098
|
+
let response = await (0, import_node_fetch2.default)(`${info2.registryUrl}/${info2.packageName}/latest`);
|
|
3099
|
+
if (!response.ok) return;
|
|
3100
|
+
let json = await response.json(), latest = parse(json.version);
|
|
3101
|
+
if (!latest) return;
|
|
3102
|
+
let kind = classify(current, latest);
|
|
3103
|
+
if (kind === "none") return;
|
|
3104
|
+
let installCmd = `npm i -g ${info2.packageName}@latest --registry=${info2.registryUrl}`;
|
|
3105
|
+
if (kind === "minorOrMajor") {
|
|
3106
|
+
logger_default.newLine(), logger_default.error(
|
|
3107
|
+
`Update required ${version} \u2192 ${json.version}
|
|
3108
|
+
This release is not backward-compatible with your installed version.`
|
|
3109
|
+
), logger_default.suggest(installCmd), process.exit(1);
|
|
3110
|
+
return;
|
|
3111
|
+
}
|
|
3112
|
+
logger_default.newLine(), logger_default.info(`\u{1F514} Update available ${version} \u2192 ${json.version}
|
|
3113
|
+
Run: ${installCmd}`);
|
|
3114
|
+
} catch {
|
|
3115
|
+
}
|
|
3116
|
+
};
|
|
3117
|
+
|
|
3118
|
+
// src/utils/shouldRunUpdateCheck.ts
|
|
3119
|
+
function shouldRunUpdateCheck(argv) {
|
|
3120
|
+
return !(argv.includes("doctor") && argv.includes("--json"));
|
|
3121
|
+
}
|
|
3122
|
+
|
|
3123
|
+
// src/index.ts
|
|
3124
|
+
init_build();
|
|
546
3125
|
|
|
547
3126
|
// src/commands/create/index.ts
|
|
3127
|
+
var path18 = __toESM(require("path")), import_prompts3 = require("@inquirer/prompts");
|
|
3128
|
+
init_constants();
|
|
3129
|
+
init_meta2();
|
|
548
3130
|
init_logger();
|
|
549
3131
|
|
|
3132
|
+
// src/commands/create/templateChoices.ts
|
|
3133
|
+
init_constants();
|
|
3134
|
+
var DEFERRED_TEMPLATE_REASON = "will be added later", DEFERRED_TEMPLATES = /* @__PURE__ */ new Set(["user-card-info", "user-card-calendar"]);
|
|
3135
|
+
function getTemplateChoices(service) {
|
|
3136
|
+
return TEMPLATES.filter((templateName) => TEMPLATE_SERVICE[templateName] === service).map(
|
|
3137
|
+
(templateName) => ({
|
|
3138
|
+
name: templateName,
|
|
3139
|
+
value: templateName,
|
|
3140
|
+
disabled: DEFERRED_TEMPLATES.has(templateName) ? DEFERRED_TEMPLATE_REASON : void 0
|
|
3141
|
+
})
|
|
3142
|
+
);
|
|
3143
|
+
}
|
|
3144
|
+
|
|
550
3145
|
// src/commands/create/utils/getWelcomeMessage.ts
|
|
551
|
-
var
|
|
552
|
-
${
|
|
3146
|
+
var import_picocolors5 = __toESM(require("picocolors")), getWelcomeMessage = (pwd) => `
|
|
3147
|
+
${import_picocolors5.default.bold(import_picocolors5.default.white("\u{1F680} Create new tracker plugin"))}
|
|
553
3148
|
|
|
554
|
-
${
|
|
3149
|
+
${import_picocolors5.default.dim(`\u{1F4C1} Creating an app in your current directory: ${pwd}`)}
|
|
555
3150
|
|
|
556
|
-
${
|
|
3151
|
+
${import_picocolors5.default.dim("Press")} ${import_picocolors5.default.yellow("Ctrl+C")} ${import_picocolors5.default.dim("to cancel.")}
|
|
557
3152
|
`;
|
|
558
3153
|
|
|
559
3154
|
// src/commands/create/utils/initManifest.ts
|
|
560
|
-
var
|
|
3155
|
+
var fs11 = __toESM(require("fs")), path13 = __toESM(require("path"));
|
|
561
3156
|
|
|
562
3157
|
// src/commands/create/utils/generateManifest.ts
|
|
3158
|
+
init_constants();
|
|
3159
|
+
var FULL_CONTEXT_TEMPLATES = /* @__PURE__ */ new Set(["user-card-info", "user-card-calendar"]);
|
|
563
3160
|
function buildSlots(template, slotTitle) {
|
|
564
3161
|
let slotNames = TEMPLATE_SLOTS[template];
|
|
565
3162
|
if (slotNames.length === 0) return;
|
|
566
|
-
let slotEntry = {
|
|
3163
|
+
let service = TEMPLATE_SERVICE[template], contextLevel = FULL_CONTEXT_TEMPLATES.has(template) ? "full" : "basic", slotEntry = {
|
|
567
3164
|
entrypoint: "index.html",
|
|
568
|
-
title: { ru: slotTitle, en: slotTitle }
|
|
3165
|
+
title: { ru: slotTitle, en: slotTitle },
|
|
3166
|
+
contextLevel
|
|
569
3167
|
};
|
|
570
3168
|
return {
|
|
571
|
-
|
|
3169
|
+
[service]: Object.fromEntries(slotNames.map((slotName) => [slotName, [slotEntry]]))
|
|
572
3170
|
};
|
|
573
3171
|
}
|
|
574
3172
|
var generateManifest = (answers) => ({
|
|
575
3173
|
$schema: "./manifest.schema.json",
|
|
576
3174
|
manifest_version: 1,
|
|
577
|
-
supported_services: [
|
|
3175
|
+
supported_services: [TEMPLATE_SERVICE[answers.template]],
|
|
578
3176
|
slug: answers.packageSlug,
|
|
579
3177
|
version: answers.version,
|
|
580
3178
|
name: {
|
|
@@ -592,57 +3190,59 @@ var generateManifest = (answers) => ({
|
|
|
592
3190
|
|
|
593
3191
|
// src/commands/create/utils/initManifest.ts
|
|
594
3192
|
var initManifest = ({ answers, targetDir }) => {
|
|
595
|
-
let generatedManifest = generateManifest(answers),
|
|
596
|
-
|
|
3193
|
+
let generatedManifest = generateManifest(answers), manifestPath = path13.join(targetDir, "manifest.json");
|
|
3194
|
+
fs11.writeFileSync(manifestPath, JSON.stringify(generatedManifest, null, 2), "utf-8");
|
|
597
3195
|
};
|
|
598
3196
|
|
|
599
3197
|
// 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");
|
|
3198
|
+
var fs14 = __toESM(require("fs")), path17 = __toESM(require("path"));
|
|
604
3199
|
|
|
605
3200
|
// src/distribution/templateSubstitution.ts
|
|
606
|
-
|
|
3201
|
+
init_flag();
|
|
3202
|
+
var isInternal = !1, templateDeps = [
|
|
3203
|
+
"@weavix/tracker-plugin-sdk",
|
|
3204
|
+
"@weavix/tracker-plugin-sdk-react",
|
|
3205
|
+
"@weavix/tracker-api-types"
|
|
3206
|
+
], overlayDirName = isInternal ? "_internal" : "_external";
|
|
607
3207
|
|
|
608
3208
|
// src/utils/copyDirectory.ts
|
|
609
|
-
var resolveTargetFileName = (file) => file.endsWith(".template") ? "." + file.replace(".template", "") : file, copyDirectory = async (sourceDir, targetDir) => {
|
|
610
|
-
let files = await (0,
|
|
3209
|
+
var fs12 = __toESM(require("fs")), import_path12 = __toESM(require("path")), import_tinyglobby2 = require("tinyglobby"), resolveTargetFileName = (file) => file.endsWith(".template") ? "." + file.replace(".template", "") : file, copyDirectory = async (sourceDir, targetDir) => {
|
|
3210
|
+
let files = await (0, import_tinyglobby2.glob)(["**/*"], {
|
|
611
3211
|
cwd: sourceDir,
|
|
612
3212
|
onlyFiles: !0,
|
|
613
3213
|
dot: !0
|
|
614
3214
|
});
|
|
615
3215
|
await Promise.all(
|
|
616
3216
|
files.map(async (file) => {
|
|
617
|
-
let sourcePath =
|
|
618
|
-
await
|
|
619
|
-
let content = await
|
|
620
|
-
await
|
|
3217
|
+
let sourcePath = import_path12.default.join(sourceDir, file), targetFile = resolveTargetFileName(file), targetPath = import_path12.default.join(targetDir, targetFile);
|
|
3218
|
+
await fs12.promises.mkdir(import_path12.default.dirname(targetPath), { recursive: !0 });
|
|
3219
|
+
let content = await fs12.promises.readFile(sourcePath);
|
|
3220
|
+
await fs12.promises.writeFile(targetPath, content);
|
|
621
3221
|
})
|
|
622
3222
|
);
|
|
623
3223
|
};
|
|
624
3224
|
|
|
625
3225
|
// src/utils/getProjectPath.ts
|
|
626
|
-
var
|
|
3226
|
+
var import_path13 = __toESM(require("path")), isDevelopment = () => __dirname.includes("/src/"), getProjectPath = (relativePath) => isDevelopment() ? import_path13.default.resolve(__dirname, "..", "..", relativePath) : import_path13.default.resolve(__dirname, relativePath), getTemplatesBaseDir = () => getProjectPath("templates"), getTemplatePath = (filename) => import_path13.default.join(getTemplatesBaseDir(), "_shared", filename), getOverlayTemplatePath = (overlayDir, filename) => import_path13.default.join(getTemplatesBaseDir(), overlayDir, filename);
|
|
627
3227
|
|
|
628
3228
|
// src/commands/create/utils/initTemplate.ts
|
|
629
3229
|
init_logger();
|
|
630
3230
|
|
|
631
3231
|
// src/commands/create/utils/updatePackageJson.ts
|
|
632
|
-
var
|
|
633
|
-
let packageJsonPath =
|
|
634
|
-
if (
|
|
635
|
-
let packageJson = JSON.parse(
|
|
636
|
-
packageJson.name = packageSlug,
|
|
3232
|
+
var fs13 = __toESM(require("fs")), path16 = __toESM(require("path")), updatePackageJson = (targetDir, packageSlug) => {
|
|
3233
|
+
let packageJsonPath = path16.join(targetDir, "package.json");
|
|
3234
|
+
if (fs13.existsSync(packageJsonPath)) {
|
|
3235
|
+
let packageJson = JSON.parse(fs13.readFileSync(packageJsonPath, "utf-8"));
|
|
3236
|
+
packageJson.name = packageSlug, fs13.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
637
3237
|
`);
|
|
638
3238
|
}
|
|
639
3239
|
};
|
|
640
3240
|
|
|
641
3241
|
// src/commands/create/utils/initTemplate.ts
|
|
642
3242
|
var initTemplate = async ({ answers, targetDir }) => {
|
|
643
|
-
|
|
644
|
-
let templatesBaseDir = getTemplatesBaseDir(), templatesDir =
|
|
645
|
-
await copyDirectory(sharedDir, targetDir), await copyDirectory(templatesDir, targetDir), updatePackageJson(targetDir, answers.packageSlug), logger_default.info("Created template with marketplace publication requirements."), logger_default.info(
|
|
3243
|
+
fs14.existsSync(targetDir) || fs14.mkdirSync(targetDir, { recursive: !0 });
|
|
3244
|
+
let templatesBaseDir = getTemplatesBaseDir(), templatesDir = path17.join(templatesBaseDir, answers.template), sharedDir = path17.join(templatesBaseDir, "_shared"), overlayDir = path17.join(templatesBaseDir, overlayDirName);
|
|
3245
|
+
await copyDirectory(sharedDir, targetDir), await copyDirectory(overlayDir, targetDir), await copyDirectory(templatesDir, targetDir), updatePackageJson(targetDir, answers.packageSlug), logger_default.info("Created template with marketplace publication requirements."), logger_default.info(
|
|
646
3246
|
"Before publishing, add ./marketplace/index.md, ./marketplace/header-image.jpg (784:325), and ./public/logo.svg (square)."
|
|
647
3247
|
);
|
|
648
3248
|
};
|
|
@@ -651,26 +3251,37 @@ var initTemplate = async ({ answers, targetDir }) => {
|
|
|
651
3251
|
var DEFAULT_VERSION = "0.0.1";
|
|
652
3252
|
async function create() {
|
|
653
3253
|
logger_default.info(getWelcomeMessage(process.cwd()));
|
|
654
|
-
let packageSlug = await (0,
|
|
3254
|
+
let packageSlug = await (0, import_prompts3.input)({
|
|
655
3255
|
message: "Enter app slug (e.g., my-tracker-plugin):",
|
|
656
3256
|
required: !0
|
|
657
|
-
}), pluginName = await (0,
|
|
3257
|
+
}), pluginName = await (0, import_prompts3.input)({
|
|
658
3258
|
message: "Enter plugin name:",
|
|
659
3259
|
required: !0
|
|
660
|
-
}), pluginDescription = await (0,
|
|
3260
|
+
}), pluginDescription = await (0, import_prompts3.input)({
|
|
661
3261
|
message: "Enter plugin description:",
|
|
662
3262
|
required: !0
|
|
663
|
-
}), supportEmail = await (0,
|
|
3263
|
+
}), supportEmail = await (0, import_prompts3.input)({
|
|
664
3264
|
message: "Enter support email:",
|
|
665
3265
|
required: !0,
|
|
666
3266
|
validate: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || "Please enter a valid email address"
|
|
667
|
-
}),
|
|
668
|
-
message: "Select a
|
|
669
|
-
choices:
|
|
670
|
-
name:
|
|
671
|
-
value:
|
|
3267
|
+
}), service = CREATE_SERVICES2.length === 1 ? CREATE_SERVICES2[0] : await (0, import_prompts3.select)({
|
|
3268
|
+
message: "Select a service:",
|
|
3269
|
+
choices: CREATE_SERVICES2.map((serviceName) => ({
|
|
3270
|
+
name: serviceName,
|
|
3271
|
+
value: serviceName
|
|
672
3272
|
}))
|
|
673
|
-
}),
|
|
3273
|
+
}), templateChoices = getTemplateChoices(service);
|
|
3274
|
+
if (templateChoices.every((choice) => choice.disabled)) {
|
|
3275
|
+
logger_default.warning(`No selectable templates are available for ${service} yet.`), logger_default.info(
|
|
3276
|
+
templateChoices.map((choice) => `- ${choice.name} ${choice.disabled ?? ""}`.trim()).join(`
|
|
3277
|
+
`)
|
|
3278
|
+
);
|
|
3279
|
+
return;
|
|
3280
|
+
}
|
|
3281
|
+
let template = await (0, import_prompts3.select)({
|
|
3282
|
+
message: "Select a template:",
|
|
3283
|
+
choices: templateChoices
|
|
3284
|
+
}), dataPermissions = await (0, import_prompts3.checkbox)({
|
|
674
3285
|
message: "Select data permissions (some popular options):",
|
|
675
3286
|
choices: TOP_DATA_PERMISSIONS.map((permission) => ({
|
|
676
3287
|
name: permission,
|
|
@@ -682,572 +3293,34 @@ async function create() {
|
|
|
682
3293
|
pluginName,
|
|
683
3294
|
pluginDescription,
|
|
684
3295
|
supportEmail,
|
|
3296
|
+
service,
|
|
685
3297
|
template,
|
|
686
3298
|
permissions: {
|
|
687
3299
|
data: dataPermissions
|
|
688
3300
|
},
|
|
689
3301
|
version: DEFAULT_VERSION
|
|
690
|
-
}, targetDir =
|
|
3302
|
+
}, targetDir = path18.join(process.cwd(), answers.packageSlug);
|
|
691
3303
|
await initTemplate({
|
|
692
3304
|
answers,
|
|
693
3305
|
targetDir
|
|
694
3306
|
}), initManifest({
|
|
695
3307
|
answers,
|
|
696
3308
|
targetDir
|
|
697
|
-
}), logger_default.newLine(), logger_default.success("
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
`${CLI_NAME2} debug`
|
|
701
|
-
]);
|
|
3309
|
+
}), logger_default.newLine(), logger_default.success("\u2705 Plugin created successfully!"), logger_default.info("\u{1F680} To start development:"), logger_default.commands("", [`cd ${answers.packageSlug}`, "npm install", `${CLI_NAME2} debug`]), logger_default.info(
|
|
3310
|
+
"\u{1F4CC} Important: After running debug, the plugin will be available in the Tracker interface, not at localhost. Open Tracker and check the plugin in the appropriate context."
|
|
3311
|
+
);
|
|
702
3312
|
}
|
|
703
3313
|
|
|
704
3314
|
// src/commands/debug/index.ts
|
|
705
|
-
var
|
|
706
|
-
|
|
707
|
-
// src/core/manifest/manifestManager.ts
|
|
708
|
-
var import_fs2 = require("fs"), import_promises = require("fs/promises"), import_ajv = __toESM(require("ajv")), import_ajv_formats = __toESM(require("ajv-formats"));
|
|
709
|
-
|
|
710
|
-
// src/core/manifest/formatValidationErrors.ts
|
|
711
|
-
var priorityOrder = [
|
|
712
|
-
"required",
|
|
713
|
-
"type",
|
|
714
|
-
"minLength",
|
|
715
|
-
"format",
|
|
716
|
-
"pattern",
|
|
717
|
-
"enum",
|
|
718
|
-
"additionalProperties",
|
|
719
|
-
"uniqueItems"
|
|
720
|
-
], errorMessages = {
|
|
721
|
-
required: (params) => `missing required property '${params.missingProperty}'`,
|
|
722
|
-
type: (params) => `must be ${params.type}`,
|
|
723
|
-
enum: (params) => `must be one of [${params.allowedValues.join(", ")}]`,
|
|
724
|
-
pattern: (params) => `must match pattern ${params.pattern}`,
|
|
725
|
-
format: (params) => `must be a valid ${params.format}`,
|
|
726
|
-
minLength: () => "must not be empty",
|
|
727
|
-
additionalProperties: (params) => `unexpected property '${params.additionalProperty}'`,
|
|
728
|
-
uniqueItems: () => "must contain unique items"
|
|
729
|
-
}, getPriority = (keyword) => {
|
|
730
|
-
let index = priorityOrder.indexOf(keyword);
|
|
731
|
-
return index === -1 ? priorityOrder.length : index;
|
|
732
|
-
}, formatValidationErrors = (errors) => {
|
|
733
|
-
let errorsByPath = {};
|
|
734
|
-
for (let error2 of errors) {
|
|
735
|
-
let path13 = error2.instancePath || "root";
|
|
736
|
-
errorsByPath[path13] || (errorsByPath[path13] = []), errorsByPath[path13].push(error2);
|
|
737
|
-
}
|
|
738
|
-
return Object.entries(errorsByPath).map(([path13, pathErrors]) => {
|
|
739
|
-
let error2 = [...pathErrors].sort(
|
|
740
|
-
(a, b) => getPriority(a.keyword) - getPriority(b.keyword)
|
|
741
|
-
)[0], formatter = errorMessages[error2.keyword], message = formatter ? formatter(error2.params) : error2.message;
|
|
742
|
-
return ` - ${path13}: ${message}`;
|
|
743
|
-
}).join(`
|
|
744
|
-
`);
|
|
745
|
-
};
|
|
746
|
-
|
|
747
|
-
// src/core/manifest/manifest.schema.json
|
|
748
|
-
var manifest_schema_default = {
|
|
749
|
-
$schema: "http://json-schema.org/draft-07/schema#",
|
|
750
|
-
title: "Manifest",
|
|
751
|
-
description: "Schema for validating plugin manifest",
|
|
752
|
-
type: "object",
|
|
753
|
-
required: [
|
|
754
|
-
"slug",
|
|
755
|
-
"version",
|
|
756
|
-
"permissions",
|
|
757
|
-
"name",
|
|
758
|
-
"description",
|
|
759
|
-
"support"
|
|
760
|
-
],
|
|
761
|
-
properties: {
|
|
762
|
-
$schema: {
|
|
763
|
-
type: "string"
|
|
764
|
-
},
|
|
765
|
-
id: {
|
|
766
|
-
type: "string",
|
|
767
|
-
description: "Unique identifier for the plugin ()",
|
|
768
|
-
minLength: 3,
|
|
769
|
-
maxLength: 63,
|
|
770
|
-
pattern: "^[a-z0-9-]+$"
|
|
771
|
-
},
|
|
772
|
-
manifest_version: {
|
|
773
|
-
type: "number",
|
|
774
|
-
description: "Manifest format version",
|
|
775
|
-
minimum: 1
|
|
776
|
-
},
|
|
777
|
-
supported_services: {
|
|
778
|
-
type: "array",
|
|
779
|
-
description: "Supported services for this plugin",
|
|
780
|
-
items: {
|
|
781
|
-
type: "string",
|
|
782
|
-
enum: [
|
|
783
|
-
"tracker"
|
|
784
|
-
]
|
|
785
|
-
},
|
|
786
|
-
minItems: 1,
|
|
787
|
-
uniqueItems: !0
|
|
788
|
-
},
|
|
789
|
-
slug: {
|
|
790
|
-
type: "string",
|
|
791
|
-
description: "Unique identifier for the plugin (lowercase letters, numbers, hyphen)",
|
|
792
|
-
minLength: 3,
|
|
793
|
-
maxLength: 63,
|
|
794
|
-
pattern: "^[a-z0-9-]+$"
|
|
795
|
-
},
|
|
796
|
-
version: {
|
|
797
|
-
type: "string",
|
|
798
|
-
description: "Version of the plugin (semver format required)",
|
|
799
|
-
minLength: 1,
|
|
800
|
-
pattern: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$"
|
|
801
|
-
},
|
|
802
|
-
name: {
|
|
803
|
-
type: "object",
|
|
804
|
-
description: "Localized plugin name",
|
|
805
|
-
required: [
|
|
806
|
-
"ru",
|
|
807
|
-
"en"
|
|
808
|
-
],
|
|
809
|
-
properties: {
|
|
810
|
-
ru: {
|
|
811
|
-
type: "string",
|
|
812
|
-
description: "Russian name",
|
|
813
|
-
minLength: 1,
|
|
814
|
-
maxLength: 30
|
|
815
|
-
},
|
|
816
|
-
en: {
|
|
817
|
-
type: "string",
|
|
818
|
-
description: "English name",
|
|
819
|
-
minLength: 1,
|
|
820
|
-
maxLength: 30
|
|
821
|
-
}
|
|
822
|
-
},
|
|
823
|
-
additionalProperties: !1
|
|
824
|
-
},
|
|
825
|
-
description: {
|
|
826
|
-
type: "object",
|
|
827
|
-
description: "Localized plugin description",
|
|
828
|
-
required: [
|
|
829
|
-
"ru",
|
|
830
|
-
"en"
|
|
831
|
-
],
|
|
832
|
-
properties: {
|
|
833
|
-
ru: {
|
|
834
|
-
type: "string",
|
|
835
|
-
description: "Russian description",
|
|
836
|
-
minLength: 1,
|
|
837
|
-
maxLength: 255
|
|
838
|
-
},
|
|
839
|
-
en: {
|
|
840
|
-
type: "string",
|
|
841
|
-
description: "English description",
|
|
842
|
-
minLength: 1,
|
|
843
|
-
maxLength: 255
|
|
844
|
-
}
|
|
845
|
-
},
|
|
846
|
-
additionalProperties: !1
|
|
847
|
-
},
|
|
848
|
-
support: {
|
|
849
|
-
type: "array",
|
|
850
|
-
description: "Support contact information",
|
|
851
|
-
items: {
|
|
852
|
-
type: "object",
|
|
853
|
-
required: [
|
|
854
|
-
"type",
|
|
855
|
-
"value"
|
|
856
|
-
],
|
|
857
|
-
properties: {
|
|
858
|
-
type: {
|
|
859
|
-
type: "string",
|
|
860
|
-
description: "Type of support contact",
|
|
861
|
-
enum: [
|
|
862
|
-
"email"
|
|
863
|
-
]
|
|
864
|
-
},
|
|
865
|
-
value: {
|
|
866
|
-
type: "string",
|
|
867
|
-
description: "Contact value",
|
|
868
|
-
minLength: 1,
|
|
869
|
-
maxLength: 100
|
|
870
|
-
}
|
|
871
|
-
},
|
|
872
|
-
additionalProperties: !1
|
|
873
|
-
},
|
|
874
|
-
minItems: 1
|
|
875
|
-
},
|
|
876
|
-
homepage: {
|
|
877
|
-
type: "string",
|
|
878
|
-
description: "Homepage URL for the plugin (http or https)",
|
|
879
|
-
pattern: "^https?://",
|
|
880
|
-
maxLength: 1e3
|
|
881
|
-
},
|
|
882
|
-
license: {
|
|
883
|
-
type: "string",
|
|
884
|
-
description: "License identifier (e.g., MIT, Apache-2.0)",
|
|
885
|
-
minLength: 1,
|
|
886
|
-
maxLength: 32
|
|
887
|
-
},
|
|
888
|
-
keywords: {
|
|
889
|
-
type: "array",
|
|
890
|
-
description: "Keywords for plugin discovery",
|
|
891
|
-
items: {
|
|
892
|
-
type: "string",
|
|
893
|
-
minLength: 1,
|
|
894
|
-
maxLength: 30
|
|
895
|
-
},
|
|
896
|
-
uniqueItems: !0
|
|
897
|
-
},
|
|
898
|
-
whatsnew: {
|
|
899
|
-
type: "string",
|
|
900
|
-
description: "What's new in this version",
|
|
901
|
-
minLength: 1,
|
|
902
|
-
maxLength: 300
|
|
903
|
-
},
|
|
904
|
-
externalHost: {
|
|
905
|
-
type: "string",
|
|
906
|
-
description: "External host URL for the plugin (https only)",
|
|
907
|
-
format: "uri",
|
|
908
|
-
pattern: "^https://",
|
|
909
|
-
maxLength: 1e3
|
|
910
|
-
},
|
|
911
|
-
permissions: {
|
|
912
|
-
type: "object",
|
|
913
|
-
description: "Permissions required by the plugin",
|
|
914
|
-
required: [
|
|
915
|
-
"data"
|
|
916
|
-
],
|
|
917
|
-
properties: {
|
|
918
|
-
data: {
|
|
919
|
-
type: "array",
|
|
920
|
-
description: "Data access permissions",
|
|
921
|
-
items: {
|
|
922
|
-
type: "string",
|
|
923
|
-
enum: [
|
|
924
|
-
"tracker:issues:read",
|
|
925
|
-
"tracker:issues:write",
|
|
926
|
-
"tracker:issuetypes:read",
|
|
927
|
-
"tracker:statuses:read",
|
|
928
|
-
"tracker:queues:read",
|
|
929
|
-
"tracker:fields:read",
|
|
930
|
-
"tracker:entities:read",
|
|
931
|
-
"tracker:attachments:read",
|
|
932
|
-
"tracker:attachments:write",
|
|
933
|
-
"tracker:applications:read",
|
|
934
|
-
"tracker:boards:read",
|
|
935
|
-
"tracker:boards:write",
|
|
936
|
-
"tracker:bulk:read",
|
|
937
|
-
"tracker:bulk:write",
|
|
938
|
-
"tracker:bulkchange:read",
|
|
939
|
-
"tracker:bulkchange:write",
|
|
940
|
-
"tracker:charts:read",
|
|
941
|
-
"tracker:commentTemplates:read",
|
|
942
|
-
"tracker:commentTemplates:write",
|
|
943
|
-
"tracker:components:read",
|
|
944
|
-
"tracker:components:write",
|
|
945
|
-
"tracker:data:read",
|
|
946
|
-
"tracker:departments:read",
|
|
947
|
-
"tracker:entities:write",
|
|
948
|
-
"tracker:externalEventTypes:write",
|
|
949
|
-
"tracker:externalEvents:write",
|
|
950
|
-
"tracker:fields:write",
|
|
951
|
-
"tracker:filterFolders:write",
|
|
952
|
-
"tracker:filters:read",
|
|
953
|
-
"tracker:filters:write",
|
|
954
|
-
"tracker:goals:read",
|
|
955
|
-
"tracker:goals:write",
|
|
956
|
-
"tracker:groups:read",
|
|
957
|
-
"tracker:issueTemplates:read",
|
|
958
|
-
"tracker:issueTemplates:write",
|
|
959
|
-
"tracker:links:read",
|
|
960
|
-
"tracker:linktypes:read",
|
|
961
|
-
"tracker:liveBoards:write",
|
|
962
|
-
"tracker:localFields:read",
|
|
963
|
-
"tracker:maillists:read",
|
|
964
|
-
"tracker:maillists:write",
|
|
965
|
-
"tracker:myself:read",
|
|
966
|
-
"tracker:myself:write",
|
|
967
|
-
"tracker:priorities:read",
|
|
968
|
-
"tracker:queues:write",
|
|
969
|
-
"tracker:reminders:read",
|
|
970
|
-
"tracker:reminders:write",
|
|
971
|
-
"tracker:remotelinks:read",
|
|
972
|
-
"tracker:reports:read",
|
|
973
|
-
"tracker:reports:write",
|
|
974
|
-
"tracker:resolutions:read",
|
|
975
|
-
"tracker:resources:read",
|
|
976
|
-
"tracker:resources:write",
|
|
977
|
-
"tracker:roles:read",
|
|
978
|
-
"tracker:screens:read",
|
|
979
|
-
"tracker:services:read",
|
|
980
|
-
"tracker:sprints:read",
|
|
981
|
-
"tracker:sprints:write",
|
|
982
|
-
"tracker:system:write",
|
|
983
|
-
"tracker:tags:read",
|
|
984
|
-
"tracker:translations:read",
|
|
985
|
-
"tracker:users:read",
|
|
986
|
-
"tracker:users:write",
|
|
987
|
-
"tracker:versions:read",
|
|
988
|
-
"tracker:versions:write",
|
|
989
|
-
"tracker:workflows:read",
|
|
990
|
-
"tracker:workflows:write",
|
|
991
|
-
"tracker:worklog:read",
|
|
992
|
-
"tracker:worklog:write"
|
|
993
|
-
]
|
|
994
|
-
},
|
|
995
|
-
uniqueItems: !0
|
|
996
|
-
},
|
|
997
|
-
ui: {
|
|
998
|
-
type: "array",
|
|
999
|
-
description: "UI permissions",
|
|
1000
|
-
items: {
|
|
1001
|
-
type: "string"
|
|
1002
|
-
},
|
|
1003
|
-
uniqueItems: !0
|
|
1004
|
-
},
|
|
1005
|
-
device: {
|
|
1006
|
-
type: "array",
|
|
1007
|
-
description: "Device permissions",
|
|
1008
|
-
items: {
|
|
1009
|
-
type: "string",
|
|
1010
|
-
enum: [
|
|
1011
|
-
"clipboard-write"
|
|
1012
|
-
]
|
|
1013
|
-
},
|
|
1014
|
-
uniqueItems: !0
|
|
1015
|
-
},
|
|
1016
|
-
external: {
|
|
1017
|
-
type: "array",
|
|
1018
|
-
description: "External permissions",
|
|
1019
|
-
items: {
|
|
1020
|
-
type: "string"
|
|
1021
|
-
},
|
|
1022
|
-
uniqueItems: !0
|
|
1023
|
-
}
|
|
1024
|
-
},
|
|
1025
|
-
additionalProperties: !1
|
|
1026
|
-
},
|
|
1027
|
-
slots: {
|
|
1028
|
-
type: "object",
|
|
1029
|
-
description: "Configuration for service slots",
|
|
1030
|
-
minProperties: 1,
|
|
1031
|
-
properties: {
|
|
1032
|
-
tracker: {
|
|
1033
|
-
type: "object",
|
|
1034
|
-
description: "Tracker service slots",
|
|
1035
|
-
minProperties: 1,
|
|
1036
|
-
properties: {
|
|
1037
|
-
"issue.action": {
|
|
1038
|
-
type: "array",
|
|
1039
|
-
description: "Issue Action slot configurations",
|
|
1040
|
-
minItems: 1,
|
|
1041
|
-
items: {
|
|
1042
|
-
$ref: "#/definitions/SlotConfig"
|
|
1043
|
-
}
|
|
1044
|
-
},
|
|
1045
|
-
"issue.block": {
|
|
1046
|
-
type: "array",
|
|
1047
|
-
description: "Issue Block slot configurations",
|
|
1048
|
-
minItems: 1,
|
|
1049
|
-
items: {
|
|
1050
|
-
$ref: "#/definitions/SlotConfig"
|
|
1051
|
-
}
|
|
1052
|
-
},
|
|
1053
|
-
"issue.tab": {
|
|
1054
|
-
type: "array",
|
|
1055
|
-
description: "Issue Tab slot configurations",
|
|
1056
|
-
minItems: 1,
|
|
1057
|
-
items: {
|
|
1058
|
-
$ref: "#/definitions/SlotConfig"
|
|
1059
|
-
}
|
|
1060
|
-
},
|
|
1061
|
-
"issue.comment.action": {
|
|
1062
|
-
type: "array",
|
|
1063
|
-
description: "Issue Comment Action slot configurations",
|
|
1064
|
-
minItems: 1,
|
|
1065
|
-
items: {
|
|
1066
|
-
$ref: "#/definitions/SlotConfig"
|
|
1067
|
-
}
|
|
1068
|
-
},
|
|
1069
|
-
navigation: {
|
|
1070
|
-
type: "array",
|
|
1071
|
-
description: "Navigation slot configurations",
|
|
1072
|
-
minItems: 1,
|
|
1073
|
-
items: {
|
|
1074
|
-
$ref: "#/definitions/SlotConfig"
|
|
1075
|
-
}
|
|
1076
|
-
},
|
|
1077
|
-
"trigger.create.action": {
|
|
1078
|
-
type: "array",
|
|
1079
|
-
description: "Trigger Create Action slot configurations",
|
|
1080
|
-
minItems: 1,
|
|
1081
|
-
items: {
|
|
1082
|
-
$ref: "#/definitions/SlotConfig"
|
|
1083
|
-
}
|
|
1084
|
-
},
|
|
1085
|
-
"trigger.edit.action": {
|
|
1086
|
-
type: "array",
|
|
1087
|
-
description: "Trigger Edit Action slot configurations",
|
|
1088
|
-
minItems: 1,
|
|
1089
|
-
items: {
|
|
1090
|
-
$ref: "#/definitions/SlotConfig"
|
|
1091
|
-
}
|
|
1092
|
-
},
|
|
1093
|
-
"project.action": {
|
|
1094
|
-
type: "array",
|
|
1095
|
-
description: "Project Action slot configurations",
|
|
1096
|
-
minItems: 1,
|
|
1097
|
-
items: {
|
|
1098
|
-
$ref: "#/definitions/SlotConfig"
|
|
1099
|
-
}
|
|
1100
|
-
},
|
|
1101
|
-
"portfolio.action": {
|
|
1102
|
-
type: "array",
|
|
1103
|
-
description: "Portfolio Action slot configurations",
|
|
1104
|
-
minItems: 1,
|
|
1105
|
-
items: {
|
|
1106
|
-
$ref: "#/definitions/SlotConfig"
|
|
1107
|
-
}
|
|
1108
|
-
},
|
|
1109
|
-
"goal.action": {
|
|
1110
|
-
type: "array",
|
|
1111
|
-
description: "Goal Action slot configurations",
|
|
1112
|
-
minItems: 1,
|
|
1113
|
-
items: {
|
|
1114
|
-
$ref: "#/definitions/SlotConfig"
|
|
1115
|
-
}
|
|
1116
|
-
},
|
|
1117
|
-
"attachment.viewer.action": {
|
|
1118
|
-
type: "array",
|
|
1119
|
-
description: "Attachment Viewer Action slot configurations",
|
|
1120
|
-
minItems: 1,
|
|
1121
|
-
items: {
|
|
1122
|
-
$ref: "#/definitions/SlotConfig"
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
},
|
|
1126
|
-
additionalProperties: !1
|
|
1127
|
-
}
|
|
1128
|
-
},
|
|
1129
|
-
additionalProperties: !1
|
|
1130
|
-
}
|
|
1131
|
-
},
|
|
1132
|
-
additionalProperties: !1,
|
|
1133
|
-
definitions: {
|
|
1134
|
-
SlotConfig: {
|
|
1135
|
-
type: "object",
|
|
1136
|
-
description: "Configuration for a specific slot",
|
|
1137
|
-
required: [
|
|
1138
|
-
"entrypoint",
|
|
1139
|
-
"title"
|
|
1140
|
-
],
|
|
1141
|
-
properties: {
|
|
1142
|
-
entrypoint: {
|
|
1143
|
-
type: "string",
|
|
1144
|
-
description: "Entry point file path for the slot",
|
|
1145
|
-
minLength: 1
|
|
1146
|
-
},
|
|
1147
|
-
title: {
|
|
1148
|
-
type: "object",
|
|
1149
|
-
description: "Localized titles for the slot",
|
|
1150
|
-
required: [
|
|
1151
|
-
"ru",
|
|
1152
|
-
"en"
|
|
1153
|
-
],
|
|
1154
|
-
properties: {
|
|
1155
|
-
ru: {
|
|
1156
|
-
type: "string",
|
|
1157
|
-
description: "Russian title",
|
|
1158
|
-
minLength: 1,
|
|
1159
|
-
maxLength: 32
|
|
1160
|
-
},
|
|
1161
|
-
en: {
|
|
1162
|
-
type: "string",
|
|
1163
|
-
description: "English title",
|
|
1164
|
-
minLength: 1,
|
|
1165
|
-
maxLength: 32
|
|
1166
|
-
}
|
|
1167
|
-
},
|
|
1168
|
-
additionalProperties: !1
|
|
1169
|
-
},
|
|
1170
|
-
description: {
|
|
1171
|
-
type: "object",
|
|
1172
|
-
description: "Localized descriptions for the slot",
|
|
1173
|
-
required: [
|
|
1174
|
-
"ru",
|
|
1175
|
-
"en"
|
|
1176
|
-
],
|
|
1177
|
-
properties: {
|
|
1178
|
-
ru: {
|
|
1179
|
-
type: "string",
|
|
1180
|
-
description: "Russian description",
|
|
1181
|
-
minLength: 1,
|
|
1182
|
-
maxLength: 300
|
|
1183
|
-
},
|
|
1184
|
-
en: {
|
|
1185
|
-
type: "string",
|
|
1186
|
-
description: "English description",
|
|
1187
|
-
minLength: 1,
|
|
1188
|
-
maxLength: 300
|
|
1189
|
-
}
|
|
1190
|
-
},
|
|
1191
|
-
additionalProperties: !1
|
|
1192
|
-
}
|
|
1193
|
-
},
|
|
1194
|
-
additionalProperties: !1
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
};
|
|
1198
|
-
|
|
1199
|
-
// src/core/manifest/manifestManager.ts
|
|
1200
|
-
var validator = (() => {
|
|
1201
|
-
let ajv = new import_ajv.default({ allErrors: !0, strict: !1 });
|
|
1202
|
-
return (0, import_ajv_formats.default)(ajv), ajv.compile(manifest_schema_default);
|
|
1203
|
-
})(), manifestPath = "./manifest.json", parseManifest = (content) => {
|
|
1204
|
-
let manifest;
|
|
1205
|
-
try {
|
|
1206
|
-
manifest = JSON.parse(content);
|
|
1207
|
-
} catch (error2) {
|
|
1208
|
-
throw error2 instanceof SyntaxError ? new Error(`File manifest.json contains invalid JSON: ${error2.message}`) : new Error(`Error reading manifest.json: ${error2.message}`);
|
|
1209
|
-
}
|
|
1210
|
-
return manifest;
|
|
1211
|
-
}, loadRaw = async () => {
|
|
1212
|
-
if (!(0, import_fs2.existsSync)(manifestPath))
|
|
1213
|
-
throw new Error(`File manifest.json not found at path: ${manifestPath}`);
|
|
1214
|
-
try {
|
|
1215
|
-
return await (0, import_promises.readFile)(manifestPath, "utf8");
|
|
1216
|
-
} catch (error2) {
|
|
1217
|
-
throw error2 instanceof Error ? new Error(`Error reading manifest.json: ${error2.message}`) : new Error("Error loading manifest");
|
|
1218
|
-
}
|
|
1219
|
-
}, load = async () => {
|
|
1220
|
-
let manifestContent = await loadRaw();
|
|
1221
|
-
return parseManifest(manifestContent);
|
|
1222
|
-
}, validate = async () => {
|
|
1223
|
-
let manifest = await load();
|
|
1224
|
-
if (!validator(manifest) && validator.errors) {
|
|
1225
|
-
let errorMessages2 = formatValidationErrors(validator.errors);
|
|
1226
|
-
throw new Error(`Manifest validation failed:
|
|
1227
|
-
${errorMessages2}`);
|
|
1228
|
-
}
|
|
1229
|
-
}, save = async (manifest) => {
|
|
1230
|
-
try {
|
|
1231
|
-
let content = JSON.stringify(manifest, null, 4);
|
|
1232
|
-
await (0, import_promises.writeFile)(manifestPath, content, "utf8");
|
|
1233
|
-
} catch (error2) {
|
|
1234
|
-
throw error2 instanceof Error ? new Error(`Error saving manifest.json: ${error2.message}`) : new Error("Error saving manifest");
|
|
1235
|
-
}
|
|
1236
|
-
}, update = async (updates) => {
|
|
1237
|
-
let updatedManifest = { ...await load(), ...updates };
|
|
1238
|
-
return await save(updatedManifest), updatedManifest;
|
|
1239
|
-
}, manifestManager = {
|
|
1240
|
-
load,
|
|
1241
|
-
loadRaw,
|
|
1242
|
-
validate,
|
|
1243
|
-
save,
|
|
1244
|
-
update
|
|
1245
|
-
};
|
|
3315
|
+
var import_fs16 = __toESM(require("fs")), import_path17 = __toESM(require("path"));
|
|
3316
|
+
init_manifestManager();
|
|
1246
3317
|
|
|
1247
3318
|
// src/core/s3config/constants.ts
|
|
1248
3319
|
var CONFIG_FILE_NAME = "config.json";
|
|
1249
3320
|
|
|
1250
3321
|
// src/commands/debug/index.ts
|
|
3322
|
+
init_meta2();
|
|
3323
|
+
init_execCommand();
|
|
1251
3324
|
init_logger();
|
|
1252
3325
|
|
|
1253
3326
|
// src/utils/registerCleanup.ts
|
|
@@ -1259,8 +3332,12 @@ var registerCleanup = (cleanup) => {
|
|
|
1259
3332
|
});
|
|
1260
3333
|
};
|
|
1261
3334
|
|
|
3335
|
+
// src/commands/debug/index.ts
|
|
3336
|
+
init_templateCommands();
|
|
3337
|
+
|
|
1262
3338
|
// src/commands/debug/utils/createDebugConfig.ts
|
|
1263
|
-
var
|
|
3339
|
+
var import_fs13 = __toESM(require("fs")), import_path14 = __toESM(require("path"));
|
|
3340
|
+
init_manifestManager();
|
|
1264
3341
|
|
|
1265
3342
|
// src/utils/convertManifestToConfig.ts
|
|
1266
3343
|
function buildPluginDownloadUrl(env, id, version) {
|
|
@@ -1289,6 +3366,7 @@ var convertManifestToConfig = (manifest, environment) => {
|
|
|
1289
3366
|
description: slotConfig.description,
|
|
1290
3367
|
entrypoint: slotConfig.entrypoint,
|
|
1291
3368
|
title: slotConfig.title,
|
|
3369
|
+
contextLevel: slotConfig.contextLevel,
|
|
1292
3370
|
downloadUrl: buildPluginDownloadUrl(
|
|
1293
3371
|
environment,
|
|
1294
3372
|
manifest.slug,
|
|
@@ -1305,21 +3383,21 @@ var convertManifestToConfig = (manifest, environment) => {
|
|
|
1305
3383
|
|
|
1306
3384
|
// src/commands/debug/utils/createDebugConfig.ts
|
|
1307
3385
|
var createDebugConfig = async () => {
|
|
1308
|
-
let manifest = await manifestManager.load(), config = convertManifestToConfig(manifest, "debug"), configPath =
|
|
1309
|
-
|
|
3386
|
+
let manifest = await manifestManager.load(), config = convertManifestToConfig(manifest, "debug"), configPath = import_path14.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
3387
|
+
import_fs13.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
1310
3388
|
};
|
|
1311
3389
|
|
|
1312
3390
|
// src/commands/debug/utils/lockFile.ts
|
|
1313
|
-
var
|
|
3391
|
+
var import_fs14 = __toESM(require("fs")), import_path15 = __toESM(require("path")), LOCK_FILE_NAME = ".yaweavix-debug.lock", getLockFilePath = () => import_path15.default.join(process.cwd(), LOCK_FILE_NAME), getRunningDebugPid = () => {
|
|
1314
3392
|
let lockPath = getLockFilePath();
|
|
1315
|
-
if (!
|
|
3393
|
+
if (!import_fs14.default.existsSync(lockPath))
|
|
1316
3394
|
return null;
|
|
1317
3395
|
try {
|
|
1318
|
-
let pid = JSON.parse(
|
|
3396
|
+
let pid = JSON.parse(import_fs14.default.readFileSync(lockPath, "utf-8")).pid;
|
|
1319
3397
|
return process.kill(pid, 0), pid;
|
|
1320
3398
|
} catch {
|
|
1321
3399
|
try {
|
|
1322
|
-
|
|
3400
|
+
import_fs14.default.unlinkSync(lockPath);
|
|
1323
3401
|
} catch {
|
|
1324
3402
|
}
|
|
1325
3403
|
return null;
|
|
@@ -1327,18 +3405,19 @@ var import_fs4 = __toESM(require("fs")), import_path6 = __toESM(require("path"))
|
|
|
1327
3405
|
}, createLockFile = () => {
|
|
1328
3406
|
let lockPath = getLockFilePath(), lockData = {
|
|
1329
3407
|
pid: process.pid
|
|
1330
|
-
}, fd =
|
|
1331
|
-
|
|
3408
|
+
}, fd = import_fs14.default.openSync(lockPath, "wx");
|
|
3409
|
+
import_fs14.default.writeSync(fd, JSON.stringify(lockData, null, 2)), import_fs14.default.closeSync(fd);
|
|
1332
3410
|
}, removeLockFile = () => {
|
|
1333
3411
|
let lockPath = getLockFilePath();
|
|
1334
|
-
|
|
3412
|
+
import_fs14.default.existsSync(lockPath) && import_fs14.default.unlinkSync(lockPath);
|
|
1335
3413
|
};
|
|
1336
3414
|
|
|
1337
3415
|
// src/commands/debug/utils/watchManifest.ts
|
|
1338
|
-
var
|
|
3416
|
+
var import_fs15 = __toESM(require("fs")), import_path16 = __toESM(require("path"));
|
|
3417
|
+
init_manifestManager();
|
|
1339
3418
|
init_logger();
|
|
1340
3419
|
var watchManifest = () => {
|
|
1341
|
-
let
|
|
3420
|
+
let manifestPath = import_path16.default.join(process.cwd(), "manifest.json"), debounceTimer = null, watcher = import_fs15.default.watch(manifestPath, async (eventType) => {
|
|
1342
3421
|
eventType === "change" && (debounceTimer && clearTimeout(debounceTimer), debounceTimer = setTimeout(async () => {
|
|
1343
3422
|
try {
|
|
1344
3423
|
logger_default.newLine(), logger_default.info("Manifest file changed, validating..."), await manifestManager.validate(), logger_default.info("Regenerating debug config..."), await createDebugConfig(), logger_default.success("Debug config regenerated successfully");
|
|
@@ -1362,94 +3441,122 @@ Please stop the existing instance before starting a new one.
|
|
|
1362
3441
|
If you lost the terminal tab, you can kill the process with:
|
|
1363
3442
|
kill ${runningPid}`
|
|
1364
3443
|
), process.exit(1));
|
|
1365
|
-
let configPath =
|
|
3444
|
+
let configPath = import_path17.default.join(process.cwd(), CONFIG_FILE_NAME);
|
|
1366
3445
|
options.lint && await manifestManager.validate(), await createDebugConfig();
|
|
1367
3446
|
let watcher = watchManifest(), cleanup = () => {
|
|
1368
|
-
watcher.close(),
|
|
3447
|
+
watcher.close(), import_fs16.default.existsSync(configPath) && import_fs16.default.unlinkSync(configPath), removeLockFile();
|
|
1369
3448
|
};
|
|
1370
|
-
registerCleanup(cleanup), createLockFile(), await execCommand(pluginCmd.dev), cleanup();
|
|
3449
|
+
registerCleanup(cleanup), createLockFile(), logger_default.newLine(), logger_default.info("\u{1F527} Debug mode started!"), logger_default.newLine(), logger_default.info("\u{1F4CC} The plugin is now available in the Tracker interface."), logger_default.info("Open Tracker and check the plugin functionality in the appropriate context."), logger_default.newLine(), logger_default.info("\u26A0\uFE0F Do not try to open localhost in the browser - the plugin works"), logger_default.info("only inside Tracker through a special loading mechanism."), logger_default.newLine(), logger_default.info("\u{1F504} Code changes will be automatically reloaded."), logger_default.info("Press Ctrl+C to stop."), logger_default.newLine(), await execCommand(pluginCmd.dev), cleanup();
|
|
1371
3450
|
}
|
|
1372
3451
|
|
|
1373
3452
|
// src/commands/lint.ts
|
|
3453
|
+
init_manifestManager();
|
|
3454
|
+
init_execCommand();
|
|
1374
3455
|
init_logger();
|
|
3456
|
+
init_templateCommands();
|
|
1375
3457
|
async function lint() {
|
|
1376
3458
|
logger_default.info("\u{1F50D} Running manifest.json validation..."), await manifestManager.validate(), logger_default.info("\u{1F50D} Running code lint check..."), await execCommand(pluginCmd.lint);
|
|
1377
3459
|
}
|
|
1378
3460
|
|
|
3461
|
+
// src/commands/up/index.ts
|
|
3462
|
+
var import_fs19 = require("fs"), import_promises5 = require("fs/promises");
|
|
3463
|
+
init_execCommand();
|
|
3464
|
+
|
|
1379
3465
|
// src/commands/up/utils/copyTemplateFiles.ts
|
|
1380
|
-
var
|
|
1381
|
-
var copyTemplateFiles = async (
|
|
3466
|
+
var import_fs17 = require("fs"), import_promises3 = require("fs/promises"), import_path18 = __toESM(require("path"));
|
|
3467
|
+
var copyTemplateFiles = async (files) => {
|
|
1382
3468
|
await Promise.all(
|
|
1383
|
-
|
|
1384
|
-
let templatePath
|
|
1385
|
-
|
|
1386
|
-
let content = await (0, import_promises2.readFile)(templatePath), rewritten = applySubstitutions2(filename, content);
|
|
1387
|
-
await (0, import_promises2.writeFile)(targetPath, rewritten);
|
|
1388
|
-
}
|
|
3469
|
+
files.map(async (file) => {
|
|
3470
|
+
let templatePath, targetPath, force = !1;
|
|
3471
|
+
typeof file == "string" ? (templatePath = getTemplatePath(file), targetPath = `./${file}`) : (templatePath = file.sourcePath ?? getTemplatePath(file.source ?? file.target), targetPath = `./${file.target}`, force = file.force ?? !1), (0, import_fs17.existsSync)(templatePath) && (force || (0, import_fs17.existsSync)(targetPath)) && (await (0, import_promises3.mkdir)(import_path18.default.dirname(targetPath), { recursive: !0 }), await (0, import_promises3.copyFile)(templatePath, targetPath));
|
|
1389
3472
|
})
|
|
1390
3473
|
);
|
|
1391
|
-
}
|
|
3474
|
+
}, overlayFileCopy = (overlayDir, sourceFilename, targetFilename) => ({
|
|
3475
|
+
sourcePath: getOverlayTemplatePath(overlayDir, sourceFilename),
|
|
3476
|
+
target: targetFilename
|
|
3477
|
+
});
|
|
1392
3478
|
|
|
1393
3479
|
// src/commands/up/utils/updateManifestCompatibility.ts
|
|
3480
|
+
init_manifestManager();
|
|
3481
|
+
function addDefaultContextLevel(slots) {
|
|
3482
|
+
if (!slots)
|
|
3483
|
+
return;
|
|
3484
|
+
let updatedSlots = {}, updates = [];
|
|
3485
|
+
for (let [service, serviceSlots] of Object.entries(slots))
|
|
3486
|
+
if (serviceSlots) {
|
|
3487
|
+
updatedSlots[service] = {};
|
|
3488
|
+
for (let [slot, slotConfigs] of Object.entries(serviceSlots))
|
|
3489
|
+
slotConfigs && (updatedSlots[service][slot] = slotConfigs.map((slotConfig) => "contextLevel" in slotConfig ? slotConfig : (updates.push(slotConfig), Object.assign({}, slotConfig, { contextLevel: "basic" }))));
|
|
3490
|
+
}
|
|
3491
|
+
return updates.length > 0 ? updatedSlots : void 0;
|
|
3492
|
+
}
|
|
1394
3493
|
async function updateManifestCompatibility() {
|
|
1395
3494
|
let manifest = await manifestManager.load(), updates = {};
|
|
1396
|
-
"manifest_version" in manifest || (updates.manifest_version = 1), "supported_services" in manifest || (updates.supported_services = ["tracker"])
|
|
3495
|
+
"manifest_version" in manifest || (updates.manifest_version = 1), "supported_services" in manifest || (updates.supported_services = ["tracker"]);
|
|
3496
|
+
let updatedSlots = addDefaultContextLevel(manifest.slots);
|
|
3497
|
+
updatedSlots && (updates.slots = updatedSlots), Object.keys(updates).length > 0 && await manifestManager.update(updates);
|
|
1397
3498
|
}
|
|
1398
3499
|
|
|
1399
3500
|
// src/commands/up/utils/updatePackageDependencies.ts
|
|
1400
|
-
var
|
|
3501
|
+
var import_fs18 = require("fs"), import_promises4 = require("fs/promises");
|
|
1401
3502
|
var updatePackageDependencies = async (dependencies) => {
|
|
1402
3503
|
let packageJsonPath = "./package.json", templatePackageJsonPath = getTemplatePath("package.json");
|
|
1403
|
-
if (!(0,
|
|
3504
|
+
if (!(0, import_fs18.existsSync)(packageJsonPath) || !(0, import_fs18.existsSync)(templatePackageJsonPath))
|
|
1404
3505
|
return;
|
|
1405
|
-
let packageJsonContent = await (0,
|
|
1406
|
-
"package.json",
|
|
1407
|
-
templatePackageJsonRaw
|
|
1408
|
-
).toString("utf8"), packageJson = JSON.parse(packageJsonContent), templatePackageJson = JSON.parse(templatePackageJsonContent), updated = !1;
|
|
3506
|
+
let packageJsonContent = await (0, import_promises4.readFile)(packageJsonPath, "utf-8"), templatePackageJsonContent = await (0, import_promises4.readFile)(templatePackageJsonPath, "utf-8"), packageJson = JSON.parse(packageJsonContent), templatePackageJson = JSON.parse(templatePackageJsonContent), updated = !1;
|
|
1409
3507
|
dependencies.forEach((dep) => {
|
|
1410
3508
|
packageJson.dependencies?.[dep] && templatePackageJson.dependencies?.[dep] && packageJson.dependencies[dep] !== templatePackageJson.dependencies[dep] && (packageJson.dependencies[dep] = templatePackageJson.dependencies[dep], updated = !0);
|
|
1411
|
-
}), updated && await (0,
|
|
3509
|
+
}), updated && await (0, import_promises4.writeFile)(packageJsonPath, JSON.stringify(packageJson, null, 4) + `
|
|
1412
3510
|
`, "utf-8");
|
|
1413
3511
|
};
|
|
1414
3512
|
|
|
1415
3513
|
// src/commands/up/index.ts
|
|
1416
|
-
var
|
|
3514
|
+
var npmrcPath = "./.npmrc", npmrcTemplateFilename = "npmrc.template", sharedFiles = [
|
|
3515
|
+
"manifest.schema.json",
|
|
3516
|
+
"vite.config.ts",
|
|
3517
|
+
{ source: "proxy.ts", target: "proxy.ts", force: !0 }
|
|
3518
|
+
];
|
|
3519
|
+
async function isNpmrcOutdated() {
|
|
3520
|
+
let templatePath = getOverlayTemplatePath(overlayDirName, npmrcTemplateFilename);
|
|
3521
|
+
if (!(0, import_fs19.existsSync)(npmrcPath) || !(0, import_fs19.existsSync)(templatePath))
|
|
3522
|
+
return !1;
|
|
3523
|
+
let [currentNpmrc, templateNpmrc] = await Promise.all([
|
|
3524
|
+
(0, import_promises5.readFile)(npmrcPath, "utf-8"),
|
|
3525
|
+
(0, import_promises5.readFile)(templatePath, "utf-8")
|
|
3526
|
+
]);
|
|
3527
|
+
return currentNpmrc !== templateNpmrc;
|
|
3528
|
+
}
|
|
1417
3529
|
async function up() {
|
|
1418
|
-
|
|
3530
|
+
let shouldCleanNpmCache = await isNpmrcOutdated();
|
|
3531
|
+
await copyTemplateFiles([
|
|
3532
|
+
...sharedFiles,
|
|
3533
|
+
{ ...overlayFileCopy(overlayDirName, npmrcTemplateFilename, ".npmrc"), force: !0 }
|
|
3534
|
+
]), await updateManifestCompatibility(), await updatePackageDependencies(templateDeps), shouldCleanNpmCache && await execCommand("npm cache clean --force"), await execCommand("npm i");
|
|
1419
3535
|
}
|
|
1420
3536
|
|
|
1421
3537
|
// src/utils/getVersion.ts
|
|
1422
|
-
var
|
|
1423
|
-
|
|
1424
|
-
let
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
3538
|
+
var import_fs20 = require("fs"), import_path19 = require("path"), UNKNOWN_VERSION = "unknown", CANDIDATES = ["..", "../.."], findVersionInPackageJson = (startDir) => {
|
|
3539
|
+
for (let rel of CANDIDATES) {
|
|
3540
|
+
let path24 = (0, import_path19.resolve)(startDir, rel, "package.json");
|
|
3541
|
+
if ((0, import_fs20.existsSync)(path24))
|
|
3542
|
+
try {
|
|
3543
|
+
let pkg = JSON.parse((0, import_fs20.readFileSync)(path24, "utf-8"));
|
|
3544
|
+
if (typeof pkg.version == "string") return pkg.version;
|
|
3545
|
+
} catch {
|
|
3546
|
+
}
|
|
1428
3547
|
}
|
|
1429
|
-
|
|
3548
|
+
return null;
|
|
3549
|
+
}, getVersion = () => findVersionInPackageJson(__dirname) ?? UNKNOWN_VERSION;
|
|
1430
3550
|
|
|
1431
3551
|
// src/index.ts
|
|
1432
3552
|
init_verbose();
|
|
1433
|
-
|
|
1434
|
-
// src/utils/withErrorHandling.ts
|
|
1435
|
-
init_logger();
|
|
1436
|
-
function withErrorHandling(fn) {
|
|
1437
|
-
return async (...args) => {
|
|
1438
|
-
try {
|
|
1439
|
-
await fn(...args);
|
|
1440
|
-
} catch (error2) {
|
|
1441
|
-
error2 instanceof Error && error2.name === "ExitPromptError" && process.exit(0), logger_default.error(error2), process.exit(1);
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
// src/index.ts
|
|
3553
|
+
init_withErrorHandling();
|
|
1447
3554
|
async function main() {
|
|
1448
|
-
let program = new
|
|
1449
|
-
await checkUpdate(version), program.name(CLI_NAME2).description(CLI_DESCRIPTION2).version(version), CLI_HELP_TEXT2 && program.addHelpText("before", CLI_HELP_TEXT2), program.hook("preAction", (thisCommand) => {
|
|
3555
|
+
let program = new import_commander2.Command(), version = getVersion();
|
|
3556
|
+
shouldRunUpdateCheck(process.argv.slice(2)) && await checkUpdate(version), program.name(CLI_NAME2).description(CLI_DESCRIPTION2).version(version).option("--verbose", "enable verbose output"), CLI_HELP_TEXT2 && program.addHelpText("before", CLI_HELP_TEXT2), program.hook("preAction", (thisCommand) => {
|
|
1450
3557
|
setVerboseEnabled(!!thisCommand.opts().verbose);
|
|
1451
3558
|
}), program.command("create").description("create your app").action(withErrorHandling(create)), program.command("up").description("update plugin from old template to latest version").action(withErrorHandling(up)), program.command("build").description("build your app").action(withErrorHandling(build)), program.command("debug").description(
|
|
1452
3559
|
"start a tunnel to connect your local code with the app running in the development environment"
|
|
1453
|
-
).option("--no-lint", "skip lint validation").action((options) => withErrorHandling(debug)(options)), program.command("lint").description("run TypeScript and ESLint checks").action(withErrorHandling(lint)), registerDistributionCommands2(program), await program.parseAsync(), process.exit(0);
|
|
3560
|
+
).option("--no-lint", "skip lint validation").action((options) => withErrorHandling(debug)(options)), program.command("lint").description("run TypeScript and ESLint checks").action(withErrorHandling(lint)), registerDistributionCommands2(program), await program.parseAsync(), process.exit(typeof process.exitCode == "number" ? process.exitCode : 0);
|
|
1454
3561
|
}
|
|
1455
3562
|
main();
|