ovsx 1.1.0 → 1.2.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.
Files changed (121) hide show
  1. package/README.md +71 -1
  2. package/lib/get.js +1 -1
  3. package/lib/get.js.map +1 -1
  4. package/lib/index.d.ts +4 -0
  5. package/lib/index.d.ts.map +1 -1
  6. package/lib/index.js +4 -0
  7. package/lib/index.js.map +1 -1
  8. package/lib/list-options.d.ts +24 -0
  9. package/lib/list-options.d.ts.map +1 -0
  10. package/lib/list-options.js +15 -0
  11. package/lib/list-options.js.map +1 -0
  12. package/lib/list.d.ts +18 -0
  13. package/lib/list.d.ts.map +1 -0
  14. package/lib/list.js +46 -0
  15. package/lib/list.js.map +1 -0
  16. package/lib/main.js +78 -2
  17. package/lib/main.js.map +1 -1
  18. package/lib/oidc.d.ts +22 -0
  19. package/lib/oidc.d.ts.map +1 -0
  20. package/lib/oidc.js +101 -0
  21. package/lib/oidc.js.map +1 -0
  22. package/lib/publish-options.d.ts +8 -1
  23. package/lib/publish-options.d.ts.map +1 -1
  24. package/lib/publish.d.ts.map +1 -1
  25. package/lib/publish.js +73 -4
  26. package/lib/publish.js.map +1 -1
  27. package/lib/registry-options.d.ts +8 -0
  28. package/lib/registry-options.d.ts.map +1 -1
  29. package/lib/registry.d.ts +119 -1
  30. package/lib/registry.d.ts.map +1 -1
  31. package/lib/registry.js +187 -19
  32. package/lib/registry.js.map +1 -1
  33. package/lib/search-options.d.ts +48 -0
  34. package/lib/search-options.d.ts.map +1 -0
  35. package/lib/search-options.js +15 -0
  36. package/lib/search-options.js.map +1 -0
  37. package/lib/search.d.ts +22 -0
  38. package/lib/search.d.ts.map +1 -0
  39. package/lib/search.js +86 -0
  40. package/lib/search.js.map +1 -0
  41. package/lib/show-options.d.ts +33 -0
  42. package/lib/show-options.d.ts.map +1 -0
  43. package/lib/show-options.js +15 -0
  44. package/lib/show-options.js.map +1 -0
  45. package/lib/show.d.ts +18 -0
  46. package/lib/show.d.ts.map +1 -0
  47. package/lib/show.js +289 -0
  48. package/lib/show.js.map +1 -0
  49. package/lib/table.d.ts +27 -0
  50. package/lib/table.d.ts.map +1 -0
  51. package/lib/table.js +56 -0
  52. package/lib/table.js.map +1 -0
  53. package/lib/trusted-publishing-options.d.ts +30 -0
  54. package/lib/trusted-publishing-options.d.ts.map +1 -0
  55. package/lib/trusted-publishing-options.js +15 -0
  56. package/lib/trusted-publishing-options.js.map +1 -0
  57. package/lib/trusted-publishing.d.ts +35 -0
  58. package/lib/trusted-publishing.d.ts.map +1 -0
  59. package/lib/trusted-publishing.js +112 -0
  60. package/lib/trusted-publishing.js.map +1 -0
  61. package/lib/unpublish-options.d.ts +34 -0
  62. package/lib/unpublish-options.d.ts.map +1 -0
  63. package/lib/unpublish-options.js +15 -0
  64. package/lib/unpublish-options.js.map +1 -0
  65. package/lib/unpublish.d.ts +22 -0
  66. package/lib/unpublish.d.ts.map +1 -0
  67. package/lib/unpublish.js +137 -0
  68. package/lib/unpublish.js.map +1 -0
  69. package/lib/util.d.ts +39 -1
  70. package/lib/util.d.ts.map +1 -1
  71. package/lib/util.js +91 -5
  72. package/lib/util.js.map +1 -1
  73. package/lib/verify-options.d.ts +24 -0
  74. package/lib/verify-options.d.ts.map +1 -0
  75. package/lib/verify-options.js +15 -0
  76. package/lib/verify-options.js.map +1 -0
  77. package/lib/verify-signature-options.d.ts +32 -0
  78. package/lib/verify-signature-options.d.ts.map +1 -0
  79. package/lib/verify-signature-options.js +15 -0
  80. package/lib/verify-signature-options.js.map +1 -0
  81. package/lib/verify-signature.d.ts +28 -0
  82. package/lib/verify-signature.d.ts.map +1 -0
  83. package/lib/verify-signature.js +105 -0
  84. package/lib/verify-signature.js.map +1 -0
  85. package/lib/verify.d.ts +21 -0
  86. package/lib/verify.d.ts.map +1 -0
  87. package/lib/verify.js +97 -0
  88. package/lib/verify.js.map +1 -0
  89. package/lib/version.d.ts +1 -1
  90. package/lib/version.js +1 -1
  91. package/lib/zip.d.ts +10 -0
  92. package/lib/zip.d.ts.map +1 -1
  93. package/lib/zip.js +31 -0
  94. package/lib/zip.js.map +1 -1
  95. package/package.json +9 -5
  96. package/src/get.ts +1 -1
  97. package/src/index.ts +4 -0
  98. package/src/list-options.ts +25 -0
  99. package/src/list.ts +48 -0
  100. package/src/main.ts +89 -3
  101. package/src/oidc.ts +107 -0
  102. package/src/publish-options.ts +8 -1
  103. package/src/publish.ts +97 -5
  104. package/src/registry-options.ts +8 -0
  105. package/src/registry.ts +292 -19
  106. package/src/search-options.ts +49 -0
  107. package/src/search.ts +95 -0
  108. package/src/show-options.ts +34 -0
  109. package/src/show.ts +328 -0
  110. package/src/table.ts +53 -0
  111. package/src/trusted-publishing-options.ts +30 -0
  112. package/src/trusted-publishing.ts +148 -0
  113. package/src/unpublish-options.ts +35 -0
  114. package/src/unpublish.ts +160 -0
  115. package/src/util.ts +102 -5
  116. package/src/verify-options.ts +25 -0
  117. package/src/verify-signature-options.ts +32 -0
  118. package/src/verify-signature.ts +124 -0
  119. package/src/verify.ts +107 -0
  120. package/src/version.ts +1 -1
  121. package/src/zip.ts +31 -1
package/lib/show.js ADDED
@@ -0,0 +1,289 @@
1
+ "use strict";
2
+ /******************************************************************************
3
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
4
+ *
5
+ * See the NOTICE file(s) distributed with this work for additional
6
+ * information regarding copyright ownership.
7
+ *
8
+ * This program and the accompanying materials are made available under the
9
+ * terms of the Eclipse Public License 2.0 which is available at
10
+ * https://www.eclipse.org/legal/epl-2.0.
11
+ *
12
+ * SPDX-License-Identifier: EPL-2.0
13
+ *****************************************************************************/
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.show = show;
16
+ const semver = require("semver");
17
+ const registry_1 = require("./registry");
18
+ const table_1 = require("./table");
19
+ const util_1 = require("./util");
20
+ /**
21
+ * How many versions the history table prints unless `--all-versions` is given. Matches what
22
+ * `vsce show` lists; the remainder is reported as a count rather than dropped silently.
23
+ */
24
+ const VERSION_HISTORY_SIZE = 6;
25
+ /**
26
+ * Tags starting with `__` are internal bookkeeping (e.g. `__web_extension`) rather than anything
27
+ * the publisher wrote, and the web UI hides them too.
28
+ */
29
+ const INTERNAL_TAG_PREFIX = '__';
30
+ /**
31
+ * Page size for the version-reference listing. Versions come back newest first, and each version
32
+ * contributes one entry per target platform, so a page has to be comfortably larger than the
33
+ * number of versions shown for the default table to be filled from a single request.
34
+ */
35
+ const VERSION_PAGE_SIZE = 100;
36
+ /**
37
+ * Prints an extension's metadata.
38
+ */
39
+ async function show(options) {
40
+ (0, util_1.addEnvOptions)(options);
41
+ const { id, version } = splitVersion(options.extensionId);
42
+ const match = (0, util_1.matchExtensionId)(id);
43
+ if (!match) {
44
+ throw new Error('The extension identifier must have the form `namespace.extension` or `namespace/extension`.');
45
+ }
46
+ const [, namespace, name] = match;
47
+ const registry = new registry_1.Registry(options);
48
+ const extension = await registry.getMetadata(namespace, name, options.target, version);
49
+ if (extension.error) {
50
+ throw new Error(extension.error);
51
+ }
52
+ if (options.json) {
53
+ console.log(JSON.stringify(extension, null, 4));
54
+ return;
55
+ }
56
+ const allVersions = options.allVersions === true;
57
+ const versions = await getVersions(registry, namespace, name, options.target, allVersions);
58
+ printSummary(extension, versions, allVersions);
59
+ }
60
+ /**
61
+ * Splits a trailing `@<version>` off the identifier, the way `vsce show` accepts it. Only the last
62
+ * `@` is considered, so it stays out of the way of the identifier itself.
63
+ *
64
+ * An `@` with nothing after it is rejected rather than read as "no version given". It usually means a
65
+ * shell variable that did not expand - `ovsx show redhat.java@$VERSION` with `VERSION` unset - and
66
+ * reporting the latest version for that would answer a question the caller did not ask.
67
+ */
68
+ function splitVersion(extensionId) {
69
+ const at = extensionId.lastIndexOf('@');
70
+ if (at <= 0) {
71
+ return { id: extensionId };
72
+ }
73
+ const version = extensionId.substring(at + 1);
74
+ if (version.length === 0) {
75
+ throw new Error('A version must follow `@`, as in `namespace.extension@1.2.3`.');
76
+ }
77
+ return { id: extensionId.substring(0, at), version };
78
+ }
79
+ /**
80
+ * Collects the version history, collapsing the one-entry-per-target-platform rows the registry
81
+ * returns into a single row per version. Fetches one page unless every version is wanted, in which
82
+ * case it pages to the end - `totalSize` counts version/target-platform pairs, not versions, so
83
+ * paging has to run on what has actually been returned rather than on a version count.
84
+ *
85
+ * Best-effort: a registry that doesn't serve this endpoint still gets everything else, just
86
+ * without the history table.
87
+ */
88
+ async function getVersions(registry, namespace, name, target, allVersions) {
89
+ const references = [];
90
+ let offset = 0;
91
+ try {
92
+ for (;;) {
93
+ const page = await registry.getVersionReferences(namespace, name, target, VERSION_PAGE_SIZE, offset);
94
+ if (page.error) {
95
+ return [];
96
+ }
97
+ const versions = page.versions ?? [];
98
+ references.push(...versions);
99
+ offset += versions.length;
100
+ if (!allVersions || versions.length === 0 || offset >= page.totalSize) {
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ catch {
106
+ return [];
107
+ }
108
+ const byVersion = new Map();
109
+ for (const reference of references) {
110
+ let summary = byVersion.get(reference.version);
111
+ if (!summary) {
112
+ summary = { version: reference.version, targetPlatforms: [] };
113
+ byVersion.set(reference.version, summary);
114
+ }
115
+ if (reference.targetPlatform && !summary.targetPlatforms.includes(reference.targetPlatform)) {
116
+ summary.targetPlatforms.push(reference.targetPlatform);
117
+ }
118
+ }
119
+ return [...byVersion.values()].sort(byNewestFirst);
120
+ }
121
+ /**
122
+ * Newest version first. Anything that isn't valid semver (the registry accepts such versions from
123
+ * a mirror) sorts after everything that is, rather than being compared incomparably.
124
+ *
125
+ * Deliberately `valid` and not `coerce`: coerce drops prerelease identifiers, so `1.2.0-alpha.1`
126
+ * and `1.2.0` would compare equal and order unstably, and it accepts inputs semver itself rejects
127
+ * (`v1.2` becomes `1.2.0`), which would defeat the fallback below.
128
+ */
129
+ function byNewestFirst(a, b) {
130
+ const left = semver.valid(a.version);
131
+ const right = semver.valid(b.version);
132
+ if (left && right) {
133
+ return semver.rcompare(left, right);
134
+ }
135
+ if (left) {
136
+ return -1;
137
+ }
138
+ if (right) {
139
+ return 1;
140
+ }
141
+ return b.version.localeCompare(a.version);
142
+ }
143
+ function printSummary(extension, versions, allVersions) {
144
+ const publisher = extension.namespaceDisplayName || extension.namespace;
145
+ console.log(extension.displayName || extension.name);
146
+ console.log(` ${publisher}${extension.verified ? ' (verified publisher)' : ''}`);
147
+ console.log(` ${(0, table_1.formatCount)(extension.downloadCount, 'download')} ${formatRating(extension)}`);
148
+ if (extension.description) {
149
+ console.log();
150
+ console.log(` ${extension.description}`);
151
+ }
152
+ printNotices(extension);
153
+ printVersionHistory(versions, allVersions);
154
+ printList('Categories', extension.categories);
155
+ printList('Tags', extension.tags?.filter(tag => !tag.startsWith(INTERNAL_TAG_PREFIX)));
156
+ printTable('More Info', moreInfo(extension));
157
+ printTable('Registry', registryInfo(extension));
158
+ printTable('Statistics', statistics(extension));
159
+ }
160
+ /**
161
+ * Anything a consumer of this extension should see before its metadata: deprecation first, since
162
+ * it changes whether they should install it at all.
163
+ */
164
+ function printNotices(extension) {
165
+ const notices = [];
166
+ if (extension.deprecated) {
167
+ const replacement = extension.replacement;
168
+ notices.push(replacement
169
+ ? `Deprecated - superseded by ${replacement.displayName ?? replacement.url}`
170
+ : 'Deprecated');
171
+ }
172
+ if (extension.downloadable === false) {
173
+ notices.push('Not downloadable from this registry');
174
+ }
175
+ if (extension.preview) {
176
+ notices.push('Preview');
177
+ }
178
+ if (extension.namespaceOwnershipConflict) {
179
+ notices.push('The namespace ownership of this extension is disputed');
180
+ }
181
+ if (notices.length > 0) {
182
+ console.log();
183
+ for (const notice of notices) {
184
+ console.log(` ! ${notice}`);
185
+ }
186
+ }
187
+ }
188
+ function printVersionHistory(versions, allVersions) {
189
+ if (versions.length === 0) {
190
+ return;
191
+ }
192
+ const shown = allVersions ? versions : versions.slice(0, VERSION_HISTORY_SIZE);
193
+ const rows = shown.map(v => [v.version, v.targetPlatforms.join(', ')]);
194
+ console.log();
195
+ console.log('Version History:');
196
+ (0, table_1.printRows)([['Version', 'Target Platforms'], ...rows]);
197
+ const remaining = versions.length - shown.length;
198
+ if (remaining > 0) {
199
+ console.log(` ... and ${remaining} more (pass --all-versions to list them)`);
200
+ }
201
+ }
202
+ function moreInfo(extension) {
203
+ const rows = [
204
+ ['Unique Identifier', `${extension.namespace}.${extension.name}`],
205
+ ['Version', extension.version]
206
+ ];
207
+ if (extension.versionAlias?.length > 0) {
208
+ rows.push(['Version Aliases', extension.versionAlias.join(', ')]);
209
+ }
210
+ if (extension.targetPlatform) {
211
+ rows.push(['Target Platform', extension.targetPlatform]);
212
+ }
213
+ rows.push(['Last Updated', extension.timestamp]);
214
+ rows.push(['Published By', extension.publishedBy?.loginName ?? '']);
215
+ addIfPresent(rows, 'License', extension.license);
216
+ addIfPresent(rows, 'Homepage', extension.homepage);
217
+ addIfPresent(rows, 'Repository', extension.repository);
218
+ addIfPresent(rows, 'Bugs', extension.bugs);
219
+ addIfPresent(rows, 'Q&A', extension.qna);
220
+ addIfPresent(rows, 'Sponsor', extension.sponsorLink);
221
+ if (extension.engines) {
222
+ rows.push(['Engines', Object.entries(extension.engines).map(([e, v]) => `${e} ${v}`).join(', ')]);
223
+ }
224
+ return rows;
225
+ }
226
+ /**
227
+ * The parts an Open VSX compatible registry reports that the Marketplace has no equivalent for.
228
+ * Kept in its own block rather than mixed into "More Info" so it's obvious what is registry
229
+ * specific, and omitted entirely when none of it applies.
230
+ */
231
+ function registryInfo(extension) {
232
+ const rows = [];
233
+ if (extension.verified !== undefined) {
234
+ rows.push(['Verified Publisher', yesNo(extension.verified)]);
235
+ }
236
+ if (extension.publishedWithTrustedPublishing) {
237
+ rows.push(['Trusted Publishing', 'yes']);
238
+ }
239
+ if (extension.preRelease !== undefined) {
240
+ rows.push(['Pre-Release', yesNo(extension.preRelease)]);
241
+ }
242
+ addIfPresent(rows, 'Extension Kind', extension.extensionKind?.join(', '));
243
+ addIfPresent(rows, 'Localized', extension.localizedLanguages?.join(', '));
244
+ addIfPresent(rows, 'Dependencies', extension.dependencies?.map(referenceId).join(', '));
245
+ addIfPresent(rows, 'Bundled Extensions', extension.bundledExtensions?.map(referenceId).join(', '));
246
+ return rows;
247
+ }
248
+ function statistics(extension) {
249
+ const rows = [['Downloads', (0, table_1.formatNumber)(extension.downloadCount)]];
250
+ if (extension.averageRating !== undefined) {
251
+ rows.push(['Average Rating', `${extension.averageRating.toFixed(1)}/5`]);
252
+ }
253
+ rows.push(['Reviews', (0, table_1.formatNumber)(Number(extension.reviewCount ?? 0))]);
254
+ return rows;
255
+ }
256
+ function referenceId(reference) {
257
+ return `${reference.namespace}.${reference.extension}`;
258
+ }
259
+ function addIfPresent(rows, label, value) {
260
+ if (value) {
261
+ rows.push([label, value]);
262
+ }
263
+ }
264
+ function printList(title, values) {
265
+ if (!values || values.length === 0) {
266
+ return;
267
+ }
268
+ console.log();
269
+ console.log(`${title}:`);
270
+ console.log(` ${values.join(', ')}`);
271
+ }
272
+ function printTable(title, rows) {
273
+ if (rows.length === 0) {
274
+ return;
275
+ }
276
+ console.log();
277
+ console.log(`${title}:`);
278
+ (0, table_1.printRows)(rows);
279
+ }
280
+ function formatRating(extension) {
281
+ if (extension.averageRating === undefined) {
282
+ return 'no ratings';
283
+ }
284
+ return `${extension.averageRating.toFixed(1)}/5 from ${(0, table_1.formatCount)(extension.reviewCount, 'review')}`;
285
+ }
286
+ function yesNo(value) {
287
+ return value ? 'yes' : 'no';
288
+ }
289
+ //# sourceMappingURL=show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../src/show.ts"],"names":[],"mappings":"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"}
package/lib/table.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ /******************************************************************************
2
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
3
+ *
4
+ * See the NOTICE file(s) distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ *
7
+ * This program and the accompanying materials are made available under the
8
+ * terms of the Eclipse Public License 2.0 which is available at
9
+ * https://www.eclipse.org/legal/epl-2.0.
10
+ *
11
+ * SPDX-License-Identifier: EPL-2.0
12
+ *****************************************************************************/
13
+ /**
14
+ * Prints rows as an aligned table, indented by two spaces. Every column but the last is padded,
15
+ * so a trailing empty cell doesn't leave ragged whitespace behind.
16
+ */
17
+ export declare function printRows(rows: string[][]): void;
18
+ /** Formats a count with thousands separators, and the noun pluralised to match. */
19
+ export declare function formatCount(count: number | undefined, noun: string): string;
20
+ export declare function formatNumber(value: number | undefined): string;
21
+ /**
22
+ * Shortens `text` to at most `max` characters, marking that it was cut. A `max` of zero or less
23
+ * leaves no room for the marker either, so it yields nothing rather than an ellipsis wider than the
24
+ * budget it was given.
25
+ */
26
+ export declare function truncate(text: string, max: number): string;
27
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;+EAW+E;AAE/E;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAYhD;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAM1D"}
package/lib/table.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /******************************************************************************
3
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
4
+ *
5
+ * See the NOTICE file(s) distributed with this work for additional
6
+ * information regarding copyright ownership.
7
+ *
8
+ * This program and the accompanying materials are made available under the
9
+ * terms of the Eclipse Public License 2.0 which is available at
10
+ * https://www.eclipse.org/legal/epl-2.0.
11
+ *
12
+ * SPDX-License-Identifier: EPL-2.0
13
+ *****************************************************************************/
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.printRows = printRows;
16
+ exports.formatCount = formatCount;
17
+ exports.formatNumber = formatNumber;
18
+ exports.truncate = truncate;
19
+ /**
20
+ * Prints rows as an aligned table, indented by two spaces. Every column but the last is padded,
21
+ * so a trailing empty cell doesn't leave ragged whitespace behind.
22
+ */
23
+ function printRows(rows) {
24
+ const widths = [];
25
+ for (const row of rows) {
26
+ row.forEach((cell, i) => widths[i] = Math.max(widths[i] ?? 0, cell.length));
27
+ }
28
+ for (const row of rows) {
29
+ const line = row
30
+ .map((cell, i) => (i === row.length - 1 ? cell : cell.padEnd(widths[i])))
31
+ .join(' ')
32
+ .trimEnd();
33
+ console.log(` ${line}`);
34
+ }
35
+ }
36
+ /** Formats a count with thousands separators, and the noun pluralised to match. */
37
+ function formatCount(count, noun) {
38
+ const value = count ?? 0;
39
+ return `${formatNumber(value)} ${value === 1 ? noun : noun + 's'}`;
40
+ }
41
+ function formatNumber(value) {
42
+ return (value ?? 0).toLocaleString('en-US');
43
+ }
44
+ /**
45
+ * Shortens `text` to at most `max` characters, marking that it was cut. A `max` of zero or less
46
+ * leaves no room for the marker either, so it yields nothing rather than an ellipsis wider than the
47
+ * budget it was given.
48
+ */
49
+ function truncate(text, max) {
50
+ if (max <= 0) {
51
+ return '';
52
+ }
53
+ const collapsed = text.replace(/\s+/g, ' ').trim();
54
+ return collapsed.length <= max ? collapsed : `${collapsed.substring(0, max - 1)}…`;
55
+ }
56
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;+EAW+E;;AAM/E,8BAYC;AAGD,kCAGC;AAED,oCAEC;AAOD,4BAMC;AAvCD;;;GAGG;AACH,SAAgB,SAAS,CAAC,IAAgB;IACtC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAChF,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,GAAG;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACxE,IAAI,CAAC,IAAI,CAAC;aACV,OAAO,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC7B,CAAC;AACL,CAAC;AAED,mFAAmF;AACnF,SAAgB,WAAW,CAAC,KAAyB,EAAE,IAAY;IAC/D,MAAM,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC;IACzB,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC;AACvE,CAAC;AAED,SAAgB,YAAY,CAAC,KAAyB;IAClD,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,SAAgB,QAAQ,CAAC,IAAY,EAAE,GAAW;IAC9C,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,OAAO,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AACvF,CAAC"}
@@ -0,0 +1,30 @@
1
+ /******************************************************************************
2
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
3
+ *
4
+ * See the NOTICE file(s) distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ *
7
+ * This program and the accompanying materials are made available under the
8
+ * terms of the Eclipse Public License 2.0 which is available at
9
+ * https://www.eclipse.org/legal/epl-2.0.
10
+ *
11
+ * SPDX-License-Identifier: EPL-2.0
12
+ *****************************************************************************/
13
+ export interface TrustedPublishingOptions {
14
+ /**
15
+ * Obtain a short-lived publishing token by exchanging an OIDC ID token. If unset, trusted
16
+ * publishing is used whenever an ID token source is detected and no access token is available.
17
+ */
18
+ trustedPublishing?: boolean;
19
+ /**
20
+ * The OIDC ID token to exchange. Only needed for CI systems that expose the token directly,
21
+ * such as GitLab CI; on GitHub Actions the token is requested from the workflow runtime.
22
+ */
23
+ idToken?: string;
24
+ /**
25
+ * The audience to request for the OIDC ID token. Defaults to the registry URL and must match
26
+ * the audience the registry expects.
27
+ */
28
+ oidcAudience?: string;
29
+ }
30
+ //# sourceMappingURL=trusted-publishing-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trusted-publishing-options.d.ts","sourceRoot":"","sources":["../src/trusted-publishing-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;+EAW+E;AAE/E,MAAM,WAAW,wBAAwB;IACrC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /******************************************************************************
3
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
4
+ *
5
+ * See the NOTICE file(s) distributed with this work for additional
6
+ * information regarding copyright ownership.
7
+ *
8
+ * This program and the accompanying materials are made available under the
9
+ * terms of the Eclipse Public License 2.0 which is available at
10
+ * https://www.eclipse.org/legal/epl-2.0.
11
+ *
12
+ * SPDX-License-Identifier: EPL-2.0
13
+ *****************************************************************************/
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ //# sourceMappingURL=trusted-publishing-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trusted-publishing-options.js","sourceRoot":"","sources":["../src/trusted-publishing-options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;+EAW+E"}
@@ -0,0 +1,35 @@
1
+ /******************************************************************************
2
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
3
+ *
4
+ * See the NOTICE file(s) distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ *
7
+ * This program and the accompanying materials are made available under the
8
+ * terms of the Eclipse Public License 2.0 which is available at
9
+ * https://www.eclipse.org/legal/epl-2.0.
10
+ *
11
+ * SPDX-License-Identifier: EPL-2.0
12
+ *****************************************************************************/
13
+ import { Registry } from './registry';
14
+ import { TrustedPublishingOptions } from './trusted-publishing-options';
15
+ /**
16
+ * Whether the given options ask for trusted publishing. If the user did not decide explicitly,
17
+ * it is used whenever the surrounding CI system can provide an OIDC ID token.
18
+ */
19
+ export declare function useTrustedPublishing(options: TrustedPublishingOptions): boolean;
20
+ /**
21
+ * Exchanges an OIDC ID token for a short-lived access token that can publish the given extension.
22
+ * The token is not stored, it is only valid for a few minutes.
23
+ */
24
+ export declare function getTrustedPublishingToken(registry: Registry, namespace: string, extension: string, options: TrustedPublishingOptions): Promise<string>;
25
+ /**
26
+ * Exchanges the ID token again after the registry refused the one this extension was publishing with.
27
+ * The issued token is short-lived and shared by every target platform of a release, so a slow fan-out
28
+ * can outlive it and be refused partway through.
29
+ *
30
+ * `stale` is the token that was refused. If the cache no longer holds it, another target has already
31
+ * replaced it and that exchange is awaited instead, so one expiry costs one exchange however many
32
+ * targets hit it at once.
33
+ */
34
+ export declare function refreshTrustedPublishingToken(registry: Registry, namespace: string, extension: string, options: TrustedPublishingOptions, stale: string): Promise<string>;
35
+ //# sourceMappingURL=trusted-publishing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trusted-publishing.d.ts","sourceRoot":"","sources":["../src/trusted-publishing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;+EAW+E;AAG/E,OAAO,EAAe,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAQxE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAE/E;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACrC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,wBAAwB,GAClC,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CACzC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAQjB"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ /******************************************************************************
3
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
4
+ *
5
+ * See the NOTICE file(s) distributed with this work for additional
6
+ * information regarding copyright ownership.
7
+ *
8
+ * This program and the accompanying materials are made available under the
9
+ * terms of the Eclipse Public License 2.0 which is available at
10
+ * https://www.eclipse.org/legal/epl-2.0.
11
+ *
12
+ * SPDX-License-Identifier: EPL-2.0
13
+ *****************************************************************************/
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.useTrustedPublishing = useTrustedPublishing;
16
+ exports.getTrustedPublishingToken = getTrustedPublishingToken;
17
+ exports.refreshTrustedPublishingToken = refreshTrustedPublishingToken;
18
+ const oidc_1 = require("./oidc");
19
+ const tokens = new Map();
20
+ // The value each cached exchange resolved to, so a token a publish was refused with can be told from one
21
+ // another publish has already replaced. Cleared while an exchange is in flight.
22
+ const issued = new Map();
23
+ /**
24
+ * Whether the given options ask for trusted publishing. If the user did not decide explicitly,
25
+ * it is used whenever the surrounding CI system can provide an OIDC ID token.
26
+ */
27
+ function useTrustedPublishing(options) {
28
+ return options.trustedPublishing ?? (0, oidc_1.hasIdTokenSource)(options);
29
+ }
30
+ /**
31
+ * Exchanges an OIDC ID token for a short-lived access token that can publish the given extension.
32
+ * The token is not stored, it is only valid for a few minutes.
33
+ */
34
+ function getTrustedPublishingToken(registry, namespace, extension, options) {
35
+ // publishing fans out over targets and package paths, but one token is enough per extension
36
+ const key = `${namespace}.${extension}`;
37
+ return tokens.get(key) ?? exchange(key, registry, namespace, extension, options);
38
+ }
39
+ /**
40
+ * Exchanges the ID token again after the registry refused the one this extension was publishing with.
41
+ * The issued token is short-lived and shared by every target platform of a release, so a slow fan-out
42
+ * can outlive it and be refused partway through.
43
+ *
44
+ * `stale` is the token that was refused. If the cache no longer holds it, another target has already
45
+ * replaced it and that exchange is awaited instead, so one expiry costs one exchange however many
46
+ * targets hit it at once.
47
+ */
48
+ function refreshTrustedPublishingToken(registry, namespace, extension, options, stale) {
49
+ const key = `${namespace}.${extension}`;
50
+ const current = tokens.get(key);
51
+ if (current && issued.get(key) !== stale) {
52
+ return current;
53
+ }
54
+ return exchange(key, registry, namespace, extension, options);
55
+ }
56
+ function exchange(key, registry, namespace, extension, options) {
57
+ // Dropped up front, so a refresh that is still in flight does not look like the stale token to the
58
+ // next caller and start a second exchange of its own.
59
+ issued.delete(key);
60
+ const token = requestToken(registry, namespace, extension, options).then(value => {
61
+ issued.set(key, value);
62
+ return value;
63
+ });
64
+ tokens.set(key, token);
65
+ return token;
66
+ }
67
+ // The registry answers 503 when it could not reach the identity provider to check the token, as opposed
68
+ // to checking it and refusing. That is worth another go: publishing runs unattended on CI, and a blip
69
+ // reaching GitHub or GitLab should not fail a release build. A refusal is never retried.
70
+ const RETRYABLE_STATUS = [502, 503, 504];
71
+ const RETRY_DELAYS_MS = [1000, 4000];
72
+ async function requestToken(registry, namespace, extension, options) {
73
+ const audience = options.oidcAudience ?? registry.url;
74
+ const idToken = await (0, oidc_1.getIdToken)(audience, options);
75
+ let result;
76
+ try {
77
+ result = await exchangeWithRetry(registry, namespace, extension, idToken);
78
+ }
79
+ catch (err) {
80
+ throw new Error(`${err.message}\n${registrationHint(registry, namespace, extension)}`);
81
+ }
82
+ if (result.error) {
83
+ throw new Error(`${result.error}\n${registrationHint(registry, namespace, extension)}`);
84
+ }
85
+ if (!result.value) {
86
+ throw new Error('The registry did not return a publishing token.');
87
+ }
88
+ const expires = result.expiresTimestamp ? `, expires at ${result.expiresTimestamp}` : '';
89
+ console.log(`\ud83d\udd10 Trusted publishing token issued for ${namespace}.${extension}${expires}`);
90
+ return result.value;
91
+ }
92
+ async function exchangeWithRetry(registry, namespace, extension, idToken) {
93
+ for (let attempt = 0;; attempt++) {
94
+ try {
95
+ return await registry.requestTrustedPublishingToken(namespace, extension, idToken);
96
+ }
97
+ catch (err) {
98
+ const status = err?.status;
99
+ if (attempt >= RETRY_DELAYS_MS.length || status === undefined || !RETRYABLE_STATUS.includes(status)) {
100
+ throw err;
101
+ }
102
+ const delay = RETRY_DELAYS_MS[attempt];
103
+ console.log(`The registry could not verify the token (${status}), retrying in ${delay / 1000}s`);
104
+ await new Promise(resolve => setTimeout(resolve, delay));
105
+ }
106
+ }
107
+ }
108
+ function registrationHint(registry, namespace, extension) {
109
+ return `Check the trusted publishers registered for '${namespace}.${extension}' at `
110
+ + `${registry.url}/user-settings/trusted-publishers.`;
111
+ }
112
+ //# sourceMappingURL=trusted-publishing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trusted-publishing.js","sourceRoot":"","sources":["../src/trusted-publishing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /******************************************************************************
2
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation.
3
+ *
4
+ * See the NOTICE file(s) distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ *
7
+ * This program and the accompanying materials are made available under the
8
+ * terms of the Eclipse Public License 2.0 which is available at
9
+ * https://www.eclipse.org/legal/epl-2.0.
10
+ *
11
+ * SPDX-License-Identifier: EPL-2.0
12
+ *****************************************************************************/
13
+ import { RegistryOptions } from './registry-options';
14
+ export interface UnpublishOptions extends RegistryOptions {
15
+ /**
16
+ * Identifier in the form `namespace.extension` or `namespace/extension`.
17
+ * Read from the `package.json` in the current directory if omitted.
18
+ */
19
+ extensionId?: string;
20
+ /**
21
+ * Versions to delete. All versions are deleted if omitted.
22
+ */
23
+ versions?: string[];
24
+ /**
25
+ * Target platforms to delete. All target platforms of the selected versions
26
+ * are deleted if omitted. Can only be used together with `versions`.
27
+ */
28
+ targets?: string[];
29
+ /**
30
+ * Delete without asking for confirmation.
31
+ */
32
+ force?: boolean;
33
+ }
34
+ //# sourceMappingURL=unpublish-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unpublish-options.d.ts","sourceRoot":"","sources":["../src/unpublish-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;+EAW+E;AAE/E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB"}