@notionhq/custom-blocks-host 0.3.4 → 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 +0 -5
- package/dist/browser.js +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/protocol/dataSources/dataSourcePage.d.ts +1 -2
- package/dist/protocol/dataSources/dataSourcePage.js +1 -2
- package/dist/protocol/messages/hostToSandbox.d.ts +1636 -241
- package/dist/protocol/messages/hostToSandbox.js +13 -6
- package/dist/protocol/messages/queryDataSourceResult.d.ts +174 -0
- package/dist/protocol/messages/queryDataSourceResult.js +15 -0
- package/package.json +1 -1
- package/src/lifecycle/legacyPage.ts +183 -0
- package/src/lifecycle/normalizeHostToSandboxMessage.ts +9 -37
- package/src/lifecycle/normalizeQueryPage.ts +25 -0
|
@@ -12,13 +12,10 @@ import { openExternalUrlResultMessageSchema } from "./openExternalUrl.js";
|
|
|
12
12
|
import { openPageResultMessageSchema } from "./openPage.js";
|
|
13
13
|
import { pageChangedMessageSchema } from "./pageChanged.js";
|
|
14
14
|
import { parentChangedMessageSchema } from "./parentChanged.js";
|
|
15
|
-
import { queryDataSourceResultMessageSchema } from "./queryDataSourceResult.js";
|
|
15
|
+
import { queryDataSourceResultMessageLegacySchema, queryDataSourceResultMessageSchema, } from "./queryDataSourceResult.js";
|
|
16
16
|
import { themeChangedMessageSchema } from "./themeChanged.js";
|
|
17
17
|
import { updatePageResultMessageSchema } from "./updatePageResult.js";
|
|
18
|
-
|
|
19
|
-
* Discriminated union of every message the host is allowed to send the sandbox.
|
|
20
|
-
*/
|
|
21
|
-
export const hostToSandboxMessageSchema = v.variant("type", [
|
|
18
|
+
const baseHostToSandboxMessageSchema = v.variant("type", [
|
|
22
19
|
initMessageSchema,
|
|
23
20
|
themeChangedMessageSchema,
|
|
24
21
|
contrastModeChangedMessageSchema,
|
|
@@ -26,7 +23,6 @@ export const hostToSandboxMessageSchema = v.variant("type", [
|
|
|
26
23
|
pageChangedMessageSchema,
|
|
27
24
|
currentUserChangedMessageSchema,
|
|
28
25
|
dataSourcesChangedMessageSchema,
|
|
29
|
-
queryDataSourceResultMessageSchema,
|
|
30
26
|
createPageResultMessageSchema,
|
|
31
27
|
getPageResultMessageSchema,
|
|
32
28
|
getUserResultMessageSchema,
|
|
@@ -36,3 +32,14 @@ export const hostToSandboxMessageSchema = v.variant("type", [
|
|
|
36
32
|
updatePageResultMessageSchema,
|
|
37
33
|
invalidSandboxMessageSchema,
|
|
38
34
|
]);
|
|
35
|
+
export const hostToSandboxMessageSchema = v.variant("type", [
|
|
36
|
+
...baseHostToSandboxMessageSchema.options,
|
|
37
|
+
queryDataSourceResultMessageSchema,
|
|
38
|
+
]);
|
|
39
|
+
/**
|
|
40
|
+
* Discriminated union of every message the host is allowed to send the sandbox.
|
|
41
|
+
*/
|
|
42
|
+
export const hostToSandboxMessageLegacySchema = v.variant("type", [
|
|
43
|
+
...baseHostToSandboxMessageSchema.options,
|
|
44
|
+
queryDataSourceResultMessageLegacySchema,
|
|
45
|
+
]);
|
|
@@ -12,6 +12,179 @@ export declare const customBlockQueryDataSourceErrorInfoSchema: v.ObjectSchema<{
|
|
|
12
12
|
* Message sent by the host to update a `queryDataSource` subscription.
|
|
13
13
|
*/
|
|
14
14
|
export declare const queryDataSourceResultMessageSchema: v.VariantSchema<"status", [v.ObjectSchema<{
|
|
15
|
+
readonly type: v.LiteralSchema<"queryDataSourceResult", undefined>;
|
|
16
|
+
readonly subscriptionId: v.StringSchema<undefined>;
|
|
17
|
+
readonly status: v.LiteralSchema<"success", undefined>;
|
|
18
|
+
readonly items: v.ArraySchema<v.ObjectSchema<{
|
|
19
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.BrandAction<string, "NotionPageId">]>;
|
|
20
|
+
readonly is_archived: v.BooleanSchema<undefined>;
|
|
21
|
+
readonly in_trash: v.BooleanSchema<undefined>;
|
|
22
|
+
readonly properties: v.RecordSchema<v.StringSchema<undefined>, v.OptionalSchema<v.VariantSchema<"type", [v.ObjectSchema<{
|
|
23
|
+
readonly id: v.StringSchema<undefined>;
|
|
24
|
+
readonly type: v.LiteralSchema<"title", undefined>;
|
|
25
|
+
readonly title: v.ArraySchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
26
|
+
}, undefined>, v.ObjectSchema<{
|
|
27
|
+
readonly id: v.StringSchema<undefined>;
|
|
28
|
+
readonly type: v.LiteralSchema<"rich_text", undefined>;
|
|
29
|
+
readonly rich_text: v.ArraySchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
30
|
+
}, undefined>, v.ObjectSchema<{
|
|
31
|
+
readonly id: v.StringSchema<undefined>;
|
|
32
|
+
readonly type: v.LiteralSchema<"number", undefined>;
|
|
33
|
+
readonly number: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
|
|
34
|
+
}, undefined>, v.ObjectSchema<{
|
|
35
|
+
readonly id: v.StringSchema<undefined>;
|
|
36
|
+
readonly type: v.LiteralSchema<"url", undefined>;
|
|
37
|
+
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
38
|
+
}, undefined>, v.ObjectSchema<{
|
|
39
|
+
readonly id: v.StringSchema<undefined>;
|
|
40
|
+
readonly type: v.LiteralSchema<"email", undefined>;
|
|
41
|
+
readonly email: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
42
|
+
}, undefined>, v.ObjectSchema<{
|
|
43
|
+
readonly id: v.StringSchema<undefined>;
|
|
44
|
+
readonly type: v.LiteralSchema<"phone_number", undefined>;
|
|
45
|
+
readonly phone_number: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
46
|
+
}, undefined>, v.ObjectSchema<{
|
|
47
|
+
readonly id: v.StringSchema<undefined>;
|
|
48
|
+
readonly type: v.LiteralSchema<"checkbox", undefined>;
|
|
49
|
+
readonly checkbox: v.BooleanSchema<undefined>;
|
|
50
|
+
}, undefined>, v.ObjectSchema<{
|
|
51
|
+
readonly id: v.StringSchema<undefined>;
|
|
52
|
+
readonly type: v.LiteralSchema<"select", undefined>;
|
|
53
|
+
readonly select: v.NullableSchema<v.UnionSchema<[v.ObjectSchema<{
|
|
54
|
+
readonly id: v.StringSchema<undefined>;
|
|
55
|
+
readonly name: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
56
|
+
readonly color: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
57
|
+
readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
58
|
+
}, undefined>, v.ObjectSchema<{
|
|
59
|
+
readonly name: v.StringSchema<undefined>;
|
|
60
|
+
readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
61
|
+
readonly color: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
62
|
+
readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
63
|
+
}, undefined>], undefined>, undefined>;
|
|
64
|
+
}, undefined>, v.ObjectSchema<{
|
|
65
|
+
readonly id: v.StringSchema<undefined>;
|
|
66
|
+
readonly type: v.LiteralSchema<"status", undefined>;
|
|
67
|
+
readonly status: v.NullableSchema<v.UnionSchema<[v.ObjectSchema<{
|
|
68
|
+
readonly id: v.StringSchema<undefined>;
|
|
69
|
+
readonly name: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
70
|
+
readonly color: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
71
|
+
readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
72
|
+
}, undefined>, v.ObjectSchema<{
|
|
73
|
+
readonly name: v.StringSchema<undefined>;
|
|
74
|
+
readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
75
|
+
readonly color: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
76
|
+
readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
77
|
+
}, undefined>], undefined>, undefined>;
|
|
78
|
+
}, undefined>, v.ObjectSchema<{
|
|
79
|
+
readonly id: v.StringSchema<undefined>;
|
|
80
|
+
readonly type: v.LiteralSchema<"multi_select", undefined>;
|
|
81
|
+
readonly multi_select: v.ArraySchema<v.UnionSchema<[v.ObjectSchema<{
|
|
82
|
+
readonly id: v.StringSchema<undefined>;
|
|
83
|
+
readonly name: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
84
|
+
readonly color: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
85
|
+
readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
86
|
+
}, undefined>, v.ObjectSchema<{
|
|
87
|
+
readonly name: v.StringSchema<undefined>;
|
|
88
|
+
readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
89
|
+
readonly color: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
90
|
+
readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
91
|
+
}, undefined>], undefined>, undefined>;
|
|
92
|
+
}, undefined>, v.ObjectSchema<{
|
|
93
|
+
readonly id: v.StringSchema<undefined>;
|
|
94
|
+
readonly type: v.LiteralSchema<"date", undefined>;
|
|
95
|
+
readonly date: v.NullableSchema<v.ObjectSchema<{
|
|
96
|
+
readonly start: v.StringSchema<undefined>;
|
|
97
|
+
readonly end: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
98
|
+
readonly time_zone: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
99
|
+
}, undefined>, undefined>;
|
|
100
|
+
}, undefined>, v.ObjectSchema<{
|
|
101
|
+
readonly id: v.StringSchema<undefined>;
|
|
102
|
+
readonly type: v.LiteralSchema<"people", undefined>;
|
|
103
|
+
readonly people: v.ArraySchema<v.UnionSchema<[v.ObjectSchema<{
|
|
104
|
+
readonly object: v.OptionalSchema<v.LiteralSchema<"user", undefined>, undefined>;
|
|
105
|
+
readonly id: v.StringSchema<undefined>;
|
|
106
|
+
}, undefined>, v.ObjectSchema<{
|
|
107
|
+
readonly object: v.LiteralSchema<"group", undefined>;
|
|
108
|
+
readonly id: v.StringSchema<undefined>;
|
|
109
|
+
readonly name: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
110
|
+
}, undefined>], undefined>, undefined>;
|
|
111
|
+
}, undefined>, v.ObjectSchema<{
|
|
112
|
+
readonly id: v.StringSchema<undefined>;
|
|
113
|
+
readonly type: v.LiteralSchema<"relation", undefined>;
|
|
114
|
+
readonly has_more: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
115
|
+
readonly relation: v.ArraySchema<v.ObjectSchema<{
|
|
116
|
+
readonly id: v.StringSchema<undefined>;
|
|
117
|
+
}, undefined>, undefined>;
|
|
118
|
+
}, undefined>, v.ObjectSchema<{
|
|
119
|
+
readonly id: v.StringSchema<undefined>;
|
|
120
|
+
readonly type: v.LiteralSchema<"files", undefined>;
|
|
121
|
+
readonly files: v.ArraySchema<v.UnionSchema<[v.ObjectSchema<{
|
|
122
|
+
readonly type: v.LiteralSchema<"external", undefined>;
|
|
123
|
+
readonly name: v.StringSchema<undefined>;
|
|
124
|
+
readonly external: v.ObjectSchema<{
|
|
125
|
+
readonly url: v.StringSchema<undefined>;
|
|
126
|
+
}, undefined>;
|
|
127
|
+
}, undefined>, v.ObjectSchema<{
|
|
128
|
+
readonly type: v.LiteralSchema<"file", undefined>;
|
|
129
|
+
readonly name: v.StringSchema<undefined>;
|
|
130
|
+
readonly file: v.ObjectSchema<{
|
|
131
|
+
readonly url: v.StringSchema<undefined>;
|
|
132
|
+
readonly expiry_time: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
133
|
+
}, undefined>;
|
|
134
|
+
}, undefined>], undefined>, undefined>;
|
|
135
|
+
}, undefined>, v.ObjectSchema<{
|
|
136
|
+
readonly id: v.StringSchema<undefined>;
|
|
137
|
+
readonly type: v.LiteralSchema<"place", undefined>;
|
|
138
|
+
readonly place: v.NullableSchema<v.ObjectSchema<{
|
|
139
|
+
readonly lat: v.NumberSchema<undefined>;
|
|
140
|
+
readonly lon: v.NumberSchema<undefined>;
|
|
141
|
+
readonly name: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
142
|
+
readonly address: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
143
|
+
readonly aws_place_id: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
144
|
+
readonly google_place_id: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
145
|
+
}, undefined>, undefined>;
|
|
146
|
+
}, undefined>, v.ObjectSchema<{
|
|
147
|
+
readonly id: v.StringSchema<undefined>;
|
|
148
|
+
readonly type: v.LiteralSchema<"created_time", undefined>;
|
|
149
|
+
readonly created_time: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
150
|
+
}, undefined>, v.ObjectSchema<{
|
|
151
|
+
readonly id: v.StringSchema<undefined>;
|
|
152
|
+
readonly type: v.LiteralSchema<"last_edited_time", undefined>;
|
|
153
|
+
readonly last_edited_time: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
154
|
+
}, undefined>, v.ObjectSchema<{
|
|
155
|
+
readonly id: v.StringSchema<undefined>;
|
|
156
|
+
readonly type: v.LiteralSchema<"created_by", undefined>;
|
|
157
|
+
readonly created_by: v.NullableSchema<v.ObjectSchema<{
|
|
158
|
+
readonly id: v.StringSchema<undefined>;
|
|
159
|
+
readonly table: v.PicklistSchema<["notion_user", "bot", "organization_bot"], undefined>;
|
|
160
|
+
readonly spaceId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
161
|
+
}, undefined>, undefined>;
|
|
162
|
+
}, undefined>, v.ObjectSchema<{
|
|
163
|
+
readonly id: v.StringSchema<undefined>;
|
|
164
|
+
readonly type: v.LiteralSchema<"last_edited_by", undefined>;
|
|
165
|
+
readonly last_edited_by: v.NullableSchema<v.ObjectSchema<{
|
|
166
|
+
readonly id: v.StringSchema<undefined>;
|
|
167
|
+
readonly table: v.PicklistSchema<["notion_user", "bot", "organization_bot"], undefined>;
|
|
168
|
+
readonly spaceId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
169
|
+
}, undefined>, undefined>;
|
|
170
|
+
}, undefined>, v.ObjectSchema<{
|
|
171
|
+
readonly id: v.StringSchema<undefined>;
|
|
172
|
+
readonly type: v.LiteralSchema<"last_visited_time", undefined>;
|
|
173
|
+
readonly last_visited_time: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
174
|
+
}, undefined>], undefined>, undefined>, undefined>;
|
|
175
|
+
}, undefined>, undefined>;
|
|
176
|
+
readonly hasMore: v.BooleanSchema<undefined>;
|
|
177
|
+
}, undefined>, v.ObjectSchema<{
|
|
178
|
+
readonly type: v.LiteralSchema<"queryDataSourceResult", undefined>;
|
|
179
|
+
readonly subscriptionId: v.StringSchema<undefined>;
|
|
180
|
+
readonly status: v.LiteralSchema<"error", undefined>;
|
|
181
|
+
readonly error: v.ObjectSchema<{
|
|
182
|
+
readonly code: v.StringSchema<undefined>;
|
|
183
|
+
readonly message: v.StringSchema<undefined>;
|
|
184
|
+
readonly isRetryable: v.BooleanSchema<undefined>;
|
|
185
|
+
}, undefined>;
|
|
186
|
+
}, undefined>], undefined>;
|
|
187
|
+
export declare const queryDataSourceResultMessageLegacySchema: v.VariantSchema<"status", [v.ObjectSchema<{
|
|
15
188
|
readonly type: v.LiteralSchema<"queryDataSourceResult", undefined>;
|
|
16
189
|
readonly subscriptionId: v.StringSchema<undefined>;
|
|
17
190
|
readonly status: v.LiteralSchema<"success", undefined>;
|
|
@@ -250,3 +423,4 @@ export declare const queryDataSourceResultMessageSchema: v.VariantSchema<"status
|
|
|
250
423
|
}, undefined>;
|
|
251
424
|
}, undefined>], undefined>;
|
|
252
425
|
export type QueryDataSourceResultMessage = v.InferOutput<typeof queryDataSourceResultMessageSchema>;
|
|
426
|
+
export type QueryDataSourceResultMessageLegacy = v.InferOutput<typeof queryDataSourceResultMessageLegacySchema>;
|
|
@@ -12,6 +12,21 @@ export const customBlockQueryDataSourceErrorInfoSchema = v.object({
|
|
|
12
12
|
* Message sent by the host to update a `queryDataSource` subscription.
|
|
13
13
|
*/
|
|
14
14
|
export const queryDataSourceResultMessageSchema = v.variant("status", [
|
|
15
|
+
v.object({
|
|
16
|
+
type: v.literal("queryDataSourceResult"),
|
|
17
|
+
subscriptionId: v.string(),
|
|
18
|
+
status: v.literal("success"),
|
|
19
|
+
items: v.array(notionDataSourcePageBridgeSchema),
|
|
20
|
+
hasMore: v.boolean(),
|
|
21
|
+
}),
|
|
22
|
+
v.object({
|
|
23
|
+
type: v.literal("queryDataSourceResult"),
|
|
24
|
+
subscriptionId: v.string(),
|
|
25
|
+
status: v.literal("error"),
|
|
26
|
+
error: customBlockQueryDataSourceErrorInfoSchema,
|
|
27
|
+
}),
|
|
28
|
+
]);
|
|
29
|
+
export const queryDataSourceResultMessageLegacySchema = v.variant("status", [
|
|
15
30
|
v.object({
|
|
16
31
|
type: v.literal("queryDataSourceResult"),
|
|
17
32
|
subscriptionId: v.string(),
|
package/package.json
CHANGED
|
@@ -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
|
+
}
|