@clowder-ai/plugin-contract 0.1.0-beta.9 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codegen/generate-contract.d.ts +6 -0
- package/dist/codegen/generate-contract.d.ts.map +1 -1
- package/dist/codegen/generate-contract.js +338 -44
- package/dist/codegen/generate-contract.js.map +1 -1
- package/dist/conformance/fixtures.d.ts +3 -1
- package/dist/conformance/fixtures.d.ts.map +1 -1
- package/dist/conformance/fixtures.js +2 -1
- package/dist/conformance/fixtures.js.map +1 -1
- package/dist/conformance/index.d.ts +3 -3
- package/dist/conformance/index.d.ts.map +1 -1
- package/dist/conformance/index.js +3 -3
- package/dist/conformance/index.js.map +1 -1
- package/dist/conformance/messaging-behavior-fixture.d.ts +12 -0
- package/dist/conformance/messaging-behavior-fixture.d.ts.map +1 -0
- package/dist/conformance/messaging-behavior-fixture.js +24 -0
- package/dist/conformance/messaging-behavior-fixture.js.map +1 -0
- package/dist/conformance/messaging-loopback-adapter.d.ts +0 -3
- package/dist/conformance/messaging-loopback-adapter.d.ts.map +1 -1
- package/dist/conformance/messaging-loopback-adapter.js +1 -77
- package/dist/conformance/messaging-loopback-adapter.js.map +1 -1
- package/dist/conformance/messaging-loopback-state.d.ts +0 -6
- package/dist/conformance/messaging-loopback-state.d.ts.map +1 -1
- package/dist/conformance/messaging-loopback-state.js +0 -20
- package/dist/conformance/messaging-loopback-state.js.map +1 -1
- package/dist/conformance/runner.d.ts.map +1 -1
- package/dist/conformance/runner.js +3 -1
- package/dist/conformance/runner.js.map +1 -1
- package/dist/docx-materialization.d.ts +8 -0
- package/dist/docx-materialization.d.ts.map +1 -0
- package/dist/docx-materialization.js +19 -0
- package/dist/docx-materialization.js.map +1 -0
- package/dist/generated/contract.generated.d.ts +1637 -87
- package/dist/generated/contract.generated.d.ts.map +1 -1
- package/dist/generated/contract.generated.js +70 -9
- package/dist/generated/contract.generated.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +1 -1
- package/dist/validation/catalog.d.ts +21 -0
- package/dist/validation/catalog.d.ts.map +1 -0
- package/dist/validation/catalog.js +140 -0
- package/dist/validation/catalog.js.map +1 -0
- package/dist/validation/cloud-conversation-host.d.ts +18 -0
- package/dist/validation/cloud-conversation-host.d.ts.map +1 -0
- package/dist/validation/cloud-conversation-host.js +83 -0
- package/dist/validation/cloud-conversation-host.js.map +1 -0
- package/dist/validation/companion-bridge.d.ts +6 -0
- package/dist/validation/companion-bridge.d.ts.map +1 -0
- package/dist/validation/companion-bridge.js +198 -0
- package/dist/validation/companion-bridge.js.map +1 -0
- package/dist/validation/docx-materialization.d.ts +6 -0
- package/dist/validation/docx-materialization.d.ts.map +1 -0
- package/dist/validation/docx-materialization.js +36 -0
- package/dist/validation/docx-materialization.js.map +1 -0
- package/dist/validation/index.d.ts +9 -1
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +9 -1
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/manifest.d.ts.map +1 -1
- package/dist/validation/manifest.js +317 -0
- package/dist/validation/manifest.js.map +1 -1
- package/dist/validation/members.d.ts +4 -0
- package/dist/validation/members.d.ts.map +1 -0
- package/dist/validation/members.js +11 -0
- package/dist/validation/members.js.map +1 -0
- package/dist/validation/messaging-semantic.d.ts.map +1 -1
- package/dist/validation/messaging-semantic.js +98 -0
- package/dist/validation/messaging-semantic.js.map +1 -1
- package/dist/validation/messaging-wire.d.ts +42 -0
- package/dist/validation/messaging-wire.d.ts.map +1 -0
- package/dist/validation/messaging-wire.js +184 -0
- package/dist/validation/messaging-wire.js.map +1 -0
- package/dist/validation/operation-rows.d.ts +25 -0
- package/dist/validation/operation-rows.d.ts.map +1 -0
- package/dist/validation/operation-rows.js +135 -0
- package/dist/validation/operation-rows.js.map +1 -0
- package/dist/validation/signals.d.ts +1 -10
- package/dist/validation/signals.d.ts.map +1 -1
- package/dist/validation/signals.js +0 -174
- package/dist/validation/signals.js.map +1 -1
- package/dist/variant.d.ts +114 -0
- package/dist/variant.d.ts.map +1 -0
- package/dist/variant.js +305 -0
- package/dist/variant.js.map +1 -0
- package/dist/wire/constants.d.ts +2 -1
- package/dist/wire/constants.d.ts.map +1 -1
- package/dist/wire/constants.js +2 -1
- package/dist/wire/constants.js.map +1 -1
- package/dist/wire/dispatch.d.ts +49 -0
- package/dist/wire/dispatch.d.ts.map +1 -0
- package/dist/wire/dispatch.js +870 -0
- package/dist/wire/dispatch.js.map +1 -0
- package/dist/wire/disposition-fixtures.d.ts +10 -2
- package/dist/wire/disposition-fixtures.d.ts.map +1 -1
- package/dist/wire/disposition-fixtures.js +539 -108
- package/dist/wire/disposition-fixtures.js.map +1 -1
- package/dist/wire/disposition.d.ts +3 -4
- package/dist/wire/disposition.d.ts.map +1 -1
- package/dist/wire/disposition.js +5 -16
- package/dist/wire/disposition.js.map +1 -1
- package/dist/wire/envelope.d.ts +31 -1
- package/dist/wire/envelope.d.ts.map +1 -1
- package/dist/wire/envelope.js +48 -1
- package/dist/wire/envelope.js.map +1 -1
- package/dist/wire/errors.d.ts +31 -1
- package/dist/wire/errors.d.ts.map +1 -1
- package/dist/wire/errors.js +36 -0
- package/dist/wire/errors.js.map +1 -1
- package/dist/wire/handshake-byte-bounds.d.ts.map +1 -1
- package/dist/wire/handshake-byte-bounds.js +1 -4
- package/dist/wire/handshake-byte-bounds.js.map +1 -1
- package/dist/wire/handshake.d.ts +12 -11
- package/dist/wire/handshake.d.ts.map +1 -1
- package/dist/wire/handshake.js +11 -15
- package/dist/wire/handshake.js.map +1 -1
- package/dist/wire/index.d.ts +15 -13
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +30 -9
- package/dist/wire/index.js.map +1 -1
- package/dist/wire/lifecycle-byte-bounds.d.ts +40 -0
- package/dist/wire/lifecycle-byte-bounds.d.ts.map +1 -0
- package/dist/wire/lifecycle-byte-bounds.js +148 -0
- package/dist/wire/lifecycle-byte-bounds.js.map +1 -0
- package/dist/wire/messaging-byte-bounds.d.ts +62 -0
- package/dist/wire/messaging-byte-bounds.d.ts.map +1 -0
- package/dist/wire/messaging-byte-bounds.js +581 -0
- package/dist/wire/messaging-byte-bounds.js.map +1 -0
- package/dist/wire/registry.d.ts +58 -107
- package/dist/wire/registry.d.ts.map +1 -1
- package/dist/wire/registry.js +45 -107
- package/dist/wire/registry.js.map +1 -1
- package/dist/wire/row-shapes.d.ts +82 -81
- package/dist/wire/row-shapes.d.ts.map +1 -1
- package/dist/wire/row-shapes.js +30 -3
- package/dist/wire/row-shapes.js.map +1 -1
- package/fixtures/behavior/messaging/adversarial-invariants.json +62 -183
- package/fixtures/manifest/invalid/contract-version-leading-zero-prerelease.json +1 -3
- package/fixtures/manifest/invalid/contract-version-range.json +1 -3
- package/fixtures/manifest/invalid/duplicate-signal-type.json +4 -4
- package/fixtures/manifest/invalid/icon-package-escape.json +20 -0
- package/fixtures/manifest/invalid/ipc-empty-entrypoint.json +1 -3
- package/fixtures/manifest/invalid/plugin-version-leading-zero-prerelease.json +1 -3
- package/fixtures/manifest/invalid/plugin-version-not-semver.json +1 -3
- package/fixtures/manifest/invalid/semver-empty-build-metadata.json +1 -3
- package/fixtures/manifest/invalid/stdio-missing-entrypoint.json +1 -3
- package/fixtures/manifest/invalid/user-authored-lifecycle.json +1 -3
- package/fixtures/manifest/valid/localized-product-metadata.json +25 -0
- package/fixtures/manifest/valid/minimal-builtin.json +1 -3
- package/fixtures/manifest/valid/protocol-intrinsic-lifecycle.json +1 -3
- package/fixtures/manifest/valid/semver-build-metadata.json +1 -3
- package/fixtures/manifest/valid/stdio-entrypoint.json +1 -3
- package/fixtures/messaging/valid/subscription-delivery.json +1 -1
- package/package.json +17 -4
- package/src/schemas/behavior-fixture.schema.json +800 -152
- package/src/schemas/catalog.schema.json +91 -0
- package/src/schemas/companion-bridge.schema.json +2256 -0
- package/src/schemas/docx-materialization.schema.json +302 -0
- package/src/schemas/manifest.schema.json +2196 -107
- package/src/schemas/messaging.schema.json +692 -41
- package/src/schemas/plugin-metadata.schema.json +62 -0
- package/src/schemas/signal.schema.json +68 -78
- package/dist/types/capability.d.ts +0 -4
- package/dist/types/capability.d.ts.map +0 -1
- package/dist/types/capability.js +0 -11
- package/dist/types/capability.js.map +0 -1
- package/dist/wire/grants.d.ts +0 -57
- package/dist/wire/grants.d.ts.map +0 -1
- package/dist/wire/grants.js +0 -59
- package/dist/wire/grants.js.map +0 -1
- package/dist/wire/signal-byte-bounds.d.ts +0 -97
- package/dist/wire/signal-byte-bounds.d.ts.map +0 -1
- package/dist/wire/signal-byte-bounds.js +0 -229
- package/dist/wire/signal-byte-bounds.js.map +0 -1
- package/fixtures/manifest/invalid/unknown-capability.json +0 -19
- package/fixtures/signals/invalid/destination-injection.json +0 -15
- package/fixtures/signals/invalid/non-utc-occurred-at.json +0 -12
- package/fixtures/signals/valid/feishu-meeting-artifact.json +0 -18
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { AppendInput, AppendResult, DeliverInput, DeliverResult, MediaReadInput, MediaReadResult, ReadInput, ReadResult, SendInput, SendResult, MessagingAckRequest, MessagingAckResult, SnapshotInput, SnapshotResult, SubscribeInput, SubscribeResult } from '../wire/row-shapes.js';
|
|
2
|
+
export interface MessagingRowValidationError {
|
|
3
|
+
readonly instancePath: string;
|
|
4
|
+
readonly schemaPath: string;
|
|
5
|
+
readonly keyword: string;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
}
|
|
8
|
+
export type MessagingRowValidationResult<Value> = {
|
|
9
|
+
readonly valid: true;
|
|
10
|
+
readonly value: Value;
|
|
11
|
+
readonly errors: readonly [];
|
|
12
|
+
} | {
|
|
13
|
+
readonly valid: false;
|
|
14
|
+
readonly errors: readonly MessagingRowValidationError[];
|
|
15
|
+
};
|
|
16
|
+
export declare const MESSAGING_ROW_METHODS: readonly ["messaging.send", "messaging.appendElements", "messaging.subscribe", "messaging.read", "messaging.ack", "messaging.snapshot", "streams.read", "host.messaging.deliver"];
|
|
17
|
+
export type MessagingRowMethod = (typeof MESSAGING_ROW_METHODS)[number];
|
|
18
|
+
export interface MessagingRowInputByMethod {
|
|
19
|
+
readonly 'messaging.send': SendInput;
|
|
20
|
+
readonly 'messaging.appendElements': AppendInput;
|
|
21
|
+
readonly 'messaging.subscribe': SubscribeInput;
|
|
22
|
+
readonly 'messaging.read': ReadInput;
|
|
23
|
+
readonly 'messaging.ack': MessagingAckRequest;
|
|
24
|
+
readonly 'messaging.snapshot': SnapshotInput;
|
|
25
|
+
readonly 'streams.read': MediaReadInput;
|
|
26
|
+
readonly 'host.messaging.deliver': DeliverInput;
|
|
27
|
+
}
|
|
28
|
+
export interface MessagingRowResultByMethod {
|
|
29
|
+
readonly 'messaging.send': SendResult;
|
|
30
|
+
readonly 'messaging.appendElements': AppendResult;
|
|
31
|
+
readonly 'messaging.subscribe': SubscribeResult;
|
|
32
|
+
readonly 'messaging.read': ReadResult;
|
|
33
|
+
readonly 'messaging.ack': MessagingAckResult;
|
|
34
|
+
readonly 'messaging.snapshot': SnapshotResult;
|
|
35
|
+
readonly 'streams.read': MediaReadResult;
|
|
36
|
+
readonly 'host.messaging.deliver': DeliverResult;
|
|
37
|
+
}
|
|
38
|
+
export declare function validateMessagingRowInput<Method extends MessagingRowMethod>(method: Method, value: unknown): MessagingRowValidationResult<MessagingRowInputByMethod[Method]>;
|
|
39
|
+
export declare function validateMessagingRowResult<Method extends MessagingRowMethod>(method: Method, value: unknown): MessagingRowValidationResult<MessagingRowResultByMethod[Method]>;
|
|
40
|
+
export declare function isPluginDeliveryInput(value: unknown): value is import('../generated/contract.generated.js').PluginDeliveryInput;
|
|
41
|
+
export declare function isPluginDeliveryReceipt(value: unknown): value is import('../generated/contract.generated.js').PluginDeliveryReceipt;
|
|
42
|
+
//# sourceMappingURL=messaging-wire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging-wire.d.ts","sourceRoot":"","sources":["../../src/validation/messaging-wire.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,SAAS,EACT,UAAU,EACV,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EAChB,MAAM,uBAAuB,CAAC;AA+B/B,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,4BAA4B,CAAC,KAAK,IAC1C;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,2BAA2B,EAAE,CAAA;CAAE,CAAC;AAEvF,eAAO,MAAM,qBAAqB,mLASxB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC;IACrC,QAAQ,CAAC,0BAA0B,EAAE,WAAW,CAAC;IACjD,QAAQ,CAAC,qBAAqB,EAAE,cAAc,CAAC;IAC/C,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,mBAAmB,CAAC;IAC9C,QAAQ,CAAC,oBAAoB,EAAE,aAAa,CAAC;IAC7C,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,wBAAwB,EAAE,YAAY,CAAC;CACjD;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,gBAAgB,EAAE,UAAU,CAAC;IACtC,QAAQ,CAAC,0BAA0B,EAAE,YAAY,CAAC;IAClD,QAAQ,CAAC,qBAAqB,EAAE,eAAe,CAAC;IAChD,QAAQ,CAAC,gBAAgB,EAAE,UAAU,CAAC;IACtC,QAAQ,CAAC,eAAe,EAAE,kBAAkB,CAAC;IAC7C,QAAQ,CAAC,oBAAoB,EAAE,cAAc,CAAC;IAC9C,QAAQ,CAAC,cAAc,EAAE,eAAe,CAAC;IACzC,QAAQ,CAAC,wBAAwB,EAAE,aAAa,CAAC;CAClD;AAwKD,wBAAgB,yBAAyB,CAAC,MAAM,SAAS,kBAAkB,EACzE,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GACb,4BAA4B,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAEjE;AAED,wBAAgB,0BAA0B,CAAC,MAAM,SAAS,kBAAkB,EAC1E,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GACb,4BAA4B,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAiBlE;AAID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,oCAAoC,EAAE,mBAAmB,CAI/H;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,oCAAoC,EAAE,qBAAqB,CAEnI"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { validateMessagingSemantics } from './messaging-semantic.js';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
const Ajv2020 = require('ajv/dist/2020');
|
|
5
|
+
const addFormats = require('ajv-formats');
|
|
6
|
+
const messagingSchema = require('@clowder-ai/plugin-contract/schemas/messaging');
|
|
7
|
+
export const MESSAGING_ROW_METHODS = [
|
|
8
|
+
'messaging.send',
|
|
9
|
+
'messaging.appendElements',
|
|
10
|
+
'messaging.subscribe',
|
|
11
|
+
'messaging.read',
|
|
12
|
+
'messaging.ack',
|
|
13
|
+
'messaging.snapshot',
|
|
14
|
+
'streams.read',
|
|
15
|
+
'host.messaging.deliver',
|
|
16
|
+
];
|
|
17
|
+
const ajv = new Ajv2020({ allErrors: true, strict: false });
|
|
18
|
+
addFormats(ajv);
|
|
19
|
+
ajv.addSchema(messagingSchema, messagingSchema['$id']);
|
|
20
|
+
function validator(definition) {
|
|
21
|
+
const validate = ajv.getSchema(`${String(messagingSchema['$id'])}#/$defs/${definition}`);
|
|
22
|
+
if (!validate)
|
|
23
|
+
throw new Error(`missing messaging schema definition: ${definition}`);
|
|
24
|
+
return { definition, validate };
|
|
25
|
+
}
|
|
26
|
+
const INPUT_VALIDATORS = {
|
|
27
|
+
'messaging.send': validator('MessageDraft'),
|
|
28
|
+
'messaging.appendElements': validator('AppendElementsRequest'),
|
|
29
|
+
'messaging.subscribe': validator('M0CSubscribeInput'),
|
|
30
|
+
'messaging.read': validator('M0CReadInput'),
|
|
31
|
+
'messaging.ack': validator('M0CAckInput'),
|
|
32
|
+
'messaging.snapshot': validator('M0CSnapshotInput'),
|
|
33
|
+
'streams.read': validator('MediaReadInput'),
|
|
34
|
+
'host.messaging.deliver': validator('PluginDeliveryInput'),
|
|
35
|
+
};
|
|
36
|
+
const RESULT_VALIDATORS = {
|
|
37
|
+
'messaging.send': validator('SendReceipt'),
|
|
38
|
+
'messaging.appendElements': validator('AppendReceipt'),
|
|
39
|
+
'messaging.subscribe': validator('M0CSubscribeResult'),
|
|
40
|
+
'messaging.read': validator('M0CReadResult'),
|
|
41
|
+
'messaging.ack': validator('M0CAckResult'),
|
|
42
|
+
'messaging.snapshot': validator('M0CSnapshotResult'),
|
|
43
|
+
'streams.read': validator('MediaReadResult'),
|
|
44
|
+
'host.messaging.deliver': validator('PluginDeliveryReceipt'),
|
|
45
|
+
};
|
|
46
|
+
function hasOnlyUnicodeScalars(value) {
|
|
47
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
48
|
+
const unit = value.charCodeAt(index);
|
|
49
|
+
if (unit >= 0xd800 && unit <= 0xdbff) {
|
|
50
|
+
const next = value.charCodeAt(index + 1);
|
|
51
|
+
if (!(next >= 0xdc00 && next <= 0xdfff))
|
|
52
|
+
return false;
|
|
53
|
+
index += 1;
|
|
54
|
+
}
|
|
55
|
+
else if (unit >= 0xdc00 && unit <= 0xdfff) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
function isJsonScalarTree(value, ancestors = new Set()) {
|
|
62
|
+
if (value === null || typeof value === 'boolean')
|
|
63
|
+
return true;
|
|
64
|
+
if (typeof value === 'string')
|
|
65
|
+
return hasOnlyUnicodeScalars(value);
|
|
66
|
+
if (typeof value === 'number')
|
|
67
|
+
return Number.isFinite(value);
|
|
68
|
+
if (typeof value !== 'object')
|
|
69
|
+
return false;
|
|
70
|
+
if (ancestors.has(value))
|
|
71
|
+
return false;
|
|
72
|
+
const prototype = Object.getPrototypeOf(value);
|
|
73
|
+
if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (Object.getOwnPropertySymbols(value).length > 0)
|
|
77
|
+
return false;
|
|
78
|
+
ancestors.add(value);
|
|
79
|
+
let valid = true;
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
82
|
+
if (!Object.hasOwn(value, index) || !isJsonScalarTree(value[index], ancestors)) {
|
|
83
|
+
valid = false;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (valid) {
|
|
88
|
+
valid = Object.keys(value).every((key) => /^(0|[1-9][0-9]*)$/.test(key));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
for (const [key, child] of Object.entries(value)) {
|
|
93
|
+
if (!hasOnlyUnicodeScalars(key) || !isJsonScalarTree(child, ancestors)) {
|
|
94
|
+
valid = false;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
ancestors.delete(value);
|
|
100
|
+
return valid;
|
|
101
|
+
}
|
|
102
|
+
function errorsOf(validate) {
|
|
103
|
+
return (validate.errors ?? []).map((error) => ({
|
|
104
|
+
instancePath: error.instancePath,
|
|
105
|
+
schemaPath: error.schemaPath,
|
|
106
|
+
keyword: error.keyword,
|
|
107
|
+
message: error.message ?? 'messaging row validation failed',
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
function invalid(instancePath, schemaPath, keyword, message) {
|
|
111
|
+
return {
|
|
112
|
+
valid: false,
|
|
113
|
+
errors: [{ instancePath, schemaPath, keyword, message }],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function validateWith(entry, value) {
|
|
117
|
+
let jsonSafe = false;
|
|
118
|
+
try {
|
|
119
|
+
jsonSafe = isJsonScalarTree(value);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
jsonSafe = false;
|
|
123
|
+
}
|
|
124
|
+
if (!jsonSafe) {
|
|
125
|
+
return invalid('', `#/$defs/${entry.definition}`, 'jsonScalarTree', 'value must contain only finite JSON values and Unicode scalar strings without cycles');
|
|
126
|
+
}
|
|
127
|
+
let structurallyValid = false;
|
|
128
|
+
try {
|
|
129
|
+
structurallyValid = entry.validate(value);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
structurallyValid = false;
|
|
133
|
+
}
|
|
134
|
+
if (!structurallyValid) {
|
|
135
|
+
const errors = errorsOf(entry.validate);
|
|
136
|
+
return errors.length > 0
|
|
137
|
+
? { valid: false, errors }
|
|
138
|
+
: invalid('', `#/$defs/${entry.definition}`, 'schema', 'schema validation failed');
|
|
139
|
+
}
|
|
140
|
+
if (entry.definition === 'PluginDeliveryInput') {
|
|
141
|
+
const delivery = value;
|
|
142
|
+
if (delivery.kind === 'message' && delivery.threadId !== delivery.envelope.threadId) {
|
|
143
|
+
return invalid('/threadId', '#/$defs/PluginDeliveryInput', 'threadIdentity', 'delivery thread must match the envelope');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const semantic = validateMessagingSemantics(entry.definition, value);
|
|
147
|
+
if (!semantic.valid) {
|
|
148
|
+
return {
|
|
149
|
+
valid: false,
|
|
150
|
+
errors: semantic.errors.map((error) => ({
|
|
151
|
+
instancePath: error.path,
|
|
152
|
+
schemaPath: `#/$defs/${entry.definition}`,
|
|
153
|
+
keyword: 'maxEncodedBytes',
|
|
154
|
+
message: error.message,
|
|
155
|
+
})),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return { valid: true, value: value, errors: [] };
|
|
159
|
+
}
|
|
160
|
+
export function validateMessagingRowInput(method, value) {
|
|
161
|
+
return validateWith(INPUT_VALIDATORS[method], value);
|
|
162
|
+
}
|
|
163
|
+
export function validateMessagingRowResult(method, value) {
|
|
164
|
+
const structural = validateWith(RESULT_VALIDATORS[method], value);
|
|
165
|
+
if (!structural.valid || method !== 'messaging.send')
|
|
166
|
+
return structural;
|
|
167
|
+
const receipt = structural.value;
|
|
168
|
+
if (receipt.messageHandle.token === receipt.messageId) {
|
|
169
|
+
return invalid('/messageHandle/token', '#/$defs/SendReceipt', 'messageHandleIdentity', 'messageHandle.token must not equal messageId');
|
|
170
|
+
}
|
|
171
|
+
return structural;
|
|
172
|
+
}
|
|
173
|
+
const PLUGIN_DELIVERY = validator('PluginDeliveryInput');
|
|
174
|
+
const PLUGIN_RECEIPT = validator('PluginDeliveryReceipt');
|
|
175
|
+
export function isPluginDeliveryInput(value) {
|
|
176
|
+
if (!validateWith(PLUGIN_DELIVERY, value).valid)
|
|
177
|
+
return false;
|
|
178
|
+
const input = value;
|
|
179
|
+
return input.kind !== 'message' || input.envelope.threadId === input.threadId;
|
|
180
|
+
}
|
|
181
|
+
export function isPluginDeliveryReceipt(value) {
|
|
182
|
+
return PLUGIN_RECEIPT.validate(value);
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=messaging-wire.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging-wire.js","sourceRoot":"","sources":["../../src/validation/messaging-wire.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ActionDef, OperationRows } from '../generated/contract.generated.js';
|
|
2
|
+
export interface OperationRowsValidationError {
|
|
3
|
+
readonly instancePath: string;
|
|
4
|
+
readonly schemaPath: string;
|
|
5
|
+
readonly keyword: string;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
}
|
|
8
|
+
export type OperationRowsValidationResult = {
|
|
9
|
+
readonly valid: true;
|
|
10
|
+
readonly value: OperationRows;
|
|
11
|
+
readonly errors: readonly [];
|
|
12
|
+
} | {
|
|
13
|
+
readonly valid: false;
|
|
14
|
+
readonly errors: readonly OperationRowsValidationError[];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Validates an `OperationActionResult` with `render: 'rows'` against the manifest's
|
|
18
|
+
* row declarations of the same operation. Host fail-closed: an undeclared or
|
|
19
|
+
* non-row action reference, a duplicate row key, or any schema violation makes the
|
|
20
|
+
* whole result invalid.
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateOperationRowsResult(operation: {
|
|
23
|
+
readonly actions: readonly ActionDef[];
|
|
24
|
+
}, value: unknown): OperationRowsValidationResult;
|
|
25
|
+
//# sourceMappingURL=operation-rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-rows.d.ts","sourceRoot":"","sources":["../../src/validation/operation-rows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAgCnF,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,6BAA6B,GACrC;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,GACrF;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,4BAA4B,EAAE,CAAA;CAAE,CAAC;AA6ExF;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,EACrD,KAAK,EAAE,OAAO,GACb,6BAA6B,CAmE/B"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
const Ajv2020 = require('ajv/dist/2020');
|
|
4
|
+
const addFormats = require('ajv-formats');
|
|
5
|
+
const manifestSchema = require('@clowder-ai/plugin-contract/schemas/manifest');
|
|
6
|
+
const messagingSchema = require('@clowder-ai/plugin-contract/schemas/messaging');
|
|
7
|
+
const pluginMetadataSchema = require('@clowder-ai/plugin-contract/schemas/plugin-metadata');
|
|
8
|
+
const signalSchema = require('@clowder-ai/plugin-contract/schemas/signals');
|
|
9
|
+
const ajv = new Ajv2020({ allErrors: true, strict: false });
|
|
10
|
+
addFormats(ajv);
|
|
11
|
+
const schemaId = manifestSchema['$id'];
|
|
12
|
+
ajv.addSchema(pluginMetadataSchema, pluginMetadataSchema['$id']);
|
|
13
|
+
ajv.addSchema(signalSchema, signalSchema['$id']);
|
|
14
|
+
ajv.addSchema(messagingSchema, messagingSchema['$id']);
|
|
15
|
+
ajv.addSchema(manifestSchema, schemaId);
|
|
16
|
+
const validateRowsShape = ajv.compile({
|
|
17
|
+
$ref: `${schemaId}#/$defs/OperationRows`,
|
|
18
|
+
});
|
|
19
|
+
function hasOnlyUnicodeScalars(value) {
|
|
20
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
21
|
+
const unit = value.charCodeAt(index);
|
|
22
|
+
if (unit >= 0xd800 && unit <= 0xdbff) {
|
|
23
|
+
const next = value.charCodeAt(index + 1);
|
|
24
|
+
if (!(next >= 0xdc00 && next <= 0xdfff))
|
|
25
|
+
return false;
|
|
26
|
+
index += 1;
|
|
27
|
+
}
|
|
28
|
+
else if (unit >= 0xdc00 && unit <= 0xdfff) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
function isJsonScalarTree(value, ancestors = new Set()) {
|
|
35
|
+
if (value === null || typeof value === 'boolean')
|
|
36
|
+
return true;
|
|
37
|
+
if (typeof value === 'string')
|
|
38
|
+
return hasOnlyUnicodeScalars(value);
|
|
39
|
+
if (typeof value === 'number')
|
|
40
|
+
return Number.isFinite(value);
|
|
41
|
+
if (typeof value !== 'object')
|
|
42
|
+
return false;
|
|
43
|
+
if (ancestors.has(value))
|
|
44
|
+
return false;
|
|
45
|
+
const prototype = Object.getPrototypeOf(value);
|
|
46
|
+
if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (Object.getOwnPropertySymbols(value).length > 0)
|
|
50
|
+
return false;
|
|
51
|
+
ancestors.add(value);
|
|
52
|
+
let valid = true;
|
|
53
|
+
if (Array.isArray(value)) {
|
|
54
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
55
|
+
if (!Object.hasOwn(value, index) || !isJsonScalarTree(value[index], ancestors)) {
|
|
56
|
+
valid = false;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (valid) {
|
|
61
|
+
valid = Object.keys(value).every((key) => /^(0|[1-9][0-9]*)$/.test(key));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
for (const [key, child] of Object.entries(value)) {
|
|
66
|
+
if (!hasOnlyUnicodeScalars(key) || !isJsonScalarTree(child, ancestors)) {
|
|
67
|
+
valid = false;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
ancestors.delete(value);
|
|
73
|
+
return valid;
|
|
74
|
+
}
|
|
75
|
+
function invalid(instancePath, schemaPath, keyword, message) {
|
|
76
|
+
return {
|
|
77
|
+
valid: false,
|
|
78
|
+
errors: [{ instancePath, schemaPath, keyword, message }],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Validates an `OperationActionResult` with `render: 'rows'` against the manifest's
|
|
83
|
+
* row declarations of the same operation. Host fail-closed: an undeclared or
|
|
84
|
+
* non-row action reference, a duplicate row key, or any schema violation makes the
|
|
85
|
+
* whole result invalid.
|
|
86
|
+
*/
|
|
87
|
+
export function validateOperationRowsResult(operation, value) {
|
|
88
|
+
let jsonSafe = false;
|
|
89
|
+
try {
|
|
90
|
+
jsonSafe = isJsonScalarTree(value);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
jsonSafe = false;
|
|
94
|
+
}
|
|
95
|
+
if (!jsonSafe) {
|
|
96
|
+
return invalid('', '#/$defs/OperationRows', 'jsonScalarTree', 'value must contain only finite JSON values and Unicode scalar strings without cycles');
|
|
97
|
+
}
|
|
98
|
+
let structurallyValid = false;
|
|
99
|
+
try {
|
|
100
|
+
structurallyValid = validateRowsShape(value);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
structurallyValid = false;
|
|
104
|
+
}
|
|
105
|
+
if (!structurallyValid) {
|
|
106
|
+
const errors = (validateRowsShape.errors ?? []).map((error) => ({
|
|
107
|
+
instancePath: error.instancePath,
|
|
108
|
+
schemaPath: error.schemaPath,
|
|
109
|
+
keyword: error.keyword,
|
|
110
|
+
message: error.message ?? 'operation rows validation failed',
|
|
111
|
+
}));
|
|
112
|
+
return errors.length > 0
|
|
113
|
+
? { valid: false, errors }
|
|
114
|
+
: invalid('', '#/$defs/OperationRows', 'schema', 'schema validation failed');
|
|
115
|
+
}
|
|
116
|
+
const rows = value;
|
|
117
|
+
const rowActionIds = new Set(operation.actions.filter((action) => action.render === 'row').map((action) => action.id));
|
|
118
|
+
const seenKeys = new Set();
|
|
119
|
+
for (let rowIndex = 0; rowIndex < rows.rows.length; rowIndex += 1) {
|
|
120
|
+
const row = rows.rows[rowIndex];
|
|
121
|
+
if (seenKeys.has(row.key)) {
|
|
122
|
+
return invalid(`/rows/${rowIndex}/key`, '#/$defs/OperationRow', 'uniqueKeys', `row key must be unique within the result: ${row.key}`);
|
|
123
|
+
}
|
|
124
|
+
seenKeys.add(row.key);
|
|
125
|
+
const actions = row.actions ?? [];
|
|
126
|
+
for (let actionIndex = 0; actionIndex < actions.length; actionIndex += 1) {
|
|
127
|
+
const reference = actions[actionIndex].action;
|
|
128
|
+
if (!rowActionIds.has(reference)) {
|
|
129
|
+
return invalid(`/rows/${rowIndex}/actions/${actionIndex}/action`, '#/$defs/OperationRowAction', 'rowActionReference', `row action must reference an ActionDef with render 'row' declared in the same operation: ${reference}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return { valid: true, value: rows, errors: [] };
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=operation-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-rows.js","sourceRoot":"","sources":["../../src/validation/operation-rows.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SignalDeclaration } from '../generated/contract.generated.js';
|
|
2
2
|
export interface SignalValidationError {
|
|
3
3
|
readonly instancePath: string;
|
|
4
4
|
readonly schemaPath: string;
|
|
@@ -13,14 +13,5 @@ export type SignalValidationResult<Value> = {
|
|
|
13
13
|
readonly valid: false;
|
|
14
14
|
readonly errors: readonly SignalValidationError[];
|
|
15
15
|
};
|
|
16
|
-
export declare const SIGNAL_PAYLOAD_MAX_ENCODED_BYTES: 65536;
|
|
17
|
-
export type SignalSchemaCatalog = Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
18
16
|
export declare function validateSignalDeclaration(value: unknown): SignalValidationResult<SignalDeclaration>;
|
|
19
|
-
export declare function validateEventsPublishInput(value: unknown): SignalValidationResult<EventsPublishInput>;
|
|
20
|
-
/**
|
|
21
|
-
* Cross-document admission: a structurally legal publish is still forbidden
|
|
22
|
-
* unless its signalType appears in this plugin manifest's declared provides.
|
|
23
|
-
*/
|
|
24
|
-
export declare function validateDeclaredEventsPublishInput(declarations: readonly unknown[], signalSchemas: SignalSchemaCatalog, value: unknown): SignalValidationResult<EventsPublishInput>;
|
|
25
|
-
export declare function validateEventsPublishResult(value: unknown): SignalValidationResult<EventsPublishResult>;
|
|
26
17
|
//# sourceMappingURL=signals.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/validation/signals.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/validation/signals.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EAClB,MAAM,oCAAoC,CAAC;AA+B5C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,sBAAsB,CAAC,KAAK,IACpC;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAAE,CAAC;AAiCjF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,sBAAsB,CAAC,iBAAiB,CAAC,CAE3C"}
|
|
@@ -3,7 +3,6 @@ const require = createRequire(import.meta.url);
|
|
|
3
3
|
const Ajv2020 = require('ajv/dist/2020');
|
|
4
4
|
const addFormats = require('ajv-formats');
|
|
5
5
|
const signalSchema = require('@clowder-ai/plugin-contract/schemas/signals');
|
|
6
|
-
export const SIGNAL_PAYLOAD_MAX_ENCODED_BYTES = 65_536;
|
|
7
6
|
const ajv = new Ajv2020({ allErrors: true, strict: false });
|
|
8
7
|
addFormats(ajv);
|
|
9
8
|
ajv.addSchema(signalSchema, signalSchema['$id']);
|
|
@@ -14,9 +13,6 @@ function validator(definition) {
|
|
|
14
13
|
return validate;
|
|
15
14
|
}
|
|
16
15
|
const validateDeclarationSchema = validator('SignalDeclaration');
|
|
17
|
-
const validatePublishInputSchema = validator('EventsPublishInput');
|
|
18
|
-
const validatePublishResultSchema = validator('EventsPublishResult');
|
|
19
|
-
const resolvedSchemaValidators = new WeakMap();
|
|
20
16
|
function errorsOf(validate) {
|
|
21
17
|
return (validate.errors ?? []).map((error) => ({
|
|
22
18
|
instancePath: error.instancePath,
|
|
@@ -30,177 +26,7 @@ function validateWith(validate, value) {
|
|
|
30
26
|
return { valid: false, errors: errorsOf(validate) };
|
|
31
27
|
return { valid: true, value: value, errors: [] };
|
|
32
28
|
}
|
|
33
|
-
function isJsonValue(value, ancestors = new Set()) {
|
|
34
|
-
if (value === null ||
|
|
35
|
-
typeof value === 'string' ||
|
|
36
|
-
typeof value === 'boolean') {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
if (typeof value === 'number')
|
|
40
|
-
return Number.isFinite(value);
|
|
41
|
-
if (typeof value !== 'object')
|
|
42
|
-
return false;
|
|
43
|
-
if (ancestors.has(value))
|
|
44
|
-
return false;
|
|
45
|
-
ancestors.add(value);
|
|
46
|
-
const valid = Array.isArray(value)
|
|
47
|
-
? value.every((item) => isJsonValue(item, ancestors))
|
|
48
|
-
: Object.values(value).every((item) => isJsonValue(item, ancestors));
|
|
49
|
-
ancestors.delete(value);
|
|
50
|
-
return valid;
|
|
51
|
-
}
|
|
52
29
|
export function validateSignalDeclaration(value) {
|
|
53
30
|
return validateWith(validateDeclarationSchema, value);
|
|
54
31
|
}
|
|
55
|
-
export function validateEventsPublishInput(value) {
|
|
56
|
-
const structural = validateWith(validatePublishInputSchema, value);
|
|
57
|
-
if (!structural.valid)
|
|
58
|
-
return structural;
|
|
59
|
-
let validJsonValue = false;
|
|
60
|
-
try {
|
|
61
|
-
validJsonValue = isJsonValue(structural.value.payload);
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
validJsonValue = false;
|
|
65
|
-
}
|
|
66
|
-
if (!validJsonValue) {
|
|
67
|
-
return {
|
|
68
|
-
valid: false,
|
|
69
|
-
errors: [
|
|
70
|
-
{
|
|
71
|
-
instancePath: '/payload',
|
|
72
|
-
schemaPath: '#/$defs/EventsPublishInput/properties/payload',
|
|
73
|
-
keyword: 'jsonValue',
|
|
74
|
-
message: 'payload must contain only finite JSON values without cycles',
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
let encodedPayloadBytes;
|
|
80
|
-
try {
|
|
81
|
-
encodedPayloadBytes = Buffer.byteLength(JSON.stringify(structural.value.payload), 'utf8');
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
return {
|
|
85
|
-
valid: false,
|
|
86
|
-
errors: [
|
|
87
|
-
{
|
|
88
|
-
instancePath: '/payload',
|
|
89
|
-
schemaPath: '#/$defs/EventsPublishInput/properties/payload',
|
|
90
|
-
keyword: 'jsonValue',
|
|
91
|
-
message: 'payload could not be safely serialized as JSON',
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
if (encodedPayloadBytes > SIGNAL_PAYLOAD_MAX_ENCODED_BYTES) {
|
|
97
|
-
return {
|
|
98
|
-
valid: false,
|
|
99
|
-
errors: [
|
|
100
|
-
{
|
|
101
|
-
instancePath: '/payload',
|
|
102
|
-
schemaPath: '#/x-clowder-payload-max-encoded-bytes',
|
|
103
|
-
keyword: 'maxEncodedBytes',
|
|
104
|
-
message: `payload exceeds ${SIGNAL_PAYLOAD_MAX_ENCODED_BYTES} encoded bytes`,
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
return structural;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Cross-document admission: a structurally legal publish is still forbidden
|
|
113
|
-
* unless its signalType appears in this plugin manifest's declared provides.
|
|
114
|
-
*/
|
|
115
|
-
export function validateDeclaredEventsPublishInput(declarations, signalSchemas, value) {
|
|
116
|
-
const input = validateEventsPublishInput(value);
|
|
117
|
-
if (!input.valid)
|
|
118
|
-
return input;
|
|
119
|
-
let matchingDeclaration;
|
|
120
|
-
for (const candidate of declarations) {
|
|
121
|
-
const declaration = validateSignalDeclaration(candidate);
|
|
122
|
-
if (!declaration.valid) {
|
|
123
|
-
return {
|
|
124
|
-
valid: false,
|
|
125
|
-
errors: [
|
|
126
|
-
{
|
|
127
|
-
instancePath: '/signals/provides',
|
|
128
|
-
schemaPath: '#/$defs/SignalContribution/properties/provides',
|
|
129
|
-
keyword: 'signalDeclaration',
|
|
130
|
-
message: 'declared signal metadata is invalid',
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
if (declaration.value.type === input.value.signalType) {
|
|
136
|
-
matchingDeclaration = declaration.value;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (matchingDeclaration === undefined) {
|
|
140
|
-
return {
|
|
141
|
-
valid: false,
|
|
142
|
-
errors: [
|
|
143
|
-
{
|
|
144
|
-
instancePath: '/signalType',
|
|
145
|
-
schemaPath: '#/$defs/SignalContribution/properties/provides',
|
|
146
|
-
keyword: 'declaredSignalType',
|
|
147
|
-
message: 'signalType is not declared by the plugin manifest',
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
const resolvedSchema = signalSchemas[matchingDeclaration.schemaRef];
|
|
153
|
-
if (typeof resolvedSchema !== 'object' ||
|
|
154
|
-
resolvedSchema === null ||
|
|
155
|
-
Array.isArray(resolvedSchema)) {
|
|
156
|
-
return {
|
|
157
|
-
valid: false,
|
|
158
|
-
errors: [
|
|
159
|
-
{
|
|
160
|
-
instancePath: '/signalType',
|
|
161
|
-
schemaPath: matchingDeclaration.schemaRef,
|
|
162
|
-
keyword: 'signalSchemaUnresolved',
|
|
163
|
-
message: 'declared signal schema is not resolved from the installed package',
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
let validateResolved = resolvedSchemaValidators.get(resolvedSchema);
|
|
169
|
-
if (validateResolved === undefined) {
|
|
170
|
-
try {
|
|
171
|
-
const schemaAjv = new Ajv2020({ allErrors: true, strict: false });
|
|
172
|
-
addFormats(schemaAjv);
|
|
173
|
-
validateResolved = schemaAjv.compile(resolvedSchema);
|
|
174
|
-
resolvedSchemaValidators.set(resolvedSchema, validateResolved);
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
resolvedSchemaValidators.set(resolvedSchema, null);
|
|
178
|
-
validateResolved = null;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (validateResolved === null) {
|
|
182
|
-
return {
|
|
183
|
-
valid: false,
|
|
184
|
-
errors: [
|
|
185
|
-
{
|
|
186
|
-
instancePath: '/signalType',
|
|
187
|
-
schemaPath: matchingDeclaration.schemaRef,
|
|
188
|
-
keyword: 'signalSchemaInvalid',
|
|
189
|
-
message: 'declared signal schema could not be compiled safely',
|
|
190
|
-
},
|
|
191
|
-
],
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
const content = {
|
|
195
|
-
payload: input.value.payload,
|
|
196
|
-
source: input.value.source,
|
|
197
|
-
};
|
|
198
|
-
if (!validateResolved(content)) {
|
|
199
|
-
return { valid: false, errors: errorsOf(validateResolved) };
|
|
200
|
-
}
|
|
201
|
-
return input;
|
|
202
|
-
}
|
|
203
|
-
export function validateEventsPublishResult(value) {
|
|
204
|
-
return validateWith(validatePublishResultSchema, value);
|
|
205
|
-
}
|
|
206
32
|
//# sourceMappingURL=signals.js.map
|