@floegence/redevplugin-contracts 0.6.24 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { generatedContractArtifacts, generatedRegistryContract } from "./contracts.gen.js";
2
2
  export * from "./release-signing.js";
3
+ export * from "./presentation.js";
3
4
  export type ContractID = (typeof generatedContractArtifacts)[number]["id"] | typeof generatedRegistryContract.id;
4
5
  export type Contract = Readonly<{
5
6
  id: ContractID;
@@ -19,9 +20,9 @@ export declare const contractRegistry: {
19
20
  readonly registry_version: "contract-registry-v2";
20
21
  readonly artifacts: readonly [{
21
22
  readonly id: "compatibility-manifest-schema";
22
- readonly path: "spec/plugin/compatibility-manifest-v13.schema.json";
23
- readonly version: "compatibility-manifest-v13";
24
- readonly sha256: "c95fdfe0c5818ba57e664c534c3d10d073545e5a31bccd7c1ee5d39d391d13b2";
23
+ readonly path: "spec/plugin/compatibility-manifest-v14.schema.json";
24
+ readonly version: "compatibility-manifest-v14";
25
+ readonly sha256: "67016ead2ed8b86410aafe3771d750ea2ab088479047475542ac65caa1691a7c";
25
26
  }, {
26
27
  readonly id: "contract-registry-schema";
27
28
  readonly path: "spec/plugin/contract-registry-v2.schema.json";
@@ -94,9 +95,9 @@ export declare const contractRegistry: {
94
95
  readonly sha256: "f4b5f04870b58e8e2363aaba98b273adccef3a3e9ac1eb1a2dbbc3fb4c71b300";
95
96
  }, {
96
97
  readonly id: "manifest-schema";
97
- readonly path: "spec/plugin/manifest-v7.schema.json";
98
- readonly version: "manifest-v7";
99
- readonly sha256: "af73ffd8ccedcb149198f847b68ed6fc23e51366122915c7129473f9fde68e35";
98
+ readonly path: "spec/plugin/manifest-v8.schema.json";
99
+ readonly version: "manifest-v8";
100
+ readonly sha256: "f4f6ec875936b19ae3371459804b5ad2c36a4bd0739a83976037efffe51ada48";
100
101
  }, {
101
102
  readonly id: "network-grant-schema";
102
103
  readonly path: "spec/plugin/network-grant-v2.schema.json";
@@ -159,9 +160,14 @@ export declare const contractRegistry: {
159
160
  readonly sha256: "4d9979f5205ec047895b64c995312c588d998bb1c1448f6c9c559f1b7ab0d796";
160
161
  }, {
161
162
  readonly id: "plugin-platform-openapi";
162
- readonly path: "spec/openapi/plugin-platform-v11.yaml";
163
- readonly version: "plugin-platform-v11";
164
- readonly sha256: "41c84c939ca9471baafdb16a1fe7d62a232a58df91e579514351dd6046e529e7";
163
+ readonly path: "spec/openapi/plugin-platform-v12.yaml";
164
+ readonly version: "plugin-platform-v12";
165
+ readonly sha256: "715698e9e1e357e243ee21b3157cc044befac83979107f54d024b5e9e48f7050";
166
+ }, {
167
+ readonly id: "presentation-locale-fixture";
168
+ readonly path: "spec/plugin/presentation-locale-fixtures-v1.json";
169
+ readonly version: "presentation-locale-fixtures-v1";
170
+ readonly sha256: "cbb4c0188d020b5fbde9a0c2c33b3677d21cc64c0f0297b7f6f3f6c0efabc40e";
165
171
  }, {
166
172
  readonly id: "process-containment-schema";
167
173
  readonly path: "spec/plugin/process-containment-v1.schema.json";
@@ -179,9 +185,9 @@ export declare const contractRegistry: {
179
185
  readonly sha256: "0aced01a8d409953d5075a799ac273cae79e285ac82debe93ac4d8b706571ad1";
180
186
  }, {
181
187
  readonly id: "release-metadata-schema";
182
- readonly path: "spec/plugin/release-metadata-v7.schema.json";
183
- readonly version: "release-metadata-v7";
184
- readonly sha256: "d9ceac9b8dd52288172bbe5d4dc2f158e2354ad4fe1f071617f6ba9309e21ebf";
188
+ readonly path: "spec/plugin/release-metadata-v8.schema.json";
189
+ readonly version: "release-metadata-v8";
190
+ readonly sha256: "f454fc1923be10fd5a4b46df4a6e376f7e9fe1d462f3da57977b92ad7c7496b0";
185
191
  }, {
186
192
  readonly id: "release-publisher-config-schema";
187
193
  readonly path: "spec/plugin/release-publisher-config-v1.schema.json";
@@ -311,45 +317,45 @@ export declare const contractRegistry: {
311
317
  };
312
318
  export declare const packageSet: {
313
319
  readonly schema_version: "redevplugin.platform_package_set.v1";
314
- readonly platform_version: "0.6.24";
320
+ readonly platform_version: "0.7.1";
315
321
  readonly go_module: {
316
322
  readonly module: "github.com/floegence/redevplugin";
317
- readonly version: "v0.6.24";
323
+ readonly version: "v0.7.1";
318
324
  };
319
325
  readonly npm_packages: readonly [{
320
326
  readonly name: "@floegence/redevplugin-contracts";
321
- readonly version: "0.6.24";
327
+ readonly version: "0.7.1";
322
328
  }, {
323
329
  readonly name: "@floegence/redevplugin-ui";
324
- readonly version: "0.6.24";
330
+ readonly version: "0.7.1";
325
331
  }];
326
332
  readonly rust_crates: readonly [{
327
333
  readonly name: "redevplugin-contracts";
328
- readonly version: "0.6.24";
334
+ readonly version: "0.7.1";
329
335
  readonly role: "contracts";
330
336
  }, {
331
337
  readonly name: "redevplugin-ipc";
332
- readonly version: "0.6.24";
338
+ readonly version: "0.7.1";
333
339
  readonly role: "ipc";
334
340
  }, {
335
341
  readonly name: "redevplugin-wasm-abi";
336
- readonly version: "0.6.24";
342
+ readonly version: "0.7.1";
337
343
  readonly role: "wasm_abi";
338
344
  }, {
339
345
  readonly name: "redevplugin-target-classifier";
340
- readonly version: "0.6.24";
346
+ readonly version: "0.7.1";
341
347
  readonly role: "target_classifier";
342
348
  }, {
343
349
  readonly name: "redevplugin-worker-sdk";
344
- readonly version: "0.6.24";
350
+ readonly version: "0.7.1";
345
351
  readonly role: "worker_sdk";
346
352
  }, {
347
353
  readonly name: "redevplugin-runtime";
348
- readonly version: "0.6.24";
354
+ readonly version: "0.7.1";
349
355
  readonly role: "runtime";
350
356
  }];
351
357
  readonly contract_registry_version: "contract-registry-v2";
352
- readonly contract_set_sha256: "22ff9be972e19ddbfb7b2e9bbb69861e6f5cc44ac02b490899f2d27cdf4f033f";
358
+ readonly contract_set_sha256: "ce37ac605cb6c618d8fb26f5e72a7c1346d0315d351f8700aadf6f7ae1708545";
353
359
  };
354
- export declare const contractSetSHA256: "22ff9be972e19ddbfb7b2e9bbb69861e6f5cc44ac02b490899f2d27cdf4f033f";
360
+ export declare const contractSetSHA256: "ce37ac605cb6c618d8fb26f5e72a7c1346d0315d351f8700aadf6f7ae1708545";
355
361
  export declare function getContract(id: ContractID): Contract;
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { generatedContractArtifacts, generatedContractRegistry, generatedContractSetSHA256, generatedPackageSet, generatedRegistryContract, } from "./contracts.gen.js";
2
2
  export * from "./release-signing.js";
3
+ export * from "./presentation.js";
3
4
  export class UnknownContractError extends RangeError {
4
5
  id;
5
6
  constructor(id) {
@@ -0,0 +1,42 @@
1
+ export type SettingOptionPresentation = Readonly<{
2
+ value: string;
3
+ label: string;
4
+ }>;
5
+ export type ResolvedSurfacePresentation = Readonly<{
6
+ surface_id: string;
7
+ label: string;
8
+ }>;
9
+ export type ResolvedSettingPresentation = Readonly<{
10
+ key: string;
11
+ label: string;
12
+ options: readonly SettingOptionPresentation[];
13
+ }>;
14
+ export type PresentationLocale = Readonly<{
15
+ locale: string;
16
+ plugin_name: string;
17
+ publisher_name?: string;
18
+ summary: string;
19
+ description: readonly string[];
20
+ highlights: readonly string[];
21
+ keywords: readonly string[];
22
+ surfaces: readonly ResolvedSurfacePresentation[];
23
+ settings: readonly ResolvedSettingPresentation[];
24
+ }>;
25
+ export type PresentationCatalog = Readonly<{
26
+ default_locale: string;
27
+ locales: readonly PresentationLocale[];
28
+ }>;
29
+ export type ResolvedPresentation = Readonly<{
30
+ requested_locale?: string;
31
+ resolved_locale: string;
32
+ default_locale: string;
33
+ plugin_name: string;
34
+ publisher_name?: string;
35
+ summary: string;
36
+ description: readonly string[];
37
+ highlights: readonly string[];
38
+ keywords: readonly string[];
39
+ surfaces: readonly ResolvedSurfacePresentation[];
40
+ settings: readonly ResolvedSettingPresentation[];
41
+ }>;
42
+ export declare function resolvePresentation(catalog: PresentationCatalog, requestedLocale: string): ResolvedPresentation;
@@ -0,0 +1,57 @@
1
+ export function resolvePresentation(catalog, requestedLocale) {
2
+ const byLocale = new Map(catalog.locales.map((locale) => [locale.locale, locale]));
3
+ const requested = canonicalLocale(requestedLocale);
4
+ let resolved = byLocale.get(catalog.default_locale);
5
+ if (resolved === undefined)
6
+ throw new TypeError("presentation default locale is missing");
7
+ if (requested !== undefined) {
8
+ for (const candidate of localeLookupCandidates(requested)) {
9
+ const match = byLocale.get(candidate);
10
+ if (match !== undefined) {
11
+ resolved = match;
12
+ break;
13
+ }
14
+ }
15
+ }
16
+ return deepClonePresentation(resolved, catalog.default_locale, requested);
17
+ }
18
+ function canonicalLocale(value) {
19
+ if (value === "" || value.trim() !== value || value.includes("_"))
20
+ return undefined;
21
+ try {
22
+ const canonical = Intl.getCanonicalLocales(value)[0];
23
+ return canonical === "und" ? undefined : canonical;
24
+ }
25
+ catch {
26
+ return undefined;
27
+ }
28
+ }
29
+ function localeLookupCandidates(locale) {
30
+ const parts = locale.split("-");
31
+ const result = [];
32
+ while (parts.length > 0) {
33
+ result.push(parts.join("-"));
34
+ parts.pop();
35
+ if (parts.at(-1)?.length === 1)
36
+ parts.pop();
37
+ }
38
+ return result;
39
+ }
40
+ function deepClonePresentation(locale, defaultLocale, requestedLocale) {
41
+ return {
42
+ ...(requestedLocale === undefined ? {} : { requested_locale: requestedLocale }),
43
+ resolved_locale: locale.locale,
44
+ default_locale: defaultLocale,
45
+ plugin_name: locale.plugin_name,
46
+ ...(locale.publisher_name === undefined ? {} : { publisher_name: locale.publisher_name }),
47
+ summary: locale.summary,
48
+ description: [...locale.description],
49
+ highlights: [...locale.highlights],
50
+ keywords: [...locale.keywords],
51
+ surfaces: locale.surfaces.map((surface) => ({ ...surface })),
52
+ settings: locale.settings.map((setting) => ({
53
+ ...setting,
54
+ options: setting.options.map((option) => ({ ...option })),
55
+ })),
56
+ };
57
+ }
@@ -1,9 +1,7 @@
1
1
  export declare const rootDelegationSchemaVersion: "redevplugin.release_root_delegation.v1";
2
2
  export declare const packageSignatureSchemaVersion: "redevplugin.package_signature.v1";
3
- export declare const releaseMetadataSchemaVersionV5: "redevplugin.release_metadata.v5";
4
- export declare const releaseMetadataSchemaVersionV6: "redevplugin.release_metadata.v6";
5
- export declare const releaseMetadataSchemaVersionV7: "redevplugin.release_metadata.v7";
6
- export declare const releaseMetadataSchemaVersion: "redevplugin.release_metadata.v7";
3
+ export declare const releaseMetadataSchemaVersionV8: "redevplugin.release_metadata.v8";
4
+ export declare const releaseMetadataSchemaVersion: "redevplugin.release_metadata.v8";
7
5
  export declare const sourcePolicySchemaVersion: "redevplugin.release_source_policy.v2";
8
6
  export declare const sourcePolicyPointerSchemaVersion: "redevplugin.release_source_policy_pointer.v1";
9
7
  export declare const revocationSchemaVersion: "redevplugin.release_revocation.v2";
@@ -145,8 +143,8 @@ export type ReleaseEvidence = Readonly<{
145
143
  provenance_sha256?: string;
146
144
  generated_at?: string;
147
145
  }>;
148
- export type ReleaseMetadataV5 = Readonly<{
149
- schema_version: typeof releaseMetadataSchemaVersionV5 | typeof releaseMetadataSchemaVersionV6 | typeof releaseMetadataSchemaVersionV7;
146
+ export type ReleaseMetadataV8 = Readonly<{
147
+ schema_version: typeof releaseMetadataSchemaVersionV8;
150
148
  source_id: string;
151
149
  release_metadata_ref: string;
152
150
  publisher_id: string;
@@ -393,10 +391,10 @@ export declare function buildPackageSignature(input: PackageSigningInput, signat
393
391
  export declare function packageSigningPreimage(input: PackageSigningInput): Uint8Array;
394
392
  export declare function canonicalPackageSignature(context: PackageVerificationContext, document: PackageSignatureV1): Uint8Array;
395
393
  export declare function verifyPackageSignature(context: PackageVerificationContext, document: PackageSignatureV1, verifier: SignatureVerifier): Promise<void>;
396
- export declare function buildReleaseMetadata(document: ReleaseMetadataV5): ReleaseMetadataV5;
397
- export declare function releaseMetadataSigningPreimage(channel: string, document: ReleaseMetadataV5): Uint8Array;
398
- export declare function canonicalReleaseMetadata(document: ReleaseMetadataV5): Uint8Array;
399
- export declare function verifyReleaseMetadata(channel: string, document: ReleaseMetadataV5, signature: Uint8Array, verifier: SignatureVerifier): Promise<void>;
394
+ export declare function buildReleaseMetadata(document: ReleaseMetadataV8): ReleaseMetadataV8;
395
+ export declare function releaseMetadataSigningPreimage(channel: string, document: ReleaseMetadataV8): Uint8Array;
396
+ export declare function canonicalReleaseMetadata(document: ReleaseMetadataV8): Uint8Array;
397
+ export declare function verifyReleaseMetadata(channel: string, document: ReleaseMetadataV8, signature: Uint8Array, verifier: SignatureVerifier): Promise<void>;
400
398
  export declare function buildSourcePolicy(input: SourcePolicyInput, signature: Uint8Array): SourcePolicyV2;
401
399
  export declare function sourcePolicySigningPreimage(input: SourcePolicyInput): Uint8Array;
402
400
  export declare function canonicalSourcePolicy(document: SourcePolicyV2): Uint8Array;
@@ -415,7 +413,7 @@ export declare function canonicalRevocationPointer(document: RevocationPointerV1
415
413
  export declare function verifyRevocationPointer(document: RevocationPointerV1, verifier: SignatureVerifier): Promise<void>;
416
414
  export declare function decodeRootDelegation(raw: Uint8Array | string): RootDelegationV1;
417
415
  export declare function decodePackageSignature(raw: Uint8Array | string, context: PackageVerificationContext): PackageSignatureV1;
418
- export declare function decodeReleaseMetadata(raw: Uint8Array | string): ReleaseMetadataV5;
416
+ export declare function decodeReleaseMetadata(raw: Uint8Array | string): ReleaseMetadataV8;
419
417
  export declare function decodeSourcePolicy(raw: Uint8Array | string): SourcePolicyV2;
420
418
  export declare function decodeSourcePolicyPointer(raw: Uint8Array | string): SourcePolicyPointerV1;
421
419
  export declare function decodeRevocation(raw: Uint8Array | string): RevocationV2;
@@ -1,9 +1,7 @@
1
1
  export const rootDelegationSchemaVersion = "redevplugin.release_root_delegation.v1";
2
2
  export const packageSignatureSchemaVersion = "redevplugin.package_signature.v1";
3
- export const releaseMetadataSchemaVersionV5 = "redevplugin.release_metadata.v5";
4
- export const releaseMetadataSchemaVersionV6 = "redevplugin.release_metadata.v6";
5
- export const releaseMetadataSchemaVersionV7 = "redevplugin.release_metadata.v7";
6
- export const releaseMetadataSchemaVersion = releaseMetadataSchemaVersionV7;
3
+ export const releaseMetadataSchemaVersionV8 = "redevplugin.release_metadata.v8";
4
+ export const releaseMetadataSchemaVersion = releaseMetadataSchemaVersionV8;
7
5
  export const sourcePolicySchemaVersion = "redevplugin.release_source_policy.v2";
8
6
  export const sourcePolicyPointerSchemaVersion = "redevplugin.release_source_policy_pointer.v1";
9
7
  export const revocationSchemaVersion = "redevplugin.release_revocation.v2";
@@ -49,6 +47,7 @@ export class InvalidReleaseSignatureError extends Error {
49
47
  const textEncoder = new TextEncoder();
50
48
  const textDecoder = new TextDecoder("utf-8", { fatal: true });
51
49
  const maximumDocumentBytes = 1024 * 1024;
50
+ const maximumPatternValueCodeUnits = 4096;
52
51
  const signingPrefix = textEncoder.encode("REDEVPLUGIN-SIGNING-V1\0");
53
52
  const newIDPattern = /^[a-z][a-z0-9._-]{0,127}$/;
54
53
  const legacyIDPattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
@@ -59,7 +58,7 @@ const prefixedSHA256Pattern = /^sha256:[0-9a-f]{64}$/;
59
58
  const legacySHA256Pattern = /^(?:sha256:)?[0-9a-f]{64}$/;
60
59
  const artifactRefPattern = /^[A-Za-z0-9._/@+-]+$/;
61
60
  const hostnamePattern = /^[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/;
62
- const semverPattern = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-(?:(?:0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
61
+ const semverPattern = { test: isCanonicalSemver };
63
62
  const canonicalTimePattern = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$/;
64
63
  const publicKeyPattern = /^[A-Za-z0-9+/]{43}=$/;
65
64
  const signaturePattern = /^[A-Za-z0-9+/]{86}==$/;
@@ -85,7 +84,55 @@ function assertRecord(value) {
85
84
  invalidDocument();
86
85
  }
87
86
  function matchesPattern(pattern, value) {
88
- return typeof value === "string" && pattern.test(value);
87
+ if (typeof value !== "string" || value.length > maximumPatternValueCodeUnits)
88
+ return false;
89
+ return pattern.test(value);
90
+ }
91
+ function isCanonicalSemver(value) {
92
+ if (value.length < 5 || value.length > 255)
93
+ return false;
94
+ const plus = value.indexOf("+");
95
+ if (plus !== value.lastIndexOf("+") || plus === value.length - 1)
96
+ return false;
97
+ const withoutBuild = plus < 0 ? value : value.slice(0, plus);
98
+ if (plus >= 0 && !validSemverIdentifiers(value.slice(plus + 1), false))
99
+ return false;
100
+ const dash = withoutBuild.indexOf("-");
101
+ if (dash === withoutBuild.length - 1)
102
+ return false;
103
+ const core = dash < 0 ? withoutBuild : withoutBuild.slice(0, dash);
104
+ if (dash >= 0 && !validSemverIdentifiers(withoutBuild.slice(dash + 1), true))
105
+ return false;
106
+ const coreIdentifiers = core.split(".");
107
+ return coreIdentifiers.length === 3 && coreIdentifiers.every(validSemverNumericIdentifier);
108
+ }
109
+ function validSemverIdentifiers(value, rejectNumericLeadingZero) {
110
+ const identifiers = value.split(".");
111
+ return identifiers.every((identifier) => {
112
+ if (identifier.length === 0)
113
+ return false;
114
+ let numeric = true;
115
+ for (let index = 0; index < identifier.length; index += 1) {
116
+ const code = identifier.charCodeAt(index);
117
+ const digit = code >= 48 && code <= 57;
118
+ const upper = code >= 65 && code <= 90;
119
+ const lower = code >= 97 && code <= 122;
120
+ if (!digit && !upper && !lower && code !== 45)
121
+ return false;
122
+ numeric = numeric && digit;
123
+ }
124
+ return !rejectNumericLeadingZero || !numeric || identifier.length === 1 || identifier[0] !== "0";
125
+ });
126
+ }
127
+ function validSemverNumericIdentifier(value) {
128
+ if (value.length === 0 || (value.length > 1 && value[0] === "0"))
129
+ return false;
130
+ for (let index = 0; index < value.length; index += 1) {
131
+ const code = value.charCodeAt(index);
132
+ if (code < 48 || code > 57)
133
+ return false;
134
+ }
135
+ return true;
89
136
  }
90
137
  function exactKeys(value, keys) {
91
138
  const actual = Object.keys(value).sort(compareUTF8);
@@ -395,9 +442,7 @@ function validateReleaseMetadata(value) {
395
442
  }
396
443
  }
397
444
  function validReleaseMetadataUIProtocolPair(schemaVersion, uiProtocolVersion) {
398
- return (schemaVersion === releaseMetadataSchemaVersionV5 && uiProtocolVersion === "plugin-ui-v5") ||
399
- (schemaVersion === releaseMetadataSchemaVersionV6 && uiProtocolVersion === "plugin-ui-v6") ||
400
- (schemaVersion === releaseMetadataSchemaVersionV7 && uiProtocolVersion === "plugin-ui-v7");
445
+ return schemaVersion === releaseMetadataSchemaVersionV8 && uiProtocolVersion === "plugin-ui-v7";
401
446
  }
402
447
  function validateCapabilityContractRef(value) {
403
448
  if (![value.publisher_id, value.contract_id, value.signature_key_id].every((item) => matchesPattern(legacyIDPattern, item)) || !matchesPattern(semverPattern, value.contract_version))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/redevplugin-contracts",
3
- "version": "0.6.24",
3
+ "version": "0.7.1",
4
4
  "description": "Embedded ReDevPlugin machine contracts and canonical release-signing APIs",
5
5
  "license": "MIT",
6
6
  "type": "module",