@filipgutica/ui 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/dist/open-vsx.js +108 -109
- package/dist/site/projects.d.ts +5 -0
- package/dist/site.js +6 -0
- package/package.json +1 -1
- package/src/components/tabs.css +4 -1
package/README.md
CHANGED
|
@@ -85,7 +85,13 @@ applySemanticTheme({ root: document.documentElement, theme })
|
|
|
85
85
|
|
|
86
86
|
Themes supply colors; the library keeps typography, spacing, and component
|
|
87
87
|
structure consistent. Open VSX search and imports are available through
|
|
88
|
-
`@filipgutica/ui/open-vsx
|
|
88
|
+
`createOpenVsxThemeService` from `@filipgutica/ui/open-vsx`. It runs on Node
|
|
89
|
+
or in a browser with HTTPS and Web Crypto. Browser requests depend on the
|
|
90
|
+
registry and its resource host allowing cross-origin access.
|
|
91
|
+
|
|
92
|
+
The gallery's search-and-install dialog is docs-only, not an exported component.
|
|
93
|
+
Applications can build their own picker with the exported components and theme
|
|
94
|
+
helpers. `UiSiteHeader` includes the built-in System, Light, and Dark control.
|
|
89
95
|
|
|
90
96
|
The default theme is unchanged. To opt in to Graphite Indigo, import it after
|
|
91
97
|
`theme.css`:
|
|
@@ -116,7 +122,7 @@ import { UiSiteHeader } from '@filipgutica/ui/site'
|
|
|
116
122
|
</template>
|
|
117
123
|
```
|
|
118
124
|
|
|
119
|
-
`project` is `wtree`, `annoterm`, `devps`, `workbench`, or `ui`. The project
|
|
125
|
+
`project` is `wtree`, `annoterm`, `devps`, `workbench`, `filip-stack`, or `ui`. The project
|
|
120
126
|
menu is a native disclosure that works without JavaScript; Escape closes it and
|
|
121
127
|
returns focus to its button. Without a default slot the header renders a
|
|
122
128
|
System, Light, and Dark picker. A page with its own appearance control passes it
|
package/dist/open-vsx.js
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
1
|
import { i as e, t } from "./theme-CIwueiir.js";
|
|
2
2
|
import { parse as n } from "jsonc-parser";
|
|
3
|
-
import
|
|
4
|
-
import i from "jszip";
|
|
3
|
+
import r from "jszip";
|
|
5
4
|
//#region src/open-vsx/index.ts
|
|
6
|
-
var
|
|
5
|
+
var i = "https://open-vsx.org", a = "https://openvsx.eclipsecontent.org", o = `${i}/api/-/search`, s = 524288, c = 262144, l = 262144, u = 1048576, d = 20971520, f = 5e3, p = 104857600, m = 200, h = 40, g = 8, _ = 15e3, v = class extends Error {
|
|
7
6
|
code;
|
|
8
7
|
constructor(e, t) {
|
|
9
8
|
super(t), this.name = "OpenVsxThemeError", this.code = e;
|
|
10
9
|
}
|
|
11
|
-
},
|
|
10
|
+
}, y = (e) => typeof e == "object" && !!e && !Array.isArray(e), b = (e, t) => {
|
|
12
11
|
let r = [], i = n(e, r, { allowTrailingComma: !0 });
|
|
13
|
-
if (r.length > 0 || !
|
|
12
|
+
if (r.length > 0 || !y(i)) throw new v("unsupported-extension", `${t} is not valid JSON.`);
|
|
14
13
|
return i;
|
|
15
|
-
},
|
|
14
|
+
}, x = (e, { allowResourceOrigin: t = !1 } = {}) => {
|
|
16
15
|
if (typeof e != "string") return null;
|
|
17
16
|
try {
|
|
18
17
|
let n = new URL(e), r = n.origin.toLowerCase();
|
|
19
|
-
return r ===
|
|
18
|
+
return r === i || t && r === a ? n.toString() : null;
|
|
20
19
|
} catch {
|
|
21
20
|
return null;
|
|
22
21
|
}
|
|
23
|
-
},
|
|
22
|
+
}, S = (e) => {
|
|
24
23
|
let t = /^([a-z0-9][a-z0-9_-]{0,99})\.([a-z0-9][a-z0-9_-]{0,99})$/i.exec(e);
|
|
25
|
-
if (!t?.[1] || !t[2]) throw new
|
|
24
|
+
if (!t?.[1] || !t[2]) throw new v("unsupported-extension", "The selected Open VSX extension identifier is invalid.");
|
|
26
25
|
return [t[1], t[2]];
|
|
27
|
-
},
|
|
28
|
-
let t =
|
|
29
|
-
return Array.isArray(t?.themes) ? t.themes.filter(
|
|
30
|
-
},
|
|
26
|
+
}, C = (e) => {
|
|
27
|
+
let t = y(e.contributes) ? e.contributes : null;
|
|
28
|
+
return Array.isArray(t?.themes) ? t.themes.filter(y) : [];
|
|
29
|
+
}, w = async (e, t, n) => {
|
|
31
30
|
let r = Number(e.headers.get("content-length"));
|
|
32
|
-
if (Number.isFinite(r) && r > t) throw new
|
|
31
|
+
if (Number.isFinite(r) && r > t) throw new v("file-too-large", n);
|
|
33
32
|
if (!e.body) {
|
|
34
33
|
let r = new Uint8Array(await e.arrayBuffer());
|
|
35
|
-
if (r.byteLength > t) throw new
|
|
34
|
+
if (r.byteLength > t) throw new v("file-too-large", n);
|
|
36
35
|
return r;
|
|
37
36
|
}
|
|
38
37
|
let i = e.body.getReader(), a = [], o = 0;
|
|
@@ -40,7 +39,7 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
40
39
|
for (;;) {
|
|
41
40
|
let { done: e, value: r } = await i.read();
|
|
42
41
|
if (e) break;
|
|
43
|
-
if (o += r.byteLength, o > t) throw await i.cancel(), new
|
|
42
|
+
if (o += r.byteLength, o > t) throw await i.cancel(), new v("file-too-large", n);
|
|
44
43
|
a.push(r);
|
|
45
44
|
}
|
|
46
45
|
} finally {
|
|
@@ -49,24 +48,24 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
49
48
|
let s = new Uint8Array(o), c = 0;
|
|
50
49
|
for (let e of a) s.set(e, c), c += e.byteLength;
|
|
51
50
|
return s;
|
|
52
|
-
},
|
|
53
|
-
let o = new AbortController(), s = setTimeout(() => o.abort(),
|
|
51
|
+
}, T = (e) => async ({ url: t, limit: n, failureMessage: r, tooLargeMessage: i, allowResourceOrigin: a = !1 }) => {
|
|
52
|
+
let o = new AbortController(), s = setTimeout(() => o.abort(), _);
|
|
54
53
|
try {
|
|
55
|
-
let s =
|
|
56
|
-
if (!s) throw new
|
|
54
|
+
let s = x(String(t), { allowResourceOrigin: a });
|
|
55
|
+
if (!s) throw new v("open-vsx-unavailable", r);
|
|
57
56
|
let c = await e(s, {
|
|
58
57
|
redirect: "follow",
|
|
59
58
|
signal: o.signal
|
|
60
59
|
});
|
|
61
|
-
if (!
|
|
62
|
-
return await
|
|
60
|
+
if (!x(c.url || s, { allowResourceOrigin: a }) || !c.ok) throw new v("open-vsx-unavailable", r);
|
|
61
|
+
return await w(c, n, i);
|
|
63
62
|
} catch (e) {
|
|
64
|
-
throw e instanceof
|
|
63
|
+
throw e instanceof v ? e : new v("open-vsx-unavailable", o.signal.aborted ? "Open VSX took too long to respond." : r);
|
|
65
64
|
} finally {
|
|
66
65
|
clearTimeout(s);
|
|
67
66
|
}
|
|
68
|
-
},
|
|
69
|
-
if (!
|
|
67
|
+
}, E = (e) => {
|
|
68
|
+
if (!y(e)) return null;
|
|
70
69
|
let t = typeof e.namespace == "string" ? e.namespace.trim() : "", n = typeof e.name == "string" ? e.name.trim() : "";
|
|
71
70
|
if (!t || !n) return null;
|
|
72
71
|
let r = typeof e.displayName == "string" && e.displayName.trim() ? e.displayName.trim() : n;
|
|
@@ -77,49 +76,49 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
77
76
|
description: typeof e.description == "string" ? e.description.slice(0, 300) : "",
|
|
78
77
|
downloadCount: typeof e.downloadCount == "number" && Number.isFinite(e.downloadCount) ? Math.max(0, e.downloadCount) : 0
|
|
79
78
|
};
|
|
80
|
-
},
|
|
81
|
-
if (e.length > 1024 || e.includes("\0") || e.startsWith("/") || /^[a-z]:/i.test(e)) throw new
|
|
82
|
-
},
|
|
83
|
-
|
|
79
|
+
}, D = (e) => {
|
|
80
|
+
if (e.length > 1024 || e.includes("\0") || e.startsWith("/") || /^[a-z]:/i.test(e)) throw new v("unsupported-extension", "A theme path is not safe.");
|
|
81
|
+
}, O = ({ path: e, initialSegments: t, minimumDepth: n }) => {
|
|
82
|
+
D(e);
|
|
84
83
|
let r = [...t];
|
|
85
84
|
for (let t of e.replaceAll("\\", "/").split("/")) if (!(!t || t === ".")) {
|
|
86
85
|
if (t === "..") {
|
|
87
|
-
if (r.length <= n) throw new
|
|
86
|
+
if (r.length <= n) throw new v("unsupported-extension", "A theme path escapes its package.");
|
|
88
87
|
r.pop();
|
|
89
88
|
} else r.push(t);
|
|
90
89
|
}
|
|
91
90
|
return r.join("/");
|
|
92
|
-
},
|
|
91
|
+
}, k = (e, t = "extension/") => {
|
|
93
92
|
let n = t.split("/").slice(0, -1);
|
|
94
|
-
return n[0] !== "extension" && n.unshift("extension"),
|
|
93
|
+
return n[0] !== "extension" && n.unshift("extension"), O({
|
|
95
94
|
path: e,
|
|
96
95
|
initialSegments: n,
|
|
97
96
|
minimumDepth: 1
|
|
98
97
|
});
|
|
99
|
-
},
|
|
100
|
-
let t =
|
|
98
|
+
}, A = (e) => {
|
|
99
|
+
let t = O({
|
|
101
100
|
path: e,
|
|
102
101
|
initialSegments: [],
|
|
103
102
|
minimumDepth: 0
|
|
104
103
|
});
|
|
105
|
-
if (!t) throw new
|
|
104
|
+
if (!t) throw new v("unsupported-extension", "The extension package has an invalid file name.");
|
|
106
105
|
return t;
|
|
107
|
-
},
|
|
106
|
+
}, j = (e) => {
|
|
108
107
|
let t = e.byteLength, n = Math.max(0, t - 65557), r = t - 22;
|
|
109
108
|
for (; r >= n && (e.getUint32(r, !0) !== 101010256 || r + 22 + e.getUint16(r + 20, !0) !== t);) --r;
|
|
110
|
-
if (r < n) throw new
|
|
109
|
+
if (r < n) throw new v("unsupported-extension", "The extension package is not a valid ZIP file.");
|
|
111
110
|
return r;
|
|
112
|
-
},
|
|
113
|
-
let t =
|
|
114
|
-
if (i !== t || i > e.byteLength) throw new
|
|
111
|
+
}, M = (e) => {
|
|
112
|
+
let t = j(e), n = e.getUint32(t + 12, !0), r = e.getUint32(t + 16, !0), i = r + n;
|
|
113
|
+
if (i !== t || i > e.byteLength) throw new v("unsupported-extension", "The extension package has an invalid ZIP directory.");
|
|
115
114
|
return {
|
|
116
115
|
start: r,
|
|
117
116
|
end: i
|
|
118
117
|
};
|
|
119
|
-
},
|
|
120
|
-
if (n + 46 > r || t.getUint32(n, !0) !== 33639248) throw new
|
|
118
|
+
}, N = ({ bytes: e, view: t, offset: n, directoryEnd: r }) => {
|
|
119
|
+
if (n + 46 > r || t.getUint32(n, !0) !== 33639248) throw new v("unsupported-extension", "The extension package has an invalid ZIP directory.");
|
|
121
120
|
let i = t.getUint32(n + 20, !0), a = t.getUint32(n + 24, !0), o = t.getUint16(n + 28, !0), s = t.getUint16(n + 30, !0), c = t.getUint16(n + 32, !0), l = n + 46 + o + s + c;
|
|
122
|
-
if (l > r || i === 4294967295 || a === 4294967295 || a > 0 && (i === 0 || a / i >
|
|
121
|
+
if (l > r || i === 4294967295 || a === 4294967295 || a > 0 && (i === 0 || a / i > m)) throw new v("unsupported-extension", "The extension package has unsafe ZIP metadata.");
|
|
123
122
|
try {
|
|
124
123
|
return {
|
|
125
124
|
name: new TextDecoder("utf-8", { fatal: !0 }).decode(e.subarray(n + 46, n + 46 + o)),
|
|
@@ -127,32 +126,32 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
127
126
|
nextOffset: l
|
|
128
127
|
};
|
|
129
128
|
} catch {
|
|
130
|
-
throw new
|
|
129
|
+
throw new v("unsupported-extension", "The extension package has an invalid file name.");
|
|
131
130
|
}
|
|
132
|
-
},
|
|
133
|
-
let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n =
|
|
131
|
+
}, P = (e) => {
|
|
132
|
+
let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = M(t), r = /* @__PURE__ */ new Map(), i = 0, a = 0, o = n.start;
|
|
134
133
|
for (; o < n.end;) {
|
|
135
|
-
if (a += 1, a >
|
|
136
|
-
let s =
|
|
134
|
+
if (a += 1, a > f) throw new v("unsupported-extension", "The extension package has an invalid ZIP directory.");
|
|
135
|
+
let s = N({
|
|
137
136
|
bytes: e,
|
|
138
137
|
view: t,
|
|
139
138
|
offset: o,
|
|
140
139
|
directoryEnd: n.end
|
|
141
140
|
});
|
|
142
|
-
if (i += s.uncompressed, i >
|
|
143
|
-
r.set(
|
|
141
|
+
if (i += s.uncompressed, i > p) throw new v("file-too-large", "The extension package expands beyond the safe limit.");
|
|
142
|
+
r.set(A(s.name), s.uncompressed), o = s.nextOffset;
|
|
144
143
|
}
|
|
145
144
|
return r;
|
|
146
|
-
},
|
|
145
|
+
}, F = async ({ zip: e, sizes: t, path: n, description: r }) => {
|
|
147
146
|
let i = t.get(n);
|
|
148
|
-
if (i === void 0) throw new
|
|
149
|
-
if (i >
|
|
147
|
+
if (i === void 0) throw new v("unsupported-extension", `${r} is missing.`);
|
|
148
|
+
if (i > u) throw new v("file-too-large", `${r} is too large.`);
|
|
150
149
|
let a = e.file(n);
|
|
151
|
-
if (!a) throw new
|
|
150
|
+
if (!a) throw new v("unsupported-extension", `${r} is missing.`);
|
|
152
151
|
return a.async("string");
|
|
153
|
-
},
|
|
154
|
-
if (r.size >=
|
|
155
|
-
let i =
|
|
152
|
+
}, I = async ({ zip: e, sizes: t, path: n, ancestors: r = /* @__PURE__ */ new Set() }) => {
|
|
153
|
+
if (r.size >= g || r.has(n)) throw new v("unsupported-extension", "Theme includes are cyclic or too deeply nested.");
|
|
154
|
+
let i = b(await F({
|
|
156
155
|
zip: e,
|
|
157
156
|
sizes: t,
|
|
158
157
|
path: n,
|
|
@@ -161,50 +160,50 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
161
160
|
if (typeof i.include != "string") return i;
|
|
162
161
|
let a = new Set(r);
|
|
163
162
|
a.add(n);
|
|
164
|
-
let o = await
|
|
163
|
+
let o = await I({
|
|
165
164
|
zip: e,
|
|
166
165
|
sizes: t,
|
|
167
|
-
path:
|
|
166
|
+
path: k(i.include, n),
|
|
168
167
|
ancestors: a
|
|
169
168
|
});
|
|
170
169
|
return {
|
|
171
170
|
...o,
|
|
172
171
|
...i,
|
|
173
172
|
colors: {
|
|
174
|
-
...
|
|
175
|
-
...
|
|
173
|
+
...y(o.colors) ? o.colors : {},
|
|
174
|
+
...y(i.colors) ? i.colors : {}
|
|
176
175
|
}
|
|
177
176
|
};
|
|
178
|
-
},
|
|
179
|
-
let [n, r] =
|
|
180
|
-
url: `${
|
|
181
|
-
limit:
|
|
177
|
+
}, L = (e) => e === "vs" ? "light" : e === "vs-dark" ? "dark" : e === "hc-black" ? "hc" : e === "hc-light" ? "hcLight" : null, R = (e, t) => e.find((e) => t === "dark" ? e.appearance === "dark" || e.appearance === "high-contrast-dark" : e.appearance === "light" || e.appearance === "high-contrast-light") ?? e[0], z = async ({ request: e, extensionId: t }) => {
|
|
178
|
+
let [n, r] = S(t), a = await e({
|
|
179
|
+
url: `${i}/api/${encodeURIComponent(n)}/${encodeURIComponent(r)}`,
|
|
180
|
+
limit: c,
|
|
182
181
|
failureMessage: "Open VSX theme details are unavailable right now.",
|
|
183
182
|
tooLargeMessage: "Open VSX returned unexpectedly large theme details."
|
|
184
|
-
}), o = JSON.parse(new TextDecoder().decode(
|
|
185
|
-
if (!
|
|
186
|
-
let s = { allowResourceOrigin: !0 },
|
|
187
|
-
if (!
|
|
183
|
+
}), o = JSON.parse(new TextDecoder().decode(a));
|
|
184
|
+
if (!y(o) || !y(o.files)) throw new v("unsupported-extension", "Open VSX returned malformed theme details.");
|
|
185
|
+
let s = { allowResourceOrigin: !0 }, l = x(o.files.manifest, s), u = x(o.files.download, s), d = x(o.files.sha256, s), f = typeof o.version == "string" ? o.version : "";
|
|
186
|
+
if (!l || !u || !d || !f) throw new v("unsupported-extension", "Open VSX returned malformed theme details.");
|
|
188
187
|
return {
|
|
189
188
|
extensionName: r,
|
|
190
|
-
manifestUrl:
|
|
189
|
+
manifestUrl: l,
|
|
191
190
|
packageUrl: u,
|
|
192
191
|
checksumUrl: d,
|
|
193
192
|
version: f
|
|
194
193
|
};
|
|
195
|
-
},
|
|
194
|
+
}, B = async ({ request: e, manifestUrl: t }) => {
|
|
196
195
|
let n = await e({
|
|
197
196
|
url: t,
|
|
198
|
-
limit:
|
|
197
|
+
limit: l,
|
|
199
198
|
failureMessage: "That extension has no readable manifest.",
|
|
200
199
|
tooLargeMessage: "That extension manifest is too large.",
|
|
201
200
|
allowResourceOrigin: !0
|
|
202
|
-
}), r =
|
|
203
|
-
if (r.length === 0 || r.length >
|
|
204
|
-
},
|
|
205
|
-
let [
|
|
201
|
+
}), r = C(b(new TextDecoder().decode(n), "The extension manifest"));
|
|
202
|
+
if (r.length === 0 || r.length > h) throw new v("unsupported-extension", "That extension does not contain a supported number of color themes.");
|
|
203
|
+
}, V = async ({ request: e, packageUrl: t, checksumUrl: n }) => {
|
|
204
|
+
let [r, i] = await Promise.all([e({
|
|
206
205
|
url: t,
|
|
207
|
-
limit:
|
|
206
|
+
limit: d,
|
|
208
207
|
failureMessage: "That Open VSX theme could not be downloaded.",
|
|
209
208
|
tooLargeMessage: "That theme extension is too large to import safely.",
|
|
210
209
|
allowResourceOrigin: !0
|
|
@@ -214,40 +213,40 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
214
213
|
failureMessage: "That Open VSX theme has no readable checksum.",
|
|
215
214
|
tooLargeMessage: "That Open VSX checksum response is invalid.",
|
|
216
215
|
allowResourceOrigin: !0
|
|
217
|
-
})]),
|
|
218
|
-
if (!
|
|
219
|
-
if (
|
|
220
|
-
return
|
|
221
|
-
},
|
|
222
|
-
let t =
|
|
216
|
+
})]), a = new TextDecoder().decode(i).trim().split(/\s+/)[0], o = await globalThis.crypto.subtle.digest("SHA-256", new Uint8Array(r)), s = Array.from(new Uint8Array(o), (e) => e.toString(16).padStart(2, "0")).join("");
|
|
217
|
+
if (!a || !/^[a-f\d]{64}$/i.test(a)) throw new v("integrity-failed", "That Open VSX theme has an invalid checksum.");
|
|
218
|
+
if (a.toLowerCase() !== s) throw new v("integrity-failed", "That Open VSX theme failed its integrity check.");
|
|
219
|
+
return r;
|
|
220
|
+
}, H = async (e) => {
|
|
221
|
+
let t = P(e);
|
|
223
222
|
try {
|
|
224
223
|
return {
|
|
225
|
-
zip: await
|
|
224
|
+
zip: await r.loadAsync(e),
|
|
226
225
|
sizes: t
|
|
227
226
|
};
|
|
228
227
|
} catch {
|
|
229
|
-
throw new
|
|
228
|
+
throw new v("unsupported-extension", "That extension package could not be opened.");
|
|
230
229
|
}
|
|
231
|
-
},
|
|
232
|
-
let i =
|
|
230
|
+
}, U = async ({ zip: e, sizes: t, extensionId: n, version: r }) => {
|
|
231
|
+
let i = b(await F({
|
|
233
232
|
zip: e,
|
|
234
233
|
sizes: t,
|
|
235
234
|
path: "extension/package.json",
|
|
236
235
|
description: "The packaged extension manifest"
|
|
237
236
|
}), "The packaged extension manifest");
|
|
238
|
-
if ((typeof i.publisher == "string" && typeof i.name == "string" ? `${i.publisher}.${i.name}` : "").toLowerCase() !== n.toLowerCase() || i.version !== r) throw new
|
|
237
|
+
if ((typeof i.publisher == "string" && typeof i.name == "string" ? `${i.publisher}.${i.name}` : "").toLowerCase() !== n.toLowerCase() || i.version !== r) throw new v("integrity-failed", "The downloaded package does not match the selected Open VSX theme.");
|
|
239
238
|
return i;
|
|
240
|
-
},
|
|
241
|
-
let a =
|
|
242
|
-
if (a.length === 0 || a.length >
|
|
239
|
+
}, W = async ({ zip: t, sizes: n, manifest: r, fallbackName: i }) => {
|
|
240
|
+
let a = C(r);
|
|
241
|
+
if (a.length === 0 || a.length > h) throw new v("unsupported-extension", "That extension has no compatible color themes.");
|
|
243
242
|
let o = [];
|
|
244
243
|
for (let r of a) {
|
|
245
|
-
if (typeof r.path != "string") throw new
|
|
246
|
-
let a =
|
|
244
|
+
if (typeof r.path != "string") throw new v("unsupported-extension", "A contributed theme has no valid path.");
|
|
245
|
+
let a = k(r.path), s = await I({
|
|
247
246
|
zip: t,
|
|
248
247
|
sizes: n,
|
|
249
248
|
path: a
|
|
250
|
-
}), c =
|
|
249
|
+
}), c = L(r.uiTheme), l = typeof r.label == "string" && r.label.trim() ? r.label.trim() : i;
|
|
251
250
|
o.push(e({
|
|
252
251
|
source: JSON.stringify({
|
|
253
252
|
...s,
|
|
@@ -258,11 +257,11 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
258
257
|
}));
|
|
259
258
|
}
|
|
260
259
|
return o;
|
|
261
|
-
},
|
|
260
|
+
}, G = ({ description: e, name: t }) => {
|
|
262
261
|
let n = `${t} ${e}`;
|
|
263
262
|
return /\b(?:color\s+scheme|theme)\b/i.test(n) && !/\b(?:file\s+icons?|product\s+icons?|icon\s+theme|icons?)\b/i.test(n);
|
|
264
|
-
},
|
|
265
|
-
let n =
|
|
263
|
+
}, K = ({ fetchImpl: e = fetch } = {}) => {
|
|
264
|
+
let n = T(e);
|
|
266
265
|
return {
|
|
267
266
|
search: async (e) => {
|
|
268
267
|
let t = e.trim();
|
|
@@ -271,20 +270,20 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
271
270
|
message: "Search terms must be 100 characters or fewer."
|
|
272
271
|
};
|
|
273
272
|
try {
|
|
274
|
-
let e = new URL(
|
|
273
|
+
let e = new URL(o);
|
|
275
274
|
t && e.searchParams.set("query", t), e.searchParams.set("category", "Themes"), e.searchParams.set("sortBy", "downloadCount"), e.searchParams.set("sortOrder", "desc"), e.searchParams.set("size", "12");
|
|
276
275
|
let r = await n({
|
|
277
276
|
url: e,
|
|
278
|
-
limit:
|
|
277
|
+
limit: s,
|
|
279
278
|
failureMessage: "Open VSX search is unavailable right now.",
|
|
280
279
|
tooLargeMessage: "Open VSX returned an unexpectedly large search response."
|
|
281
280
|
}), i = JSON.parse(new TextDecoder().decode(r));
|
|
282
|
-
if (!
|
|
281
|
+
if (!y(i) || !Array.isArray(i.extensions)) throw Error("invalid response");
|
|
283
282
|
return {
|
|
284
283
|
status: "success",
|
|
285
284
|
themes: i.extensions.flatMap((e) => {
|
|
286
|
-
let t =
|
|
287
|
-
return t &&
|
|
285
|
+
let t = E(e);
|
|
286
|
+
return t && G(t) ? [t] : [];
|
|
288
287
|
}).slice(0, 12)
|
|
289
288
|
};
|
|
290
289
|
} catch {
|
|
@@ -296,24 +295,24 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
296
295
|
},
|
|
297
296
|
importTheme: async (e, r) => {
|
|
298
297
|
try {
|
|
299
|
-
let t = await
|
|
298
|
+
let t = await z({
|
|
300
299
|
request: n,
|
|
301
300
|
extensionId: e
|
|
302
301
|
});
|
|
303
|
-
await
|
|
302
|
+
await B({
|
|
304
303
|
request: n,
|
|
305
304
|
manifestUrl: t.manifestUrl
|
|
306
305
|
});
|
|
307
|
-
let { zip: i, sizes: a } = await
|
|
306
|
+
let { zip: i, sizes: a } = await H(await V({
|
|
308
307
|
request: n,
|
|
309
308
|
...t
|
|
310
309
|
}));
|
|
311
310
|
return {
|
|
312
311
|
status: "success",
|
|
313
|
-
theme:
|
|
312
|
+
theme: R(await W({
|
|
314
313
|
zip: i,
|
|
315
314
|
sizes: a,
|
|
316
|
-
manifest: await
|
|
315
|
+
manifest: await U({
|
|
317
316
|
zip: i,
|
|
318
317
|
sizes: a,
|
|
319
318
|
extensionId: e,
|
|
@@ -323,7 +322,7 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
323
322
|
}), r)
|
|
324
323
|
};
|
|
325
324
|
} catch (e) {
|
|
326
|
-
return e instanceof t || e instanceof
|
|
325
|
+
return e instanceof t || e instanceof v ? {
|
|
327
326
|
status: "error",
|
|
328
327
|
error: {
|
|
329
328
|
code: e.code,
|
|
@@ -341,4 +340,4 @@ var a = "https://open-vsx.org", o = "https://openvsx.eclipsecontent.org", s = `$
|
|
|
341
340
|
};
|
|
342
341
|
};
|
|
343
342
|
//#endregion
|
|
344
|
-
export {
|
|
343
|
+
export { K as createOpenVsxThemeService };
|
package/dist/site/projects.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ declare const projects: readonly [{
|
|
|
18
18
|
readonly label: "Workbench";
|
|
19
19
|
readonly href: "https://filipgutica.github.io/t3code/";
|
|
20
20
|
readonly repository: "https://github.com/filipgutica/t3code";
|
|
21
|
+
}, {
|
|
22
|
+
readonly id: "filip-stack";
|
|
23
|
+
readonly label: "Filip Stack";
|
|
24
|
+
readonly href: "https://filipgutica.github.io/filip-stack/";
|
|
25
|
+
readonly repository: "https://github.com/filipgutica/filip-stack";
|
|
21
26
|
}, {
|
|
22
27
|
readonly id: "ui";
|
|
23
28
|
readonly label: "UI";
|
package/dist/site.js
CHANGED
|
@@ -60,6 +60,12 @@ var y = "tool-site-theme", b = (e) => e === "system" || e === "light" || e === "
|
|
|
60
60
|
href: "https://filipgutica.github.io/t3code/",
|
|
61
61
|
repository: "https://github.com/filipgutica/t3code"
|
|
62
62
|
},
|
|
63
|
+
{
|
|
64
|
+
id: "filip-stack",
|
|
65
|
+
label: "Filip Stack",
|
|
66
|
+
href: "https://filipgutica.github.io/filip-stack/",
|
|
67
|
+
repository: "https://github.com/filipgutica/filip-stack"
|
|
68
|
+
},
|
|
63
69
|
{
|
|
64
70
|
id: "ui",
|
|
65
71
|
label: "UI",
|
package/package.json
CHANGED
package/src/components/tabs.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.fg-tabs {
|
|
3
|
+
width: 100%;
|
|
3
4
|
min-width: 0;
|
|
4
5
|
font-family: var(--font-ui);
|
|
5
6
|
font-size: var(--text-md);
|
|
@@ -8,8 +9,10 @@
|
|
|
8
9
|
|
|
9
10
|
.fg-tabs__list {
|
|
10
11
|
display: flex;
|
|
12
|
+
width: max-content;
|
|
11
13
|
max-width: 100%;
|
|
12
14
|
overflow-x: auto;
|
|
15
|
+
margin-block-end: var(--space-4);
|
|
13
16
|
border-bottom: 1px solid var(--color-border-subtle);
|
|
14
17
|
}
|
|
15
18
|
|
|
@@ -22,6 +25,7 @@
|
|
|
22
25
|
color: var(--color-muted);
|
|
23
26
|
background: transparent;
|
|
24
27
|
font: inherit;
|
|
28
|
+
font-weight: var(--weight-medium);
|
|
25
29
|
white-space: nowrap;
|
|
26
30
|
cursor: pointer;
|
|
27
31
|
}
|
|
@@ -30,7 +34,6 @@
|
|
|
30
34
|
.fg-tabs__tab[aria-selected="true"] {
|
|
31
35
|
border-bottom-color: var(--color-link);
|
|
32
36
|
color: var(--color-text);
|
|
33
|
-
font-weight: var(--weight-medium);
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
.fg-tabs__panel { min-width: 0; }
|