artifacty 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +54 -8
- package/README.md +56 -10
- package/THIRD_PARTY_NOTICES.md +53 -0
- package/docs/README.md +6 -0
- package/docs/ko/README.md +6 -0
- package/docs/ko/language-packs.md +40 -0
- package/docs/ko/smtp.md +27 -0
- package/docs/ko/upgrade-backups.md +16 -0
- package/docs/language-packs.md +38 -0
- package/docs/roadmap-design.md +31 -2
- package/docs/smtp.md +25 -0
- package/docs/upgrade-backups.md +16 -0
- package/package.json +10 -1
- package/scripts/build-ui.mjs +16 -0
- package/src/cli.js +4 -4
- package/src/client/api-docs.js +32 -0
- package/src/client/auto-apply.js +20 -0
- package/src/client/editor.js +75 -20
- package/src/client/sidebar.js +31 -0
- package/src/client/theme.js +42 -0
- package/src/client/ui-controls.css +2 -0
- package/src/client/update.js +33 -0
- package/src/client/viewer.js +17 -6
- package/src/lib/background.js +3 -1
- package/src/lib/events.js +4 -4
- package/src/lib/i18n.js +601 -9
- package/src/lib/language-settings.js +114 -0
- package/src/lib/openapi.js +93 -74
- package/src/lib/render.js +888 -628
- package/src/lib/sample-content.js +6 -6
- package/src/lib/self-update.js +12 -0
- package/src/lib/smtp-client.js +206 -0
- package/src/lib/smtp-settings.js +109 -0
- package/src/lib/storage.js +71 -17
- package/src/lib/ui-icons.js +32 -0
- package/src/lib/web-update.js +177 -0
- package/src/mcp-server.js +3 -3
- package/src/server.js +250 -18
- package/src/styles/ui-controls.scss +63 -0
- package/src/update-runner.js +7 -0
package/src/client/viewer.js
CHANGED
|
@@ -5,6 +5,17 @@ import { html } from "@codemirror/lang-html";
|
|
|
5
5
|
import { json } from "@codemirror/lang-json";
|
|
6
6
|
import { markdown } from "@codemirror/lang-markdown";
|
|
7
7
|
|
|
8
|
+
const viewerMessages = {
|
|
9
|
+
filter: "Filter", filterColumn: "Filter column {column}", ruleFilter: "Filter by rule id",
|
|
10
|
+
rowsShown: "{visible} of {total} rows shown", resultsShown: "{visible} of {total} results shown"
|
|
11
|
+
};
|
|
12
|
+
try {
|
|
13
|
+
Object.assign(viewerMessages, JSON.parse(document.getElementById("artifacty-viewer-i18n")?.textContent || "{}"));
|
|
14
|
+
} catch { /* Keep English fallback when optional configuration is unavailable. */ }
|
|
15
|
+
function viewerText(key, params = {}) {
|
|
16
|
+
return viewerMessages[key].replace(/\{(\w+)\}/g, (match, name) => String(params[name] ?? match));
|
|
17
|
+
}
|
|
18
|
+
|
|
8
19
|
const viewerTheme = EditorView.theme({
|
|
9
20
|
"&": {
|
|
10
21
|
minHeight: "50vh"
|
|
@@ -235,8 +246,8 @@ function enhanceCsvViewer(section) {
|
|
|
235
246
|
const input = document.createElement("input");
|
|
236
247
|
input.type = "text";
|
|
237
248
|
input.className = "csv-filter-input";
|
|
238
|
-
input.placeholder = "
|
|
239
|
-
input.setAttribute("aria-label",
|
|
249
|
+
input.placeholder = viewerText("filter");
|
|
250
|
+
input.setAttribute("aria-label", viewerText("filterColumn", { column: index + 1 }));
|
|
240
251
|
input.addEventListener("input", apply);
|
|
241
252
|
cell.append(input);
|
|
242
253
|
filterRow.append(cell);
|
|
@@ -289,7 +300,7 @@ function enhanceCsvViewer(section) {
|
|
|
289
300
|
tbody.append(fragment);
|
|
290
301
|
|
|
291
302
|
status.hidden = false;
|
|
292
|
-
status.textContent =
|
|
303
|
+
status.textContent = viewerText("rowsShown", { visible: visible.length, total: rows.length });
|
|
293
304
|
}
|
|
294
305
|
|
|
295
306
|
apply();
|
|
@@ -335,8 +346,8 @@ function enhanceSarifViewer(section) {
|
|
|
335
346
|
const ruleInput = document.createElement("input");
|
|
336
347
|
ruleInput.type = "text";
|
|
337
348
|
ruleInput.className = "sarif-rule-filter";
|
|
338
|
-
ruleInput.placeholder = "
|
|
339
|
-
ruleInput.setAttribute("aria-label", "
|
|
349
|
+
ruleInput.placeholder = viewerText("ruleFilter");
|
|
350
|
+
ruleInput.setAttribute("aria-label", viewerText("ruleFilter"));
|
|
340
351
|
ruleInput.addEventListener("input", apply);
|
|
341
352
|
|
|
342
353
|
controls.append(chipsWrap, ruleInput);
|
|
@@ -437,7 +448,7 @@ function enhanceSarifViewer(section) {
|
|
|
437
448
|
tbody.append(fragment);
|
|
438
449
|
|
|
439
450
|
status.hidden = false;
|
|
440
|
-
status.textContent =
|
|
451
|
+
status.textContent = viewerText("resultsShown", { visible: visible.length, total: rows.length });
|
|
441
452
|
}
|
|
442
453
|
|
|
443
454
|
apply();
|
package/src/lib/background.js
CHANGED
|
@@ -352,7 +352,9 @@ function isPidRunning(pid) {
|
|
|
352
352
|
async function fetchHealth(url) {
|
|
353
353
|
try {
|
|
354
354
|
const response = await fetch(`${url}/health`, {
|
|
355
|
-
|
|
355
|
+
// Match the updater health deadline so brief CPU or I/O contention
|
|
356
|
+
// does not report a live background server as stopped.
|
|
357
|
+
signal: AbortSignal.timeout(2000)
|
|
356
358
|
});
|
|
357
359
|
return { ok: response.ok, status: response.status };
|
|
358
360
|
} catch {
|
package/src/lib/events.js
CHANGED
|
@@ -81,9 +81,9 @@ export function eventFromAudit(auditRow = {}) {
|
|
|
81
81
|
* True when `event` is visible to `access`. Mirrors storage.js's
|
|
82
82
|
* canReadArtifactMeta: a falsy `access` means an internal/trusted caller
|
|
83
83
|
* (or single-user mode) and always sees everything; otherwise a
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
84
|
+
* public events allow anonymous readers, team events require a user, and
|
|
85
|
+
* private events require their owner or an admin. Legacy events without a
|
|
86
|
+
* visibility field use team semantics.
|
|
87
87
|
*/
|
|
88
88
|
export function eventVisibleTo(event, access) {
|
|
89
89
|
if (!event) {
|
|
@@ -95,7 +95,7 @@ export function eventVisibleTo(event, access) {
|
|
|
95
95
|
if (access.role === "admin") {
|
|
96
96
|
return true;
|
|
97
97
|
}
|
|
98
|
-
if (event.visibility !== "private") {
|
|
98
|
+
if (event.visibility === "public" || (event.visibility !== "private" && Boolean(access.userId))) {
|
|
99
99
|
return true;
|
|
100
100
|
}
|
|
101
101
|
return Boolean(access.userId) && access.userId === event.ownerUserId;
|