space-data-module-sdk 0.2.6 → 0.2.8

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.
@@ -8,6 +8,8 @@ import {
8
8
  ExternalInterfaceDirection,
9
9
  ExternalInterfaceKind,
10
10
  InvokeSurface,
11
+ ProtocolRole,
12
+ ProtocolTransportKind,
11
13
  RuntimeTarget,
12
14
  } from "../runtime/constants.js";
13
15
 
@@ -50,7 +52,16 @@ export const RecommendedCapabilityIds = Object.freeze([
50
52
  "render_hooks",
51
53
  ]);
52
54
 
55
+ export const StandaloneWasiCapabilityIds = Object.freeze([
56
+ "logging",
57
+ "clock",
58
+ "random",
59
+ "filesystem",
60
+ "pipe",
61
+ ]);
62
+
53
63
  const RecommendedCapabilitySet = new Set(RecommendedCapabilityIds);
64
+ const StandaloneWasiCapabilitySet = new Set(StandaloneWasiCapabilityIds);
54
65
  const RecommendedRuntimeTargets = Object.freeze(Object.values(RuntimeTarget));
55
66
  const RecommendedRuntimeTargetSet = new Set(RecommendedRuntimeTargets);
56
67
  const DrainPolicySet = new Set(Object.values(DrainPolicy));
@@ -59,6 +70,8 @@ const ExternalInterfaceDirectionSet = new Set(
59
70
  Object.values(ExternalInterfaceDirection),
60
71
  );
61
72
  const ExternalInterfaceKindSet = new Set(Object.values(ExternalInterfaceKind));
73
+ const ProtocolRoleSet = new Set(Object.values(ProtocolRole));
74
+ const ProtocolTransportKindSet = new Set(Object.values(ProtocolTransportKind));
62
75
  const BrowserIncompatibleCapabilitySet = new Set([
63
76
  "filesystem",
64
77
  "pipe",
@@ -79,6 +92,9 @@ const BrowserIncompatibleCapabilitySet = new Set([
79
92
  "entity_access",
80
93
  "render_hooks",
81
94
  ]);
95
+ const StandaloneWasiProtocolTransportKindSet = new Set([
96
+ ProtocolTransportKind.WASI_PIPE,
97
+ ]);
82
98
  const IgnoredDirectoryNames = new Set([
83
99
  ".git",
84
100
  ".hg",
@@ -120,6 +136,57 @@ function hasNonEmptyByteSequence(value) {
120
136
  return false;
121
137
  }
122
138
 
139
+ function normalizeTypeIdentityString(value) {
140
+ if (!isNonEmptyString(value)) {
141
+ return null;
142
+ }
143
+ return value.trim().toLowerCase();
144
+ }
145
+
146
+ function normalizeTypeIdentityBytes(value) {
147
+ if (typeof value === "string") {
148
+ const trimmed = value.trim().toLowerCase();
149
+ return trimmed.length > 0 ? trimmed : null;
150
+ }
151
+ const bytes = ArrayBuffer.isView(value)
152
+ ? Array.from(value)
153
+ : Array.isArray(value)
154
+ ? value
155
+ : null;
156
+ if (!bytes || bytes.length === 0) {
157
+ return null;
158
+ }
159
+ return bytes
160
+ .map((entry) => Number(entry).toString(16).padStart(2, "0"))
161
+ .join("");
162
+ }
163
+
164
+ function allowedTypesReferToSameLogicalSchema(left, right) {
165
+ const leftSchemaName = normalizeTypeIdentityString(left?.schemaName);
166
+ const rightSchemaName = normalizeTypeIdentityString(right?.schemaName);
167
+ if (leftSchemaName && rightSchemaName && leftSchemaName === rightSchemaName) {
168
+ return true;
169
+ }
170
+
171
+ const leftFileIdentifier = normalizeTypeIdentityString(left?.fileIdentifier);
172
+ const rightFileIdentifier = normalizeTypeIdentityString(right?.fileIdentifier);
173
+ if (
174
+ leftFileIdentifier &&
175
+ rightFileIdentifier &&
176
+ leftFileIdentifier === rightFileIdentifier
177
+ ) {
178
+ return true;
179
+ }
180
+
181
+ const leftSchemaHash = normalizeTypeIdentityBytes(left?.schemaHash);
182
+ const rightSchemaHash = normalizeTypeIdentityBytes(right?.schemaHash);
183
+ if (leftSchemaHash && rightSchemaHash && leftSchemaHash === rightSchemaHash) {
184
+ return true;
185
+ }
186
+
187
+ return false;
188
+ }
189
+
123
190
  function normalizePayloadWireFormatName(value) {
124
191
  if (value === undefined || value === null || value === "") {
125
192
  return "flatbuffer";
@@ -151,7 +218,13 @@ function validateStringField(issues, value, location, label) {
151
218
  return true;
152
219
  }
153
220
 
154
- function validateIntegerField(issues, value, location, label, { min = null } = {}) {
221
+ function validateIntegerField(
222
+ issues,
223
+ value,
224
+ location,
225
+ label,
226
+ { min = null, max = null } = {},
227
+ ) {
155
228
  if (!Number.isInteger(value)) {
156
229
  pushIssue(issues, "error", "invalid-integer", `${label} must be an integer.`, location);
157
230
  return false;
@@ -166,6 +239,16 @@ function validateIntegerField(issues, value, location, label, { min = null } = {
166
239
  );
167
240
  return false;
168
241
  }
242
+ if (max !== null && value > max) {
243
+ pushIssue(
244
+ issues,
245
+ "error",
246
+ "integer-range",
247
+ `${label} must be less than or equal to ${max}.`,
248
+ location,
249
+ );
250
+ return false;
251
+ }
169
252
  return true;
170
253
  }
171
254
 
@@ -182,6 +265,61 @@ function validateOptionalIntegerField(
182
265
  return validateIntegerField(issues, value, location, label, options);
183
266
  }
184
267
 
268
+ function validateOptionalBooleanField(issues, value, location, label) {
269
+ if (value === undefined || value === null) {
270
+ return true;
271
+ }
272
+ if (typeof value !== "boolean") {
273
+ pushIssue(
274
+ issues,
275
+ "error",
276
+ "invalid-boolean",
277
+ `${label} must be a boolean when present.`,
278
+ location,
279
+ );
280
+ return false;
281
+ }
282
+ return true;
283
+ }
284
+
285
+ function validateOptionalStringField(issues, value, location, label) {
286
+ if (value === undefined || value === null) {
287
+ return true;
288
+ }
289
+ return validateStringField(issues, value, location, label);
290
+ }
291
+
292
+ function normalizeProtocolTransportKind(value) {
293
+ if (value === undefined || value === null || value === "") {
294
+ return null;
295
+ }
296
+ const normalized = String(value)
297
+ .trim()
298
+ .toLowerCase()
299
+ .replace(/_/g, "-");
300
+ if (normalized === "websocket") {
301
+ return ProtocolTransportKind.WS;
302
+ }
303
+ if (normalized === "pipe") {
304
+ return ProtocolTransportKind.WASI_PIPE;
305
+ }
306
+ return normalized;
307
+ }
308
+
309
+ function normalizeProtocolRole(value) {
310
+ if (value === undefined || value === null || value === "") {
311
+ return null;
312
+ }
313
+ const normalized = String(value)
314
+ .trim()
315
+ .toLowerCase()
316
+ .replace(/_/g, "-");
317
+ if (normalized === "handler") {
318
+ return ProtocolRole.HANDLE;
319
+ }
320
+ return normalized;
321
+ }
322
+
185
323
  function validateAllowedType(type, issues, location) {
186
324
  if (!type || typeof type !== "object" || Array.isArray(type)) {
187
325
  pushIssue(issues, "error", "invalid-type-record", "Allowed type entries must be objects.", location);
@@ -307,6 +445,35 @@ function validateAcceptedTypeSet(typeSet, issues, location) {
307
445
  typeSet.allowedTypes.forEach((allowedType, index) => {
308
446
  validateAllowedType(allowedType, issues, `${location}.allowedTypes[${index}]`);
309
447
  });
448
+
449
+ const regularConcreteTypes = [];
450
+ const alignedTypes = [];
451
+
452
+ typeSet.allowedTypes.forEach((allowedType, index) => {
453
+ const wireFormat = normalizePayloadWireFormatName(allowedType?.wireFormat);
454
+ if (wireFormat === "aligned-binary") {
455
+ alignedTypes.push({ allowedType, index });
456
+ return;
457
+ }
458
+ if (wireFormat === "flatbuffer" && allowedType?.acceptsAnyFlatbuffer !== true) {
459
+ regularConcreteTypes.push({ allowedType, index });
460
+ }
461
+ });
462
+
463
+ alignedTypes.forEach(({ allowedType, index }) => {
464
+ const hasRegularFallback = regularConcreteTypes.some(({ allowedType: regularType }) =>
465
+ allowedTypesReferToSameLogicalSchema(allowedType, regularType),
466
+ );
467
+ if (!hasRegularFallback) {
468
+ pushIssue(
469
+ issues,
470
+ "error",
471
+ "missing-flatbuffer-fallback",
472
+ "Aligned-binary allowed types must be paired with a regular flatbuffer fallback for the same schema in the same acceptedTypeSet.",
473
+ `${location}.allowedTypes[${index}]`,
474
+ );
475
+ }
476
+ });
310
477
  }
311
478
 
312
479
  function validatePort(port, issues, location, label) {
@@ -576,6 +743,85 @@ function validateProtocol(protocol, issues, location, methodLookup, declaredCapa
576
743
  );
577
744
  }
578
745
  }
746
+ const wireIdValid = validateStringField(
747
+ issues,
748
+ protocol.wireId,
749
+ `${location}.wireId`,
750
+ "Protocol wireId",
751
+ );
752
+ const normalizedTransportKind = normalizeProtocolTransportKind(
753
+ protocol.transportKind,
754
+ );
755
+ if (!validateStringField(
756
+ issues,
757
+ protocol.transportKind,
758
+ `${location}.transportKind`,
759
+ "Protocol transportKind",
760
+ )) {
761
+ // already reported
762
+ } else if (!ProtocolTransportKindSet.has(normalizedTransportKind)) {
763
+ pushIssue(
764
+ issues,
765
+ "error",
766
+ "unknown-protocol-transport-kind",
767
+ `Protocol "${protocol.protocolId ?? "protocol"}" transportKind must be one of: ${Array.from(ProtocolTransportKindSet).join(", ")}.`,
768
+ `${location}.transportKind`,
769
+ );
770
+ }
771
+ const normalizedRole = normalizeProtocolRole(protocol.role);
772
+ if (!validateStringField(
773
+ issues,
774
+ protocol.role,
775
+ `${location}.role`,
776
+ "Protocol role",
777
+ )) {
778
+ // already reported
779
+ } else if (!ProtocolRoleSet.has(normalizedRole)) {
780
+ pushIssue(
781
+ issues,
782
+ "error",
783
+ "unknown-protocol-role",
784
+ `Protocol "${protocol.protocolId ?? "protocol"}" role must be one of: ${Array.from(ProtocolRoleSet).join(", ")}.`,
785
+ `${location}.role`,
786
+ );
787
+ }
788
+ validateOptionalStringField(
789
+ issues,
790
+ protocol.specUri,
791
+ `${location}.specUri`,
792
+ "Protocol specUri",
793
+ );
794
+ validateOptionalStringField(
795
+ issues,
796
+ protocol.discoveryKey,
797
+ `${location}.discoveryKey`,
798
+ "Protocol discoveryKey",
799
+ );
800
+ validateOptionalBooleanField(
801
+ issues,
802
+ protocol.autoInstall,
803
+ `${location}.autoInstall`,
804
+ "Protocol autoInstall",
805
+ );
806
+ validateOptionalBooleanField(
807
+ issues,
808
+ protocol.advertise,
809
+ `${location}.advertise`,
810
+ "Protocol advertise",
811
+ );
812
+ validateOptionalBooleanField(
813
+ issues,
814
+ protocol.requireSecureTransport,
815
+ `${location}.requireSecureTransport`,
816
+ "Protocol requireSecureTransport",
817
+ );
818
+ validateOptionalIntegerField(
819
+ issues,
820
+ protocol.defaultPort,
821
+ `${location}.defaultPort`,
822
+ "Protocol defaultPort",
823
+ { min: 0, max: 65535 },
824
+ );
579
825
  if (
580
826
  protocolIdValid &&
581
827
  Array.isArray(declaredCapabilities) &&
@@ -590,6 +836,77 @@ function validateProtocol(protocol, issues, location, methodLookup, declaredCapa
590
836
  location,
591
837
  );
592
838
  }
839
+ if (
840
+ protocolIdValid &&
841
+ normalizedRole &&
842
+ (normalizedRole === ProtocolRole.HANDLE ||
843
+ normalizedRole === ProtocolRole.BOTH) &&
844
+ Array.isArray(declaredCapabilities) &&
845
+ !declaredCapabilities.includes("protocol_handle")
846
+ ) {
847
+ pushIssue(
848
+ issues,
849
+ "error",
850
+ "missing-handle-protocol-capability",
851
+ `Protocol "${protocol.protocolId}" with role "${normalizedRole}" requires the "protocol_handle" capability.`,
852
+ location,
853
+ );
854
+ }
855
+ if (
856
+ protocolIdValid &&
857
+ normalizedRole &&
858
+ (normalizedRole === ProtocolRole.DIAL ||
859
+ normalizedRole === ProtocolRole.BOTH) &&
860
+ Array.isArray(declaredCapabilities) &&
861
+ !declaredCapabilities.includes("protocol_dial")
862
+ ) {
863
+ pushIssue(
864
+ issues,
865
+ "error",
866
+ "missing-dial-protocol-capability",
867
+ `Protocol "${protocol.protocolId}" with role "${normalizedRole}" requires the "protocol_dial" capability.`,
868
+ location,
869
+ );
870
+ }
871
+ if (
872
+ protocol.advertise === true &&
873
+ normalizedRole === ProtocolRole.DIAL
874
+ ) {
875
+ pushIssue(
876
+ issues,
877
+ "error",
878
+ "protocol-advertise-role-conflict",
879
+ `Protocol "${protocol.protocolId ?? "protocol"}" cannot advertise when role is "dial".`,
880
+ `${location}.advertise`,
881
+ );
882
+ }
883
+ if (
884
+ normalizedTransportKind === ProtocolTransportKind.LIBP2P &&
885
+ Array.isArray(declaredCapabilities) &&
886
+ !declaredCapabilities.includes("ipfs")
887
+ ) {
888
+ pushIssue(
889
+ issues,
890
+ "error",
891
+ "missing-ipfs-capability",
892
+ `Protocol "${protocol.protocolId ?? "protocol"}" with transportKind "libp2p" requires the "ipfs" capability.`,
893
+ location,
894
+ );
895
+ }
896
+ if (
897
+ wireIdValid &&
898
+ normalizedTransportKind === ProtocolTransportKind.WS &&
899
+ protocol.defaultPort === 443 &&
900
+ protocol.requireSecureTransport !== true
901
+ ) {
902
+ pushIssue(
903
+ issues,
904
+ "warning",
905
+ "insecure-secure-port-hint",
906
+ `Protocol "${protocol.protocolId ?? "protocol"}" uses defaultPort 443 without requireSecureTransport=true.`,
907
+ `${location}.defaultPort`,
908
+ );
909
+ }
593
910
  }
594
911
 
595
912
  function validateRuntimeTargets(runtimeTargets, declaredCapabilities, issues, sourceName) {
@@ -658,6 +975,66 @@ function validateRuntimeTargets(runtimeTargets, declaredCapabilities, issues, so
658
975
  }
659
976
  }
660
977
 
978
+ function validateStandaloneWasiTarget(
979
+ manifest,
980
+ normalizedInvokeSurfaces,
981
+ declaredCapabilities,
982
+ issues,
983
+ sourceName,
984
+ ) {
985
+ const runtimeTargets = Array.isArray(manifest?.runtimeTargets)
986
+ ? manifest.runtimeTargets
987
+ : [];
988
+ if (!runtimeTargets.includes(RuntimeTarget.WASI)) {
989
+ return;
990
+ }
991
+
992
+ if (!normalizedInvokeSurfaces.includes(InvokeSurface.COMMAND)) {
993
+ pushIssue(
994
+ issues,
995
+ "error",
996
+ "missing-wasi-command-surface",
997
+ 'Artifacts targeting the canonical "wasi" runtime must declare the "command" invoke surface so they can run as standalone WASI programs without host wrappers.',
998
+ `${sourceName}.invokeSurfaces`,
999
+ );
1000
+ }
1001
+
1002
+ if (Array.isArray(declaredCapabilities)) {
1003
+ for (const capability of declaredCapabilities) {
1004
+ if (!StandaloneWasiCapabilitySet.has(capability)) {
1005
+ pushIssue(
1006
+ issues,
1007
+ "error",
1008
+ "capability-wasi-standalone-conflict",
1009
+ `Capability "${capability}" is not available to a standalone WASI artifact without host wrappers.`,
1010
+ `${sourceName}.capabilities`,
1011
+ );
1012
+ }
1013
+ }
1014
+ }
1015
+
1016
+ if (!Array.isArray(manifest?.protocols)) {
1017
+ return;
1018
+ }
1019
+ manifest.protocols.forEach((protocol, index) => {
1020
+ const normalizedTransportKind = normalizeProtocolTransportKind(
1021
+ protocol?.transportKind,
1022
+ );
1023
+ if (
1024
+ normalizedTransportKind &&
1025
+ !StandaloneWasiProtocolTransportKindSet.has(normalizedTransportKind)
1026
+ ) {
1027
+ pushIssue(
1028
+ issues,
1029
+ "error",
1030
+ "protocol-wasi-standalone-conflict",
1031
+ `Protocol "${protocol?.protocolId ?? "protocol"}" uses transportKind "${protocol?.transportKind}", which requires a host wrapper rather than a standalone WASI runtime.`,
1032
+ `${sourceName}.protocols[${index}].transportKind`,
1033
+ );
1034
+ }
1035
+ });
1036
+ }
1037
+
661
1038
  function validateInvokeSurfaces(invokeSurfaces, issues, sourceName) {
662
1039
  if (invokeSurfaces === undefined) {
663
1040
  return [];
@@ -781,7 +1158,11 @@ export function validatePluginManifest(manifest, options = {}) {
781
1158
  issues,
782
1159
  sourceName,
783
1160
  );
784
- validateInvokeSurfaces(manifest.invokeSurfaces, issues, sourceName);
1161
+ const normalizedInvokeSurfaces = validateInvokeSurfaces(
1162
+ manifest.invokeSurfaces,
1163
+ issues,
1164
+ sourceName,
1165
+ );
785
1166
 
786
1167
  if (!Array.isArray(manifest.externalInterfaces)) {
787
1168
  pushIssue(
@@ -922,6 +1303,14 @@ export function validatePluginManifest(manifest, options = {}) {
922
1303
  }
923
1304
  }
924
1305
 
1306
+ validateStandaloneWasiTarget(
1307
+ manifest,
1308
+ normalizedInvokeSurfaces,
1309
+ declaredCapabilities,
1310
+ issues,
1311
+ sourceName,
1312
+ );
1313
+
925
1314
  if (manifest.schemasUsed !== undefined && !Array.isArray(manifest.schemasUsed)) {
926
1315
  pushIssue(
927
1316
  issues,
@@ -0,0 +1,224 @@
1
+ import type {
2
+ PluginManifest,
3
+ ProtocolRoleName,
4
+ ProtocolSpec,
5
+ ProtocolTransportKindName,
6
+ } from "../index.js";
7
+
8
+ export type InputBindingSourceKindName =
9
+ | "pubsub"
10
+ | "protocol-stream"
11
+ | "catalog-sync";
12
+ export type DeploymentBindingModeName = "local" | "delegated";
13
+ export type ScheduleBindingKindName = "interval" | "cron" | "once";
14
+
15
+ export interface ResolvedProtocolInstallation {
16
+ protocolId: string;
17
+ wireId: string;
18
+ transportKind: ProtocolTransportKindName | string;
19
+ role: ProtocolRoleName | string;
20
+ peerId?: string | null;
21
+ listenMultiaddrs?: string[];
22
+ advertisedMultiaddrs?: string[];
23
+ nodeInfoUrl?: string | null;
24
+ serviceName?: string | null;
25
+ resolvedPort?: number;
26
+ artifactCid?: string | null;
27
+ description?: string | null;
28
+ }
29
+
30
+ export interface InputBinding {
31
+ bindingId: string;
32
+ targetPluginId?: string | null;
33
+ targetMethodId: string;
34
+ targetInputPortId: string;
35
+ sourceKind: InputBindingSourceKindName | string;
36
+ topic?: string | null;
37
+ wireId?: string | null;
38
+ nodeInfoUrl?: string | null;
39
+ multiaddrs?: string[];
40
+ allowPeerIds?: string[];
41
+ allowServerKeys?: string[];
42
+ deliveryMode?: string | null;
43
+ description?: string | null;
44
+ }
45
+
46
+ export interface ScheduleBinding {
47
+ scheduleId: string;
48
+ bindingMode: DeploymentBindingModeName | string;
49
+ triggerId?: string | null;
50
+ targetMethodId?: string | null;
51
+ targetInputPortId?: string | null;
52
+ scheduleKind: ScheduleBindingKindName | string;
53
+ cron?: string | null;
54
+ intervalMs?: number;
55
+ runAtStartup?: boolean;
56
+ startupDelayMs?: number;
57
+ timezone?: string | null;
58
+ description?: string | null;
59
+ }
60
+
61
+ export interface ServiceBinding {
62
+ serviceId: string;
63
+ bindingMode: DeploymentBindingModeName | string;
64
+ serviceKind: string;
65
+ triggerId?: string | null;
66
+ protocolId?: string | null;
67
+ routePath?: string | null;
68
+ method?: string | null;
69
+ transportKind?: ProtocolTransportKindName | string | null;
70
+ adapter?: string | null;
71
+ listenHost?: string | null;
72
+ listenPort?: number;
73
+ remoteUrl?: string | null;
74
+ allowTransports?: string[];
75
+ authPolicyId?: string | null;
76
+ description?: string | null;
77
+ properties?: Record<string, unknown>;
78
+ }
79
+
80
+ export interface AuthPolicy {
81
+ policyId: string;
82
+ bindingMode: DeploymentBindingModeName | string;
83
+ targetKind: string;
84
+ targetId?: string | null;
85
+ adapter?: string | null;
86
+ walletProfileId?: string | null;
87
+ trustMapId?: string | null;
88
+ allowPeerIds?: string[];
89
+ allowServerKeys?: string[];
90
+ allowEntityIds?: string[];
91
+ requireSignedRequests?: boolean;
92
+ requireEncryptedTransport?: boolean;
93
+ description?: string | null;
94
+ properties?: Record<string, unknown>;
95
+ }
96
+
97
+ export interface PublicationBinding {
98
+ publicationId: string;
99
+ bindingMode: DeploymentBindingModeName | string;
100
+ sourceKind: string;
101
+ sourceMethodId?: string | null;
102
+ sourceOutputPortId?: string | null;
103
+ sourceNodeId?: string | null;
104
+ sourceTriggerId?: string | null;
105
+ topic?: string | null;
106
+ wireId?: string | null;
107
+ schemaName?: string | null;
108
+ mediaType?: string | null;
109
+ archivePath?: string | null;
110
+ queryServiceId?: string | null;
111
+ emitPnm?: boolean;
112
+ emitFlatbufferArchive?: boolean;
113
+ pinPolicy?: string | null;
114
+ maxRecords?: number;
115
+ maxBytes?: number;
116
+ minLivelinessSeconds?: number;
117
+ recordRangeStartField?: string | null;
118
+ recordRangeStopField?: string | null;
119
+ description?: string | null;
120
+ properties?: Record<string, unknown>;
121
+ }
122
+
123
+ export interface ModuleDeploymentPlan {
124
+ formatVersion?: number;
125
+ pluginId?: string | null;
126
+ version?: string | null;
127
+ artifactCid?: string | null;
128
+ bundleCid?: string | null;
129
+ environmentId?: string | null;
130
+ protocolInstallations?: ResolvedProtocolInstallation[];
131
+ inputBindings?: InputBinding[];
132
+ scheduleBindings?: ScheduleBinding[];
133
+ serviceBindings?: ServiceBinding[];
134
+ authPolicies?: AuthPolicy[];
135
+ publicationBindings?: PublicationBinding[];
136
+ }
137
+
138
+ export interface DeploymentPlanIssue {
139
+ severity: "error" | "warning";
140
+ code: string;
141
+ message: string;
142
+ location?: string;
143
+ }
144
+
145
+ export interface DeploymentPlanValidationReport {
146
+ ok: boolean;
147
+ plan: ModuleDeploymentPlan;
148
+ issues: DeploymentPlanIssue[];
149
+ errors: DeploymentPlanIssue[];
150
+ warnings: DeploymentPlanIssue[];
151
+ }
152
+
153
+ export const DEPLOYMENT_PLAN_FORMAT_VERSION: number;
154
+
155
+ export const InputBindingSourceKind: {
156
+ PUBSUB: InputBindingSourceKindName;
157
+ PROTOCOL_STREAM: InputBindingSourceKindName;
158
+ CATALOG_SYNC: InputBindingSourceKindName;
159
+ };
160
+
161
+ export const DeploymentBindingMode: {
162
+ LOCAL: DeploymentBindingModeName;
163
+ DELEGATED: DeploymentBindingModeName;
164
+ };
165
+
166
+ export const ScheduleBindingKind: {
167
+ INTERVAL: ScheduleBindingKindName;
168
+ CRON: ScheduleBindingKindName;
169
+ ONCE: ScheduleBindingKindName;
170
+ };
171
+
172
+ export function normalizeProtocolTransportKindName(
173
+ value: ProtocolTransportKindName | string | null | undefined,
174
+ ): ProtocolTransportKindName | string | null;
175
+
176
+ export function normalizeProtocolRoleName(
177
+ value: ProtocolRoleName | string | null | undefined,
178
+ ): ProtocolRoleName | string | null;
179
+
180
+ export function normalizeInputBindingSourceKindName(
181
+ value: InputBindingSourceKindName | string | null | undefined,
182
+ ): InputBindingSourceKindName | string | null;
183
+
184
+ export function normalizeDeploymentBindingModeName(
185
+ value: DeploymentBindingModeName | string | null | undefined,
186
+ ): DeploymentBindingModeName | string | null;
187
+
188
+ export function normalizeScheduleBindingKindName(
189
+ value: ScheduleBindingKindName | string | null | undefined,
190
+ ): ScheduleBindingKindName | string | null;
191
+
192
+ export function normalizeDeploymentPlan(
193
+ plan: ModuleDeploymentPlan | null | undefined,
194
+ ): ModuleDeploymentPlan;
195
+
196
+ export function validateDeploymentPlan(
197
+ plan: ModuleDeploymentPlan | null | undefined,
198
+ options?: { manifest?: PluginManifest | null },
199
+ ): DeploymentPlanValidationReport;
200
+
201
+ export function createDeploymentPlanBundleEntry(
202
+ plan: ModuleDeploymentPlan | null | undefined,
203
+ options?: {
204
+ entryId?: string;
205
+ role?: string;
206
+ sectionName?: string;
207
+ mediaType?: string;
208
+ description?: string;
209
+ },
210
+ ): {
211
+ entryId: string;
212
+ role: string;
213
+ sectionName: string;
214
+ payloadEncoding: "json-utf8";
215
+ mediaType: string;
216
+ payload: ModuleDeploymentPlan;
217
+ description: string;
218
+ };
219
+
220
+ export function findDeploymentPlanEntry(bundleLike: unknown): unknown | null;
221
+
222
+ export function readDeploymentPlanFromBundle(
223
+ bundleLike: unknown,
224
+ ): ModuleDeploymentPlan | null;