@notionhq/custom-blocks-host 0.2.9 → 0.2.11
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/browser.js +1 -3308
- package/dist/createCustomBlockHost.d.ts.map +1 -1
- package/dist/createCustomBlockHost.js +11 -11
- package/dist/lifecycle/initErrors.d.ts +21 -10
- package/dist/lifecycle/initErrors.d.ts.map +1 -1
- package/dist/lifecycle/initErrors.js +104 -155
- package/dist/lifecycle/initializationController.d.ts.map +1 -1
- package/dist/lifecycle/initializationController.js +11 -9
- package/dist/messages/sandboxMessageRouter.d.ts.map +1 -1
- package/dist/messages/sandboxMessageRouter.js +3 -3
- package/package.json +1 -1
- package/src/createCustomBlockHost.ts +18 -13
- package/src/lifecycle/initErrors.ts +120 -166
- package/src/lifecycle/initializationController.ts +21 -15
- package/src/messages/sandboxMessageRouter.ts +6 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createCustomBlockHost.d.ts","sourceRoot":"","sources":["../src/createCustomBlockHost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAA;AAI5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AAiBvF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAA;AAC3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAA;AAEpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAA;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"createCustomBlockHost.d.ts","sourceRoot":"","sources":["../src/createCustomBlockHost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAA;AAI5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AAiBvF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAA;AAC3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAA;AAEpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAA;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAUzC,OAAO,KAAK,EACX,iCAAiC,EACjC,8BAA8B,EAI9B,MAAM,sBAAsB,CAAA;AAG7B,OAAO,KAAK,EACX,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,MAAM,qBAAqB,CAAA;AAe5B,MAAM,MAAM,sBAAsB,GAAG;IACpC,MAAM,EAAE,iBAAiB,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,EAAE,uBAAuB,CAAA;IACjC,oHAAoH;IACpH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,IAAI,CAAA;IACpD,gGAAgG;IAChG,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QACvB,QAAQ,EAAE,mBAAmB,CAAA;QAC7B,aAAa,CAAC,EAAE,MAAM,CAAA;KACtB,KAAK,IAAI,CAAA;IACV;;;;;OAKG;IACH,mBAAmB,EAAE,CAAC,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC1E,+FAA+F;IAC/F,mBAAmB,EAAE,CAAC,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACnE,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC1E,eAAe,EAAE,8BAA8B,CAAA;IAC/C,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAAK,IAAI,CAAA;IAC/D,eAAe,EAAE,CAChB,YAAY,EAAE,UAAU,CAAC,OAAO,wBAAwB,CAAC,KACrD,IAAI,CAAA;IACT,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,KAAK,IAAI,CAAA;IAClE,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,KAAK,IAAI,CAAA;IACjE,cAAc,EAAE,CAAC,WAAW,EAAE,iCAAiC,KAAK,IAAI,CAAA;IACxE,cAAc,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,KAAK,IAAI,CAAA;IAC1E,YAAY,EAAE,CAAC,IAAI,EAAE;QACpB,YAAY,EAAE,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAA;KACzD,KAAK,IAAI,CAAA;CACV,CAAA;AAQD,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,sBAAsB,GAC7B,qBAAqB,CA8YvB"}
|
|
@@ -5,7 +5,7 @@ import { hostToSandboxMessageSchema, } from "./protocol/messages/hostToSandbox.j
|
|
|
5
5
|
import { initMessageSchema, } from "./protocol/messages/init.js";
|
|
6
6
|
import { LATEST_BRIDGE_PROTOCOL_VERSION } from "./protocol/protocolVersion.js";
|
|
7
7
|
import * as v from "valibot";
|
|
8
|
-
import {
|
|
8
|
+
import { contextUnavailableError, invalidPropertyBindingError, missingDataSourceBindingError, missingPropertyBindingError, } from "./lifecycle/initErrors.js";
|
|
9
9
|
import { createInitializationController } from "./lifecycle/initializationController.js";
|
|
10
10
|
import { normalizeHostToSandboxMessage } from "./lifecycle/normalizeHostToSandboxMessage.js";
|
|
11
11
|
import { customBlockHostInitialStateSchema } from "./lifecycle/types.js";
|
|
@@ -231,14 +231,14 @@ export function createCustomBlockHost(options) {
|
|
|
231
231
|
initialState.page.type === "unavailable") {
|
|
232
232
|
return {
|
|
233
233
|
status: "error",
|
|
234
|
-
error:
|
|
234
|
+
error: contextUnavailableError(),
|
|
235
235
|
};
|
|
236
236
|
}
|
|
237
|
-
const
|
|
238
|
-
if (
|
|
237
|
+
const bindingError = getBindingError(initialState.manifest, initialState.dataSources);
|
|
238
|
+
if (bindingError !== undefined) {
|
|
239
239
|
return {
|
|
240
240
|
status: "error",
|
|
241
|
-
error:
|
|
241
|
+
error: bindingError,
|
|
242
242
|
};
|
|
243
243
|
}
|
|
244
244
|
activeDataSources = initialState.dataSources;
|
|
@@ -297,7 +297,7 @@ export function createCustomBlockHost(options) {
|
|
|
297
297
|
hasPreparedInitialState) ||
|
|
298
298
|
initializationController.status === "waitingForInitResult" ||
|
|
299
299
|
initializationController.status === "initialized")) {
|
|
300
|
-
stopWithFailure(
|
|
300
|
+
stopWithFailure(contextUnavailableError());
|
|
301
301
|
return;
|
|
302
302
|
}
|
|
303
303
|
updateHostState({ page });
|
|
@@ -311,7 +311,7 @@ export function createCustomBlockHost(options) {
|
|
|
311
311
|
};
|
|
312
312
|
if (initializationController.hasConnectedSandbox &&
|
|
313
313
|
manifest !== undefined &&
|
|
314
|
-
|
|
314
|
+
getBindingError(manifest, normalizedDataSources) !== undefined) {
|
|
315
315
|
emit("warn", {
|
|
316
316
|
message: "Ignored invalid data source bindings update",
|
|
317
317
|
payload: normalizedDataSources,
|
|
@@ -340,21 +340,21 @@ export function createCustomBlockHost(options) {
|
|
|
340
340
|
function getCollectionSchema(dataSources, dataSourceId) {
|
|
341
341
|
return Object.values(dataSources?.bindings ?? {}).find(binding => binding.collectionPointer?.id === dataSourceId)?.collectionSchema;
|
|
342
342
|
}
|
|
343
|
-
function
|
|
343
|
+
function getBindingError(manifest, dataSources) {
|
|
344
344
|
for (const [dataSourceKey, manifestDataSource] of Object.entries(manifest.dataSources)) {
|
|
345
345
|
const binding = dataSources.bindings[dataSourceKey];
|
|
346
346
|
if (binding?.collectionPointer === undefined ||
|
|
347
347
|
binding.collectionSchema === undefined) {
|
|
348
|
-
return
|
|
348
|
+
return missingDataSourceBindingError();
|
|
349
349
|
}
|
|
350
350
|
for (const [propertyKey, manifestProperty] of Object.entries(manifestDataSource.properties ?? {})) {
|
|
351
351
|
const propertyId = binding.propertyIdsByKey?.[propertyKey];
|
|
352
352
|
if (propertyId === undefined) {
|
|
353
|
-
return
|
|
353
|
+
return missingPropertyBindingError();
|
|
354
354
|
}
|
|
355
355
|
if (binding.collectionSchema.propertiesById[propertyId]?.type !==
|
|
356
356
|
manifestProperty.type) {
|
|
357
|
-
return
|
|
357
|
+
return invalidPropertyBindingError();
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
360
|
}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CustomBlockErrorInfo } from "../protocol/errors.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `connect` message. `isRetryable` means a fresh iframe / `init` attempt could plausibly succeed
|
|
7
|
-
* without changing block code or host configuration.
|
|
3
|
+
* Initialization handshakes are one-shot: after an error, this host instance will not answer
|
|
4
|
+
* another `connect` message. `isRetryable` means a fresh host and iframe could plausibly
|
|
5
|
+
* initialize without changing block code or host configuration.
|
|
8
6
|
*/
|
|
9
|
-
export declare function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
export declare function noConnectError(): CustomBlockErrorInfo<"no_connect">;
|
|
8
|
+
export declare function invalidConnectPayloadError(): CustomBlockErrorInfo<"invalid_connect_payload">;
|
|
9
|
+
export declare function invalidProtocolVersionError(args: {
|
|
10
|
+
currentBridgeProtocolVersion: number | undefined;
|
|
11
|
+
}): CustomBlockErrorInfo<"invalid_protocol_version">;
|
|
12
|
+
export declare function unsupportedProtocolVersionError(args: {
|
|
13
|
+
currentBridgeProtocolVersion: number;
|
|
14
|
+
minBridgeProtocolVersion: number;
|
|
15
|
+
}): CustomBlockErrorInfo<"unsupported_protocol_version">;
|
|
16
|
+
export declare function contextUnavailableError(): CustomBlockErrorInfo<"context_unavailable">;
|
|
17
|
+
export declare function initialStateTimeoutError(): CustomBlockErrorInfo<"initial_state_timeout">;
|
|
18
|
+
export declare function missingDataSourceBindingError(): CustomBlockErrorInfo<"missing_data_source_binding">;
|
|
19
|
+
export declare function missingPropertyBindingError(): CustomBlockErrorInfo<"missing_property_binding">;
|
|
20
|
+
export declare function invalidPropertyBindingError(): CustomBlockErrorInfo<"invalid_property_binding">;
|
|
21
|
+
export declare function noInitResultError(): CustomBlockErrorInfo<"no_init_result">;
|
|
22
|
+
export declare function invalidInitResultPayloadError(): CustomBlockErrorInfo<"invalid_init_result_payload">;
|
|
23
|
+
export declare function unknownInitializationError(): CustomBlockErrorInfo<"unknown_error">;
|
|
13
24
|
//# sourceMappingURL=initErrors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initErrors.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"initErrors.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAA;AAEtF;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAAC,YAAY,CAAC,CAOnE;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAAC,yBAAyB,CAAC,CAO5F;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IACjD,4BAA4B,EAAE,MAAM,GAAG,SAAS,CAAA;CAChD,GAAG,oBAAoB,CAAC,0BAA0B,CAAC,CAWnD;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACrD,4BAA4B,EAAE,MAAM,CAAA;IACpC,wBAAwB,EAAE,MAAM,CAAA;CAChC,GAAG,oBAAoB,CAAC,8BAA8B,CAAC,CAQvD;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAAC,qBAAqB,CAAC,CAOrF;AAED,wBAAgB,wBAAwB,IAAI,oBAAoB,CAAC,uBAAuB,CAAC,CAOxF;AAED,wBAAgB,6BAA6B,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAOnG;AAED,wBAAgB,2BAA2B,IAAI,oBAAoB,CAAC,0BAA0B,CAAC,CAO9F;AAED,wBAAgB,2BAA2B,IAAI,oBAAoB,CAAC,0BAA0B,CAAC,CAQ9F;AAED,wBAAgB,iBAAiB,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,CAO1E;AAED,wBAAgB,6BAA6B,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAOnG;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAAC,eAAe,CAAC,CAOlF"}
|
|
@@ -1,158 +1,107 @@
|
|
|
1
|
-
const UNKNOWN_ERROR_MESSAGE = "Unexpected error while initializing custom block.";
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `connect` message. `isRetryable` means a fresh iframe / `init` attempt could plausibly succeed
|
|
7
|
-
* without changing block code or host configuration.
|
|
2
|
+
* Initialization handshakes are one-shot: after an error, this host instance will not answer
|
|
3
|
+
* another `connect` message. `isRetryable` means a fresh host and iframe could plausibly
|
|
4
|
+
* initialize without changing block code or host configuration.
|
|
8
5
|
*/
|
|
9
|
-
export function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
code: reason,
|
|
112
|
-
message: "A mapped data source property is missing or incompatible.",
|
|
113
|
-
// The bound property's schema must be updated or the binding must be updated to
|
|
114
|
-
// a property with a compatible schema.
|
|
115
|
-
isRetryable: false,
|
|
116
|
-
};
|
|
117
|
-
case "no_init_result":
|
|
118
|
-
return {
|
|
119
|
-
code: reason,
|
|
120
|
-
message: "Sandbox did not acknowledge initialization.",
|
|
121
|
-
isRetryable: true,
|
|
122
|
-
};
|
|
123
|
-
case "invalid_init_result_payload":
|
|
124
|
-
return {
|
|
125
|
-
code: reason,
|
|
126
|
-
message: "Sandbox sent an invalid initialization result.",
|
|
127
|
-
isRetryable: false,
|
|
128
|
-
};
|
|
129
|
-
case "invalid_init_bindings":
|
|
130
|
-
return {
|
|
131
|
-
code: reason,
|
|
132
|
-
message: "Sandbox rejected the host-provided data source bindings.",
|
|
133
|
-
isRetryable: false,
|
|
134
|
-
};
|
|
135
|
-
case "not_in_iframe":
|
|
136
|
-
return {
|
|
137
|
-
code: reason,
|
|
138
|
-
message: "<NotionCustomBlock> only works inside an iframe.",
|
|
139
|
-
// The block must be embedded in an iframe.
|
|
140
|
-
isRetryable: false,
|
|
141
|
-
};
|
|
142
|
-
case "unknown_error":
|
|
143
|
-
return {
|
|
144
|
-
code: reason,
|
|
145
|
-
message: UNKNOWN_ERROR_MESSAGE,
|
|
146
|
-
// Treat unknown errors as non-retryable.
|
|
147
|
-
isRetryable: false,
|
|
148
|
-
};
|
|
149
|
-
default:
|
|
150
|
-
console.warn(`Unexpected custom block init error: ${reason}`);
|
|
151
|
-
return {
|
|
152
|
-
code: reason,
|
|
153
|
-
message: UNKNOWN_ERROR_MESSAGE,
|
|
154
|
-
// Treat unknown error codes as non-retryable.
|
|
155
|
-
isRetryable: false,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
6
|
+
export function noConnectError() {
|
|
7
|
+
return {
|
|
8
|
+
code: "no_connect",
|
|
9
|
+
message: "Sandbox did not send a connect message.",
|
|
10
|
+
// A fresh iframe may finish loading and send connect before the timeout.
|
|
11
|
+
isRetryable: true,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function invalidConnectPayloadError() {
|
|
15
|
+
return {
|
|
16
|
+
code: "invalid_connect_payload",
|
|
17
|
+
message: "Sandbox sent an invalid connect message.",
|
|
18
|
+
// The sandbox must be updated to send a valid connect message.
|
|
19
|
+
isRetryable: false,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function invalidProtocolVersionError(args) {
|
|
23
|
+
const { currentBridgeProtocolVersion } = args;
|
|
24
|
+
const versionText = currentBridgeProtocolVersion
|
|
25
|
+
? `: ${currentBridgeProtocolVersion}`
|
|
26
|
+
: ".";
|
|
27
|
+
return {
|
|
28
|
+
code: "invalid_protocol_version",
|
|
29
|
+
message: `Sandbox reported an invalid bridge protocol version ${versionText}`,
|
|
30
|
+
// The sandbox must be updated to a supported protocol version.
|
|
31
|
+
isRetryable: false,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function unsupportedProtocolVersionError(args) {
|
|
35
|
+
const { currentBridgeProtocolVersion, minBridgeProtocolVersion } = args;
|
|
36
|
+
return {
|
|
37
|
+
code: "unsupported_protocol_version",
|
|
38
|
+
message: `Sandbox bridge protocol version ${currentBridgeProtocolVersion} is not supported. Minimum supported version is ${minBridgeProtocolVersion}.`,
|
|
39
|
+
// The sandbox must be updated to a supported protocol version.
|
|
40
|
+
isRetryable: false,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function contextUnavailableError() {
|
|
44
|
+
return {
|
|
45
|
+
code: "context_unavailable",
|
|
46
|
+
message: "Host page context is unavailable.",
|
|
47
|
+
// Page context may become available before a fresh initialization attempt.
|
|
48
|
+
isRetryable: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function initialStateTimeoutError() {
|
|
52
|
+
return {
|
|
53
|
+
code: "initial_state_timeout",
|
|
54
|
+
message: "Host did not prepare initial state before the timeout.",
|
|
55
|
+
// A fresh attempt may finish loading host dependencies before the timeout.
|
|
56
|
+
isRetryable: true,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function missingDataSourceBindingError() {
|
|
60
|
+
return {
|
|
61
|
+
code: "missing_data_source_binding",
|
|
62
|
+
message: "A required data source is not mapped.",
|
|
63
|
+
// Host configuration must be changed before this block can initialize.
|
|
64
|
+
isRetryable: false,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function missingPropertyBindingError() {
|
|
68
|
+
return {
|
|
69
|
+
code: "missing_property_binding",
|
|
70
|
+
message: "A required data source property is not mapped.",
|
|
71
|
+
// Host configuration must be changed before this block can initialize.
|
|
72
|
+
isRetryable: false,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function invalidPropertyBindingError() {
|
|
76
|
+
return {
|
|
77
|
+
code: "invalid_property_binding",
|
|
78
|
+
message: "A mapped data source property is missing or incompatible.",
|
|
79
|
+
// The bound property's schema must be updated or the binding must be updated to
|
|
80
|
+
// a property with a compatible schema.
|
|
81
|
+
isRetryable: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function noInitResultError() {
|
|
85
|
+
return {
|
|
86
|
+
code: "no_init_result",
|
|
87
|
+
message: "Sandbox did not acknowledge initialization.",
|
|
88
|
+
// A fresh iframe may process init and acknowledge it before the timeout.
|
|
89
|
+
isRetryable: true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function invalidInitResultPayloadError() {
|
|
93
|
+
return {
|
|
94
|
+
code: "invalid_init_result_payload",
|
|
95
|
+
message: "Sandbox sent an invalid initialization result.",
|
|
96
|
+
// The sandbox must be updated to send a valid initialization result.
|
|
97
|
+
isRetryable: false,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function unknownInitializationError() {
|
|
101
|
+
return {
|
|
102
|
+
code: "unknown_error",
|
|
103
|
+
message: "Unexpected error while initializing custom block.",
|
|
104
|
+
// Without a known transient cause, conservatively treat unknown errors as non-retryable.
|
|
105
|
+
isRetryable: false,
|
|
106
|
+
};
|
|
158
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initializationController.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initializationController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EACX,wBAAwB,EACxB,iBAAiB,EACjB,MAAM,mDAAmD,CAAA;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"initializationController.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initializationController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EACX,wBAAwB,EACxB,iBAAiB,EACjB,MAAM,mDAAmD,CAAA;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAWlE,OAAO,KAAK,EACX,qBAAqB,EACrB,iCAAiC,EACjC,UAAU,EACV,MAAM,YAAY,CAAA;AAMnB,MAAM,MAAM,+BAA+B,GAAG;IAC7C,WAAW,EAAE,CACZ,OAAO,EAAE,qBAAqB,KAC1B,OAAO,CAAC,iCAAiC,CAAC,CAAA;IAC/C,eAAe,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAAK,IAAI,CAAA;IACxE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,4BAA4B,EAAE,MAAM,IAAI,CAAA;IACxC,wBAAwB,EAAE,MAAM,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mBAAmB,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;IAC5D,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACnD,mBAAmB,EAAE,CAAC,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CAC1E,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC,aAAa,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAChD,gBAAgB,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACtD,oBAAoB,EAAE,CAAC,IAAI,EAAE;QAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;QACpC,KAAK,EAAE,wBAAwB,CAAA;QAC/B,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAA;KACzC,KAAK,SAAS,GAAG,MAAM,CAAA;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE;QAC/B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;QACpC,KAAK,EAAE,wBAAwB,CAAA;KAC/B,KAAK,IAAI,CAAA;IACV,YAAY,EAAE,MAAM,IAAI,CAAA;IACxB,IAAI,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,+BAA+B,GACtC,wBAAwB,CAgU1B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_CONTRAST_MODE } from "../protocol/contrast.js";
|
|
2
2
|
import { unreachable } from "../utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import { initialStateTimeoutError, invalidProtocolVersionError, noConnectError, noInitResultError, unknownInitializationError, unsupportedProtocolVersionError, } from "./initErrors.js";
|
|
4
4
|
import { isValidBridgeProtocolVersion } from "./protocolVersion.js";
|
|
5
5
|
const DEFAULT_NO_CONNECT_TIMEOUT_MS = 5_000;
|
|
6
6
|
const DEFAULT_INITIAL_STATE_TIMEOUT_MS = 5_000;
|
|
@@ -69,7 +69,7 @@ export function createInitializationController(options) {
|
|
|
69
69
|
if (initStatus !== "preparingInit") {
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
|
-
const error =
|
|
72
|
+
const error = initialStateTimeoutError();
|
|
73
73
|
warn({
|
|
74
74
|
...error,
|
|
75
75
|
initializationId: connect.initializationId,
|
|
@@ -109,7 +109,7 @@ export function createInitializationController(options) {
|
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
111
111
|
initStatus = "error";
|
|
112
|
-
const error =
|
|
112
|
+
const error = noInitResultError();
|
|
113
113
|
onConnectionFailure?.(error);
|
|
114
114
|
warn({
|
|
115
115
|
...error,
|
|
@@ -127,7 +127,7 @@ export function createInitializationController(options) {
|
|
|
127
127
|
});
|
|
128
128
|
sendInitError({
|
|
129
129
|
initializationId: connect.initializationId,
|
|
130
|
-
error:
|
|
130
|
+
error: unknownInitializationError(),
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -140,7 +140,7 @@ export function createInitializationController(options) {
|
|
|
140
140
|
}
|
|
141
141
|
// Verify the bridge protocol version is valid.
|
|
142
142
|
if (!isValidBridgeProtocolVersion(message.bridgeProtocolVersion)) {
|
|
143
|
-
const initError =
|
|
143
|
+
const initError = invalidProtocolVersionError({
|
|
144
144
|
currentBridgeProtocolVersion: message.bridgeProtocolVersion,
|
|
145
145
|
});
|
|
146
146
|
sendInitError({
|
|
@@ -150,7 +150,7 @@ export function createInitializationController(options) {
|
|
|
150
150
|
return;
|
|
151
151
|
}
|
|
152
152
|
if (message.bridgeProtocolVersion < minBridgeProtocolVersion) {
|
|
153
|
-
const initError =
|
|
153
|
+
const initError = unsupportedProtocolVersionError({
|
|
154
154
|
currentBridgeProtocolVersion: message.bridgeProtocolVersion,
|
|
155
155
|
minBridgeProtocolVersion,
|
|
156
156
|
});
|
|
@@ -187,10 +187,12 @@ export function createInitializationController(options) {
|
|
|
187
187
|
// when the malformed message includes a numeric version.
|
|
188
188
|
if (bridgeProtocolVersion !== undefined) {
|
|
189
189
|
if (!isValidBridgeProtocolVersion(bridgeProtocolVersion)) {
|
|
190
|
-
error =
|
|
190
|
+
error = invalidProtocolVersionError({
|
|
191
|
+
currentBridgeProtocolVersion: undefined,
|
|
192
|
+
});
|
|
191
193
|
}
|
|
192
194
|
else if (bridgeProtocolVersion < minBridgeProtocolVersion) {
|
|
193
|
-
error =
|
|
195
|
+
error = unsupportedProtocolVersionError({
|
|
194
196
|
currentBridgeProtocolVersion: bridgeProtocolVersion,
|
|
195
197
|
minBridgeProtocolVersion,
|
|
196
198
|
});
|
|
@@ -236,7 +238,7 @@ export function createInitializationController(options) {
|
|
|
236
238
|
return;
|
|
237
239
|
}
|
|
238
240
|
initStatus = "error";
|
|
239
|
-
const error =
|
|
241
|
+
const error = noConnectError();
|
|
240
242
|
warn(error);
|
|
241
243
|
onConnectionFailure?.(error);
|
|
242
244
|
}, noConnectTimeoutMs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandboxMessageRouter.d.ts","sourceRoot":"","sources":["../../src/messages/sandboxMessageRouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAA;AAE/G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wDAAwD,CAAA;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AAC5F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8DAA8D,CAAA;AAC1G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qDAAqD,CAAA;AAExF,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,yEAAyE,CAAA;AAChI,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;
|
|
1
|
+
{"version":3,"file":"sandboxMessageRouter.d.ts","sourceRoot":"","sources":["../../src/messages/sandboxMessageRouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAA;AAE/G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wDAAwD,CAAA;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AAC5F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8DAA8D,CAAA;AAC1G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qDAAqD,CAAA;AAExF,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,yEAAyE,CAAA;AAChI,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAMhG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAA;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAY7D,MAAM,MAAM,2BAA2B,GAAG;IACzC,MAAM,EAAE,iBAAiB,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,UAAU,CAAA;IAC/B,IAAI,EAAE,CAAC,SAAS,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACxE,QAAQ,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAClD,gBAAgB,EAAE,wBAAwB,CAAC,sBAAsB,CAAC,CAAA;IAClE,mBAAmB,EAAE,wBAAwB,CAAC,yBAAyB,CAAC,CAAA;IACxE,SAAS,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAC5C,YAAY,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAClD,iBAAiB,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5E,4BAA4B,EAAE,CAC7B,OAAO,EAAE,iCAAiC,KACtC,IAAI,CAAA;IACT,YAAY,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,UAAU,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9D,SAAS,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,SAAS,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,WAAW,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,YAAY,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,QAAQ,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;CAC1C,CAAA;AAED,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,2BAA2B,GAClC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAsI/B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isInitHandshakeMessage } from "../protocol/messages/isInitHandshakeMessage.js";
|
|
2
2
|
import { sandboxToHostMessageSchema } from "../protocol/messages/sandboxToHost.js";
|
|
3
3
|
import * as v from "valibot";
|
|
4
|
-
import {
|
|
4
|
+
import { invalidConnectPayloadError, invalidInitResultPayloadError, } from "../lifecycle/initErrors.js";
|
|
5
5
|
import { unreachable } from "../utils.js";
|
|
6
6
|
import { getInvalidSandboxMessageResponse } from "./invalidSandboxMessage.js";
|
|
7
7
|
const initializationIdentitySchema = v.object({
|
|
@@ -28,7 +28,7 @@ export function createSandboxMessageRouter(options) {
|
|
|
28
28
|
initializationId: parsedIdentity.success
|
|
29
29
|
? parsedIdentity.output.initializationId
|
|
30
30
|
: undefined,
|
|
31
|
-
error:
|
|
31
|
+
error: invalidConnectPayloadError(),
|
|
32
32
|
bridgeProtocolVersion: parsedVersion.success
|
|
33
33
|
? parsedVersion.output.bridgeProtocolVersion
|
|
34
34
|
: undefined,
|
|
@@ -44,7 +44,7 @@ export function createSandboxMessageRouter(options) {
|
|
|
44
44
|
initializationId: parsedIdentity.success
|
|
45
45
|
? parsedIdentity.output.initializationId
|
|
46
46
|
: undefined,
|
|
47
|
-
error:
|
|
47
|
+
error: invalidInitResultPayloadError(),
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
// Other messages get NACKed indicating they were invalid and skipped.
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
hostToSandboxMessageSchema,
|
|
11
11
|
} from "@notionhq/custom-blocks-protocol/messages/hostToSandbox.js"
|
|
12
12
|
import {
|
|
13
|
-
type
|
|
13
|
+
type CustomBlockInitErrorInfo,
|
|
14
14
|
initMessageSchema,
|
|
15
15
|
} from "@notionhq/custom-blocks-protocol/messages/init.js"
|
|
16
16
|
import type { InvalidSandboxMessage } from "@notionhq/custom-blocks-protocol/messages/invalidSandboxMessage.js"
|
|
@@ -27,7 +27,12 @@ import type { notionThemeSchema } from "@notionhq/custom-blocks-protocol/theme.j
|
|
|
27
27
|
import type { notionUserSchema } from "@notionhq/custom-blocks-protocol/users/user.js"
|
|
28
28
|
import type { InferInput } from "valibot"
|
|
29
29
|
import * as v from "valibot"
|
|
30
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
contextUnavailableError,
|
|
32
|
+
invalidPropertyBindingError,
|
|
33
|
+
missingDataSourceBindingError,
|
|
34
|
+
missingPropertyBindingError,
|
|
35
|
+
} from "./lifecycle/initErrors.js"
|
|
31
36
|
import { createInitializationController } from "./lifecycle/initializationController.js"
|
|
32
37
|
import { normalizeHostToSandboxMessage } from "./lifecycle/normalizeHostToSandboxMessage.js"
|
|
33
38
|
import type {
|
|
@@ -387,17 +392,17 @@ export function createCustomBlockHost(
|
|
|
387
392
|
) {
|
|
388
393
|
return {
|
|
389
394
|
status: "error",
|
|
390
|
-
error:
|
|
395
|
+
error: contextUnavailableError(),
|
|
391
396
|
}
|
|
392
397
|
}
|
|
393
|
-
const
|
|
398
|
+
const bindingError = getBindingError(
|
|
394
399
|
initialState.manifest,
|
|
395
400
|
initialState.dataSources,
|
|
396
401
|
)
|
|
397
|
-
if (
|
|
402
|
+
if (bindingError !== undefined) {
|
|
398
403
|
return {
|
|
399
404
|
status: "error",
|
|
400
|
-
error:
|
|
405
|
+
error: bindingError,
|
|
401
406
|
}
|
|
402
407
|
}
|
|
403
408
|
activeDataSources = initialState.dataSources
|
|
@@ -464,7 +469,7 @@ export function createCustomBlockHost(
|
|
|
464
469
|
initializationController.status === "waitingForInitResult" ||
|
|
465
470
|
initializationController.status === "initialized")
|
|
466
471
|
) {
|
|
467
|
-
stopWithFailure(
|
|
472
|
+
stopWithFailure(contextUnavailableError())
|
|
468
473
|
return
|
|
469
474
|
}
|
|
470
475
|
updateHostState({ page })
|
|
@@ -483,7 +488,7 @@ export function createCustomBlockHost(
|
|
|
483
488
|
if (
|
|
484
489
|
initializationController.hasConnectedSandbox &&
|
|
485
490
|
manifest !== undefined &&
|
|
486
|
-
|
|
491
|
+
getBindingError(manifest, normalizedDataSources) !== undefined
|
|
487
492
|
) {
|
|
488
493
|
emit("warn", {
|
|
489
494
|
message: "Ignored invalid data source bindings update",
|
|
@@ -523,10 +528,10 @@ function getCollectionSchema(
|
|
|
523
528
|
)?.collectionSchema
|
|
524
529
|
}
|
|
525
530
|
|
|
526
|
-
function
|
|
531
|
+
function getBindingError(
|
|
527
532
|
manifest: InferInput<typeof manifestSchema>,
|
|
528
533
|
dataSources: CustomBlockHostDataSourcesPayload,
|
|
529
|
-
):
|
|
534
|
+
): CustomBlockInitErrorInfo | undefined {
|
|
530
535
|
for (const [dataSourceKey, manifestDataSource] of Object.entries(
|
|
531
536
|
manifest.dataSources,
|
|
532
537
|
)) {
|
|
@@ -535,20 +540,20 @@ function getBindingErrorCode(
|
|
|
535
540
|
binding?.collectionPointer === undefined ||
|
|
536
541
|
binding.collectionSchema === undefined
|
|
537
542
|
) {
|
|
538
|
-
return
|
|
543
|
+
return missingDataSourceBindingError()
|
|
539
544
|
}
|
|
540
545
|
for (const [propertyKey, manifestProperty] of Object.entries(
|
|
541
546
|
manifestDataSource.properties ?? {},
|
|
542
547
|
)) {
|
|
543
548
|
const propertyId = binding.propertyIdsByKey?.[propertyKey]
|
|
544
549
|
if (propertyId === undefined) {
|
|
545
|
-
return
|
|
550
|
+
return missingPropertyBindingError()
|
|
546
551
|
}
|
|
547
552
|
if (
|
|
548
553
|
binding.collectionSchema.propertiesById[propertyId]?.type !==
|
|
549
554
|
manifestProperty.type
|
|
550
555
|
) {
|
|
551
|
-
return
|
|
556
|
+
return invalidPropertyBindingError()
|
|
552
557
|
}
|
|
553
558
|
}
|
|
554
559
|
}
|