@pipeline-builder/api-core 4.1.13 → 4.1.14

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 (187) hide show
  1. package/README.md +3 -2
  2. package/lib/constants/index.d.ts +0 -1
  3. package/lib/constants/index.js +1 -2
  4. package/lib/errors/app-errors.d.ts +8 -3
  5. package/lib/errors/app-errors.js +10 -5
  6. package/lib/helpers/access-helpers.d.ts +4 -6
  7. package/lib/helpers/access-helpers.js +6 -8
  8. package/lib/helpers/index.d.ts +3 -3
  9. package/lib/helpers/index.js +4 -4
  10. package/lib/helpers/org-hierarchy-http.d.ts +11 -10
  11. package/lib/helpers/org-hierarchy-http.js +24 -35
  12. package/lib/helpers/org-hierarchy.d.ts +37 -3
  13. package/lib/helpers/org-hierarchy.js +45 -4
  14. package/lib/helpers/restore-helpers.d.ts +44 -24
  15. package/lib/helpers/restore-helpers.js +41 -52
  16. package/lib/helpers/sse-helpers.d.ts +29 -7
  17. package/lib/helpers/sse-helpers.js +36 -9
  18. package/lib/index.d.ts +16 -14
  19. package/lib/index.js +17 -15
  20. package/lib/middleware/assurance.d.ts +116 -0
  21. package/lib/middleware/assurance.js +176 -0
  22. package/lib/middleware/auth.d.ts +5 -427
  23. package/lib/middleware/auth.js +36 -789
  24. package/lib/middleware/ecosystem-guard.d.ts +47 -0
  25. package/lib/middleware/ecosystem-guard.js +60 -0
  26. package/lib/middleware/index.d.ts +11 -4
  27. package/lib/middleware/index.js +12 -5
  28. package/lib/middleware/jwt-verify.d.ts +52 -0
  29. package/lib/middleware/jwt-verify.js +105 -0
  30. package/lib/middleware/permission-gates.d.ts +133 -0
  31. package/lib/middleware/permission-gates.js +260 -0
  32. package/lib/middleware/revocation.d.ts +96 -0
  33. package/lib/middleware/revocation.js +162 -0
  34. package/lib/middleware/route-table.d.ts +11 -0
  35. package/lib/middleware/route-table.js +4 -1
  36. package/lib/middleware/service-tokens.d.ts +83 -0
  37. package/lib/middleware/service-tokens.js +158 -0
  38. package/lib/middleware/step-up.d.ts +2 -2
  39. package/lib/middleware/step-up.js +8 -7
  40. package/lib/middleware/system-org.d.ts +20 -0
  41. package/lib/middleware/system-org.js +25 -0
  42. package/lib/openapi/routes/plugin-routes.js +133 -10
  43. package/lib/openapi/schema-registry.js +2 -5
  44. package/lib/routes/index.d.ts +1 -1
  45. package/lib/routes/index.js +2 -2
  46. package/lib/services/api-key-exchange.js +7 -5
  47. package/lib/services/audit-spool.d.ts +34 -10
  48. package/lib/services/audit-spool.js +75 -34
  49. package/lib/services/cache-service.d.ts +7 -0
  50. package/lib/services/cache-service.js +1 -1
  51. package/lib/services/circuit-breaker.d.ts +14 -1
  52. package/lib/services/circuit-breaker.js +36 -10
  53. package/lib/services/compliance-client.d.ts +10 -2
  54. package/lib/services/compliance-client.js +17 -10
  55. package/lib/services/compliance-event-subscriber.js +6 -6
  56. package/lib/services/durable-event-bus.js +8 -11
  57. package/lib/services/ecosystem-notify-client.d.ts +32 -0
  58. package/lib/services/ecosystem-notify-client.js +71 -0
  59. package/lib/services/env-redis.d.ts +4 -1
  60. package/lib/services/env-redis.js +32 -3
  61. package/lib/services/http-client.d.ts +19 -0
  62. package/lib/services/http-client.js +98 -19
  63. package/lib/services/index.d.ts +25 -24
  64. package/lib/services/index.js +25 -22
  65. package/lib/services/jwks-cache.js +5 -4
  66. package/lib/services/leader-lock.d.ts +22 -5
  67. package/lib/services/leader-lock.js +61 -6
  68. package/lib/services/quota.d.ts +9 -4
  69. package/lib/services/quota.js +34 -40
  70. package/lib/services/remote-audit-client.d.ts +28 -32
  71. package/lib/services/remote-audit-client.js +166 -49
  72. package/lib/services/retry-forever.js +5 -11
  73. package/lib/services/retry-strategy.d.ts +1 -1
  74. package/lib/services/retry-strategy.js +5 -4
  75. package/lib/services/scheduler.d.ts +8 -3
  76. package/lib/services/scheduler.js +17 -5
  77. package/lib/services/service-boot.d.ts +14 -13
  78. package/lib/services/service-boot.js +18 -15
  79. package/lib/services/service-keys.d.ts +1 -1
  80. package/lib/services/service-keys.js +12 -18
  81. package/lib/services/sse-ticket-store.d.ts +9 -1
  82. package/lib/services/sse-ticket-store.js +24 -9
  83. package/lib/services/system-notification.d.ts +27 -0
  84. package/lib/services/system-notification.js +50 -0
  85. package/lib/services/token-revocation.d.ts +50 -1
  86. package/lib/services/token-revocation.js +103 -3
  87. package/lib/types/audit-events.d.ts +6 -6
  88. package/lib/types/audit-events.js +1 -1
  89. package/lib/types/common.d.ts +32 -13
  90. package/lib/types/common.js +2 -1
  91. package/lib/types/ecosystem-notifications.d.ts +142 -0
  92. package/lib/types/ecosystem-notifications.js +210 -0
  93. package/lib/types/ecosystem.d.ts +77 -0
  94. package/lib/types/ecosystem.js +119 -0
  95. package/lib/types/error-codes.d.ts +81 -0
  96. package/lib/types/error-codes.js +108 -1
  97. package/lib/types/feature-flags.d.ts +21 -1
  98. package/lib/types/feature-flags.js +36 -2
  99. package/lib/types/index.d.ts +14 -9
  100. package/lib/types/index.js +15 -10
  101. package/lib/types/permissions.d.ts +46 -8
  102. package/lib/types/permissions.js +75 -12
  103. package/lib/types/plugin-catalog.d.ts +35 -0
  104. package/lib/types/plugin-catalog.js +39 -0
  105. package/lib/types/plugin-health.d.ts +102 -0
  106. package/lib/types/plugin-health.js +184 -0
  107. package/lib/types/quota-tiers.d.ts +15 -0
  108. package/lib/types/quota-tiers.js +23 -3
  109. package/lib/types/wire-vocabulary.d.ts +102 -0
  110. package/lib/types/wire-vocabulary.js +94 -0
  111. package/lib/utils/alias-resolver.js +2 -2
  112. package/lib/utils/audit.d.ts +5 -2
  113. package/lib/utils/audit.js +6 -3
  114. package/lib/utils/compliance-attributes.js +3 -4
  115. package/lib/utils/concurrency.d.ts +7 -0
  116. package/lib/utils/concurrency.js +13 -1
  117. package/lib/utils/env.d.ts +3 -4
  118. package/lib/utils/env.js +4 -5
  119. package/lib/utils/identity.d.ts +13 -4
  120. package/lib/utils/identity.js +18 -10
  121. package/lib/utils/index.d.ts +13 -10
  122. package/lib/utils/index.js +13 -10
  123. package/lib/utils/jwk.d.ts +4 -0
  124. package/lib/utils/jwk.js +13 -1
  125. package/lib/utils/logger.d.ts +1 -1
  126. package/lib/utils/logger.js +1 -1
  127. package/lib/utils/object.d.ts +11 -0
  128. package/lib/utils/object.js +24 -1
  129. package/lib/utils/params.d.ts +8 -22
  130. package/lib/utils/params.js +15 -43
  131. package/lib/utils/plugin-compliance.d.ts +98 -0
  132. package/lib/utils/plugin-compliance.js +78 -0
  133. package/lib/utils/proof-of-work.d.ts +69 -0
  134. package/lib/utils/proof-of-work.js +139 -0
  135. package/lib/utils/response.d.ts +16 -6
  136. package/lib/utils/response.js +18 -15
  137. package/lib/utils/retention.d.ts +17 -0
  138. package/lib/utils/retention.js +30 -0
  139. package/lib/utils/secret-encryption.d.ts +7 -7
  140. package/lib/utils/secret-encryption.js +9 -10
  141. package/lib/utils/secret-rotation.js +2 -2
  142. package/lib/utils/sensitive-patterns.js +4 -5
  143. package/lib/utils/service-registry.d.ts +15 -0
  144. package/lib/utils/service-registry.js +24 -0
  145. package/lib/utils/ssrf.d.ts +11 -2
  146. package/lib/utils/ssrf.js +112 -33
  147. package/lib/validation/ai-schemas.js +3 -2
  148. package/lib/validation/common-schemas.d.ts +0 -9
  149. package/lib/validation/common-schemas.js +1 -7
  150. package/lib/validation/dockerfile-static.d.ts +26 -0
  151. package/lib/validation/dockerfile-static.js +210 -0
  152. package/lib/validation/index.d.ts +13 -4
  153. package/lib/validation/index.js +14 -5
  154. package/lib/validation/message-schemas.js +6 -4
  155. package/lib/validation/pipeline-schemas.d.ts +8 -2
  156. package/lib/validation/pipeline-schemas.js +30 -4
  157. package/lib/validation/plugin-base-images.d.ts +20 -0
  158. package/lib/validation/plugin-base-images.js +17 -0
  159. package/lib/validation/plugin-catalog-detect.d.ts +86 -0
  160. package/lib/validation/plugin-catalog-detect.js +237 -0
  161. package/lib/validation/plugin-catalog-metadata.d.ts +141 -0
  162. package/lib/validation/plugin-catalog-metadata.js +162 -0
  163. package/lib/validation/plugin-heuristics.d.ts +41 -0
  164. package/lib/validation/plugin-heuristics.js +211 -0
  165. package/lib/validation/plugin-lint.d.ts +18 -0
  166. package/lib/validation/plugin-lint.js +136 -0
  167. package/lib/validation/plugin-name-confusable.d.ts +15 -0
  168. package/lib/validation/plugin-name-confusable.js +81 -0
  169. package/lib/validation/plugin-schemas.d.ts +40 -26
  170. package/lib/validation/plugin-schemas.js +26 -23
  171. package/lib/validation/plugin-spec-schema.d.ts +112 -0
  172. package/lib/validation/plugin-spec-schema.js +163 -0
  173. package/lib/validation/plugin-template-contract.d.ts +64 -0
  174. package/lib/validation/plugin-template-contract.js +113 -0
  175. package/package.json +69 -4
  176. package/lib/testing/mock-api-core.d.ts +0 -150
  177. package/lib/testing/mock-api-core.js +0 -246
  178. package/lib/testing/mock-drizzle.d.ts +0 -6
  179. package/lib/testing/mock-drizzle.js +0 -57
  180. package/lib/testing/route-coverage.d.ts +0 -64
  181. package/lib/testing/route-coverage.js +0 -183
  182. package/lib/testing/service-tokens.d.ts +0 -66
  183. package/lib/testing/service-tokens.js +0 -137
  184. package/lib/testing/tier-mock.d.ts +0 -44
  185. package/lib/testing/tier-mock.js +0 -65
  186. package/lib/testing/user-tokens.d.ts +0 -75
  187. package/lib/testing/user-tokens.js +0 -115
@@ -0,0 +1,136 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * The catalog's STATIC plugin checks (deploy/bin/test-plugins.sh), for a plugin
5
+ * directory outside the repo: the spec fields the catalog tooling requires and
6
+ * the Dockerfile rules (deploy/plugins/README.md "Dockerfile rules"). Shared
7
+ * from api-core so the CLI (`plugin validate --lint`, `plugin publish`) and the
8
+ * plugin service (AI generation) apply ONE implementation (plugin-ecosystem W6):
9
+ *
10
+ * - the final stage ends as a non-root `USER`, set in the plugin's own Dockerfile;
11
+ * - every download goes through `fetch-verified` (no raw curl/wget, no `ADD <url>`
12
+ * without `--checksum=`);
13
+ * - no pipe-to-shell installers;
14
+ * - no secrets in `ENV`/`ARG`; apt caches cleaned; a `WORKDIR`;
15
+ * - the spec never downloads a tool at runtime.
16
+ *
17
+ * Only the repo-layout rules (name = directory, category = parent directory)
18
+ * are left to test-plugins.sh: a publisher's plugin doesn't live in that tree.
19
+ * Warnings never fail; errors do.
20
+ */
21
+ import { parseDockerfile } from './dockerfile-static.js';
22
+ /** Spec fields test-plugins.sh requires on every plugin. */
23
+ export const PLUGIN_LINT_REQUIRED_FIELDS = ['name', 'description', 'keywords', 'category', 'version', 'pluginType', 'computeType', 'timeout', 'failureBehavior', 'secrets'];
24
+ /** …and on every CodeBuildStep. */
25
+ export const PLUGIN_LINT_CODEBUILD_FIELDS = ['primaryOutputDirectory', 'dockerfile', 'installCommands', 'commands'];
26
+ /** Logical Dockerfile instructions: comment lines dropped, `\` continuations joined. */
27
+ export function dockerfileInstructions(content) {
28
+ const out = [];
29
+ let buf = '';
30
+ for (const raw of content.replace(/\r\n?/g, '\n').split('\n')) {
31
+ if (/^\s*#/.test(raw))
32
+ continue;
33
+ if (/\\\s*$/.test(raw)) {
34
+ buf += `${raw.replace(/\\\s*$/, '')} `;
35
+ continue;
36
+ }
37
+ buf += raw;
38
+ if (/\S/.test(buf))
39
+ out.push(buf.trim());
40
+ buf = '';
41
+ }
42
+ if (/\S/.test(buf))
43
+ out.push(buf.trim());
44
+ return out;
45
+ }
46
+ const instructionOf = (line) => (/^(\S+)/.exec(line)?.[1] ?? '').toUpperCase();
47
+ /** RUN instructions that pipe into a shell (`curl … | bash`). */
48
+ export function pipeInstallers(content) {
49
+ return dockerfileInstructions(content).filter(l => instructionOf(l) === 'RUN' && /(^|[^|])\|\s*(sudo\s+)?(\/usr)?(\/bin\/)?(ba|da|z|k)?sh(\s|$)/.test(l));
50
+ }
51
+ /** curl/wget DOWNLOADS in RUN, and `ADD <url>` without `--checksum=`. */
52
+ export function rawDownloads(content) {
53
+ const found = [];
54
+ for (const line of dockerfileInstructions(content)) {
55
+ const instr = instructionOf(line);
56
+ if (instr === 'ADD' && /https?:\/\//.test(line) && !/--checksum=/.test(line)) {
57
+ found.push(`ADD ${line}`);
58
+ continue;
59
+ }
60
+ if (instr !== 'RUN')
61
+ continue;
62
+ const body = line.replace(/^\s*run\s+/i, '');
63
+ for (let part of body.split(/&&|\|\||;|\||\$\(|`|\(|\{/)) {
64
+ for (;;) {
65
+ part = part.replace(/^\s+/, '');
66
+ const prefix = /^(if|then|do|else|elif|while|until|!|sudo|exec|command|time|--[a-z-]+(=\S*)?|[A-Za-z_][A-Za-z0-9_]*=\S*)\s+/.exec(part);
67
+ if (!prefix)
68
+ break;
69
+ part = part.slice(prefix[0].length);
70
+ }
71
+ if (/^(curl|wget)(\s|$)/.test(part) && (/:\/\//.test(part) || /\$/.test(part) || /\s(-o|-O|--output|--output-document)([\s=]|$)/.test(part))) {
72
+ found.push(part.trim());
73
+ }
74
+ }
75
+ }
76
+ return found;
77
+ }
78
+ /** Lint a Dockerfile against the catalog's rules. */
79
+ export function lintPluginDockerfile(content) {
80
+ const findings = [];
81
+ const err = (message) => findings.push({ level: 'error', message });
82
+ const instructions = dockerfileInstructions(content);
83
+ if (!instructions.some(l => instructionOf(l) === 'FROM')) {
84
+ err('Dockerfile: missing FROM instruction');
85
+ return findings;
86
+ }
87
+ if (!instructions.some(l => instructionOf(l) === 'WORKDIR'))
88
+ err('Dockerfile: missing WORKDIR instruction');
89
+ if (/^(ENV|ARG)\s+(.*TOKEN|.*SECRET|.*PASSWORD|.*API_KEY|.*PRIVATE_KEY)/m.test(content)) {
90
+ err('Dockerfile: potential secret in an ENV/ARG instruction (pass secrets at run time via the spec\'s `secrets`)');
91
+ }
92
+ const finalUser = parseDockerfile(content).finalUser;
93
+ const userPart = (finalUser ?? '').split(':')[0];
94
+ if (!finalUser)
95
+ err('Dockerfile: the final stage sets no USER (end with `USER 1000:1000`)');
96
+ else if (userPart === 'root' || userPart === '0')
97
+ err(`Dockerfile: the final stage runs as root (USER ${finalUser}); end with \`USER 1000:1000\``);
98
+ const pipes = pipeInstallers(content);
99
+ if (pipes.length)
100
+ err(`Dockerfile: pipes a download into a shell (use a pinned release via fetch-verified, a fetch-apt-key apt repo, or an ecosystem base): ${pipes[0].slice(0, 160)}`);
101
+ const downloads = rawDownloads(content);
102
+ if (downloads.length)
103
+ err(`Dockerfile: raw download not via fetch-verified: ${downloads[0].slice(0, 160)}`);
104
+ if (/apt-get install/.test(content) && !/rm -rf \/var\/lib\/apt\/lists/.test(content)) {
105
+ err('Dockerfile: missing apt cache cleanup (rm -rf /var/lib/apt/lists/*)');
106
+ }
107
+ return findings;
108
+ }
109
+ /** Lint the spec document (as parsed) the way test-plugins.sh does. */
110
+ export function lintPluginSpec(spec, specText) {
111
+ const findings = [];
112
+ const err = (message) => findings.push({ level: 'error', message });
113
+ for (const f of PLUGIN_LINT_REQUIRED_FIELDS)
114
+ if (!(f in spec))
115
+ err(`plugin-spec.yaml: missing required field: ${f}`);
116
+ if (spec.pluginType === 'CodeBuildStep' || spec.pluginType === undefined) {
117
+ for (const f of PLUGIN_LINT_CODEBUILD_FIELDS)
118
+ if (!(f in spec))
119
+ err(`plugin-spec.yaml: missing CodeBuild field: ${f}`);
120
+ }
121
+ if (typeof spec.version === 'string' && !/^\d+\.\d+\.\d+$/.test(spec.version)) {
122
+ err(`plugin-spec.yaml: catalog versions are plain semver x.y.z (got ${spec.version})`);
123
+ }
124
+ if (typeof spec.description !== 'string' || spec.description.trim() === '')
125
+ err('plugin-spec.yaml: empty description');
126
+ if ('keywords' in spec && (!Array.isArray(spec.keywords) || spec.keywords.length === 0))
127
+ err('plugin-spec.yaml: empty keywords list');
128
+ const download = /(curl|wget)\s.*https?:\/\/[^\s"]*(releases\/download\/|\.tar\.gz|\.tgz|\.tar\.xz|\.zip)/.exec(specText);
129
+ if (download)
130
+ err(`plugin-spec.yaml: downloads a tool at runtime (bake it into the image via fetch-verified): ${download[0].slice(0, 160)}`);
131
+ if (/^\s*- \|/m.test(specText) && !/set -e/.test(specText)) {
132
+ findings.push({ level: 'warning', message: 'plugin-spec.yaml: multi-line command(s) without `set -e` — intermediate failures will silently pass' });
133
+ }
134
+ return findings;
135
+ }
136
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWxpbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGlvbi9wbHVnaW4tbGludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQU96RCw0REFBNEQ7QUFDNUQsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBQXNCLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUMvTCxtQ0FBbUM7QUFDbkMsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQXNCLENBQUMsd0JBQXdCLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBRXZJLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsc0JBQXNCLENBQUMsT0FBZTtJQUNwRCxNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7SUFDekIsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDO0lBQ2IsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM5RCxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQUUsU0FBUztRQUNoQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixHQUFHLElBQUksR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDO1lBQ3ZDLFNBQVM7UUFDWCxDQUFDO1FBQ0QsR0FBRyxJQUFJLEdB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QUNELElBQUksT0FBTyxJQUFJLENBQUMsT0FBTyxLQUFLLFFBQVEsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUM5RSxHQUFHLENBQUMsa0VBQWtFLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ3pGLENBQUM7SUFDRCxJQUFJLE9BQU8sSUFBSSxDQUFDLFdBQVcsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFO1FBQUUsR0FBRyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7SUFDdkgsSUFBSSxVQUFVLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7UUFBRSxHQUFHLENBQUMsdUNBQXVDLENBQUMsQ0FBQztJQUN0SSxNQUFNLFFBQVEsR0FBRyx5RkFBeUYsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDMUgsSUFBSSxRQUFRO1FBQUUsR0FBRyxDQUFDLDhGQUE4RixRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDN0ksSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQzNELFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxxR0FBcUcsRUFBRSxDQUFDLENBQUM7SUFDdEosQ0FBQztJQUNELE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBUaGUgY2F0YWxvZydzIFNUQVRJQyBwbHVnaW4gY2hlY2tzIChkZXBsb3kvYmluL3Rlc3QtcGx1Z2lucy5zaCksIGZvciBhIHBsdWdpblxuICogZGlyZWN0b3J5IG91dHNpZGUgdGhlIHJlcG86IHRoZSBzcGVjIGZpZWxkcyB0aGUgY2F0YWxvZyB0b29saW5nIHJlcXVpcmVzIGFuZFxuICogdGhlIERvY2tlcmZpbGUgcnVsZXMgKGRlcGxveS9wbHVnaW5zL1JFQURNRS5tZCBcIkRvY2tlcmZpbGUgcnVsZXNcIikuIFNoYXJlZFxuICogZnJvbSBhcGktY29yZSBzbyB0aGUgQ0xJIChgcGx1Z2luIHZhbGlkYXRlIC0tbGludGAsIGBwbHVnaW4gcHVibGlzaGApIGFuZCB0aGVcbiAqIHBsdWdpbiBzZXJ2aWNlIChBSSBnZW5lcmF0aW9uKSBhcHBseSBPTkUgaW1wbGVtZW50YXRpb24gKHBsdWdpbi1lY29zeXN0ZW0gVzYpOlxuICpcbiAqICAtIHRoZSBmaW5hbCBzdGFnZSBlbmRzIGFzIGEgbm9uLXJvb3QgYFVTRVJgLCBzZXQgaW4gdGhlIHBsdWdpbidzIG93biBEb2NrZXJmaWxlO1xuICogIC0gZXZlcnkgZG93bmxvYWQgZ29lcyB0aHJvdWdoIGBmZXRjaC12ZXJpZmllZGAgKG5vIHJhdyBjdXJsL3dnZXQsIG5vIGBBREQgPHVybD5gXG4gKiAgICB3aXRob3V0IGAtLWNoZWNrc3VtPWApO1xuICogIC0gbm8gcGlwZS10by1zaGVsbCBpbnN0YWxsZXJzO1xuICogIC0gbm8gc2VjcmV0cyBpbiBgRU5WYC9gQVJHYDsgYXB0IGNhY2hlcyBjbGVhbmVkOyBhIGBXT1JLRElSYDtcbiAqICAtIHRoZSBzcGVjIG5ldmVyIGRvd25sb2FkcyBhIHRvb2wgYXQgcnVudGltZS5cbiAqXG4gKiBPbmx5IHRoZSByZXBvLWxheW91dCBydWxlcyAobmFtZSA9IGRpcmVjdG9yeSwgY2F0ZWdvcnkgPSBwYXJlbnQgZGlyZWN0b3J5KVxuICogYXJlIGxlZnQgdG8gdGVzdC1wbHVnaW5zLnNoOiBhIHB1Ymxpc2hlcidzIHBsdWdpbiBkb2Vzbid0IGxpdmUgaW4gdGhhdCB0cmVlLlxuICogV2FybmluZ3MgbmV2ZXIgZmFpbDsgZXJyb3JzIGRvLlxuICovXG5cbmltcG9ydCB7IHBhcnNlRG9ja2VyZmlsZSB9IGZyb20gJy4vZG9ja2VyZmlsZS1zdGF0aWMuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBsdWdpbkxpbnRGaW5kaW5nIHtcbiAgbGV2ZWw6ICdlcnJvcicgfCAnd2FybmluZyc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbn1cblxuLyoqIFNwZWMgZmllbGRzIHRlc3QtcGx1Z2lucy5zaCByZXF1aXJlcyBvbiBldmVyeSBwbHVnaW4uICovXG5leHBvcnQgY29uc3QgUExVR0lOX0xJTlRfUkVRVUlSRURfRklFTERTOiByZWFkb25seSBzdHJpbmdbXSA9IFsnbmFtZScsICdkZXNjcmlwdGlvbicsICdrZXl3b3JkcycsICdjYXRlZ29yeScsICd2ZXJzaW9uJywgJ3BsdWdpblR5cGUnLCAnY29tcHV0ZVR5cGUnLCAndGltZW91dCcsICdmYWlsdXJlQmVoYXZpb3InLCAnc2VjcmV0cyddO1xuLyoqIOKApmFuZCBvbiBldmVyeSBDb2RlQnVpbGRTdGVwLiAqL1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9MSU5UX0NPREVCVUlMRF9GSUVMRFM6IHJlYWRvbmx5IHN0cmluZ1tdID0gWydwcmltYXJ5T3V0cHV0RGlyZWN0b3J5JywgJ2RvY2tlcmZpbGUnLCAnaW5zdGFsbENvbW1hbmRzJywgJ2NvbW1hbmRzJ107XG5cbi8qKiBMb2dpY2FsIERvY2tlcmZpbGUgaW5zdHJ1Y3Rpb25zOiBjb21tZW50IGxpbmVzIGRyb3BwZWQsIGBcXGAgY29udGludWF0aW9ucyBqb2luZWQuICovXG5leHBvcnQgZnVuY3Rpb24gZG9ja2VyZmlsZUluc3RydWN0aW9ucyhjb250ZW50OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG91dDogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGJ1ZiA9ICcnO1xuICBmb3IgKGNvbnN0IHJhdyBvZiBjb250ZW50LnJlcGxhY2UoL1xcclxcbj8vZywgJ1xcbicpLnNwbGl0KCdcXG4nKSkge1xuICAgIGlmICgvXlxccyojLy50ZXN0KHJhdykpIGNvbnRpbnVlO1xuICAgIGlmICgvXFxcXFxccyokLy50ZXN0KHJhdykpIHtcbiAgICAgIGJ1ZiArPSBgJHtyYXcucmVwbGFjZSgvXFxcXFxccyokLywgJycpfSBgO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGJ1ZiArPSByYXc7XG4gICAgaWYgKC9cXFMvLnRlc3QoYnVmKSkgb3V0LnB1c2goYnVmLnRyaW0oKSk7XG4gICAgYnVmID0gJyc7XG4gIH1cbiAgaWYgKC9cXFMvLnRlc3QoYnVmKSkgb3V0LnB1c2goYnVmLnRyaW0oKSk7XG4gIHJldHVybiBvdXQ7XG59XG5cbmNvbnN0IGluc3RydWN0aW9uT2YgPSAobGluZTogc3RyaW5nKTogc3RyaW5nID0+ICgvXihcXFMrKS8uZXhlYyhsaW5lKT8uWzFdID8/ICcnKS50b1VwcGVyQ2FzZSgpO1xuXG4vKiogUlVOIGluc3RydWN0aW9ucyB0aGF0IHBpcGUgaW50byBhIHNoZWxsIChgY3VybCDigKYgfCBiYXNoYCkuICovXG5leHBvcnQgZnVuY3Rpb24gcGlwZUluc3RhbGxlcnMoY29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICByZXR1cm4gZG9ja2VyZmlsZUluc3RydWN0aW9ucyhjb250ZW50KS5maWx0ZXIobCA9PlxuICAgIGluc3RydWN0aW9uT2YobCkgPT09ICdSVU4nICYmIC8oXnxbXnxdKVxcfFxccyooc3Vkb1xccyspPyhcXC91c3IpPyhcXC9iaW5cXC8pPyhiYXxkYXx6fGspP3NoKFxcc3wkKS8udGVzdChsKSk7XG59XG5cbi8qKiBjdXJsL3dnZXQgRE9XTkxPQURTIGluIFJVTiwgYW5kIGBBREQgPHVybD5gIHdpdGhvdXQgYC0tY2hlY2tzdW09YC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYXdEb3dubG9hZHMoY29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBmb3VuZDogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChjb25zdCBsaW5lIG9mIGRvY2tlcmZpbGVJbnN0cnVjdGlvbnMoY29udGVudCkpIHtcbiAgICBjb25zdCBpbnN0ciA9IGluc3RydWN0aW9uT2YobGluZSk7XG4gICAgaWYgKGluc3RyID09PSAnQUREJyAmJiAvaHR0cHM/OlxcL1xcLy8udGVzdChsaW5lKSAmJiAhLy0tY2hlY2tzdW09Ly50ZXN0KGxpbmUpKSB7XG4gICAgICBmb3VuZC5wdXNoKGBBREQgJHtsaW5lfWApO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChpbnN0ciAhPT0gJ1JVTicpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGJvZHkgPSBsaW5lLnJlcGxhY2UoL15cXHMqcnVuXFxzKy9pLCAnJyk7XG4gICAgZm9yIChsZXQgcGFydCBvZiBib2R5LnNwbGl0KC8mJnxcXHxcXHx8O3xcXHx8XFwkXFwofGB8XFwofFxcey8pKSB7XG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIHBhcnQgPSBwYXJ0LnJlcGxhY2UoL15cXHMrLywgJycpO1xuICAgICAgICBjb25zdCBwcmVmaXggPSAvXihpZnx0aGVufGRvfGVsc2V8ZWxpZnx3aGlsZXx1bnRpbHwhfHN1ZG98ZXhlY3xjb21tYW5kfHRpbWV8LS1bYS16LV0rKD1cXFMqKT98W0EtWmEtel9dW0EtWmEtejAtOV9dKj1cXFMqKVxccysvLmV4ZWMocGFydCk7XG4gICAgICAgIGlmICghcHJlZml4KSBicmVhaztcbiAgICAgICAgcGFydCA9IHBhcnQuc2xpY2UocHJlZml4WzBdLmxlbmd0aCk7XG4gICAgICB9XG4gICAgICBpZiAoL14oY3VybHx3Z2V0KShcXHN8JCkvLnRlc3QocGFydCkgJiYgKC86XFwvXFwvLy50ZXN0KHBhcnQpIHx8IC9cXCQvLnRlc3QocGFydCkgfHwgL1xccygtb3wtT3wtLW91dHB1dHwtLW91dHB1dC1kb2N1bWVudCkoW1xccz1dfCQpLy50ZXN0KHBhcnQpKSkge1xuICAgICAgICBmb3VuZC5wdXNoKHBhcnQudHJpbSgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvdW5kO1xufVxuXG4vKiogTGludCBhIERvY2tlcmZpbGUgYWdhaW5zdCB0aGUgY2F0YWxvZydzIHJ1bGVzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbnRQbHVnaW5Eb2NrZXJmaWxlKGNvbnRlbnQ6IHN0cmluZyk6IFBsdWdpbkxpbnRGaW5kaW5nW10ge1xuICBjb25zdCBmaW5kaW5nczogUGx1Z2luTGludEZpbmRpbmdbXSA9IFtdO1xuICBjb25zdCBlcnIgPSAobWVzc2FnZTogc3RyaW5nKSA9PiBmaW5kaW5ncy5wdXNoKHsgbGV2ZWw6ICdlcnJvcicsIG1lc3NhZ2UgfSk7XG4gIGNvbnN0IGluc3RydWN0aW9ucyA9IGRvY2tlcmZpbGVJbnN0cnVjdGlvbnMoY29udGVudCk7XG4gIGlmICghaW5zdHJ1Y3Rpb25zLnNvbWUobCA9PiBpbnN0cnVjdGlvbk9mKGwpID09PSAnRlJPTScpKSB7XG4gICAgZXJyKCdEb2NrZXJmaWxlOiBtaXNzaW5nIEZST00gaW5zdHJ1Y3Rpb24nKTtcbiAgICByZXR1cm4gZmluZGluZ3M7XG4gIH1cbiAgaWYgKCFpbnN0cnVjdGlvbnMuc29tZShsID0+IGluc3RydWN0aW9uT2YobCkgPT09ICdXT1JLRElSJykpIGVycignRG9ja2VyZmlsZTogbWlzc2luZyBXT1JLRElSIGluc3RydWN0aW9uJyk7XG4gIGlmICgvXihFTlZ8QVJHKVxccysoLipUT0tFTnwuKlNFQ1JFVHwuKlBBU1NXT1JEfC4qQVBJX0tFWXwuKlBSSVZBVEVfS0VZKS9tLnRlc3QoY29udGVudCkpIHtcbiAgICBlcnIoJ0RvY2tlcmZpbGU6IHBvdGVudGlhbCBzZWNyZXQgaW4gYW4gRU5WL0FSRyBpbnN0cnVjdGlvbiAocGFzcyBzZWNyZXRzIGF0IHJ1biB0aW1lIHZpYSB0aGUgc3BlY1xcJ3MgYHNlY3JldHNgKScpO1xuICB9XG4gIGNvbnN0IGZpbmFsVXNlciA9IHBhcnNlRG9ja2VyZmlsZShjb250ZW50KS5maW5hbFVzZXI7XG4gIGNvbnN0IHVzZXJQYXJ0ID0gKGZpbmFsVXNlciA/PyAnJykuc3BsaXQoJzonKVswXTtcbiAgaWYgKCFmaW5hbFVzZXIpIGVycignRG9ja2VyZmlsZTogdGhlIGZpbmFsIHN0YWdlIHNldHMgbm8gVVNFUiAoZW5kIHdpdGggYFVTRVIgMTAwMDoxMDAwYCknKTtcbiAgZWxzZSBpZiAodXNlclBhcnQgPT09ICdyb290JyB8fCB1c2VyUGFydCA9PT0gJzAnKSBlcnIoYERvY2tlcmZpbGU6IHRoZSBmaW5hbCBzdGFnZSBydW5zIGFzIHJvb3QgKFVTRVIgJHtmaW5hbFVzZXJ9KTsgZW5kIHdpdGggXFxgVVNFUiAxMDAwOjEwMDBcXGBgKTtcbiAgY29uc3QgcGlwZXMgPSBwaXBlSW5zdGFsbGVycyhjb250ZW50KTtcbiAgaWYgKHBpcGVzLmxlbmd0aCkgZXJyKGBEb2NrZXJmaWxlOiBwaXBlcyBhIGRvd25sb2FkIGludG8gYSBzaGVsbCAodXNlIGEgcGlubmVkIHJlbGVhc2UgdmlhIGZldGNoLXZlcmlmaWVkLCBhIGZldGNoLWFwdC1rZXkgYXB0IHJlcG8sIG9yIGFuIGVjb3N5c3RlbSBiYXNlKTogJHtwaXBlc1swXSEuc2xpY2UoMCwgMTYwKX1gKTtcbiAgY29uc3QgZG93bmxvYWRzID0gcmF3RG93bmxvYWRzKGNvbnRlbnQpO1xuICBpZiAoZG93bmxvYWRzLmxlbmd0aCkgZXJyKGBEb2NrZXJmaWxlOiByYXcgZG93bmxvYWQgbm90IHZpYSBmZXRjaC12ZXJpZmllZDogJHtkb3dubG9hZHNbMF0hLnNsaWNlKDAsIDE2MCl9YCk7XG4gIGlmICgvYXB0LWdldCBpbnN0YWxsLy50ZXN0KGNvbnRlbnQpICYmICEvcm0gLXJmIFxcL3ZhclxcL2xpYlxcL2FwdFxcL2xpc3RzLy50ZXN0KGNvbnRlbnQpKSB7XG4gICAgZXJyKCdEb2NrZXJmaWxlOiBtaXNzaW5nIGFwdCBjYWNoZSBjbGVhbnVwIChybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyopJyk7XG4gIH1cbiAgcmV0dXJuIGZpbmRpbmdzO1xufVxuXG4vKiogTGludCB0aGUgc3BlYyBkb2N1bWVudCAoYXMgcGFyc2VkKSB0aGUgd2F5IHRlc3QtcGx1Z2lucy5zaCBkb2VzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbnRQbHVnaW5TcGVjKHNwZWM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBzcGVjVGV4dDogc3RyaW5nKTogUGx1Z2luTGludEZpbmRpbmdbXSB7XG4gIGNvbnN0IGZpbmRpbmdzOiBQbHVnaW5MaW50RmluZGluZ1tdID0gW107XG4gIGNvbnN0IGVyciA9IChtZXNzYWdlOiBzdHJpbmcpID0+IGZpbmRpbmdzLnB1c2goeyBsZXZlbDogJ2Vycm9yJywgbWVzc2FnZSB9KTtcbiAgZm9yIChjb25zdCBmIG9mIFBMVUdJTl9MSU5UX1JFUVVJUkVEX0ZJRUxEUykgaWYgKCEoZiBpbiBzcGVjKSkgZXJyKGBwbHVnaW4tc3BlYy55YW1sOiBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkOiAke2Z9YCk7XG4gIGlmIChzcGVjLnBsdWdpblR5cGUgPT09ICdDb2RlQnVpbGRTdGVwJyB8fCBzcGVjLnBsdWdpblR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgIGZvciAoY29uc3QgZiBvZiBQTFVHSU5fTElOVF9DT0RFQlVJTERfRklFTERTKSBpZiAoIShmIGluIHNwZWMpKSBlcnIoYHBsdWdpbi1zcGVjLnlhbWw6IG1pc3NpbmcgQ29kZUJ1aWxkIGZpZWxkOiAke2Z9YCk7XG4gIH1cbiAgaWYgKHR5cGVvZiBzcGVjLnZlcnNpb24gPT09ICdzdHJpbmcnICYmICEvXlxcZCtcXC5cXGQrXFwuXFxkKyQvLnRlc3Qoc3BlYy52ZXJzaW9uKSkge1xuICAgIGVycihgcGx1Z2luLXNwZWMueWFtbDogY2F0YWxvZyB2ZXJzaW9ucyBhcmUgcGxhaW4gc2VtdmVyIHgueS56IChnb3QgJHtzcGVjLnZlcnNpb259KWApO1xuICB9XG4gIGlmICh0eXBlb2Ygc3BlYy5kZXNjcmlwdGlvbiAhPT0gJ3N0cmluZycgfHwgc3BlYy5kZXNjcmlwdGlvbi50cmltKCkgPT09ICcnKSBlcnIoJ3BsdWdpbi1zcGVjLnlhbWw6IGVtcHR5IGRlc2NyaXB0aW9uJyk7XG4gIGlmICgna2V5d29yZHMnIGluIHNwZWMgJiYgKCFBcnJheS5pc0FycmF5KHNwZWMua2V5d29yZHMpIHx8IHNwZWMua2V5d29yZHMubGVuZ3RoID09PSAwKSkgZXJyKCdwbHVnaW4tc3BlYy55YW1sOiBlbXB0eSBrZXl3b3JkcyBsaXN0Jyk7XG4gIGNvbnN0IGRvd25sb2FkID0gLyhjdXJsfHdnZXQpXFxzLipodHRwcz86XFwvXFwvW15cXHNcIl0qKHJlbGVhc2VzXFwvZG93bmxvYWRcXC98XFwudGFyXFwuZ3p8XFwudGd6fFxcLnRhclxcLnh6fFxcLnppcCkvLmV4ZWMoc3BlY1RleHQpO1xuICBpZiAoZG93bmxvYWQpIGVycihgcGx1Z2luLXNwZWMueWFtbDogZG93bmxvYWRzIGEgdG9vbCBhdCBydW50aW1lIChiYWtlIGl0IGludG8gdGhlIGltYWdlIHZpYSBmZXRjaC12ZXJpZmllZCk6ICR7ZG93bmxvYWRbMF0uc2xpY2UoMCwgMTYwKX1gKTtcbiAgaWYgKC9eXFxzKi0gXFx8L20udGVzdChzcGVjVGV4dCkgJiYgIS9zZXQgLWUvLnRlc3Qoc3BlY1RleHQpKSB7XG4gICAgZmluZGluZ3MucHVzaCh7IGxldmVsOiAnd2FybmluZycsIG1lc3NhZ2U6ICdwbHVnaW4tc3BlYy55YW1sOiBtdWx0aS1saW5lIGNvbW1hbmQocykgd2l0aG91dCBgc2V0IC1lYCDigJQgaW50ZXJtZWRpYXRlIGZhaWx1cmVzIHdpbGwgc2lsZW50bHkgcGFzcycgfSk7XG4gIH1cbiAgcmV0dXJuIGZpbmRpbmdzO1xufVxuIl19
@@ -0,0 +1,15 @@
1
+ /** The comparison form of a plugin name. */
2
+ export declare function normalizeConfusableName(name: string): string;
3
+ /**
4
+ * Optimal-string-alignment Damerau–Levenshtein distance between `a` and `b`,
5
+ * giving up (returning `limit + 1`) once it must exceed `limit`.
6
+ */
7
+ export declare function damerauLevenshtein(a: string, b: string, limit?: number): number;
8
+ /**
9
+ * The first of `names` that `candidate` is confusable with (see the module
10
+ * note), or null. An EXACT match counts too — the caller decides whether the
11
+ * same name is a conflict or the same listing.
12
+ */
13
+ export declare function findConfusableName(candidate: string, names: Iterable<string>): string | null;
14
+ /** Whether `candidate` is confusable with any of `names`. */
15
+ export declare function isConfusableName(candidate: string, names: Iterable<string>): boolean;
@@ -0,0 +1,81 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Confusable plugin names (docs/plugin-publishing.md):
5
+ * a new community listing — an anonymous submission or a `new_listing`
6
+ * request — may not look like one of the directory's most-installed plugins
7
+ * (`terraf0rm`, `kube-ctl`, `docker_build`, `tfsec` → `tfsed`).
8
+ *
9
+ * Two names are CONFUSABLE when, after {@link normalizeConfusableName}
10
+ * (lowercase; strip `-`, `_`, `.`; `rn`→`m`, `vv`→`w`, `0`→`o`, `1`→`l`,
11
+ * `3`→`e`, `5`→`s`), they are equal or one Damerau–Levenshtein edit apart
12
+ * (an insertion, deletion, substitution or adjacent transposition).
13
+ *
14
+ * Pure, so the CLI can warn before a publish and the plugin service decides
15
+ * with the same rule.
16
+ */
17
+ const MULTI_CHAR = [[/rn/g, 'm'], [/vv/g, 'w']];
18
+ const SINGLE_CHAR = { 0: 'o', 1: 'l', 3: 'e', 5: 's' };
19
+ /** The comparison form of a plugin name. */
20
+ export function normalizeConfusableName(name) {
21
+ let out = name.toLowerCase().replace(/[-_.]/g, '');
22
+ for (const [from, to] of MULTI_CHAR)
23
+ out = out.replace(from, to);
24
+ return out.replace(/[0135]/g, (c) => SINGLE_CHAR[c] ?? c);
25
+ }
26
+ /**
27
+ * Optimal-string-alignment Damerau–Levenshtein distance between `a` and `b`,
28
+ * giving up (returning `limit + 1`) once it must exceed `limit`.
29
+ */
30
+ export function damerauLevenshtein(a, b, limit = Number.POSITIVE_INFINITY) {
31
+ if (a === b)
32
+ return 0;
33
+ if (Math.abs(a.length - b.length) > limit)
34
+ return limit + 1;
35
+ if (a.length === 0)
36
+ return b.length;
37
+ if (b.length === 0)
38
+ return a.length;
39
+ let prevPrev = [];
40
+ let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
41
+ for (let i = 1; i <= a.length; i++) {
42
+ const cur = [i];
43
+ let rowMin = i;
44
+ for (let j = 1; j <= b.length; j++) {
45
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
46
+ let d = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost);
47
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1])
48
+ d = Math.min(d, prevPrev[j - 2] + 1);
49
+ cur.push(d);
50
+ rowMin = Math.min(rowMin, d);
51
+ }
52
+ if (rowMin > limit)
53
+ return limit + 1;
54
+ prevPrev = prev;
55
+ prev = cur;
56
+ }
57
+ return prev[b.length];
58
+ }
59
+ /**
60
+ * The first of `names` that `candidate` is confusable with (see the module
61
+ * note), or null. An EXACT match counts too — the caller decides whether the
62
+ * same name is a conflict or the same listing.
63
+ */
64
+ export function findConfusableName(candidate, names) {
65
+ const c = normalizeConfusableName(candidate);
66
+ if (c.length === 0)
67
+ return null;
68
+ for (const name of names) {
69
+ const n = normalizeConfusableName(name);
70
+ if (n.length === 0)
71
+ continue;
72
+ if (c === n || damerauLevenshtein(c, n, 1) <= 1)
73
+ return name;
74
+ }
75
+ return null;
76
+ }
77
+ /** Whether `candidate` is confusable with any of `names`. */
78
+ export function isConfusableName(candidate, names) {
79
+ return findConfusableName(candidate, names) !== null;
80
+ }
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLW5hbWUtY29uZnVzYWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uL3BsdWdpbi1uYW1lLWNvbmZ1c2FibGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsTUFBTSxVQUFVLEdBQW9DLENBQUMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNqRixNQUFNLFdBQVcsR0FBcUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFFekYsNENBQTRDO0FBQzVDLE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxJQUFZO0lBQ2xELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ25ELEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxVQUFVO1FBQUUsR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM1RCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLENBQVMsRUFBRSxDQUFTLEVBQUUsS0FBSyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUI7SUFDdkYsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3RCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLO1FBQUUsT0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQzVELElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3BDLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3BDLElBQUksUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUM1QixJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ25DLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEIsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNuQyxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBRSxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBRSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQ3JFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzVHLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDWixNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksTUFBTSxHQUFHLEtBQUs7WUFBRSxPQUFPLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDckMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNoQixJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUUsQ0FBQztBQUN6QixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxTQUFpQixFQUFFLEtBQXVCO0lBQzNFLE1BQU0sQ0FBQyxHQUFHLHVCQUF1QixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDaEMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN6QixNQUFNLENBQUMsR0FBRyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLFNBQVM7UUFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLGtCQUFrQixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO0lBQy9ELENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCw2REFBNkQ7QUFDN0QsTUFBTSxVQUFVLGdCQUFnQixDQUFDLFNBQWlCLEVBQUUsS0FBdUI7SUFDekUsT0FBTyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEtBQUssSUFBSSxDQUFDO0FBQ3ZELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBDb25mdXNhYmxlIHBsdWdpbiBuYW1lcyAoZG9jcy9wbHVnaW4tcHVibGlzaGluZy5tZCk6XG4gKiBhIG5ldyBjb21tdW5pdHkgbGlzdGluZyDigJQgYW4gYW5vbnltb3VzIHN1Ym1pc3Npb24gb3IgYSBgbmV3X2xpc3RpbmdgXG4gKiByZXF1ZXN0IOKAlCBtYXkgbm90IGxvb2sgbGlrZSBvbmUgb2YgdGhlIGRpcmVjdG9yeSdzIG1vc3QtaW5zdGFsbGVkIHBsdWdpbnNcbiAqIChgdGVycmFmMHJtYCwgYGt1YmUtY3RsYCwgYGRvY2tlcl9idWlsZGAsIGB0ZnNlY2Ag4oaSIGB0ZnNlZGApLlxuICpcbiAqIFR3byBuYW1lcyBhcmUgQ09ORlVTQUJMRSB3aGVuLCBhZnRlciB7QGxpbmsgbm9ybWFsaXplQ29uZnVzYWJsZU5hbWV9XG4gKiAobG93ZXJjYXNlOyBzdHJpcCBgLWAsIGBfYCwgYC5gOyBgcm5g4oaSYG1gLCBgdnZg4oaSYHdgLCBgMGDihpJgb2AsIGAxYOKGkmBsYCxcbiAqIGAzYOKGkmBlYCwgYDVg4oaSYHNgKSwgdGhleSBhcmUgZXF1YWwgb3Igb25lIERhbWVyYXXigJNMZXZlbnNodGVpbiBlZGl0IGFwYXJ0XG4gKiAoYW4gaW5zZXJ0aW9uLCBkZWxldGlvbiwgc3Vic3RpdHV0aW9uIG9yIGFkamFjZW50IHRyYW5zcG9zaXRpb24pLlxuICpcbiAqIFB1cmUsIHNvIHRoZSBDTEkgY2FuIHdhcm4gYmVmb3JlIGEgcHVibGlzaCBhbmQgdGhlIHBsdWdpbiBzZXJ2aWNlIGRlY2lkZXNcbiAqIHdpdGggdGhlIHNhbWUgcnVsZS5cbiAqL1xuXG5jb25zdCBNVUxUSV9DSEFSOiBSZWFkb25seUFycmF5PFtSZWdFeHAsIHN0cmluZ10+ID0gW1svcm4vZywgJ20nXSwgWy92di9nLCAndyddXTtcbmNvbnN0IFNJTkdMRV9DSEFSOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiA9IHsgMDogJ28nLCAxOiAnbCcsIDM6ICdlJywgNTogJ3MnIH07XG5cbi8qKiBUaGUgY29tcGFyaXNvbiBmb3JtIG9mIGEgcGx1Z2luIG5hbWUuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQ29uZnVzYWJsZU5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IG91dCA9IG5hbWUudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV8uXS9nLCAnJyk7XG4gIGZvciAoY29uc3QgW2Zyb20sIHRvXSBvZiBNVUxUSV9DSEFSKSBvdXQgPSBvdXQucmVwbGFjZShmcm9tLCB0byk7XG4gIHJldHVybiBvdXQucmVwbGFjZSgvWzAxMzVdL2csIChjKSA9PiBTSU5HTEVfQ0hBUltjXSA/PyBjKTtcbn1cblxuLyoqXG4gKiBPcHRpbWFsLXN0cmluZy1hbGlnbm1lbnQgRGFtZXJhdeKAk0xldmVuc2h0ZWluIGRpc3RhbmNlIGJldHdlZW4gYGFgIGFuZCBgYmAsXG4gKiBnaXZpbmcgdXAgKHJldHVybmluZyBgbGltaXQgKyAxYCkgb25jZSBpdCBtdXN0IGV4Y2VlZCBgbGltaXRgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGFtZXJhdUxldmVuc2h0ZWluKGE6IHN0cmluZywgYjogc3RyaW5nLCBsaW1pdCA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSk6IG51bWJlciB7XG4gIGlmIChhID09PSBiKSByZXR1cm4gMDtcbiAgaWYgKE1hdGguYWJzKGEubGVuZ3RoIC0gYi5sZW5ndGgpID4gbGltaXQpIHJldHVybiBsaW1pdCArIDE7XG4gIGlmIChhLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGIubGVuZ3RoO1xuICBpZiAoYi5sZW5ndGggPT09IDApIHJldHVybiBhLmxlbmd0aDtcbiAgbGV0IHByZXZQcmV2OiBudW1iZXJbXSA9IFtdO1xuICBsZXQgcHJldiA9IEFycmF5LmZyb20oeyBsZW5ndGg6IGIubGVuZ3RoICsgMSB9LCAoXywgaikgPT4gaik7XG4gIGZvciAobGV0IGkgPSAxOyBpIDw9IGEubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjdXIgPSBbaV07XG4gICAgbGV0IHJvd01pbiA9IGk7XG4gICAgZm9yIChsZXQgaiA9IDE7IGogPD0gYi5sZW5ndGg7IGorKykge1xuICAgICAgY29uc3QgY29zdCA9IGFbaSAtIDFdID09PSBiW2ogLSAxXSA/IDAgOiAxO1xuICAgICAgbGV0IGQgPSBNYXRoLm1pbihwcmV2W2pdISArIDEsIGN1cltqIC0gMV0hICsgMSwgcHJldltqIC0gMV0hICsgY29zdCk7XG4gICAgICBpZiAoaSA+IDEgJiYgaiA+IDEgJiYgYVtpIC0gMV0gPT09IGJbaiAtIDJdICYmIGFbaSAtIDJdID09PSBiW2ogLSAxXSkgZCA9IE1hdGgubWluKGQsIHByZXZQcmV2W2ogLSAyXSEgKyAxKTtcbiAgICAgIGN1ci5wdXNoKGQpO1xuICAgICAgcm93TWluID0gTWF0aC5taW4ocm93TWluLCBkKTtcbiAgICB9XG4gICAgaWYgKHJvd01pbiA+IGxpbWl0KSByZXR1cm4gbGltaXQgKyAxO1xuICAgIHByZXZQcmV2ID0gcHJldjtcbiAgICBwcmV2ID0gY3VyO1xuICB9XG4gIHJldHVybiBwcmV2W2IubGVuZ3RoXSE7XG59XG5cbi8qKlxuICogVGhlIGZpcnN0IG9mIGBuYW1lc2AgdGhhdCBgY2FuZGlkYXRlYCBpcyBjb25mdXNhYmxlIHdpdGggKHNlZSB0aGUgbW9kdWxlXG4gKiBub3RlKSwgb3IgbnVsbC4gQW4gRVhBQ1QgbWF0Y2ggY291bnRzIHRvbyDigJQgdGhlIGNhbGxlciBkZWNpZGVzIHdoZXRoZXIgdGhlXG4gKiBzYW1lIG5hbWUgaXMgYSBjb25mbGljdCBvciB0aGUgc2FtZSBsaXN0aW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZENvbmZ1c2FibGVOYW1lKGNhbmRpZGF0ZTogc3RyaW5nLCBuYW1lczogSXRlcmFibGU8c3RyaW5nPik6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBjID0gbm9ybWFsaXplQ29uZnVzYWJsZU5hbWUoY2FuZGlkYXRlKTtcbiAgaWYgKGMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgZm9yIChjb25zdCBuYW1lIG9mIG5hbWVzKSB7XG4gICAgY29uc3QgbiA9IG5vcm1hbGl6ZUNvbmZ1c2FibGVOYW1lKG5hbWUpO1xuICAgIGlmIChuLmxlbmd0aCA9PT0gMCkgY29udGludWU7XG4gICAgaWYgKGMgPT09IG4gfHwgZGFtZXJhdUxldmVuc2h0ZWluKGMsIG4sIDEpIDw9IDEpIHJldHVybiBuYW1lO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKiogV2hldGhlciBgY2FuZGlkYXRlYCBpcyBjb25mdXNhYmxlIHdpdGggYW55IG9mIGBuYW1lc2AuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb25mdXNhYmxlTmFtZShjYW5kaWRhdGU6IHN0cmluZywgbmFtZXM6IEl0ZXJhYmxlPHN0cmluZz4pOiBib29sZWFuIHtcbiAgcmV0dXJuIGZpbmRDb25mdXNhYmxlTmFtZShjYW5kaWRhdGUsIG5hbWVzKSAhPT0gbnVsbDtcbn1cbiJdfQ==
@@ -24,6 +24,7 @@ export declare const PluginFilterSchema: z.ZodObject<{
24
24
  production: "production";
25
25
  }>>;
26
26
  name: z.ZodOptional<z.ZodString>;
27
+ publisher: z.ZodOptional<z.ZodString>;
27
28
  version: z.ZodOptional<z.ZodString>;
28
29
  orgId: z.ZodOptional<z.ZodString>;
29
30
  pluginType: z.ZodOptional<z.ZodString>;
@@ -96,7 +97,13 @@ export declare const PluginCreateSchema: z.ZodObject<{
96
97
  }, z.core.$strip>>>;
97
98
  }, z.core.$strip>;
98
99
  /**
99
- * Plugin update schema
100
+ * Plugin update schema (`PUT /plugins/:id`).
101
+ *
102
+ * DESCRIPTIVE catalog fields only plus the version's operational
103
+ * flags and developer-portal metadata. Execution-contract keys (commands, env,
104
+ * secrets, compute type, …) are never accepted — the route refuses them with a
105
+ * 400 naming the keys before this schema runs, and `.strict()` refuses anything
106
+ * else unknown rather than silently dropping it.
100
107
  */
101
108
  export declare const PluginUpdateSchema: z.ZodObject<{
102
109
  ownerId: z.ZodOptional<z.ZodString>;
@@ -121,19 +128,6 @@ export declare const PluginUpdateSchema: z.ZodObject<{
121
128
  url: z.ZodString;
122
129
  icon: z.ZodOptional<z.ZodString>;
123
130
  }, z.core.$strip>>>;
124
- name: z.ZodOptional<z.ZodString>;
125
- description: z.ZodOptional<z.ZodString>;
126
- keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
127
- category: z.ZodOptional<z.ZodString>;
128
- version: z.ZodOptional<z.ZodString>;
129
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
130
- pluginType: z.ZodOptional<z.ZodString>;
131
- computeType: z.ZodOptional<z.ZodString>;
132
- primaryOutputDirectory: z.ZodOptional<z.ZodNullable<z.ZodString>>;
133
- env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
134
- buildArgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
135
- installCommands: z.ZodOptional<z.ZodArray<z.ZodString>>;
136
- commands: z.ZodOptional<z.ZodArray<z.ZodString>>;
137
131
  isActive: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodPipe<z.ZodEnum<{
138
132
  false: "false";
139
133
  true: "true";
@@ -147,18 +141,33 @@ export declare const PluginUpdateSchema: z.ZodObject<{
147
141
  private: "private";
148
142
  public: "public";
149
143
  }>>;
150
- timeout: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
151
- failureBehavior: z.ZodOptional<z.ZodEnum<{
152
- fail: "fail";
153
- ignore: "ignore";
154
- warn: "warn";
155
- }>>;
156
- secrets: z.ZodOptional<z.ZodArray<z.ZodObject<{
157
- name: z.ZodString;
158
- required: z.ZodBoolean;
159
- description: z.ZodOptional<z.ZodString>;
160
- }, z.core.$strip>>>;
161
- }, z.core.$strip>;
144
+ category: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
145
+ ai: "ai";
146
+ artifact: "artifact";
147
+ deploy: "deploy";
148
+ infrastructure: "infrastructure";
149
+ language: "language";
150
+ monitoring: "monitoring";
151
+ notification: "notification";
152
+ quality: "quality";
153
+ security: "security";
154
+ testing: "testing";
155
+ }>>>;
156
+ changelog: z.ZodOptional<z.ZodNullable<z.ZodString>>;
157
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
158
+ displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
159
+ documentationUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
160
+ homepageUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
161
+ icon: z.ZodOptional<z.ZodNullable<z.ZodPreprocess<z.ZodObject<{
162
+ key: z.ZodString;
163
+ badge: z.ZodOptional<z.ZodString>;
164
+ }, z.core.$strict>>>>;
165
+ keywords: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
166
+ license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
167
+ readme: z.ZodOptional<z.ZodNullable<z.ZodString>>;
168
+ sourceUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
169
+ summary: z.ZodOptional<z.ZodNullable<z.ZodString>>;
170
+ }, z.core.$strict>;
162
171
  /**
163
172
  * Plugin upload body schema (multipart form-data text fields)
164
173
  */
@@ -168,4 +177,9 @@ export declare const PluginUploadBodySchema: z.ZodObject<{
168
177
  private: "private";
169
178
  public: "public";
170
179
  }>>;
180
+ metadata: z.ZodOptional<z.ZodString>;
181
+ publishRequest: z.ZodOptional<z.ZodEnum<{
182
+ false: "false";
183
+ true: "true";
184
+ }>>;
171
185
  }, z.core.$strip>;
@@ -2,11 +2,15 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { z } from 'zod';
4
4
  import { BaseFilterSchema, BooleanQuerySchema, VisibilitySchema, CatalogMetadataShape } from './common-schemas.js';
5
+ import { PluginCatalogEditsSchema } from './plugin-catalog-metadata.js';
6
+ import { PUBLISHER_HANDLE_PATTERN } from '../types/ecosystem.js';
5
7
  /**
6
8
  * Plugin filter schema for query parameters
7
9
  */
8
10
  export const PluginFilterSchema = BaseFilterSchema.extend({
9
11
  name: z.string().min(1).optional(),
12
+ /** Resolve through this publisher's installed listing; lookup only. */
13
+ publisher: z.string().max(39).regex(PUBLISHER_HANDLE_PATTERN).optional(),
10
14
  version: z.string().min(1).optional(),
11
15
  orgId: z.string().min(1).optional(),
12
16
  pluginType: z.string().optional(),
@@ -44,38 +48,37 @@ export const PluginCreateSchema = z.object({
44
48
  })).optional(),
45
49
  });
46
50
  /**
47
- * Plugin update schema
51
+ * Plugin update schema (`PUT /plugins/:id`).
52
+ *
53
+ * DESCRIPTIVE catalog fields only plus the version's operational
54
+ * flags and developer-portal metadata. Execution-contract keys (commands, env,
55
+ * secrets, compute type, …) are never accepted — the route refuses them with a
56
+ * 400 naming the keys before this schema runs, and `.strict()` refuses anything
57
+ * else unknown rather than silently dropping it.
48
58
  */
49
59
  export const PluginUpdateSchema = z.object({
50
60
  ...CatalogMetadataShape,
51
- name: z.string().min(1).optional(),
52
- description: z.string().optional(),
53
- keywords: z.array(z.string()).optional(),
54
- category: z.string().min(1).optional(),
55
- version: z.string().min(1).optional(),
56
- metadata: z.record(z.string(), z.unknown()).optional(),
57
- pluginType: z.string().optional(),
58
- computeType: z.string().optional(),
59
- primaryOutputDirectory: z.string().nullable().optional(),
60
- env: z.record(z.string(), z.string()).optional(),
61
- buildArgs: z.record(z.string(), z.string()).optional(),
62
- installCommands: z.array(z.string()).optional(),
63
- commands: z.array(z.string()).optional(),
61
+ ...PluginCatalogEditsSchema.shape,
64
62
  isActive: BooleanQuerySchema.optional(),
65
63
  isDefault: BooleanQuerySchema.optional(),
66
64
  visibility: VisibilitySchema.optional(),
67
- timeout: z.number().int().positive().nullable().optional(),
68
- failureBehavior: z.enum(['fail', 'warn', 'ignore']).optional(),
69
- secrets: z.array(z.object({
70
- name: z.string().min(1),
71
- required: z.boolean(),
72
- description: z.string().optional(),
73
- })).optional(),
74
- });
65
+ }).strict();
75
66
  /**
76
67
  * Plugin upload body schema (multipart form-data text fields)
77
68
  */
78
69
  export const PluginUploadBodySchema = z.object({
79
70
  visibility: VisibilitySchema.optional(),
71
+ /**
72
+ * Catalog metadata edits as a JSON object (a {@link PluginCatalogEditsSchema}
73
+ * document). Absent ⇒ every value detected from the package is accepted.
74
+ */
75
+ metadata: z.string().max(256 * 1024).optional(),
76
+ /**
77
+ * `true`: once the build completes, submit a publish request (new listing, or
78
+ * new version of the org's existing listing) for the built version as the
79
+ * uploader (docs/plugin-publishing.md). Needs `plugins:publish` and
80
+ * `visibility=public`. The Official catalog loader always sets it.
81
+ */
82
+ publishRequest: z.enum(['true', 'false']).optional(),
80
83
  });
81
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLXNjaGVtYXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGlvbi9wbHVnaW4tc2NoZW1hcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLGdCQUFnQixFQUFFLG9CQUFvQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFbkg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7SUFDeEQsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQ2xDLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUNyQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDbkMsVUFBVSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDakMsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQ3JDLFFBQVEsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRTtDQUN2QyxDQUFDLENBQUM7QUFFSDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUN6QyxHQUFHLG9CQUFvQjtJQUN2QixLQUFLLEVBQUUsQ0FBQyxDQUFD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RSxDQUFDLFFBQVEsRUFBRTtJQUMxRCxlQUFlLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDOUQsT0FBTyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUN4QixJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdkIsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUU7UUFDckIsV0FBVyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7S0FDbkMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0NBQ2YsQ0FBQyxDQUFDO0FBRUg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzdDLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7Q0FDeEMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHogfSBmcm9tICd6b2QnO1xuaW1wb3J0IHsgQmFzZUZpbHRlclNjaGVtYSwgQm9vbGVhblF1ZXJ5U2NoZW1hLCBWaXNpYmlsaXR5U2NoZW1hLCBDYXRhbG9nTWV0YWRhdGFTaGFwZSB9IGZyb20gJy4vY29tbW9uLXNjaGVtYXMuanMnO1xuXG4vKipcbiAqIFBsdWdpbiBmaWx0ZXIgc2NoZW1hIGZvciBxdWVyeSBwYXJhbWV0ZXJzXG4gKi9cbmV4cG9ydCBjb25zdCBQbHVnaW5GaWx0ZXJTY2hlbWEgPSBCYXNlRmlsdGVyU2NoZW1hLmV4dGVuZCh7XG4gIG5hbWU6IHouc3RyaW5nKCkubWluKDEpLm9wdGlvbmFsKCksXG4gIHZlcnNpb246IHouc3RyaW5nKCkubWluKDEpLm9wdGlvbmFsKCksXG4gIG9yZ0lkOiB6LnN0cmluZygpLm1pbigxKS5vcHRpb25hbCgpLFxuICBwbHVnaW5UeXBlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIGtleXdvcmQ6IHouc3RyaW5nKCkubWluKDEpLm9wdGlvbmFsKCksXG4gIGNhdGVnb3J5OiB6LnN0cmluZygpLm1pbigxKS5vcHRpb25hbCgpLFxufSk7XG5cbi8qKlxuICogUGx1Z2luIGNyZWF0aW9uIHNjaGVtYSDigJQgdXNlZCBmb3IgT3BlbkFQSSBkb2N1bWVudGF0aW9uIGFuZCBkaXJlY3QgQVBJIGNyZWF0aW9uLlxuICogQ3VycmVudGx5IG5vIHJvdXRlIHVzZXMgdGhpcyBkaXJlY3RseTsgcGx1Z2lucyBhcmUgY3JlYXRlZCB2aWEgdXBsb2FkIG9yIEFJIGdlbmVyYXRpb24uXG4gKiBSZXRhaW5lZCBmb3IgZnV0dXJlIGRpcmVjdC1jcmVhdGUgZW5kcG9pbnQgYW5kIE9wZW5BUEkgc3BlYyBjb21wbGV0ZW5lc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBQbHVnaW5DcmVhdGVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIC4uLkNhdGFsb2dNZXRhZGF0YVNoYXBlLFxuICBvcmdJZDogei5zdHJpbmcoKS5taW4oMSwgJ09yZ2FuaXphdGlvbiBJRCBpcyByZXF1aXJlZCcpLFxuICBuYW1lOiB6LnN0cmluZygpLm1pbigxLCAnUGx1Z2luIG5hbWUgaXMgcmVxdWlyZWQnKSxcbiAgdmVyc2lvbjogei5zdHJpbmcoKS5taW4oMSwgJ1ZlcnNpb24gaXMgcmVxdWlyZWQnKSxcbiAgdmlzaWJpbGl0eTogVmlzaWJpbGl0eVNjaGVtYS5vcHRpb25hbCgpLFxuICBjYXRlZ29yeTogei5zdHJpbmcoKS5taW4oMSkub3B0aW9uYWwoKSxcbiAgcGx1Z2luVHlwZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBjb21wdXRlVHlwZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBwcmltYXJ5T3V0cHV0RGlyZWN0b3J5OiB6LnN0cmluZygpLm51bGxhYmxlKCkub3B0aW9uYWwoKSxcbiAgbWV0YWRhdGE6IHoucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKS5vcHRpb25hbCgpLFxuICBlbnY6IHoucmVjb3JkKHouc3RyaW5nKCksIHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGJ1aWxkQXJnczogei5yZWNvcmQoei5zdHJpbmcoKSwgei5zdHJpbmcoKSkub3B0aW9uYWwoKSxcbiAgaW5zdGFsbENvbW1hbmRzOiB6LmFycmF5KHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGNvbW1hbmRzOiB6LmFycmF5KHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGlzQWN0aXZlOiBCb29sZWFuUXVlcnlTY2hlbWEub3B0aW9uYWwoKSxcbiAgaXNEZWZhdWx0OiBCb29sZWFuUXVlcnlTY2hlbWEub3B0aW9uYWwoKSxcbiAgdGltZW91dDogei5udW1iZXIoKS5pbnQoKS5wb3NpdGl2ZSgpLm51bGxhYmxlKCkub3B0aW9uYWwoKSxcbiAgZmFpbHVyZUJlaGF2aW9yOiB6LmVudW0oWydmYWlsJywgJ3dhcm4nLCAnaWdub3JlJ10pLm9wdGlvbmFsKCksXG4gIHNlY3JldHM6IHouYXJyYXkoei5vYmplY3Qoe1xuICAgIG5hbWU6IHouc3RyaW5nKCkubWluKDEpLFxuICAgIHJlcXVpcmVkOiB6LmJvb2xlYW4oKSxcbiAgICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB9KSkub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbiAqIFBsdWdpbiB1cGRhdGUgc2NoZW1hXG4gKi9cbmV4cG9ydCBjb25zdCBQbHVnaW5VcGRhdGVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIC4uLkNhdGFsb2dNZXRhZGF0YVNoYXBlLFxuICBuYW1lOiB6LnN0cmluZygpLm1pbigxKS5vcHRpb25hbCgpLFxuICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBrZXl3b3Jkczogei5hcnJheSh6LnN0cmluZygpKS5vcHRpb25hbCgpLFxuICBjYXRlZ29yeTogei5zdHJpbmcoKS5taW4oMSkub3B0aW9uYWwoKSxcbiAgdmVyc2lvbjogei5zdHJpbmcoKS5taW4oMSkub3B0aW9uYWwoKSxcbiAgbWV0YWRhdGE6IHoucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKS5vcHRpb25hbCgpLFxuICBwbHVnaW5UeXBlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIGNvbXB1dGVUeXBlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIHByaW1hcnlPdXRwdXREaXJlY3Rvcnk6IHouc3RyaW5nKCkubnVsbGFibGUoKS5vcHRpb25hbCgpLFxuICBlbnY6IHoucmVjb3JkKHouc3RyaW5nKCksIHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGJ1aWxkQXJnczogei5yZWNvcmQoei5zdHJpbmcoKSwgei5zdHJpbmcoKSkub3B0aW9uYWwoKSxcbiAgaW5zdGFsbENvbW1hbmRzOiB6LmFycmF5KHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGNvbW1hbmRzOiB6LmFycmF5KHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGlzQWN0aXZlOiBCb29sZWFuUXVlcnlTY2hlbWEub3B0aW9uYWwoKSxcbiAgaXNEZWZhdWx0OiBCb29sZWFuUXVlcnlTY2hlbWEub3B0aW9uYWwoKSxcbiAgdmlzaWJpbGl0eTogVmlzaWJpbGl0eVNjaGVtYS5vcHRpb25hbCgpLFxuICB0aW1lb3V0OiB6Lm51bWJlcigpLmludCgpLnBvc2l0aXZlKCkubnVsbGFibGUoKS5vcHRpb25hbCgpLFxuICBmYWlsdXJlQmVoYXZpb3I6IHouZW51bShbJ2ZhaWwnLCAnd2FybicsICdpZ25vcmUnXSkub3B0aW9uYWwoKSxcbiAgc2VjcmV0czogei5hcnJheSh6Lm9iamVjdCh7XG4gICAgbmFtZTogei5zdHJpbmcoKS5taW4oMSksXG4gICAgcmVxdWlyZWQ6IHouYm9vbGVhbigpLFxuICAgIGRlc2NyaXB0aW9uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIH0pKS5vcHRpb25hbCgpLFxufSk7XG5cbi8qKlxuICogUGx1Z2luIHVwbG9hZCBib2R5IHNjaGVtYSAobXVsdGlwYXJ0IGZvcm0tZGF0YSB0ZXh0IGZpZWxkcylcbiAqL1xuZXhwb3J0IGNvbnN0IFBsdWdpblVwbG9hZEJvZHlTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHZpc2liaWxpdHk6IFZpc2liaWxpdHlTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuIl19
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLXNjaGVtYXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGlvbi9wbHVnaW4tc2NoZW1hcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLGdCQUFnQixFQUFFLG9CQUFvQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbkgsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDeEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFakU7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7SUFDeEQsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQ2xDLHVFQUF1RTtJQUN2RSxTQUFTLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDeEUsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQ3JDLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUNuQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFR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RUFBRTtJQUN2QyxTQUFTLEVBQUUsa0JBQWtCLENBQUMsUUFBUSxFQUFFO0lBQ3hDLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7Q0FDeEMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBRVo7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzdDLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7SUFDdkM7OztPQUdHO0lBQ0gsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUMvQzs7Ozs7T0FLRztJQUNILGNBQWMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0NBQ3JELENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcbmltcG9ydCB7IEJhc2VGaWx0ZXJTY2hlbWEsIEJvb2xlYW5RdWVyeVNjaGVtYSwgVmlzaWJpbGl0eVNjaGVtYSwgQ2F0YWxvZ01ldGFkYXRhU2hhcGUgfSBmcm9tICcuL2NvbW1vbi1zY2hlbWFzLmpzJztcbmltcG9ydCB7IFBsdWdpbkNhdGFsb2dFZGl0c1NjaGVtYSB9IGZyb20gJy4vcGx1Z2luLWNhdGFsb2ctbWV0YWRhdGEuanMnO1xuaW1wb3J0IHsgUFVCTElTSEVSX0hBTkRMRV9QQVRURVJOIH0gZnJvbSAnLi4vdHlwZXMvZWNvc3lzdGVtLmpzJztcblxuLyoqXG4gKiBQbHVnaW4gZmlsdGVyIHNjaGVtYSBmb3IgcXVlcnkgcGFyYW1ldGVyc1xuICovXG5leHBvcnQgY29uc3QgUGx1Z2luRmlsdGVyU2NoZW1hID0gQmFzZUZpbHRlclNjaGVtYS5leHRlbmQoe1xuICBuYW1lOiB6LnN0cmluZygpLm1pbigxKS5vcHRpb25hbCgpLFxuICAvKiogUmVzb2x2ZSB0aHJvdWdoIHRoaXMgcHVibGlzaGVyJ3MgaW5zdGFsbGVkIGxpc3Rpbmc7IGxvb2t1cCBvbmx5LiAqL1xuICBwdWJsaXNoZXI6IHouc3RyaW5nKCkubWF4KDM5KS5yZWdleChQVUJMSVNIRVJfSEFORExFX1BBVFRFUk4pLm9wdGlvbmFsKCksXG4gIHZlcnNpb246IHouc3RyaW5nKCkubWluKDEpLm9wdGlvbmFsKCksXG4gIG9yZ0lkOiB6LnN0cmluZygpLm1pbigxKS5vcHRpb25hbCgpLFxuICBwbHVnaW5UeXBlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIGtleXdvcmQ6IHouc3RyaW5nKCkubWluKDEpLm9wdGlvbmFsKCksXG4gIGNhdGVnb3J5OiB6LnN0cmluZygpLm1pbigxKS5vcHRpb25hbCgpLFxufSk7XG5cbi8qKlxuICogUGx1Z2luIGNyZWF0aW9uIHNjaGVtYSDigJQgdXNlZCBmb3IgT3BlbkFQSSBkb2N1bWVudGF0aW9uIGFuZCBkaXJlY3QgQVBJIGNyZWF0aW9uLlxuICogQ3VycmVudGx5IG5vIHJvdXRlIHVzZXMgdGhpcyBkaXJlY3RseTsgcGx1Z2lucyBhcmUgY3JlYXRlZCB2aWEgdXBsb2FkIG9yIEFJIGdlbmVyYXRpb24uXG4gKiBSZXRhaW5lZCBmb3IgZnV0dXJlIGRpcmVjdC1jcmVhdGUgZW5kcG9pbnQgYW5kIE9wZW5BUEkgc3BlYyBjb21wbGV0ZW5lc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBQbHVnaW5DcmVhdGVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIC4uLkNhdGFsb2dNZXRhZGF0YVNoYXBlLFxuICBvcmdJZDogei5zdHJpbmcoKS5taW4oMSwgJ09yZ2FuaXphdGlvbiBJRCBpcyByZXF1aXJlZCcpLFxuICBuYW1lOiB6LnN0cmluZygpLm1pbigxLCAnUGx1Z2luIG5hbWUgaXMgcmVxdWlyZWQnKSxcbiAgdmVyc2lvbjogei5zdHJpbmcoKS5taW4oMSwgJ1ZlcnNpb24gaXMgcmVxdWlyZWQnKSxcbiAgdmlzaWJpbGl0eTogVmlzaWJpbGl0eVNjaGVtYS5vcHRpb25hbCgpLFxuICBjYXRlZ29yeTogei5zdHJpbmcoKS5taW4oMSkub3B0aW9uYWwoKSxcbiAgcGx1Z2luVHlwZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBjb21wdXRlVHlwZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBwcmltYXJ5T3V0cHV0RGlyZWN0b3J5OiB6LnN0cmluZygpLm51bGxhYmxlKCkub3B0aW9uYWwoKSxcbiAgbWV0YWRhdGE6IHoucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKS5vcHRpb25hbCgpLFxuICBlbnY6IHoucmVjb3JkKHouc3RyaW5nKCksIHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGJ1aWxkQXJnczogei5yZWNvcmQoei5zdHJpbmcoKSwgei5zdHJpbmcoKSkub3B0aW9uYWwoKSxcbiAgaW5zdGFsbENvbW1hbmRzOiB6LmFycmF5KHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGNvbW1hbmRzOiB6LmFycmF5KHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIGlzQWN0aXZlOiBCb29sZWFuUXVlcnlTY2hlbWEub3B0aW9uYWwoKSxcbiAgaXNEZWZhdWx0OiBCb29sZWFuUXVlcnlTY2hlbWEub3B0aW9uYWwoKSxcbiAgdGltZW91dDogei5udW1iZXIoKS5pbnQoKS5wb3NpdGl2ZSgpLm51bGxhYmxlKCkub3B0aW9uYWwoKSxcbiAgZmFpbHVyZUJlaGF2aW9yOiB6LmVudW0oWydmYWlsJywgJ3dhcm4nLCAnaWdub3JlJ10pLm9wdGlvbmFsKCksXG4gIHNlY3JldHM6IHouYXJyYXkoei5vYmplY3Qoe1xuICAgIG5hbWU6IHouc3RyaW5nKCkubWluKDEpLFxuICAgIHJlcXVpcmVkOiB6LmJvb2xlYW4oKSxcbiAgICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB9KSkub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbiAqIFBsdWdpbiB1cGRhdGUgc2NoZW1hIChgUFVUIC9wbHVnaW5zLzppZGApLlxuICpcbiAqIERFU0NSSVBUSVZFIGNhdGFsb2cgZmllbGRzIG9ubHkgcGx1cyB0aGUgdmVyc2lvbidzIG9wZXJhdGlvbmFsXG4gKiBmbGFncyBhbmQgZGV2ZWxvcGVyLXBvcnRhbCBtZXRhZGF0YS4gRXhlY3V0aW9uLWNvbnRyYWN0IGtleXMgKGNvbW1hbmRzLCBlbnYsXG4gKiBzZWNyZXRzLCBjb21wdXRlIHR5cGUsIOKApikgYXJlIG5ldmVyIGFjY2VwdGVkIOKAlCB0aGUgcm91dGUgcmVmdXNlcyB0aGVtIHdpdGggYVxuICogNDAwIG5hbWluZyB0aGUga2V5cyBiZWZvcmUgdGhpcyBzY2hlbWEgcnVucywgYW5kIGAuc3RyaWN0KClgIHJlZnVzZXMgYW55dGhpbmdcbiAqIGVsc2UgdW5rbm93biByYXRoZXIgdGhhbiBzaWxlbnRseSBkcm9wcGluZyBpdC5cbiAqL1xuZXhwb3J0IGNvbnN0IFBsdWdpblVwZGF0ZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgLi4uQ2F0YWxvZ01ldGFkYXRhU2hhcGUsXG4gIC4uLlBsdWdpbkNhdGFsb2dFZGl0c1NjaGVtYS5zaGFwZSxcbiAgaXNBY3RpdmU6IEJvb2xlYW5RdWVyeVNjaGVtYS5vcHRpb25hbCgpLFxuICBpc0RlZmF1bHQ6IEJvb2xlYW5RdWVyeVNjaGVtYS5vcHRpb25hbCgpLFxuICB2aXNpYmlsaXR5OiBWaXNpYmlsaXR5U2NoZW1hLm9wdGlvbmFsKCksXG59KS5zdHJpY3QoKTtcblxuLyoqXG4gKiBQbHVnaW4gdXBsb2FkIGJvZHkgc2NoZW1hIChtdWx0aXBhcnQgZm9ybS1kYXRhIHRleHQgZmllbGRzKVxuICovXG5leHBvcnQgY29uc3QgUGx1Z2luVXBsb2FkQm9keVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgdmlzaWJpbGl0eTogVmlzaWJpbGl0eVNjaGVtYS5vcHRpb25hbCgpLFxuICAvKipcbiAgICogQ2F0YWxvZyBtZXRhZGF0YSBlZGl0cyBhcyBhIEpTT04gb2JqZWN0IChhIHtAbGluayBQbHVnaW5DYXRhbG9nRWRpdHNTY2hlbWF9XG4gICAqIGRvY3VtZW50KS4gQWJzZW50IOKHkiBldmVyeSB2YWx1ZSBkZXRlY3RlZCBmcm9tIHRoZSBwYWNrYWdlIGlzIGFjY2VwdGVkLlxuICAgKi9cbiAgbWV0YWRhdGE6IHouc3RyaW5nKCkubWF4KDI1NiAqIDEwMjQpLm9wdGlvbmFsKCksXG4gIC8qKlxuICAgKiBgdHJ1ZWA6IG9uY2UgdGhlIGJ1aWxkIGNvbXBsZXRlcywgc3VibWl0IGEgcHVibGlzaCByZXF1ZXN0IChuZXcgbGlzdGluZywgb3JcbiAgICogbmV3IHZlcnNpb24gb2YgdGhlIG9yZydzIGV4aXN0aW5nIGxpc3RpbmcpIGZvciB0aGUgYnVpbHQgdmVyc2lvbiBhcyB0aGVcbiAgICogdXBsb2FkZXIgKGRvY3MvcGx1Z2luLXB1Ymxpc2hpbmcubWQpLiBOZWVkcyBgcGx1Z2luczpwdWJsaXNoYCBhbmRcbiAgICogYHZpc2liaWxpdHk9cHVibGljYC4gVGhlIE9mZmljaWFsIGNhdGFsb2cgbG9hZGVyIGFsd2F5cyBzZXRzIGl0LlxuICAgKi9cbiAgcHVibGlzaFJlcXVlc3Q6IHouZW51bShbJ3RydWUnLCAnZmFsc2UnXSkub3B0aW9uYWwoKSxcbn0pO1xuIl19
@@ -0,0 +1,112 @@
1
+ /**
2
+ * The plugin PACKAGE schemas: `plugin-spec.yaml` and `config.yaml`, exactly as
3
+ * the plugin service validates an upload. Shared from api-core so the upload
4
+ * path (api/plugin) and the CLI (`pipeline-manager plugin validate` /
5
+ * `plugin publish`) apply ONE schema and can't drift.
6
+ *
7
+ * Pure: no YAML parsing, no filesystem. Callers parse (with their own size and
8
+ * alias bounds) and hand the resulting object to {@link checkPluginSpec} /
9
+ * {@link checkPluginConfig}.
10
+ */
11
+ import { z } from 'zod';
12
+ export declare const PLUGIN_TYPES: readonly ['CodeBuildStep', 'ShellStep', 'ManualApprovalStep'];
13
+ export declare const PLUGIN_COMPUTE_TYPES: readonly ['SMALL', 'MEDIUM', 'LARGE', 'X2_LARGE'];
14
+ export declare const PLUGIN_FAILURE_BEHAVIORS: readonly ['fail', 'warn', 'ignore'];
15
+ export declare const PLUGIN_BUILD_TYPES: readonly ['build_image', 'prebuilt', 'metadata_only'];
16
+ export type PluginBuildType = typeof PLUGIN_BUILD_TYPES[number];
17
+ /** Plugin name: lowercase letters, digits and hyphens. */
18
+ export declare const PLUGIN_NAME_PATTERN: RegExp;
19
+ /** Plugin version: semver, with optional `-prerelease` and `+build` metadata. */
20
+ export declare const PLUGIN_VERSION_PATTERN: RegExp;
21
+ /** Max declared `network.egress` hostnames. */
22
+ export declare const EGRESS_MAX_HOSTS = 50;
23
+ /** True when `host` is an acceptable `network.egress` entry. */
24
+ export declare function isValidEgressHost(host: string): boolean;
25
+ export declare const PluginConfigSchema: z.ZodObject<{
26
+ pluginSpec: z.ZodOptional<z.ZodString>;
27
+ dockerfile: z.ZodOptional<z.ZodString>;
28
+ buildType: z.ZodOptional<z.ZodEnum<{
29
+ build_image: "build_image";
30
+ metadata_only: "metadata_only";
31
+ prebuilt: "prebuilt";
32
+ }>>;
33
+ imageTag: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strict>;
35
+ export type PluginConfigInput = z.infer<typeof PluginConfigSchema>;
36
+ export declare const PluginSpecSchema: z.ZodObject<{
37
+ name: z.ZodOptional<z.ZodString>;
38
+ description: z.ZodOptional<z.ZodString>;
39
+ keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
40
+ category: z.ZodOptional<z.ZodString>;
41
+ version: z.ZodOptional<z.ZodString>;
42
+ pluginType: z.ZodOptional<z.ZodEnum<{
43
+ CodeBuildStep: "CodeBuildStep";
44
+ ManualApprovalStep: "ManualApprovalStep";
45
+ ShellStep: "ShellStep";
46
+ }>>;
47
+ computeType: z.ZodOptional<z.ZodEnum<{
48
+ LARGE: "LARGE";
49
+ MEDIUM: "MEDIUM";
50
+ SMALL: "SMALL";
51
+ X2_LARGE: "X2_LARGE";
52
+ }>>;
53
+ timeout: z.ZodOptional<z.ZodNumber>;
54
+ failureBehavior: z.ZodOptional<z.ZodEnum<{
55
+ fail: "fail";
56
+ ignore: "ignore";
57
+ warn: "warn";
58
+ }>>;
59
+ secrets: z.ZodOptional<z.ZodArray<z.ZodObject<{
60
+ name: z.ZodString;
61
+ required: z.ZodBoolean;
62
+ description: z.ZodOptional<z.ZodString>;
63
+ }, z.core.$strip>>>;
64
+ primaryOutputDirectory: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | undefined, string | null | undefined>>;
65
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
66
+ dockerfile: z.ZodOptional<z.ZodString>;
67
+ installCommands: z.ZodOptional<z.ZodArray<z.ZodString>>;
68
+ commands: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
70
+ buildArgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
71
+ requiredMetadata: z.ZodOptional<z.ZodArray<z.ZodString>>;
72
+ requiredVars: z.ZodOptional<z.ZodArray<z.ZodString>>;
73
+ metadataTypes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
74
+ varsTypes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
75
+ smokeTest: z.ZodOptional<z.ZodString>;
76
+ license: z.ZodOptional<z.ZodString>;
77
+ changelog: z.ZodOptional<z.ZodString>;
78
+ homepageUrl: z.ZodOptional<z.ZodString>;
79
+ sourceUrl: z.ZodOptional<z.ZodString>;
80
+ summary: z.ZodOptional<z.ZodString>;
81
+ documentationUrl: z.ZodOptional<z.ZodString>;
82
+ icon: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
83
+ key: z.ZodString;
84
+ badge: z.ZodOptional<z.ZodString>;
85
+ }, z.core.$strict>]>>;
86
+ network: z.ZodOptional<z.ZodObject<{
87
+ egress: z.ZodOptional<z.ZodArray<z.ZodString>>;
88
+ }, z.core.$strict>>;
89
+ }, z.core.$strict>;
90
+ export type PluginSpecInput = z.infer<typeof PluginSpecSchema>;
91
+ /**
92
+ * Result of checking a parsed YAML document against a package schema:
93
+ * `issues` are the individual problems, `message` the one-line form the upload
94
+ * API reports (`plugin-spec.yaml: <path>: <problem>; …`).
95
+ */
96
+ export type PackageCheck<T> = {
97
+ ok: true;
98
+ value: T;
99
+ } | {
100
+ ok: false;
101
+ issues: string[];
102
+ message: string;
103
+ };
104
+ /** Check a parsed `plugin-spec.yaml` document against {@link PluginSpecSchema}. */
105
+ export declare function checkPluginSpec(raw: unknown): PackageCheck<PluginSpecInput>;
106
+ /** Check a parsed `config.yaml` document against {@link PluginConfigSchema}. */
107
+ export declare function checkPluginConfig(raw: unknown): PackageCheck<PluginConfigInput>;
108
+ /**
109
+ * The required-field contract: `name` and `version` always, `commands` for
110
+ * every type except `ManualApprovalStep`. Returns the upload's message, or null.
111
+ */
112
+ export declare function pluginSpecRequiredFieldsProblem(spec: Pick<PluginSpecInput, 'name' | 'version' | 'commands' | 'pluginType'>): string | null;