space-data-module-sdk 0.2.5 → 0.2.7
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/README.md +64 -2
- package/package.json +8 -2
- package/schemas/PluginManifest.fbs +9 -0
- package/src/bundle/constants.js +4 -1
- package/src/bundle/wasm.js +30 -2
- package/src/compiler/compileModule.js +12 -141
- package/src/compiler/emception.d.ts +60 -0
- package/src/compiler/emception.js +191 -0
- package/src/compiler/emceptionNode.js +51 -34
- package/src/compiler/index.d.ts +24 -0
- package/src/compiler/index.js +5 -0
- package/src/compliance/pluginCompliance.js +306 -1
- package/src/deployment/index.d.ts +224 -0
- package/src/deployment/index.js +1552 -0
- package/src/generated/orbpro/manifest/protocol-spec.d.ts +35 -3
- package/src/generated/orbpro/manifest/protocol-spec.js +120 -6
- package/src/generated/orbpro/manifest/protocol-spec.ts +191 -1
- package/src/index.d.ts +149 -3
- package/src/index.js +4 -0
- package/src/manifest/index.js +7 -0
- package/src/manifest/normalize.js +75 -5
- package/src/manifest/typeRefs.js +143 -0
- package/src/runtime/constants.js +13 -0
- package/src/runtime/index.d.ts +15 -0
- package/src/runtime/index.js +2 -0
- package/src/testing/index.d.ts +84 -0
- package/src/testing/index.js +414 -0
|
@@ -16,8 +16,6 @@ const FILE_URL_FETCH_PATCH_FLAG =
|
|
|
16
16
|
"__spaceDataModuleSdkFileUrlFetchPatched";
|
|
17
17
|
|
|
18
18
|
let patchedEmceptionRootPromise = null;
|
|
19
|
-
let emceptionInstancePromise = null;
|
|
20
|
-
let emceptionExecutionQueue = Promise.resolve();
|
|
21
19
|
|
|
22
20
|
function installNodeRuntimeShims() {
|
|
23
21
|
if (typeof globalThis.require !== "function") {
|
|
@@ -175,43 +173,62 @@ async function preparePatchedEmceptionRoot() {
|
|
|
175
173
|
return patchedEmceptionRootPromise;
|
|
176
174
|
}
|
|
177
175
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
176
|
+
class EmceptionController {
|
|
177
|
+
#instancePromise = null;
|
|
178
|
+
#executionQueue = Promise.resolve();
|
|
179
|
+
|
|
180
|
+
async load() {
|
|
181
|
+
if (!this.#instancePromise) {
|
|
182
|
+
this.#instancePromise = (async () => {
|
|
183
|
+
installNodeRuntimeShims();
|
|
184
|
+
const patchedRoot = await preparePatchedEmceptionRoot();
|
|
185
|
+
const moduleUrl = pathToFileURL(path.join(patchedRoot, "emception.mjs")).href;
|
|
186
|
+
const { default: Emception } = await import(moduleUrl);
|
|
187
|
+
const emception = new Emception({
|
|
188
|
+
baseUrl: pathToFileURL(`${patchedRoot}${path.sep}`).href,
|
|
189
|
+
});
|
|
190
|
+
await emception.init();
|
|
191
|
+
return emception;
|
|
192
|
+
})().catch((error) => {
|
|
193
|
+
this.#instancePromise = null;
|
|
194
|
+
throw error;
|
|
187
195
|
});
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return this.#instancePromise;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async withLock(task) {
|
|
202
|
+
const previous = this.#executionQueue;
|
|
203
|
+
let release = () => {};
|
|
204
|
+
this.#executionQueue = new Promise((resolve) => {
|
|
205
|
+
release = resolve;
|
|
193
206
|
});
|
|
207
|
+
await previous.catch(() => {});
|
|
208
|
+
try {
|
|
209
|
+
const emception = await this.load().catch((error) => {
|
|
210
|
+
if (!error.code) {
|
|
211
|
+
error.code = "EMCEPTION_LOAD_FAILED";
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
});
|
|
215
|
+
return await task(emception);
|
|
216
|
+
} finally {
|
|
217
|
+
release();
|
|
218
|
+
}
|
|
194
219
|
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const sharedEmceptionController = new EmceptionController();
|
|
195
223
|
|
|
196
|
-
|
|
224
|
+
export function getSharedEmceptionController() {
|
|
225
|
+
return sharedEmceptionController;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export async function loadEmception() {
|
|
229
|
+
return sharedEmceptionController.load();
|
|
197
230
|
}
|
|
198
231
|
|
|
199
232
|
export async function runWithEmceptionLock(task) {
|
|
200
|
-
|
|
201
|
-
let release = () => {};
|
|
202
|
-
emceptionExecutionQueue = new Promise((resolve) => {
|
|
203
|
-
release = resolve;
|
|
204
|
-
});
|
|
205
|
-
await previous.catch(() => {});
|
|
206
|
-
try {
|
|
207
|
-
const emception = await loadEmception().catch((error) => {
|
|
208
|
-
if (!error.code) {
|
|
209
|
-
error.code = "EMCEPTION_LOAD_FAILED";
|
|
210
|
-
}
|
|
211
|
-
throw error;
|
|
212
|
-
});
|
|
213
|
-
return await task(emception);
|
|
214
|
-
} finally {
|
|
215
|
-
release();
|
|
216
|
-
}
|
|
233
|
+
return sharedEmceptionController.withLock(task);
|
|
217
234
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
CompilationResult,
|
|
3
|
+
ProtectedArtifact,
|
|
4
|
+
} from "../index.js";
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
cleanupCompilation,
|
|
8
|
+
compileModuleFromSource,
|
|
9
|
+
createRecipientKeypairHex,
|
|
10
|
+
protectModuleArtifact,
|
|
11
|
+
} from "../index.js";
|
|
12
|
+
|
|
13
|
+
export type {
|
|
14
|
+
EmceptionCommandResult,
|
|
15
|
+
SharedEmceptionFileContent,
|
|
16
|
+
SharedEmceptionHandle,
|
|
17
|
+
SharedEmceptionSession,
|
|
18
|
+
} from "./emception.js";
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
createSharedEmceptionSession,
|
|
22
|
+
loadSharedEmception,
|
|
23
|
+
withSharedEmception,
|
|
24
|
+
} from "./emception.js";
|
package/src/compiler/index.js
CHANGED
|
@@ -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
|
|
|
@@ -59,6 +61,8 @@ const ExternalInterfaceDirectionSet = new Set(
|
|
|
59
61
|
Object.values(ExternalInterfaceDirection),
|
|
60
62
|
);
|
|
61
63
|
const ExternalInterfaceKindSet = new Set(Object.values(ExternalInterfaceKind));
|
|
64
|
+
const ProtocolRoleSet = new Set(Object.values(ProtocolRole));
|
|
65
|
+
const ProtocolTransportKindSet = new Set(Object.values(ProtocolTransportKind));
|
|
62
66
|
const BrowserIncompatibleCapabilitySet = new Set([
|
|
63
67
|
"filesystem",
|
|
64
68
|
"pipe",
|
|
@@ -120,6 +124,57 @@ function hasNonEmptyByteSequence(value) {
|
|
|
120
124
|
return false;
|
|
121
125
|
}
|
|
122
126
|
|
|
127
|
+
function normalizeTypeIdentityString(value) {
|
|
128
|
+
if (!isNonEmptyString(value)) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
return value.trim().toLowerCase();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function normalizeTypeIdentityBytes(value) {
|
|
135
|
+
if (typeof value === "string") {
|
|
136
|
+
const trimmed = value.trim().toLowerCase();
|
|
137
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
138
|
+
}
|
|
139
|
+
const bytes = ArrayBuffer.isView(value)
|
|
140
|
+
? Array.from(value)
|
|
141
|
+
: Array.isArray(value)
|
|
142
|
+
? value
|
|
143
|
+
: null;
|
|
144
|
+
if (!bytes || bytes.length === 0) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
return bytes
|
|
148
|
+
.map((entry) => Number(entry).toString(16).padStart(2, "0"))
|
|
149
|
+
.join("");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function allowedTypesReferToSameLogicalSchema(left, right) {
|
|
153
|
+
const leftSchemaName = normalizeTypeIdentityString(left?.schemaName);
|
|
154
|
+
const rightSchemaName = normalizeTypeIdentityString(right?.schemaName);
|
|
155
|
+
if (leftSchemaName && rightSchemaName && leftSchemaName === rightSchemaName) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const leftFileIdentifier = normalizeTypeIdentityString(left?.fileIdentifier);
|
|
160
|
+
const rightFileIdentifier = normalizeTypeIdentityString(right?.fileIdentifier);
|
|
161
|
+
if (
|
|
162
|
+
leftFileIdentifier &&
|
|
163
|
+
rightFileIdentifier &&
|
|
164
|
+
leftFileIdentifier === rightFileIdentifier
|
|
165
|
+
) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const leftSchemaHash = normalizeTypeIdentityBytes(left?.schemaHash);
|
|
170
|
+
const rightSchemaHash = normalizeTypeIdentityBytes(right?.schemaHash);
|
|
171
|
+
if (leftSchemaHash && rightSchemaHash && leftSchemaHash === rightSchemaHash) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
123
178
|
function normalizePayloadWireFormatName(value) {
|
|
124
179
|
if (value === undefined || value === null || value === "") {
|
|
125
180
|
return "flatbuffer";
|
|
@@ -151,7 +206,13 @@ function validateStringField(issues, value, location, label) {
|
|
|
151
206
|
return true;
|
|
152
207
|
}
|
|
153
208
|
|
|
154
|
-
function validateIntegerField(
|
|
209
|
+
function validateIntegerField(
|
|
210
|
+
issues,
|
|
211
|
+
value,
|
|
212
|
+
location,
|
|
213
|
+
label,
|
|
214
|
+
{ min = null, max = null } = {},
|
|
215
|
+
) {
|
|
155
216
|
if (!Number.isInteger(value)) {
|
|
156
217
|
pushIssue(issues, "error", "invalid-integer", `${label} must be an integer.`, location);
|
|
157
218
|
return false;
|
|
@@ -166,6 +227,16 @@ function validateIntegerField(issues, value, location, label, { min = null } = {
|
|
|
166
227
|
);
|
|
167
228
|
return false;
|
|
168
229
|
}
|
|
230
|
+
if (max !== null && value > max) {
|
|
231
|
+
pushIssue(
|
|
232
|
+
issues,
|
|
233
|
+
"error",
|
|
234
|
+
"integer-range",
|
|
235
|
+
`${label} must be less than or equal to ${max}.`,
|
|
236
|
+
location,
|
|
237
|
+
);
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
169
240
|
return true;
|
|
170
241
|
}
|
|
171
242
|
|
|
@@ -182,6 +253,61 @@ function validateOptionalIntegerField(
|
|
|
182
253
|
return validateIntegerField(issues, value, location, label, options);
|
|
183
254
|
}
|
|
184
255
|
|
|
256
|
+
function validateOptionalBooleanField(issues, value, location, label) {
|
|
257
|
+
if (value === undefined || value === null) {
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
if (typeof value !== "boolean") {
|
|
261
|
+
pushIssue(
|
|
262
|
+
issues,
|
|
263
|
+
"error",
|
|
264
|
+
"invalid-boolean",
|
|
265
|
+
`${label} must be a boolean when present.`,
|
|
266
|
+
location,
|
|
267
|
+
);
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function validateOptionalStringField(issues, value, location, label) {
|
|
274
|
+
if (value === undefined || value === null) {
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
return validateStringField(issues, value, location, label);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function normalizeProtocolTransportKind(value) {
|
|
281
|
+
if (value === undefined || value === null || value === "") {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
const normalized = String(value)
|
|
285
|
+
.trim()
|
|
286
|
+
.toLowerCase()
|
|
287
|
+
.replace(/_/g, "-");
|
|
288
|
+
if (normalized === "websocket") {
|
|
289
|
+
return ProtocolTransportKind.WS;
|
|
290
|
+
}
|
|
291
|
+
if (normalized === "pipe") {
|
|
292
|
+
return ProtocolTransportKind.WASI_PIPE;
|
|
293
|
+
}
|
|
294
|
+
return normalized;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function normalizeProtocolRole(value) {
|
|
298
|
+
if (value === undefined || value === null || value === "") {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const normalized = String(value)
|
|
302
|
+
.trim()
|
|
303
|
+
.toLowerCase()
|
|
304
|
+
.replace(/_/g, "-");
|
|
305
|
+
if (normalized === "handler") {
|
|
306
|
+
return ProtocolRole.HANDLE;
|
|
307
|
+
}
|
|
308
|
+
return normalized;
|
|
309
|
+
}
|
|
310
|
+
|
|
185
311
|
function validateAllowedType(type, issues, location) {
|
|
186
312
|
if (!type || typeof type !== "object" || Array.isArray(type)) {
|
|
187
313
|
pushIssue(issues, "error", "invalid-type-record", "Allowed type entries must be objects.", location);
|
|
@@ -307,6 +433,35 @@ function validateAcceptedTypeSet(typeSet, issues, location) {
|
|
|
307
433
|
typeSet.allowedTypes.forEach((allowedType, index) => {
|
|
308
434
|
validateAllowedType(allowedType, issues, `${location}.allowedTypes[${index}]`);
|
|
309
435
|
});
|
|
436
|
+
|
|
437
|
+
const regularConcreteTypes = [];
|
|
438
|
+
const alignedTypes = [];
|
|
439
|
+
|
|
440
|
+
typeSet.allowedTypes.forEach((allowedType, index) => {
|
|
441
|
+
const wireFormat = normalizePayloadWireFormatName(allowedType?.wireFormat);
|
|
442
|
+
if (wireFormat === "aligned-binary") {
|
|
443
|
+
alignedTypes.push({ allowedType, index });
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (wireFormat === "flatbuffer" && allowedType?.acceptsAnyFlatbuffer !== true) {
|
|
447
|
+
regularConcreteTypes.push({ allowedType, index });
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
alignedTypes.forEach(({ allowedType, index }) => {
|
|
452
|
+
const hasRegularFallback = regularConcreteTypes.some(({ allowedType: regularType }) =>
|
|
453
|
+
allowedTypesReferToSameLogicalSchema(allowedType, regularType),
|
|
454
|
+
);
|
|
455
|
+
if (!hasRegularFallback) {
|
|
456
|
+
pushIssue(
|
|
457
|
+
issues,
|
|
458
|
+
"error",
|
|
459
|
+
"missing-flatbuffer-fallback",
|
|
460
|
+
"Aligned-binary allowed types must be paired with a regular flatbuffer fallback for the same schema in the same acceptedTypeSet.",
|
|
461
|
+
`${location}.allowedTypes[${index}]`,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
});
|
|
310
465
|
}
|
|
311
466
|
|
|
312
467
|
function validatePort(port, issues, location, label) {
|
|
@@ -576,6 +731,85 @@ function validateProtocol(protocol, issues, location, methodLookup, declaredCapa
|
|
|
576
731
|
);
|
|
577
732
|
}
|
|
578
733
|
}
|
|
734
|
+
const wireIdValid = validateStringField(
|
|
735
|
+
issues,
|
|
736
|
+
protocol.wireId,
|
|
737
|
+
`${location}.wireId`,
|
|
738
|
+
"Protocol wireId",
|
|
739
|
+
);
|
|
740
|
+
const normalizedTransportKind = normalizeProtocolTransportKind(
|
|
741
|
+
protocol.transportKind,
|
|
742
|
+
);
|
|
743
|
+
if (!validateStringField(
|
|
744
|
+
issues,
|
|
745
|
+
protocol.transportKind,
|
|
746
|
+
`${location}.transportKind`,
|
|
747
|
+
"Protocol transportKind",
|
|
748
|
+
)) {
|
|
749
|
+
// already reported
|
|
750
|
+
} else if (!ProtocolTransportKindSet.has(normalizedTransportKind)) {
|
|
751
|
+
pushIssue(
|
|
752
|
+
issues,
|
|
753
|
+
"error",
|
|
754
|
+
"unknown-protocol-transport-kind",
|
|
755
|
+
`Protocol "${protocol.protocolId ?? "protocol"}" transportKind must be one of: ${Array.from(ProtocolTransportKindSet).join(", ")}.`,
|
|
756
|
+
`${location}.transportKind`,
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
const normalizedRole = normalizeProtocolRole(protocol.role);
|
|
760
|
+
if (!validateStringField(
|
|
761
|
+
issues,
|
|
762
|
+
protocol.role,
|
|
763
|
+
`${location}.role`,
|
|
764
|
+
"Protocol role",
|
|
765
|
+
)) {
|
|
766
|
+
// already reported
|
|
767
|
+
} else if (!ProtocolRoleSet.has(normalizedRole)) {
|
|
768
|
+
pushIssue(
|
|
769
|
+
issues,
|
|
770
|
+
"error",
|
|
771
|
+
"unknown-protocol-role",
|
|
772
|
+
`Protocol "${protocol.protocolId ?? "protocol"}" role must be one of: ${Array.from(ProtocolRoleSet).join(", ")}.`,
|
|
773
|
+
`${location}.role`,
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
validateOptionalStringField(
|
|
777
|
+
issues,
|
|
778
|
+
protocol.specUri,
|
|
779
|
+
`${location}.specUri`,
|
|
780
|
+
"Protocol specUri",
|
|
781
|
+
);
|
|
782
|
+
validateOptionalStringField(
|
|
783
|
+
issues,
|
|
784
|
+
protocol.discoveryKey,
|
|
785
|
+
`${location}.discoveryKey`,
|
|
786
|
+
"Protocol discoveryKey",
|
|
787
|
+
);
|
|
788
|
+
validateOptionalBooleanField(
|
|
789
|
+
issues,
|
|
790
|
+
protocol.autoInstall,
|
|
791
|
+
`${location}.autoInstall`,
|
|
792
|
+
"Protocol autoInstall",
|
|
793
|
+
);
|
|
794
|
+
validateOptionalBooleanField(
|
|
795
|
+
issues,
|
|
796
|
+
protocol.advertise,
|
|
797
|
+
`${location}.advertise`,
|
|
798
|
+
"Protocol advertise",
|
|
799
|
+
);
|
|
800
|
+
validateOptionalBooleanField(
|
|
801
|
+
issues,
|
|
802
|
+
protocol.requireSecureTransport,
|
|
803
|
+
`${location}.requireSecureTransport`,
|
|
804
|
+
"Protocol requireSecureTransport",
|
|
805
|
+
);
|
|
806
|
+
validateOptionalIntegerField(
|
|
807
|
+
issues,
|
|
808
|
+
protocol.defaultPort,
|
|
809
|
+
`${location}.defaultPort`,
|
|
810
|
+
"Protocol defaultPort",
|
|
811
|
+
{ min: 0, max: 65535 },
|
|
812
|
+
);
|
|
579
813
|
if (
|
|
580
814
|
protocolIdValid &&
|
|
581
815
|
Array.isArray(declaredCapabilities) &&
|
|
@@ -590,6 +824,77 @@ function validateProtocol(protocol, issues, location, methodLookup, declaredCapa
|
|
|
590
824
|
location,
|
|
591
825
|
);
|
|
592
826
|
}
|
|
827
|
+
if (
|
|
828
|
+
protocolIdValid &&
|
|
829
|
+
normalizedRole &&
|
|
830
|
+
(normalizedRole === ProtocolRole.HANDLE ||
|
|
831
|
+
normalizedRole === ProtocolRole.BOTH) &&
|
|
832
|
+
Array.isArray(declaredCapabilities) &&
|
|
833
|
+
!declaredCapabilities.includes("protocol_handle")
|
|
834
|
+
) {
|
|
835
|
+
pushIssue(
|
|
836
|
+
issues,
|
|
837
|
+
"error",
|
|
838
|
+
"missing-handle-protocol-capability",
|
|
839
|
+
`Protocol "${protocol.protocolId}" with role "${normalizedRole}" requires the "protocol_handle" capability.`,
|
|
840
|
+
location,
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
if (
|
|
844
|
+
protocolIdValid &&
|
|
845
|
+
normalizedRole &&
|
|
846
|
+
(normalizedRole === ProtocolRole.DIAL ||
|
|
847
|
+
normalizedRole === ProtocolRole.BOTH) &&
|
|
848
|
+
Array.isArray(declaredCapabilities) &&
|
|
849
|
+
!declaredCapabilities.includes("protocol_dial")
|
|
850
|
+
) {
|
|
851
|
+
pushIssue(
|
|
852
|
+
issues,
|
|
853
|
+
"error",
|
|
854
|
+
"missing-dial-protocol-capability",
|
|
855
|
+
`Protocol "${protocol.protocolId}" with role "${normalizedRole}" requires the "protocol_dial" capability.`,
|
|
856
|
+
location,
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
if (
|
|
860
|
+
protocol.advertise === true &&
|
|
861
|
+
normalizedRole === ProtocolRole.DIAL
|
|
862
|
+
) {
|
|
863
|
+
pushIssue(
|
|
864
|
+
issues,
|
|
865
|
+
"error",
|
|
866
|
+
"protocol-advertise-role-conflict",
|
|
867
|
+
`Protocol "${protocol.protocolId ?? "protocol"}" cannot advertise when role is "dial".`,
|
|
868
|
+
`${location}.advertise`,
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
if (
|
|
872
|
+
normalizedTransportKind === ProtocolTransportKind.LIBP2P &&
|
|
873
|
+
Array.isArray(declaredCapabilities) &&
|
|
874
|
+
!declaredCapabilities.includes("ipfs")
|
|
875
|
+
) {
|
|
876
|
+
pushIssue(
|
|
877
|
+
issues,
|
|
878
|
+
"error",
|
|
879
|
+
"missing-ipfs-capability",
|
|
880
|
+
`Protocol "${protocol.protocolId ?? "protocol"}" with transportKind "libp2p" requires the "ipfs" capability.`,
|
|
881
|
+
location,
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
if (
|
|
885
|
+
wireIdValid &&
|
|
886
|
+
normalizedTransportKind === ProtocolTransportKind.WS &&
|
|
887
|
+
protocol.defaultPort === 443 &&
|
|
888
|
+
protocol.requireSecureTransport !== true
|
|
889
|
+
) {
|
|
890
|
+
pushIssue(
|
|
891
|
+
issues,
|
|
892
|
+
"warning",
|
|
893
|
+
"insecure-secure-port-hint",
|
|
894
|
+
`Protocol "${protocol.protocolId ?? "protocol"}" uses defaultPort 443 without requireSecureTransport=true.`,
|
|
895
|
+
`${location}.defaultPort`,
|
|
896
|
+
);
|
|
897
|
+
}
|
|
593
898
|
}
|
|
594
899
|
|
|
595
900
|
function validateRuntimeTargets(runtimeTargets, declaredCapabilities, issues, sourceName) {
|