@notionhq/custom-blocks-host 0.3.3 → 0.3.5
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 +11 -4
- package/dist/browser.js +1 -1
- package/dist/createCustomBlockHost.d.ts.map +1 -1
- package/dist/createCustomBlockHost.js +68 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lifecycle/legacyPage.d.ts +68 -0
- package/dist/lifecycle/legacyPage.d.ts.map +1 -0
- package/dist/lifecycle/legacyPage.js +159 -0
- package/dist/lifecycle/normalizeHostToSandboxMessage.d.ts +2 -2
- package/dist/lifecycle/normalizeHostToSandboxMessage.d.ts.map +1 -1
- package/dist/lifecycle/normalizeHostToSandboxMessage.js +4 -32
- package/dist/lifecycle/normalizeQueryPage.d.ts +3 -0
- package/dist/lifecycle/normalizeQueryPage.d.ts.map +1 -0
- package/dist/lifecycle/normalizeQueryPage.js +13 -0
- package/dist/messages/parseExternalUrl.d.ts +3 -0
- package/dist/messages/parseExternalUrl.d.ts.map +1 -0
- package/dist/messages/parseExternalUrl.js +15 -0
- package/dist/messages/sandboxMessageRouter.d.ts +2 -0
- package/dist/messages/sandboxMessageRouter.d.ts.map +1 -1
- package/dist/messages/sandboxMessageRouter.js +19 -4
- package/dist/messages/types.d.ts +7 -0
- package/dist/messages/types.d.ts.map +1 -1
- package/dist/protocol/dataSources/dataSourcePage.d.ts +1 -2
- package/dist/protocol/dataSources/dataSourcePage.js +1 -2
- package/dist/protocol/index.d.ts +1 -0
- package/dist/protocol/index.js +1 -0
- package/dist/protocol/messages/hostToSandbox.d.ts +1649 -241
- package/dist/protocol/messages/hostToSandbox.js +15 -6
- package/dist/protocol/messages/openExternalUrl.d.ts +32 -0
- package/dist/protocol/messages/openExternalUrl.js +26 -0
- package/dist/protocol/messages/queryDataSourceResult.d.ts +174 -0
- package/dist/protocol/messages/queryDataSourceResult.js +15 -0
- package/dist/protocol/messages/sandboxToHost.d.ts +4 -0
- package/dist/protocol/messages/sandboxToHost.js +2 -0
- package/package.json +1 -1
- package/src/createCustomBlockHost.ts +79 -1
- package/src/index.ts +4 -0
- package/src/lifecycle/legacyPage.ts +183 -0
- package/src/lifecycle/normalizeHostToSandboxMessage.ts +9 -37
- package/src/lifecycle/normalizeQueryPage.ts +25 -0
- package/src/messages/parseExternalUrl.ts +18 -0
- package/src/messages/sandboxMessageRouter.ts +24 -3
- package/src/messages/types.ts +23 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import type { NotionDataSourcePageBridge } from "@notionhq/custom-blocks-protocol/dataSources/dataSourcePage.js"
|
|
2
|
+
import type { NotionDataSourceValue } from "@notionhq/custom-blocks-protocol/dataSources/dataSourceValue.js"
|
|
3
|
+
import type { NotionPagePropertyValue } from "@notionhq/custom-blocks-protocol/pages/page.js"
|
|
4
|
+
import { unreachable } from "../utils.js"
|
|
5
|
+
|
|
6
|
+
export function toLegacyQueryPage(page: NotionDataSourcePageBridge) {
|
|
7
|
+
const propertiesById: Record<string, NotionDataSourceValue | undefined> = {}
|
|
8
|
+
for (const property of Object.values(page.properties)) {
|
|
9
|
+
if (property) {
|
|
10
|
+
propertiesById[property.id] = toLegacyProperty(property)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
id: page.id,
|
|
15
|
+
is_archived: page.is_archived,
|
|
16
|
+
in_trash: page.in_trash,
|
|
17
|
+
propertiesById,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function plainText(items: Record<string, unknown>[]): string {
|
|
22
|
+
return items
|
|
23
|
+
.map(item => {
|
|
24
|
+
if (typeof item.plain_text === "string") {
|
|
25
|
+
return item.plain_text
|
|
26
|
+
}
|
|
27
|
+
const text = item.text
|
|
28
|
+
return text &&
|
|
29
|
+
typeof text === "object" &&
|
|
30
|
+
"content" in text &&
|
|
31
|
+
typeof text.content === "string"
|
|
32
|
+
? text.content
|
|
33
|
+
: ""
|
|
34
|
+
})
|
|
35
|
+
.join("")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function timestamp(
|
|
39
|
+
value: string | number | null | undefined,
|
|
40
|
+
): NotionDataSourceValue | undefined {
|
|
41
|
+
if (value === undefined || value === null || value === "") {
|
|
42
|
+
return undefined
|
|
43
|
+
}
|
|
44
|
+
const date = new Date(value)
|
|
45
|
+
if (!Number.isFinite(date.getTime())) {
|
|
46
|
+
return undefined
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
type: "datetime",
|
|
50
|
+
start_date: date.toISOString().slice(0, 10),
|
|
51
|
+
start_time: date.toISOString().slice(11, 16),
|
|
52
|
+
time_zone: "UTC",
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function legacyDate(value: {
|
|
57
|
+
start: string
|
|
58
|
+
end?: string | null
|
|
59
|
+
time_zone?: string | null
|
|
60
|
+
}): NotionDataSourceValue {
|
|
61
|
+
const timed = value.start.includes("T") || value.time_zone != null
|
|
62
|
+
const offset = value.start.match(/([+-])(\d{2}):(\d{2})$/)
|
|
63
|
+
const offsetMinutes = offset
|
|
64
|
+
? (Number(offset[2]) * 60 + Number(offset[3])) *
|
|
65
|
+
(offset[1] === "-" ? -1 : 1)
|
|
66
|
+
: 0
|
|
67
|
+
const parts = (input: string) => {
|
|
68
|
+
if (!input.includes("T")) {
|
|
69
|
+
return { date: input, time: "00:00" }
|
|
70
|
+
}
|
|
71
|
+
const wallClock = input.match(
|
|
72
|
+
/^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?$/,
|
|
73
|
+
)
|
|
74
|
+
if (wallClock) {
|
|
75
|
+
return { date: wallClock[1], time: wallClock[2] }
|
|
76
|
+
}
|
|
77
|
+
if (!value.time_zone) {
|
|
78
|
+
const local = new Date(
|
|
79
|
+
new Date(input).getTime() + offsetMinutes * 60_000,
|
|
80
|
+
).toISOString()
|
|
81
|
+
return { date: local.slice(0, 10), time: local.slice(11, 16) }
|
|
82
|
+
}
|
|
83
|
+
const entries = new Intl.DateTimeFormat("en-CA", {
|
|
84
|
+
timeZone: value.time_zone,
|
|
85
|
+
year: "numeric",
|
|
86
|
+
month: "2-digit",
|
|
87
|
+
day: "2-digit",
|
|
88
|
+
hour: "2-digit",
|
|
89
|
+
minute: "2-digit",
|
|
90
|
+
hourCycle: "h23",
|
|
91
|
+
}).formatToParts(new Date(input))
|
|
92
|
+
const get = (type: string) =>
|
|
93
|
+
entries.find(part => part.type === type)?.value
|
|
94
|
+
return {
|
|
95
|
+
date: `${get("year")}-${get("month")}-${get("day")}`,
|
|
96
|
+
time: `${get("hour")}:${get("minute")}`,
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const start = parts(value.start)
|
|
100
|
+
const end = value.end ? parts(value.end) : undefined
|
|
101
|
+
if (!timed) {
|
|
102
|
+
return end
|
|
103
|
+
? { type: "daterange", start_date: start.date, end_date: end.date }
|
|
104
|
+
: { type: "date", start_date: start.date }
|
|
105
|
+
}
|
|
106
|
+
const zone =
|
|
107
|
+
value.time_zone ??
|
|
108
|
+
(offsetMinutes === 0
|
|
109
|
+
? "UTC"
|
|
110
|
+
: `UTC${offsetMinutes < 0 ? "-" : "+"}${Math.floor(Math.abs(offsetMinutes) / 60)}${Math.abs(offsetMinutes) % 60 === 0 ? "" : `:${String(Math.abs(offsetMinutes) % 60).padStart(2, "0")}`}`)
|
|
111
|
+
return end
|
|
112
|
+
? {
|
|
113
|
+
type: "datetimerange",
|
|
114
|
+
start_date: start.date,
|
|
115
|
+
start_time: start.time,
|
|
116
|
+
end_date: end.date,
|
|
117
|
+
end_time: end.time,
|
|
118
|
+
time_zone: zone,
|
|
119
|
+
}
|
|
120
|
+
: {
|
|
121
|
+
type: "datetime",
|
|
122
|
+
start_date: start.date,
|
|
123
|
+
start_time: start.time,
|
|
124
|
+
time_zone: zone,
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function toLegacyProperty(
|
|
129
|
+
property: NotionPagePropertyValue,
|
|
130
|
+
): NotionDataSourceValue | undefined {
|
|
131
|
+
switch (property.type) {
|
|
132
|
+
case "title":
|
|
133
|
+
return plainText(property.title)
|
|
134
|
+
case "rich_text":
|
|
135
|
+
return plainText(property.rich_text)
|
|
136
|
+
case "number":
|
|
137
|
+
return property.number ?? undefined
|
|
138
|
+
case "checkbox":
|
|
139
|
+
return property.checkbox
|
|
140
|
+
case "url":
|
|
141
|
+
return property.url ?? ""
|
|
142
|
+
case "email":
|
|
143
|
+
return property.email ?? ""
|
|
144
|
+
case "phone_number":
|
|
145
|
+
return property.phone_number ?? ""
|
|
146
|
+
case "select":
|
|
147
|
+
return property.select?.name
|
|
148
|
+
case "status":
|
|
149
|
+
return property.status?.name
|
|
150
|
+
case "multi_select":
|
|
151
|
+
return property.multi_select.flatMap(option => option.name ?? [])
|
|
152
|
+
case "date":
|
|
153
|
+
return property.date ? legacyDate(property.date) : undefined
|
|
154
|
+
case "people":
|
|
155
|
+
return property.people.map(person =>
|
|
156
|
+
person.object === "group"
|
|
157
|
+
? {
|
|
158
|
+
id: person.id,
|
|
159
|
+
table: "space_permission_group",
|
|
160
|
+
spaceId: person.id.split("|")[1],
|
|
161
|
+
}
|
|
162
|
+
: { id: person.id, table: "notion_user" },
|
|
163
|
+
)
|
|
164
|
+
case "relation":
|
|
165
|
+
return property.relation.map(page => ({ id: page.id, table: "block" }))
|
|
166
|
+
case "files":
|
|
167
|
+
return property.files.map(file => file.name).join(",")
|
|
168
|
+
case "place":
|
|
169
|
+
return ""
|
|
170
|
+
case "created_time":
|
|
171
|
+
return timestamp(property.created_time)
|
|
172
|
+
case "last_edited_time":
|
|
173
|
+
return timestamp(property.last_edited_time)
|
|
174
|
+
case "last_visited_time":
|
|
175
|
+
return timestamp(property.last_visited_time)
|
|
176
|
+
case "created_by":
|
|
177
|
+
return property.created_by ? [property.created_by] : undefined
|
|
178
|
+
case "last_edited_by":
|
|
179
|
+
return property.last_edited_by ? [property.last_edited_by] : undefined
|
|
180
|
+
default:
|
|
181
|
+
return unreachable(property)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -1,46 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
HostToSandboxMessage,
|
|
3
|
+
HostToSandboxMessageLegacy,
|
|
4
|
+
} from "@notionhq/custom-blocks-protocol/messages/hostToSandbox.js"
|
|
5
|
+
import { normalizeQueryPage } from "./normalizeQueryPage.js"
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* Normalizes an outgoing message for the bridge protocol version requested by the sandbox.
|
|
6
9
|
*/
|
|
7
10
|
// TODO(custom-blocks): Remove this function when MIN_HOST_SUPPORTED_BRIDGE_PROTOCOL_VERSION
|
|
8
|
-
// reaches
|
|
11
|
+
// reaches 6.
|
|
9
12
|
export function normalizeHostToSandboxMessage(
|
|
10
13
|
message: HostToSandboxMessage,
|
|
11
14
|
bridgeProtocolVersion: number,
|
|
12
|
-
):
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return message
|
|
16
|
-
}
|
|
17
|
-
const containsDataSources =
|
|
18
|
-
(message.type === "init" && message.status === "success") ||
|
|
19
|
-
message.type === "dataSourcesChanged"
|
|
20
|
-
if (!containsDataSources) {
|
|
21
|
-
return message
|
|
22
|
-
}
|
|
23
|
-
// Protocol 5 excludes synthetic IDs such as created_time from collectionSchema.propertiesById.
|
|
24
|
-
// Older SDKs derive read schemas from that map. Restore those entries in outgoing copies so
|
|
25
|
-
// host query validation still uses the actual database schema.
|
|
26
|
-
return {
|
|
27
|
-
...message,
|
|
28
|
-
dataSources: {
|
|
29
|
-
bindings: Object.fromEntries(
|
|
30
|
-
Object.entries(message.dataSources.bindings).map(([key, binding]) => [
|
|
31
|
-
key,
|
|
32
|
-
{
|
|
33
|
-
...binding,
|
|
34
|
-
collectionSchema: {
|
|
35
|
-
...binding.collectionSchema,
|
|
36
|
-
propertiesById: {
|
|
37
|
-
...binding.collectionSchema?.propertiesById,
|
|
38
|
-
...NOTION_BUILTIN_PROPERTY_SCHEMAS,
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
]),
|
|
43
|
-
),
|
|
44
|
-
},
|
|
45
|
-
}
|
|
15
|
+
): HostToSandboxMessageLegacy {
|
|
16
|
+
const normalizedMessage = normalizeQueryPage(message, bridgeProtocolVersion)
|
|
17
|
+
return normalizedMessage
|
|
46
18
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HostToSandboxMessage,
|
|
3
|
+
HostToSandboxMessageLegacy,
|
|
4
|
+
} from "@notionhq/custom-blocks-protocol/messages/hostToSandbox.js"
|
|
5
|
+
import { LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION } from "@notionhq/custom-blocks-protocol/protocolVersion.js"
|
|
6
|
+
import { toLegacyQueryPage } from "./legacyPage.js"
|
|
7
|
+
|
|
8
|
+
export function normalizeQueryPage(
|
|
9
|
+
message: HostToSandboxMessageLegacy | HostToSandboxMessage,
|
|
10
|
+
bridgeProtocolVersion: number,
|
|
11
|
+
): HostToSandboxMessageLegacy {
|
|
12
|
+
if (
|
|
13
|
+
bridgeProtocolVersion < LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION &&
|
|
14
|
+
message.type === "queryDataSourceResult" &&
|
|
15
|
+
message.status === "success"
|
|
16
|
+
) {
|
|
17
|
+
return {
|
|
18
|
+
...message,
|
|
19
|
+
items: message.items.map(page =>
|
|
20
|
+
"properties" in page ? toLegacyQueryPage(page) : page,
|
|
21
|
+
),
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return message
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const MAX_EXTERNAL_URL_LENGTH = 2048
|
|
2
|
+
|
|
3
|
+
/** Returns a normalized, credential-free HTTP or HTTPS URL. */
|
|
4
|
+
export function parseExternalUrl(input: string): string | undefined {
|
|
5
|
+
if (input.length > MAX_EXTERNAL_URL_LENGTH || !URL.canParse(input)) {
|
|
6
|
+
return undefined
|
|
7
|
+
}
|
|
8
|
+
const parsed = new URL(input)
|
|
9
|
+
if (
|
|
10
|
+
(parsed.protocol !== "http:" && parsed.protocol !== "https:") ||
|
|
11
|
+
parsed.username !== "" ||
|
|
12
|
+
parsed.password !== "" ||
|
|
13
|
+
parsed.href.length > MAX_EXTERNAL_URL_LENGTH
|
|
14
|
+
) {
|
|
15
|
+
return undefined
|
|
16
|
+
}
|
|
17
|
+
return parsed.href
|
|
18
|
+
}
|
|
@@ -6,6 +6,7 @@ import type { InitResultMessage } from "@notionhq/custom-blocks-protocol/message
|
|
|
6
6
|
import type { InvalidSandboxMessage } from "@notionhq/custom-blocks-protocol/messages/invalidSandboxMessage.js"
|
|
7
7
|
import { isInitHandshakeMessage } from "@notionhq/custom-blocks-protocol/messages/isInitHandshakeMessage.js"
|
|
8
8
|
import type { ListUsersMessage } from "@notionhq/custom-blocks-protocol/messages/listUsers.js"
|
|
9
|
+
import type { OpenExternalUrlMessage } from "@notionhq/custom-blocks-protocol/messages/openExternalUrl.js"
|
|
9
10
|
import type { OpenPageMessage } from "@notionhq/custom-blocks-protocol/messages/openPage.js"
|
|
10
11
|
import type { QueryDataSourceMessage } from "@notionhq/custom-blocks-protocol/messages/queryDataSource.js"
|
|
11
12
|
import type { ResizeMessage } from "@notionhq/custom-blocks-protocol/messages/resize.js"
|
|
@@ -49,6 +50,7 @@ export type SandboxMessageRouterOptions = {
|
|
|
49
50
|
) => void
|
|
50
51
|
onCreatePage: (message: CreatePageMessage) => void | Promise<void>
|
|
51
52
|
onOpenPage: (message: OpenPageMessage) => void | Promise<void>
|
|
53
|
+
onOpenExternalUrl: (message: OpenExternalUrlMessage) => void | Promise<void>
|
|
52
54
|
onGetPage: (message: GetPageMessage) => void | Promise<void>
|
|
53
55
|
onGetUser: (message: GetUserMessage) => void | Promise<void>
|
|
54
56
|
onListUsers: (message: ListUsersMessage) => void | Promise<void>
|
|
@@ -74,6 +76,7 @@ export function createSandboxMessageRouter(
|
|
|
74
76
|
onCreatePage,
|
|
75
77
|
onGetPage,
|
|
76
78
|
onOpenPage,
|
|
79
|
+
onOpenExternalUrl,
|
|
77
80
|
onGetUser,
|
|
78
81
|
onListUsers,
|
|
79
82
|
onUpdatePage,
|
|
@@ -86,7 +89,7 @@ export function createSandboxMessageRouter(
|
|
|
86
89
|
) {
|
|
87
90
|
emit("warn", {
|
|
88
91
|
message: "Ignored unsupported sandbox message",
|
|
89
|
-
payload: data,
|
|
92
|
+
payload: redactExternalUrl(data),
|
|
90
93
|
issues,
|
|
91
94
|
})
|
|
92
95
|
const response = getInvalidSandboxMessageResponse(data)
|
|
@@ -145,12 +148,12 @@ export function createSandboxMessageRouter(
|
|
|
145
148
|
if (!isInitHandshakeMessage(message) && getInitStatus() !== "initialized") {
|
|
146
149
|
emit("warn", {
|
|
147
150
|
message: `Ignored ${message.type} before initialization completed`,
|
|
148
|
-
payload: message,
|
|
151
|
+
payload: redactExternalUrl(message),
|
|
149
152
|
})
|
|
150
153
|
return
|
|
151
154
|
}
|
|
152
155
|
|
|
153
|
-
emit("in", message)
|
|
156
|
+
emit("in", redactExternalUrl(message))
|
|
154
157
|
switch (message.type) {
|
|
155
158
|
case "connect":
|
|
156
159
|
onConnect(message)
|
|
@@ -170,6 +173,9 @@ export function createSandboxMessageRouter(
|
|
|
170
173
|
case "openPage":
|
|
171
174
|
void onOpenPage(message)
|
|
172
175
|
return
|
|
176
|
+
case "openExternalUrl":
|
|
177
|
+
void onOpenExternalUrl(message)
|
|
178
|
+
return
|
|
173
179
|
case "getPage":
|
|
174
180
|
void onGetPage(message)
|
|
175
181
|
return
|
|
@@ -193,3 +199,18 @@ export function createSandboxMessageRouter(
|
|
|
193
199
|
}
|
|
194
200
|
}
|
|
195
201
|
}
|
|
202
|
+
|
|
203
|
+
function redactExternalUrl(data: unknown): unknown {
|
|
204
|
+
if (
|
|
205
|
+
typeof data === "object" &&
|
|
206
|
+
data !== null &&
|
|
207
|
+
"type" in data &&
|
|
208
|
+
data.type === "openExternalUrl"
|
|
209
|
+
) {
|
|
210
|
+
return {
|
|
211
|
+
type: "openExternalUrl",
|
|
212
|
+
...("requestId" in data ? { requestId: data.requestId } : {}),
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return data
|
|
216
|
+
}
|
package/src/messages/types.ts
CHANGED
|
@@ -26,6 +26,12 @@ import type {
|
|
|
26
26
|
listUsersResultMessageSchema,
|
|
27
27
|
} from "@notionhq/custom-blocks-protocol/messages/listUsers.js"
|
|
28
28
|
import type { BridgeMessagePayload } from "@notionhq/custom-blocks-protocol/messages/messagePayload.js"
|
|
29
|
+
import type {
|
|
30
|
+
CustomBlockOpenExternalUrlErrorInfo,
|
|
31
|
+
OpenExternalUrlMessage,
|
|
32
|
+
OpenExternalUrlResultMessage,
|
|
33
|
+
openExternalUrlMessageSchema,
|
|
34
|
+
} from "@notionhq/custom-blocks-protocol/messages/openExternalUrl.js"
|
|
29
35
|
import type {
|
|
30
36
|
CustomBlockOpenPageErrorInfo,
|
|
31
37
|
OpenPageMessage,
|
|
@@ -88,6 +94,15 @@ export type CustomBlockHostOpenPageResult = BridgeMessagePayload<
|
|
|
88
94
|
CustomBlockOpenPageErrorInfo
|
|
89
95
|
>
|
|
90
96
|
|
|
97
|
+
export type CustomBlockHostOpenExternalUrlResult = BridgeMessagePayload<
|
|
98
|
+
OpenExternalUrlResultMessage,
|
|
99
|
+
CustomBlockOpenExternalUrlErrorInfo
|
|
100
|
+
>
|
|
101
|
+
|
|
102
|
+
export type CustomBlockHostNavigationContext = {
|
|
103
|
+
signal: AbortSignal
|
|
104
|
+
}
|
|
105
|
+
|
|
91
106
|
export type CustomBlockHostHandlers = {
|
|
92
107
|
queryDataSource: (
|
|
93
108
|
message: QueryDataSourceMessage,
|
|
@@ -107,6 +122,10 @@ export type CustomBlockHostHandlers = {
|
|
|
107
122
|
openPage?: (
|
|
108
123
|
message: OpenPageMessage,
|
|
109
124
|
) => MaybePromise<CustomBlockHostOpenPageResult>
|
|
125
|
+
openExternalUrl?: (
|
|
126
|
+
message: OpenExternalUrlMessage,
|
|
127
|
+
context: CustomBlockHostNavigationContext,
|
|
128
|
+
) => MaybePromise<CustomBlockHostOpenExternalUrlResult>
|
|
110
129
|
updatePage?: (
|
|
111
130
|
message: UpdatePageMessage,
|
|
112
131
|
) => MaybePromise<CustomBlockHostUpdatePageResult>
|
|
@@ -139,6 +158,10 @@ export type ListUsersMessageInput = InferInput<typeof listUsersMessageSchema>
|
|
|
139
158
|
|
|
140
159
|
export type OpenPageMessageInput = InferInput<typeof openPageMessageSchema>
|
|
141
160
|
|
|
161
|
+
export type OpenExternalUrlMessageInput = InferInput<
|
|
162
|
+
typeof openExternalUrlMessageSchema
|
|
163
|
+
>
|
|
164
|
+
|
|
142
165
|
export type QueryDataSourceMessageInput = InferInput<
|
|
143
166
|
typeof queryDataSourceMessageSchema
|
|
144
167
|
>
|