@notionhq/custom-blocks-host 0.3.5 → 0.3.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 +5 -0
- package/dist/browser.js +1 -1
- package/dist/dateValue.d.ts +11 -0
- package/dist/dateValue.d.ts.map +1 -0
- package/dist/dateValue.js +96 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lifecycle/legacyPage.d.ts +4 -2
- package/dist/lifecycle/legacyPage.d.ts.map +1 -1
- package/dist/lifecycle/legacyPage.js +14 -62
- package/dist/lifecycle/normalizeHostToSandboxMessage.d.ts.map +1 -1
- package/dist/lifecycle/normalizeHostToSandboxMessage.js +8 -2
- package/dist/lifecycle/normalizePage.d.ts +7 -0
- package/dist/lifecycle/normalizePage.d.ts.map +1 -0
- package/dist/lifecycle/normalizePage.js +22 -0
- package/dist/messages/types.d.ts +1 -2
- package/dist/messages/types.d.ts.map +1 -1
- package/dist/protocol/dataSources/dataSourcePage.d.ts +0 -160
- package/dist/protocol/dataSources/dataSourcePage.js +0 -7
- package/dist/protocol/dataSources/dateValue.d.ts +2 -2
- package/dist/protocol/dataSources/dateValue.js +9 -7
- package/dist/protocol/messages/createPage.d.ts +40 -2
- package/dist/protocol/messages/createPage.js +2 -2
- package/dist/protocol/messages/createPageResult.d.ts +584 -3
- package/dist/protocol/messages/createPageResult.js +17 -2
- package/dist/protocol/messages/getPage.d.ts +584 -3
- package/dist/protocol/messages/getPage.js +18 -3
- package/dist/protocol/messages/hostToSandbox.d.ts +1638 -376
- package/dist/protocol/messages/hostToSandbox.js +9 -6
- package/dist/protocol/messages/queryDataSourceResult.d.ts +222 -10
- package/dist/protocol/messages/queryDataSourceResult.js +4 -6
- package/dist/protocol/messages/sandboxToHost.d.ts +82 -4
- package/dist/protocol/messages/updatePage.d.ts +41 -2
- package/dist/protocol/messages/updatePage.js +4 -3
- package/dist/protocol/messages/updatePageResult.d.ts +583 -3
- package/dist/protocol/messages/updatePageResult.js +16 -2
- package/dist/protocol/pages/page.d.ts +622 -14
- package/dist/protocol/pages/page.js +41 -4
- package/dist/protocol/protocolVersion.js +1 -1
- package/package.json +1 -1
- package/src/dateValue.ts +120 -0
- package/src/index.ts +7 -4
- package/src/lifecycle/legacyPage.ts +30 -76
- package/src/lifecycle/normalizeHostToSandboxMessage.ts +13 -2
- package/src/lifecycle/normalizePage.ts +35 -0
- package/src/messages/types.ts +1 -1
- package/dist/lifecycle/normalizeQueryPage.d.ts +0 -3
- package/dist/lifecycle/normalizeQueryPage.d.ts.map +0 -1
- package/dist/lifecycle/normalizeQueryPage.js +0 -13
- package/src/lifecycle/normalizeQueryPage.ts +0 -25
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* shape the host delivers for messages like `createPageResult`.
|
|
6
6
|
*/
|
|
7
7
|
import * as v from "valibot";
|
|
8
|
+
import { notionDateReminderSchema, notionDateTimeReminderSchema, notionDisabledReminderSchema, } from "../dataSources/dateValue.js";
|
|
8
9
|
import { notionRecordPointerSchema } from "../dataSources/recordPointer.js";
|
|
9
10
|
import { notionPageIdSchema } from "../ids.js";
|
|
10
11
|
import { notionParentSchema } from "../parent.js";
|
|
@@ -75,11 +76,26 @@ const notionSelectOptionInputSchema = v.union([
|
|
|
75
76
|
description: v.optional(nullableStringSchema),
|
|
76
77
|
}),
|
|
77
78
|
]);
|
|
78
|
-
const
|
|
79
|
+
const dateInputEntries = {
|
|
79
80
|
start: v.string(),
|
|
80
81
|
end: v.optional(nullableStringSchema),
|
|
81
82
|
time_zone: v.optional(nullableStringSchema),
|
|
82
|
-
|
|
83
|
+
reminder: v.optional(v.union([notionDateTimeReminderSchema, notionDisabledReminderSchema])),
|
|
84
|
+
};
|
|
85
|
+
const notionDateInputSchema = v.union([
|
|
86
|
+
v.object({
|
|
87
|
+
...dateInputEntries,
|
|
88
|
+
start: v.pipe(v.string(), v.includes("T")),
|
|
89
|
+
}),
|
|
90
|
+
v.object({
|
|
91
|
+
...dateInputEntries,
|
|
92
|
+
time_zone: v.string(),
|
|
93
|
+
}),
|
|
94
|
+
v.object({
|
|
95
|
+
...dateInputEntries,
|
|
96
|
+
reminder: v.optional(v.union([notionDateReminderSchema, notionDisabledReminderSchema])),
|
|
97
|
+
}),
|
|
98
|
+
]);
|
|
83
99
|
const notionUserInputSchema = v.union([
|
|
84
100
|
v.object({
|
|
85
101
|
object: v.optional(v.literal("user")),
|
|
@@ -118,6 +134,7 @@ const notionPlaceInputSchema = v.object({
|
|
|
118
134
|
const pagePropertyBaseSchema = {
|
|
119
135
|
id: v.string(),
|
|
120
136
|
};
|
|
137
|
+
// TODO(custom-blocks): Make spaceId required for metadataActor
|
|
121
138
|
const metadataActorSchema = v.nullable(v.object({
|
|
122
139
|
...notionRecordPointerSchema.entries,
|
|
123
140
|
table: v.picklist(["notion_user", "bot", "organization_bot"]),
|
|
@@ -229,15 +246,35 @@ export const notionPagePropertyValueSchema = v.variant("type", [
|
|
|
229
246
|
last_visited_time: nullableStringSchema,
|
|
230
247
|
}),
|
|
231
248
|
]);
|
|
232
|
-
export const
|
|
249
|
+
export const notionPagePropertyWriteMapSchema = v.record(v.string(), notionPagePropertyValueSchema);
|
|
250
|
+
export const notionPagePropertyReadMapSchema = v.record(v.string(), v.nullable(notionPagePropertyValueSchema));
|
|
233
251
|
/**
|
|
234
252
|
* The `Page` object returned in `createPageResult` messages.
|
|
235
253
|
*/
|
|
236
|
-
export const
|
|
254
|
+
export const notionPageDataSchema = v.object({
|
|
237
255
|
object: v.literal("page"),
|
|
238
256
|
id: notionPageIdSchema,
|
|
239
257
|
parent: notionParentSchema,
|
|
240
258
|
properties: notionPagePropertyReadMapSchema,
|
|
259
|
+
created_by: v.optional(metadataActorSchema, null),
|
|
260
|
+
last_edited_by: v.optional(metadataActorSchema, null),
|
|
261
|
+
last_visited_time: v.optional(v.nullable(v.string()), null),
|
|
262
|
+
created_time: v.optional(v.nullable(v.string()), null),
|
|
263
|
+
last_edited_time: v.optional(v.nullable(v.string()), null),
|
|
264
|
+
icon: v.optional(v.nullable(notionPageIconSchema), null),
|
|
265
|
+
cover: v.optional(v.nullable(notionPageCoverSchema), null),
|
|
266
|
+
url: v.optional(v.nullable(v.string()), null),
|
|
267
|
+
public_url: v.optional(v.nullable(v.string()), null),
|
|
268
|
+
/** Whether the page or an ancestor is archived. */
|
|
269
|
+
is_archived: v.boolean(),
|
|
270
|
+
/** Whether the page or an ancestor is in Trash. */
|
|
271
|
+
in_trash: v.boolean(),
|
|
272
|
+
});
|
|
273
|
+
export const legacyNotionPageSchema = v.object({
|
|
274
|
+
object: v.literal("page"),
|
|
275
|
+
id: notionPageIdSchema,
|
|
276
|
+
parent: notionParentSchema,
|
|
277
|
+
properties: notionPagePropertyWriteMapSchema,
|
|
241
278
|
created_time: v.optional(v.string()),
|
|
242
279
|
last_edited_time: v.optional(v.string()),
|
|
243
280
|
icon: v.optional(notionPageIconSchema),
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* older versions, so this value does not set the minimum or maximum they accept.
|
|
5
5
|
*/
|
|
6
6
|
export const LATEST_BRIDGE_PROTOCOL_VERSION = 6;
|
|
7
|
-
// Protocol 6 introduces name-keyed property objects
|
|
7
|
+
// Protocol 6 introduces unified pages with name-keyed property objects.
|
|
8
8
|
// Keep this cutoff fixed when the latest protocol version increases.
|
|
9
9
|
export const LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION = 6;
|
package/package.json
CHANGED
package/src/dateValue.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NotionDate,
|
|
3
|
+
NotionDateRange,
|
|
4
|
+
NotionDateTime,
|
|
5
|
+
NotionDateTimeRange,
|
|
6
|
+
} from "@notionhq/custom-blocks-protocol/dataSources/dateValue.js"
|
|
7
|
+
import type { NotionDateInput } from "@notionhq/custom-blocks-protocol/pages/page.js"
|
|
8
|
+
|
|
9
|
+
export type CustomBlockDateValue =
|
|
10
|
+
| NotionDate
|
|
11
|
+
| NotionDateRange
|
|
12
|
+
| (NotionDateTime & { time_zone: string })
|
|
13
|
+
| (NotionDateTimeRange & { time_zone: string })
|
|
14
|
+
|
|
15
|
+
export class InvalidNotionDateError extends Error {}
|
|
16
|
+
|
|
17
|
+
export function toNotionDateValue(
|
|
18
|
+
value: NotionDateInput,
|
|
19
|
+
): CustomBlockDateValue {
|
|
20
|
+
try {
|
|
21
|
+
return convertDateValue(value)
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error instanceof RangeError) {
|
|
24
|
+
throw new InvalidNotionDateError(error.message)
|
|
25
|
+
}
|
|
26
|
+
throw error
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function convertDateValue(value: NotionDateInput): CustomBlockDateValue {
|
|
31
|
+
const { start, end, time_zone, reminder } = value
|
|
32
|
+
if (!start.split("T")[0]) {
|
|
33
|
+
throw new InvalidNotionDateError("Date values must include a date.")
|
|
34
|
+
}
|
|
35
|
+
const timed = start.includes("T") || time_zone != null
|
|
36
|
+
const offset = start.match(/([+-])(\d{2}):(\d{2})$/)
|
|
37
|
+
const offsetMinutes = offset
|
|
38
|
+
? (Number(offset[2]) * 60 + Number(offset[3])) *
|
|
39
|
+
(offset[1] === "-" ? -1 : 1)
|
|
40
|
+
: 0
|
|
41
|
+
const fixedZone = time_zone?.match(/^UTC(?:([+-])(\d{1,2})(?::(\d{2}))?)?$/)
|
|
42
|
+
const targetOffsetMinutes = fixedZone
|
|
43
|
+
? (Number(fixedZone[2] ?? 0) * 60 + Number(fixedZone[3] ?? 0)) *
|
|
44
|
+
(fixedZone[1] === "-" ? -1 : 1)
|
|
45
|
+
: offsetMinutes
|
|
46
|
+
const parts = (input: string) => {
|
|
47
|
+
if (!input.split("T")[0]) {
|
|
48
|
+
throw new InvalidNotionDateError("Date values must include a date.")
|
|
49
|
+
}
|
|
50
|
+
if (!input.includes("T")) {
|
|
51
|
+
return { date: input, time: "00:00" }
|
|
52
|
+
}
|
|
53
|
+
const wallClock = input.match(
|
|
54
|
+
/^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?$/,
|
|
55
|
+
)
|
|
56
|
+
if (wallClock) {
|
|
57
|
+
return { date: wallClock[1], time: wallClock[2] }
|
|
58
|
+
}
|
|
59
|
+
if (!time_zone || fixedZone) {
|
|
60
|
+
const local = new Date(
|
|
61
|
+
new Date(input).getTime() + targetOffsetMinutes * 60_000,
|
|
62
|
+
).toISOString()
|
|
63
|
+
return { date: local.slice(0, 10), time: local.slice(11, 16) }
|
|
64
|
+
}
|
|
65
|
+
const entries = new Intl.DateTimeFormat("en-CA", {
|
|
66
|
+
timeZone: time_zone,
|
|
67
|
+
year: "numeric",
|
|
68
|
+
month: "2-digit",
|
|
69
|
+
day: "2-digit",
|
|
70
|
+
hour: "2-digit",
|
|
71
|
+
minute: "2-digit",
|
|
72
|
+
hourCycle: "h23",
|
|
73
|
+
}).formatToParts(new Date(input))
|
|
74
|
+
const get = (type: string) =>
|
|
75
|
+
entries.find(part => part.type === type)?.value
|
|
76
|
+
return {
|
|
77
|
+
date: `${get("year")}-${get("month")}-${get("day")}`,
|
|
78
|
+
time: `${get("hour")}:${get("minute")}`,
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const startParts = parts(start)
|
|
82
|
+
const endParts = end ? parts(end) : undefined
|
|
83
|
+
if (!timed) {
|
|
84
|
+
if (reminder && !("time" in reminder) && reminder.unit !== "none") {
|
|
85
|
+
throw new InvalidNotionDateError(
|
|
86
|
+
"Hour and minute reminders require a date with a time.",
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
return endParts
|
|
90
|
+
? {
|
|
91
|
+
type: "daterange",
|
|
92
|
+
start_date: startParts.date,
|
|
93
|
+
end_date: endParts.date,
|
|
94
|
+
reminder,
|
|
95
|
+
}
|
|
96
|
+
: { type: "date", start_date: startParts.date, reminder }
|
|
97
|
+
}
|
|
98
|
+
const zone =
|
|
99
|
+
time_zone ??
|
|
100
|
+
(offsetMinutes === 0
|
|
101
|
+
? "UTC"
|
|
102
|
+
: `UTC${offsetMinutes < 0 ? "-" : "+"}${Math.floor(Math.abs(offsetMinutes) / 60)}${Math.abs(offsetMinutes) % 60 === 0 ? "" : `:${String(Math.abs(offsetMinutes) % 60).padStart(2, "0")}`}`)
|
|
103
|
+
return endParts
|
|
104
|
+
? {
|
|
105
|
+
type: "datetimerange",
|
|
106
|
+
start_date: startParts.date,
|
|
107
|
+
start_time: startParts.time,
|
|
108
|
+
end_date: endParts.date,
|
|
109
|
+
end_time: endParts.time,
|
|
110
|
+
time_zone: zone,
|
|
111
|
+
reminder,
|
|
112
|
+
}
|
|
113
|
+
: {
|
|
114
|
+
type: "datetime",
|
|
115
|
+
start_date: startParts.date,
|
|
116
|
+
start_time: startParts.time,
|
|
117
|
+
time_zone: zone,
|
|
118
|
+
reminder,
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
LegacyNotionDataSourcePageBridge,
|
|
3
|
-
NotionDataSourcePageBridge,
|
|
4
|
-
} from "@notionhq/custom-blocks-protocol/dataSources/dataSourcePage.js"
|
|
1
|
+
export type { LegacyNotionDataSourcePageBridge } from "@notionhq/custom-blocks-protocol/dataSources/dataSourcePage.js"
|
|
5
2
|
export type { NotionPropertySchemasById } from "@notionhq/custom-blocks-protocol/dataSources/propertySchema.js"
|
|
6
3
|
export type { CustomBlockErrorInfo } from "@notionhq/custom-blocks-protocol/errors.js"
|
|
7
4
|
export type { NotionPageId } from "@notionhq/custom-blocks-protocol/ids.js"
|
|
@@ -37,6 +34,7 @@ export type {
|
|
|
37
34
|
NotionDateInput,
|
|
38
35
|
NotionFileInput,
|
|
39
36
|
NotionPageCover,
|
|
37
|
+
NotionPageData,
|
|
40
38
|
NotionPageIcon,
|
|
41
39
|
NotionPagePropertyReadMap,
|
|
42
40
|
NotionPagePropertyValue,
|
|
@@ -57,6 +55,11 @@ export {
|
|
|
57
55
|
type CustomBlockHostOptions,
|
|
58
56
|
createCustomBlockHost,
|
|
59
57
|
} from "./createCustomBlockHost.js"
|
|
58
|
+
export {
|
|
59
|
+
type CustomBlockDateValue,
|
|
60
|
+
InvalidNotionDateError,
|
|
61
|
+
toNotionDateValue,
|
|
62
|
+
} from "./dateValue.js"
|
|
60
63
|
export { toNotionPageId } from "./ids.js"
|
|
61
64
|
export type { CustomBlockHostManifestOptions } from "./lifecycle/manifestOptions.js"
|
|
62
65
|
export type {
|
|
@@ -1,9 +1,35 @@
|
|
|
1
|
-
import type { NotionDataSourcePageBridge } from "@notionhq/custom-blocks-protocol/dataSources/dataSourcePage.js"
|
|
2
1
|
import type { NotionDataSourceValue } from "@notionhq/custom-blocks-protocol/dataSources/dataSourceValue.js"
|
|
3
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
LegacyNotionPage,
|
|
4
|
+
NotionPagePropertyValue,
|
|
5
|
+
notionPageDataSchema,
|
|
6
|
+
} from "@notionhq/custom-blocks-protocol/pages/page.js"
|
|
7
|
+
import type { InferOutput } from "valibot"
|
|
8
|
+
import { toNotionDateValue } from "../dateValue.js"
|
|
4
9
|
import { unreachable } from "../utils.js"
|
|
5
10
|
|
|
6
|
-
export function
|
|
11
|
+
export function toLegacyPage(
|
|
12
|
+
page: InferOutput<typeof notionPageDataSchema>,
|
|
13
|
+
): LegacyNotionPage {
|
|
14
|
+
return {
|
|
15
|
+
...page,
|
|
16
|
+
properties: Object.fromEntries(
|
|
17
|
+
Object.values(page.properties).flatMap(property =>
|
|
18
|
+
property ? [[property.id, property]] : [],
|
|
19
|
+
),
|
|
20
|
+
),
|
|
21
|
+
icon: page.icon ?? undefined,
|
|
22
|
+
cover: page.cover ?? undefined,
|
|
23
|
+
created_time: page.created_time ?? undefined,
|
|
24
|
+
last_edited_time: page.last_edited_time ?? undefined,
|
|
25
|
+
url: page.url ?? undefined,
|
|
26
|
+
public_url: page.public_url ?? undefined,
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function toLegacyQueryPage(
|
|
31
|
+
page: InferOutput<typeof notionPageDataSchema>,
|
|
32
|
+
) {
|
|
7
33
|
const propertiesById: Record<string, NotionDataSourceValue | undefined> = {}
|
|
8
34
|
for (const property of Object.values(page.properties)) {
|
|
9
35
|
if (property) {
|
|
@@ -53,78 +79,6 @@ function timestamp(
|
|
|
53
79
|
}
|
|
54
80
|
}
|
|
55
81
|
|
|
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
82
|
function toLegacyProperty(
|
|
129
83
|
property: NotionPagePropertyValue,
|
|
130
84
|
): NotionDataSourceValue | undefined {
|
|
@@ -150,7 +104,7 @@ function toLegacyProperty(
|
|
|
150
104
|
case "multi_select":
|
|
151
105
|
return property.multi_select.flatMap(option => option.name ?? [])
|
|
152
106
|
case "date":
|
|
153
|
-
return property.date ?
|
|
107
|
+
return property.date ? toNotionDateValue(property.date) : undefined
|
|
154
108
|
case "people":
|
|
155
109
|
return property.people.map(person =>
|
|
156
110
|
person.object === "group"
|
|
@@ -2,7 +2,7 @@ import type {
|
|
|
2
2
|
HostToSandboxMessage,
|
|
3
3
|
HostToSandboxMessageLegacy,
|
|
4
4
|
} from "@notionhq/custom-blocks-protocol/messages/hostToSandbox.js"
|
|
5
|
-
import {
|
|
5
|
+
import { normalizeToLegacyPage } from "./normalizePage.js"
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Normalizes an outgoing message for the bridge protocol version requested by the sandbox.
|
|
@@ -13,6 +13,17 @@ export function normalizeHostToSandboxMessage(
|
|
|
13
13
|
message: HostToSandboxMessage,
|
|
14
14
|
bridgeProtocolVersion: number,
|
|
15
15
|
): HostToSandboxMessageLegacy {
|
|
16
|
-
|
|
16
|
+
if (
|
|
17
|
+
message.type !== "queryDataSourceResult" &&
|
|
18
|
+
message.type !== "getPageResult" &&
|
|
19
|
+
message.type !== "createPageResult" &&
|
|
20
|
+
message.type !== "updatePageResult"
|
|
21
|
+
) {
|
|
22
|
+
return message
|
|
23
|
+
}
|
|
24
|
+
const normalizedMessage = normalizeToLegacyPage(
|
|
25
|
+
message,
|
|
26
|
+
bridgeProtocolVersion,
|
|
27
|
+
)
|
|
17
28
|
return normalizedMessage
|
|
18
29
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CreatePageResultMessage } from "@notionhq/custom-blocks-protocol/messages/createPageResult.js"
|
|
2
|
+
import type { GetPageResultMessage } from "@notionhq/custom-blocks-protocol/messages/getPage.js"
|
|
3
|
+
import type { HostToSandboxMessageLegacy } from "@notionhq/custom-blocks-protocol/messages/hostToSandbox.js"
|
|
4
|
+
import type { QueryDataSourceResultMessage } from "@notionhq/custom-blocks-protocol/messages/queryDataSourceResult.js"
|
|
5
|
+
import type { UpdatePageResultMessage } from "@notionhq/custom-blocks-protocol/messages/updatePageResult.js"
|
|
6
|
+
import { LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION } from "@notionhq/custom-blocks-protocol/protocolVersion.js"
|
|
7
|
+
import { unreachable } from "../utils.js"
|
|
8
|
+
import { toLegacyPage, toLegacyQueryPage } from "./legacyPage.js"
|
|
9
|
+
|
|
10
|
+
export function normalizeToLegacyPage(
|
|
11
|
+
message:
|
|
12
|
+
| CreatePageResultMessage
|
|
13
|
+
| GetPageResultMessage
|
|
14
|
+
| UpdatePageResultMessage
|
|
15
|
+
| QueryDataSourceResultMessage,
|
|
16
|
+
bridgeProtocolVersion: number,
|
|
17
|
+
): HostToSandboxMessageLegacy {
|
|
18
|
+
// Forward up to date messages
|
|
19
|
+
if (bridgeProtocolVersion >= LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION) {
|
|
20
|
+
return message
|
|
21
|
+
}
|
|
22
|
+
if (message.status === "error") {
|
|
23
|
+
return message
|
|
24
|
+
}
|
|
25
|
+
switch (message.type) {
|
|
26
|
+
case "queryDataSourceResult":
|
|
27
|
+
return { ...message, items: message.items.map(toLegacyQueryPage) }
|
|
28
|
+
case "getPageResult":
|
|
29
|
+
case "createPageResult":
|
|
30
|
+
case "updatePageResult":
|
|
31
|
+
return { ...message, page: toLegacyPage(message.page) }
|
|
32
|
+
default:
|
|
33
|
+
return unreachable(message)
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/messages/types.ts
CHANGED
|
@@ -57,7 +57,7 @@ import type {
|
|
|
57
57
|
import type { InferInput } from "valibot"
|
|
58
58
|
import type { CustomBlockHostQueryDataSourceResult } from "../queries/types.js"
|
|
59
59
|
|
|
60
|
-
type MaybePromise<T> = T | Promise<T>
|
|
60
|
+
export type MaybePromise<T> = T | Promise<T>
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* Host results use InferInput so adapters can return plain string IDs.
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { HostToSandboxMessage, HostToSandboxMessageLegacy } from "../protocol/messages/hostToSandbox.js";
|
|
2
|
-
export declare function normalizeQueryPage(message: HostToSandboxMessageLegacy | HostToSandboxMessage, bridgeProtocolVersion: number): HostToSandboxMessageLegacy;
|
|
3
|
-
//# sourceMappingURL=normalizeQueryPage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeQueryPage.d.ts","sourceRoot":"","sources":["../../src/lifecycle/normalizeQueryPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oBAAoB,EACpB,0BAA0B,EAC1B,MAAM,4DAA4D,CAAA;AAInE,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,0BAA0B,GAAG,oBAAoB,EAC1D,qBAAqB,EAAE,MAAM,GAC3B,0BAA0B,CAc5B"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION } from "../protocol/protocolVersion.js";
|
|
2
|
-
import { toLegacyQueryPage } from "./legacyPage.js";
|
|
3
|
-
export function normalizeQueryPage(message, bridgeProtocolVersion) {
|
|
4
|
-
if (bridgeProtocolVersion < LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION &&
|
|
5
|
-
message.type === "queryDataSourceResult" &&
|
|
6
|
-
message.status === "success") {
|
|
7
|
-
return {
|
|
8
|
-
...message,
|
|
9
|
-
items: message.items.map(page => "properties" in page ? toLegacyQueryPage(page) : page),
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
return message;
|
|
13
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
}
|