@visus-io/notion-sdk-ts 3.1.0 → 3.2.0

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.
Files changed (122) hide show
  1. package/README.md +20 -88
  2. package/dist/api/asyncTasks.api.d.ts +5 -3
  3. package/dist/api/asyncTasks.api.js +5 -3
  4. package/dist/api/base.api.d.ts +15 -4
  5. package/dist/api/base.api.js +19 -8
  6. package/dist/api/blocks.api.d.ts +2 -0
  7. package/dist/api/blocks.api.js +5 -2
  8. package/dist/api/comments.api.d.ts +2 -0
  9. package/dist/api/comments.api.js +2 -0
  10. package/dist/api/customEmojis.api.d.ts +2 -0
  11. package/dist/api/customEmojis.api.js +2 -0
  12. package/dist/api/dataSources.api.d.ts +10 -3
  13. package/dist/api/dataSources.api.js +4 -1
  14. package/dist/api/databases.api.d.ts +21 -8
  15. package/dist/api/databases.api.js +8 -4
  16. package/dist/api/fileUploads.api.d.ts +7 -4
  17. package/dist/api/fileUploads.api.js +11 -7
  18. package/dist/api/pages.api.d.ts +8 -3
  19. package/dist/api/pages.api.js +5 -3
  20. package/dist/api/search.api.d.ts +4 -2
  21. package/dist/api/search.api.js +5 -2
  22. package/dist/api/users.api.d.ts +2 -0
  23. package/dist/api/users.api.js +2 -0
  24. package/dist/api/views.api.d.ts +15 -13
  25. package/dist/api/views.api.js +10 -7
  26. package/dist/client.d.ts +17 -17
  27. package/dist/client.js +22 -27
  28. package/dist/errors.d.ts +21 -4
  29. package/dist/errors.js +17 -4
  30. package/dist/helpers/block.helpers.d.ts +22 -15
  31. package/dist/helpers/block.helpers.js +14 -12
  32. package/dist/helpers/file.helpers.d.ts +12 -6
  33. package/dist/helpers/file.helpers.js +12 -6
  34. package/dist/helpers/filter.helpers.d.ts +2 -0
  35. package/dist/helpers/filter.helpers.js +2 -0
  36. package/dist/helpers/pagination.helpers.d.ts +52 -36
  37. package/dist/helpers/pagination.helpers.js +49 -29
  38. package/dist/helpers/parent.helpers.d.ts +5 -3
  39. package/dist/helpers/parent.helpers.js +5 -3
  40. package/dist/helpers/property.helpers.d.ts +2 -0
  41. package/dist/helpers/property.helpers.js +3 -1
  42. package/dist/helpers/richText.helpers.d.ts +10 -5
  43. package/dist/helpers/richText.helpers.js +11 -6
  44. package/dist/helpers/sort.helpers.d.ts +2 -0
  45. package/dist/helpers/sort.helpers.js +2 -0
  46. package/dist/helpers/webhook.helpers.d.ts +14 -12
  47. package/dist/helpers/webhook.helpers.js +17 -15
  48. package/dist/models/asyncTask.model.d.ts +8 -6
  49. package/dist/models/asyncTask.model.js +8 -6
  50. package/dist/models/base.model.d.ts +16 -4
  51. package/dist/models/base.model.js +17 -5
  52. package/dist/models/block.model.d.ts +6 -2
  53. package/dist/models/block.model.js +48 -36
  54. package/dist/models/comment.model.d.ts +4 -2
  55. package/dist/models/comment.model.js +4 -2
  56. package/dist/models/customEmoji.model.d.ts +7 -5
  57. package/dist/models/customEmoji.model.js +7 -5
  58. package/dist/models/dataSource.model.d.ts +10 -3
  59. package/dist/models/dataSource.model.js +11 -2
  60. package/dist/models/database.model.d.ts +11 -3
  61. package/dist/models/database.model.js +14 -4
  62. package/dist/models/fileUpload.model.d.ts +6 -4
  63. package/dist/models/fileUpload.model.js +6 -4
  64. package/dist/models/page.model.d.ts +6 -2
  65. package/dist/models/page.model.js +8 -4
  66. package/dist/models/richText.model.d.ts +3 -1
  67. package/dist/models/richText.model.js +3 -1
  68. package/dist/models/user.model.d.ts +9 -2
  69. package/dist/models/user.model.js +14 -2
  70. package/dist/models/view.model.d.ts +9 -7
  71. package/dist/models/view.model.js +9 -7
  72. package/dist/notion.d.ts +6 -1
  73. package/dist/notion.js +6 -1
  74. package/dist/schemas/asyncTask.schema.d.ts +11 -0
  75. package/dist/schemas/asyncTask.schema.js +5 -0
  76. package/dist/schemas/block.schema.d.ts +12 -1
  77. package/dist/schemas/block.schema.js +6 -1
  78. package/dist/schemas/codeLanguages.d.ts +7 -1
  79. package/dist/schemas/codeLanguages.js +4 -1
  80. package/dist/schemas/colors.d.ts +7 -1
  81. package/dist/schemas/colors.js +4 -1
  82. package/dist/schemas/comment.schema.d.ts +20 -2
  83. package/dist/schemas/comment.schema.js +11 -2
  84. package/dist/schemas/customEmoji.schema.d.ts +5 -0
  85. package/dist/schemas/customEmoji.schema.js +2 -0
  86. package/dist/schemas/dataSource.schema.d.ts +24 -3
  87. package/dist/schemas/dataSource.schema.js +15 -5
  88. package/dist/schemas/database.schema.d.ts +31 -1
  89. package/dist/schemas/database.schema.js +18 -2
  90. package/dist/schemas/emoji.schema.d.ts +7 -2
  91. package/dist/schemas/emoji.schema.js +4 -2
  92. package/dist/schemas/file.schema.d.ts +18 -2
  93. package/dist/schemas/file.schema.js +6 -2
  94. package/dist/schemas/fileUpload.schema.d.ts +8 -2
  95. package/dist/schemas/fileUpload.schema.js +5 -2
  96. package/dist/schemas/icon.schema.d.ts +28 -4
  97. package/dist/schemas/icon.schema.js +16 -4
  98. package/dist/schemas/meetingNotesQuery.schema.d.ts +13 -2
  99. package/dist/schemas/meetingNotesQuery.schema.js +7 -2
  100. package/dist/schemas/page.schema.d.ts +8 -0
  101. package/dist/schemas/page.schema.js +2 -0
  102. package/dist/schemas/pageMarkdown.schema.d.ts +15 -4
  103. package/dist/schemas/pageMarkdown.schema.js +9 -4
  104. package/dist/schemas/pageProperties.schema.d.ts +81 -3
  105. package/dist/schemas/pageProperties.schema.js +7 -3
  106. package/dist/schemas/pagination.schema.d.ts +33 -10
  107. package/dist/schemas/pagination.schema.js +12 -5
  108. package/dist/schemas/parent.schema.d.ts +29 -2
  109. package/dist/schemas/parent.schema.js +8 -2
  110. package/dist/schemas/propertyObjects.schema.d.ts +81 -3
  111. package/dist/schemas/propertyObjects.schema.js +11 -5
  112. package/dist/schemas/richText.schema.d.ts +15 -0
  113. package/dist/schemas/richText.schema.js +6 -3
  114. package/dist/schemas/shared.schema.d.ts +6 -3
  115. package/dist/schemas/shared.schema.js +6 -3
  116. package/dist/schemas/user.schema.d.ts +15 -0
  117. package/dist/schemas/user.schema.js +5 -2
  118. package/dist/schemas/view.schema.d.ts +46 -9
  119. package/dist/schemas/view.schema.js +28 -9
  120. package/dist/validation.d.ts +11 -4
  121. package/dist/validation.js +11 -4
  122. package/package.json +20 -16
@@ -28,8 +28,8 @@ function database(databaseId) {
28
28
  }
29
29
  /**
30
30
  * Create a data source parent object.
31
- * Both data_source_id and database_id are required when creating a page
32
- * with a data source parent.
31
+ * A page with a data source parent needs both `data_source_id` and
32
+ * `database_id`.
33
33
  *
34
34
  * @example
35
35
  * ```ts
@@ -56,7 +56,7 @@ function workspace() {
56
56
  return { workspace: true };
57
57
  }
58
58
  /**
59
- * Create a block parent object (used for comments on blocks).
59
+ * Create a block parent object for comments on blocks.
60
60
  *
61
61
  * @example
62
62
  * ```ts
@@ -94,6 +94,8 @@ function blockParent(blockId) {
94
94
  * rich_text: [...],
95
95
  * });
96
96
  * ```
97
+ *
98
+ * @category Helpers
97
99
  */
98
100
  exports.parent = {
99
101
  page,
@@ -255,6 +255,8 @@ declare function files(entries: FileEntry[]): {
255
255
  * },
256
256
  * });
257
257
  * ```
258
+ *
259
+ * @category Helpers
258
260
  */
259
261
  export declare const prop: {
260
262
  title: typeof title;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.prop = void 0;
4
4
  const validation_1 = require("../validation");
5
5
  const richText_helpers_1 = require("./richText.helpers");
6
- /** Resolve rich text input to a `NotionRichText` array. */
6
+ /** Resolve rich text input to a `NotionRichText`. */
7
7
  function resolveRichText(input) {
8
8
  if (typeof input === 'string') {
9
9
  (0, validation_1.validateStringLength)(input, validation_1.LIMITS.RICH_TEXT_CONTENT, 'Rich text content');
@@ -278,6 +278,8 @@ function files(entries) {
278
278
  * },
279
279
  * });
280
280
  * ```
281
+ *
282
+ * @category Helpers
281
283
  */
282
284
  exports.prop = {
283
285
  title,
@@ -5,8 +5,9 @@ import type { NotionColor, NotionRichText, NotionUser, TextRichText } from '../s
5
5
  * Do not instantiate directly — use the {@link richText} factory function or
6
6
  * the static helpers on it (`richText.mentionPage`, `richText.equation`, etc.).
7
7
  *
8
- * Call `.build()` to produce a `NotionRichText` array (single-element),
9
- * or pass builders directly to `richText.join()` which calls `.build()` for you.
8
+ * Call `.build()` to produce a single-element `NotionRichText`.
9
+ * Alternatively, pass builders directly to `richText.join()`. This method
10
+ * calls `.build()` for you.
10
11
  *
11
12
  * @example
12
13
  * ```ts
@@ -26,6 +27,8 @@ import type { NotionColor, NotionRichText, NotionUser, TextRichText } from '../s
26
27
  * richText('!'),
27
28
  * );
28
29
  * ```
30
+ *
31
+ * @category Rich Text
29
32
  */
30
33
  export declare class RichTextBuilder {
31
34
  /** @internal */
@@ -52,7 +55,7 @@ export declare class RichTextBuilder {
52
55
  */
53
56
  link(url: string): this;
54
57
  /**
55
- * Build a single-element `NotionRichText` array from this builder.
58
+ * Build a single-element `NotionRichText` from this builder.
56
59
  */
57
60
  build(): NotionRichText;
58
61
  }
@@ -99,8 +102,8 @@ declare function mentionLinkPreview(url: string): RichTextBuilder;
99
102
  */
100
103
  declare function equation(expression: string): RichTextBuilder;
101
104
  /**
102
- * Combine multiple rich text builders (or pre-built `NotionRichText` arrays)
103
- * into a single `NotionRichText` array.
105
+ * Combine multiple rich text builders (or pre-built `NotionRichText` values)
106
+ * into a single `NotionRichText`.
104
107
  *
105
108
  * @example
106
109
  * ```ts
@@ -136,6 +139,8 @@ declare function join(...parts: Array<RichTextBuilder | NotionRichText>): Notion
136
139
  * richText('italic').italic(),
137
140
  * );
138
141
  * ```
142
+ *
143
+ * @category Rich Text
139
144
  */
140
145
  export declare const richText: typeof createRichText & {
141
146
  mentionPage: typeof mentionPage;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.richText = exports.RichTextBuilder = void 0;
4
4
  const validation_1 = require("../validation");
5
5
  /**
6
- * Default annotations object with no formatting applied.
6
+ * Default annotations object with no formatting.
7
7
  */
8
8
  const DEFAULT_ANNOTATIONS = {
9
9
  bold: false,
@@ -19,8 +19,9 @@ const DEFAULT_ANNOTATIONS = {
19
19
  * Do not instantiate directly — use the {@link richText} factory function or
20
20
  * the static helpers on it (`richText.mentionPage`, `richText.equation`, etc.).
21
21
  *
22
- * Call `.build()` to produce a `NotionRichText` array (single-element),
23
- * or pass builders directly to `richText.join()` which calls `.build()` for you.
22
+ * Call `.build()` to produce a single-element `NotionRichText`.
23
+ * Alternatively, pass builders directly to `richText.join()`. This method
24
+ * calls `.build()` for you.
24
25
  *
25
26
  * @example
26
27
  * ```ts
@@ -40,6 +41,8 @@ const DEFAULT_ANNOTATIONS = {
40
41
  * richText('!'),
41
42
  * );
42
43
  * ```
44
+ *
45
+ * @category Rich Text
43
46
  */
44
47
  class RichTextBuilder {
45
48
  /** @internal */
@@ -93,7 +96,7 @@ class RichTextBuilder {
93
96
  return this;
94
97
  }
95
98
  /**
96
- * Build a single-element `NotionRichText` array from this builder.
99
+ * Build a single-element `NotionRichText` from this builder.
97
100
  */
98
101
  build() {
99
102
  return [{ ...this.segment, annotations: { ...this.annotations } }];
@@ -218,8 +221,8 @@ function equation(expression) {
218
221
  return new RichTextBuilder(segment);
219
222
  }
220
223
  /**
221
- * Combine multiple rich text builders (or pre-built `NotionRichText` arrays)
222
- * into a single `NotionRichText` array.
224
+ * Combine multiple rich text builders (or pre-built `NotionRichText` values)
225
+ * into a single `NotionRichText`.
223
226
  *
224
227
  * @example
225
228
  * ```ts
@@ -269,6 +272,8 @@ function join(...parts) {
269
272
  * richText('italic').italic(),
270
273
  * );
271
274
  * ```
275
+ *
276
+ * @category Rich Text
272
277
  */
273
278
  exports.richText = Object.assign(createRichText, {
274
279
  mentionPage,
@@ -34,6 +34,8 @@ declare class TimestampSortBuilder {
34
34
  * ],
35
35
  * });
36
36
  * ```
37
+ *
38
+ * @category Helpers
37
39
  */
38
40
  export declare const sort: {
39
41
  /**
@@ -46,6 +46,8 @@ class TimestampSortBuilder {
46
46
  * ],
47
47
  * });
48
48
  * ```
49
+ *
50
+ * @category Helpers
49
51
  */
50
52
  exports.sort = {
51
53
  /**
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Sign a payload, for generating test webhook signatures.
2
+ * Sign a payload to generate test webhook signatures.
3
3
  *
4
- * @param body - The payload to sign. A string is signed as-is; anything else is
5
- * `JSON.stringify`'d first -- safe here because the caller controls the exact
6
- * serialization of a payload they're constructing themselves.
4
+ * @param body - The payload to sign. This function signs a string as-is. It
5
+ * converts anything else with `JSON.stringify` first. This is safe because the
6
+ * caller controls the serialization of their own payload.
7
7
  * @param verificationToken - The webhook subscription's verification token
8
8
  * @returns The `sha256=<hex digest>` signature
9
9
  *
@@ -16,18 +16,18 @@ declare function sign(body: unknown, verificationToken: string): string;
16
16
  /**
17
17
  * Verify an incoming webhook's `X-Notion-Signature` header via constant-time comparison.
18
18
  *
19
- * IMPORTANT: `rawBody` must be the exact raw request body Notion sent, not
20
- * `JSON.stringify(parsedBody)` -- re-serializing a parsed object can produce a
21
- * different byte sequence (key order, whitespace) than what was actually signed,
22
- * silently breaking verification. Use your framework's raw-body access (e.g.
23
- * Express's `express.raw()` / `req.rawBody`), not `req.body` after JSON middleware
24
- * has already parsed it.
19
+ * IMPORTANT: `rawBody` must be the exact raw request body that Notion sent. Do not use
20
+ * `JSON.stringify(parsedBody)`. Re-serializing a parsed object can produce a different
21
+ * byte sequence (key order, whitespace) than the original signed body, and this
22
+ * silently breaks verification. Use your framework's raw-body access, for example
23
+ * Express's `express.raw()` or `req.rawBody`. Do not use `req.body` after JSON
24
+ * middleware parses it.
25
25
  *
26
26
  * @param rawBody - The exact raw request body string Notion sent
27
27
  * @param signatureHeader - The value of the `X-Notion-Signature` request header
28
28
  * @param verificationToken - The webhook subscription's verification token
29
- * @returns `true` if the signature is valid; `false` for any mismatch or malformed
30
- * input (never throws)
29
+ * @returns `true` if the signature is valid. Returns `false` for a mismatch or
30
+ * malformed input. This function never throws.
31
31
  *
32
32
  * @example
33
33
  * ```ts
@@ -44,6 +44,8 @@ declare function verifySignature(rawBody: string, signatureHeader: string | null
44
44
  *
45
45
  * const isValid = webhook.verifySignature(rawBody, req.headers['x-notion-signature'], verificationToken);
46
46
  * ```
47
+ *
48
+ * @category Helpers
47
49
  */
48
50
  export declare const webhook: {
49
51
  sign: typeof sign;
@@ -5,9 +5,9 @@ const node_crypto_1 = require("node:crypto");
5
5
  /**
6
6
  * Webhook signature helpers.
7
7
  *
8
- * Notion signs webhook payloads with HMAC-SHA256, keyed by the subscription's
9
- * verification token, over the raw JSON request body. The signature is sent in the
10
- * `X-Notion-Signature` header as `sha256=<hex digest>`.
8
+ * Notion signs webhook payloads with HMAC-SHA256. It signs the raw JSON request body
9
+ * and keys the signature with the subscription's verification token. Notion sends the
10
+ * signature in the `X-Notion-Signature` header as `sha256=<hex digest>`.
11
11
  *
12
12
  * Notion API reference:
13
13
  * https://developers.notion.com/reference/webhooks
@@ -16,11 +16,11 @@ function computeSignature(rawBody, verificationToken) {
16
16
  return `sha256=${(0, node_crypto_1.createHmac)('sha256', verificationToken).update(rawBody).digest('hex')}`;
17
17
  }
18
18
  /**
19
- * Sign a payload, for generating test webhook signatures.
19
+ * Sign a payload to generate test webhook signatures.
20
20
  *
21
- * @param body - The payload to sign. A string is signed as-is; anything else is
22
- * `JSON.stringify`'d first -- safe here because the caller controls the exact
23
- * serialization of a payload they're constructing themselves.
21
+ * @param body - The payload to sign. This function signs a string as-is. It
22
+ * converts anything else with `JSON.stringify` first. This is safe because the
23
+ * caller controls the serialization of their own payload.
24
24
  * @param verificationToken - The webhook subscription's verification token
25
25
  * @returns The `sha256=<hex digest>` signature
26
26
  *
@@ -35,18 +35,18 @@ function sign(body, verificationToken) {
35
35
  /**
36
36
  * Verify an incoming webhook's `X-Notion-Signature` header via constant-time comparison.
37
37
  *
38
- * IMPORTANT: `rawBody` must be the exact raw request body Notion sent, not
39
- * `JSON.stringify(parsedBody)` -- re-serializing a parsed object can produce a
40
- * different byte sequence (key order, whitespace) than what was actually signed,
41
- * silently breaking verification. Use your framework's raw-body access (e.g.
42
- * Express's `express.raw()` / `req.rawBody`), not `req.body` after JSON middleware
43
- * has already parsed it.
38
+ * IMPORTANT: `rawBody` must be the exact raw request body that Notion sent. Do not use
39
+ * `JSON.stringify(parsedBody)`. Re-serializing a parsed object can produce a different
40
+ * byte sequence (key order, whitespace) than the original signed body, and this
41
+ * silently breaks verification. Use your framework's raw-body access, for example
42
+ * Express's `express.raw()` or `req.rawBody`. Do not use `req.body` after JSON
43
+ * middleware parses it.
44
44
  *
45
45
  * @param rawBody - The exact raw request body string Notion sent
46
46
  * @param signatureHeader - The value of the `X-Notion-Signature` request header
47
47
  * @param verificationToken - The webhook subscription's verification token
48
- * @returns `true` if the signature is valid; `false` for any mismatch or malformed
49
- * input (never throws)
48
+ * @returns `true` if the signature is valid. Returns `false` for a mismatch or
49
+ * malformed input. This function never throws.
50
50
  *
51
51
  * @example
52
52
  * ```ts
@@ -74,6 +74,8 @@ function verifySignature(rawBody, signatureHeader, verificationToken) {
74
74
  *
75
75
  * const isValid = webhook.verifySignature(rawBody, req.headers['x-notion-signature'], verificationToken);
76
76
  * ```
77
+ *
78
+ * @category Helpers
77
79
  */
78
80
  exports.webhook = {
79
81
  sign,
@@ -1,13 +1,15 @@
1
- import { BaseModel } from './base.model';
1
+ import { BaseModel, type TRUSTED } from './base.model';
2
2
  import { type NotionAsyncTask } from '../schemas';
3
3
  /**
4
- * Async Task model class with helper methods.
4
+ * AsyncTask model class with helper methods.
5
5
  *
6
- * Represents a long-running operation (e.g. an async markdown write) that must be
7
- * polled until it reaches a terminal status.
6
+ * Represents a long-running operation, for example an async markdown write. Poll the
7
+ * task until it reaches a terminal status.
8
+ *
9
+ * @category Async Tasks
8
10
  */
9
11
  export declare class AsyncTask extends BaseModel<NotionAsyncTask> {
10
- constructor(data: NotionAsyncTask);
12
+ constructor(data: NotionAsyncTask, trusted?: typeof TRUSTED);
11
13
  /**
12
14
  * Returns "async_task" - the object type.
13
15
  */
@@ -21,7 +23,7 @@ export declare class AsyncTask extends BaseModel<NotionAsyncTask> {
21
23
  */
22
24
  get status(): NotionAsyncTask['status'];
23
25
  /**
24
- * Returns the URL that can be polled for task status.
26
+ * Returns the URL to poll for the task status.
25
27
  */
26
28
  get statusUrl(): string;
27
29
  /**
@@ -4,14 +4,16 @@ exports.AsyncTask = void 0;
4
4
  const base_model_1 = require("./base.model");
5
5
  const schemas_1 = require("../schemas");
6
6
  /**
7
- * Async Task model class with helper methods.
7
+ * AsyncTask model class with helper methods.
8
8
  *
9
- * Represents a long-running operation (e.g. an async markdown write) that must be
10
- * polled until it reaches a terminal status.
9
+ * Represents a long-running operation, for example an async markdown write. Poll the
10
+ * task until it reaches a terminal status.
11
+ *
12
+ * @category Async Tasks
11
13
  */
12
14
  class AsyncTask extends base_model_1.BaseModel {
13
- constructor(data) {
14
- super(data, schemas_1.asyncTaskSchema);
15
+ constructor(data, trusted) {
16
+ super(data, schemas_1.asyncTaskSchema, trusted);
15
17
  }
16
18
  /**
17
19
  * Returns "async_task" - the object type.
@@ -32,7 +34,7 @@ class AsyncTask extends base_model_1.BaseModel {
32
34
  return this.data.status;
33
35
  }
34
36
  /**
35
- * Returns the URL that can be polled for task status.
37
+ * Returns the URL to poll for the task status.
36
38
  */
37
39
  get statusUrl() {
38
40
  return this.data.status_url;
@@ -1,17 +1,29 @@
1
1
  import type * as z from 'zod';
2
2
  /**
3
- * Base model class providing common functionality for all Notion models.
4
- * Models wrap validated data from schemas with methods and business logic.
3
+ * Internal marker for trusted, already-validated data.
4
+ *
5
+ * Pass this to a model constructor to skip re-parsing data an API module already
6
+ * validated. This symbol is not exported from the package's public barrel, so
7
+ * external consumers can never construct or forge it. Direct construction from
8
+ * outside the SDK always validates.
9
+ */
10
+ export declare const TRUSTED: unique symbol;
11
+ /**
12
+ * Base class for all Notion models.
13
+ *
14
+ * This class wraps validated data from a schema. It adds methods and logic for each model.
15
+ *
16
+ * @category Client & Core
5
17
  */
6
18
  export declare abstract class BaseModel<T> {
7
19
  protected readonly data: T;
8
- protected constructor(data: T, schema: z.ZodType<T>);
20
+ protected constructor(data: T, schema: z.ZodType<T>, trusted?: typeof TRUSTED);
9
21
  /**
10
22
  * Returns the raw validated data as a plain object.
11
23
  */
12
24
  toJSON(): T;
13
25
  /**
14
- * Returns the object type (e.g., "page", "block", "user").
26
+ * Returns the object type, for example "page", "block", or "user".
15
27
  */
16
28
  abstract get object(): string;
17
29
  /**
@@ -1,13 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseModel = void 0;
3
+ exports.BaseModel = exports.TRUSTED = void 0;
4
4
  /**
5
- * Base model class providing common functionality for all Notion models.
6
- * Models wrap validated data from schemas with methods and business logic.
5
+ * Internal marker for trusted, already-validated data.
6
+ *
7
+ * Pass this to a model constructor to skip re-parsing data an API module already
8
+ * validated. This symbol is not exported from the package's public barrel, so
9
+ * external consumers can never construct or forge it. Direct construction from
10
+ * outside the SDK always validates.
11
+ */
12
+ exports.TRUSTED = Symbol('trusted');
13
+ /**
14
+ * Base class for all Notion models.
15
+ *
16
+ * This class wraps validated data from a schema. It adds methods and logic for each model.
17
+ *
18
+ * @category Client & Core
7
19
  */
8
20
  class BaseModel {
9
- constructor(data, schema) {
10
- this.data = schema.parse(data);
21
+ constructor(data, schema, trusted) {
22
+ this.data = trusted === exports.TRUSTED ? data : schema.parse(data);
11
23
  }
12
24
  /**
13
25
  * Returns the raw validated data as a plain object.
@@ -1,10 +1,14 @@
1
- import { BaseModel } from './base.model';
1
+ import { BaseModel, type TRUSTED } from './base.model';
2
2
  import { type NotionBlock } from '../schemas';
3
3
  /**
4
4
  * Block model wrapping a validated Notion block object with helper methods.
5
+ *
6
+ * @category Blocks
5
7
  */
6
8
  export declare class Block extends BaseModel<NotionBlock> {
7
- constructor(data: unknown);
9
+ private cachedCreatedTimeMs?;
10
+ private cachedLastEditedTimeMs?;
11
+ constructor(data: unknown, trusted?: typeof TRUSTED);
8
12
  get object(): string;
9
13
  get id(): string;
10
14
  get type(): NotionBlock['type'];
@@ -3,12 +3,51 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Block = void 0;
4
4
  const base_model_1 = require("./base.model");
5
5
  const schemas_1 = require("../schemas");
6
+ const TEXT_BLOCK_TYPES = new Set([
7
+ 'paragraph',
8
+ 'heading_1',
9
+ 'heading_2',
10
+ 'heading_3',
11
+ 'heading_4',
12
+ 'quote',
13
+ 'callout',
14
+ 'bulleted_list_item',
15
+ 'numbered_list_item',
16
+ 'to_do',
17
+ 'toggle',
18
+ ]);
19
+ const HEADING_BLOCK_TYPES = new Set([
20
+ 'heading_1',
21
+ 'heading_2',
22
+ 'heading_3',
23
+ 'heading_4',
24
+ ]);
25
+ const CHILD_CONTAINER_BLOCK_TYPES = new Set([
26
+ 'paragraph',
27
+ 'heading_1',
28
+ 'heading_2',
29
+ 'heading_3',
30
+ 'heading_4',
31
+ 'bulleted_list_item',
32
+ 'numbered_list_item',
33
+ 'to_do',
34
+ 'toggle',
35
+ 'quote',
36
+ 'callout',
37
+ 'synced_block',
38
+ 'column',
39
+ 'column_list',
40
+ 'tab',
41
+ 'table',
42
+ ]);
6
43
  /**
7
44
  * Block model wrapping a validated Notion block object with helper methods.
45
+ *
46
+ * @category Blocks
8
47
  */
9
48
  class Block extends base_model_1.BaseModel {
10
- constructor(data) {
11
- super(data, schemas_1.blockSchema);
49
+ constructor(data, trusted) {
50
+ super(data, schemas_1.blockSchema, trusted);
12
51
  }
13
52
  get object() {
14
53
  return this.data.object;
@@ -20,10 +59,12 @@ class Block extends base_model_1.BaseModel {
20
59
  return this.data.type;
21
60
  }
22
61
  get createdTime() {
23
- return new Date(this.data.created_time);
62
+ this.cachedCreatedTimeMs ??= new Date(this.data.created_time).getTime();
63
+ return new Date(this.cachedCreatedTimeMs);
24
64
  }
25
65
  get lastEditedTime() {
26
- return new Date(this.data.last_edited_time);
66
+ this.cachedLastEditedTimeMs ??= new Date(this.data.last_edited_time).getTime();
67
+ return new Date(this.cachedLastEditedTimeMs);
27
68
  }
28
69
  get inTrash() {
29
70
  return this.data.in_trash;
@@ -35,48 +76,19 @@ class Block extends base_model_1.BaseModel {
35
76
  * Check if this is a text-based block type.
36
77
  */
37
78
  isTextBlock() {
38
- return [
39
- 'paragraph',
40
- 'heading_1',
41
- 'heading_2',
42
- 'heading_3',
43
- 'heading_4',
44
- 'quote',
45
- 'callout',
46
- 'bulleted_list_item',
47
- 'numbered_list_item',
48
- 'to_do',
49
- 'toggle',
50
- ].includes(this.data.type);
79
+ return TEXT_BLOCK_TYPES.has(this.data.type);
51
80
  }
52
81
  /**
53
82
  * Check if this is a heading block.
54
83
  */
55
84
  isHeading() {
56
- return ['heading_1', 'heading_2', 'heading_3', 'heading_4'].includes(this.data.type);
85
+ return HEADING_BLOCK_TYPES.has(this.data.type);
57
86
  }
58
87
  /**
59
88
  * Check if this block can contain children.
60
89
  */
61
90
  canHaveChildren() {
62
- return [
63
- 'paragraph',
64
- 'heading_1',
65
- 'heading_2',
66
- 'heading_3',
67
- 'heading_4',
68
- 'bulleted_list_item',
69
- 'numbered_list_item',
70
- 'to_do',
71
- 'toggle',
72
- 'quote',
73
- 'callout',
74
- 'synced_block',
75
- 'column',
76
- 'column_list',
77
- 'tab',
78
- 'table',
79
- ].includes(this.data.type);
91
+ return CHILD_CONTAINER_BLOCK_TYPES.has(this.data.type);
80
92
  }
81
93
  /**
82
94
  * Get the plain text content from text-based blocks.
@@ -1,10 +1,12 @@
1
- import { BaseModel } from './base.model';
1
+ import { BaseModel, type TRUSTED } from './base.model';
2
2
  import { type CommentAttachment, type CommentDisplayName, type NotionComment, type NotionParent, type NotionRichText, type NotionUser } from '../schemas';
3
3
  /**
4
4
  * Comment model class with helper methods.
5
+ *
6
+ * @category Comments
5
7
  */
6
8
  export declare class Comment extends BaseModel<NotionComment> {
7
- constructor(data: NotionComment);
9
+ constructor(data: NotionComment, trusted?: typeof TRUSTED);
8
10
  /**
9
11
  * Returns "comment" - the object type.
10
12
  */
@@ -5,10 +5,12 @@ const base_model_1 = require("./base.model");
5
5
  const schemas_1 = require("../schemas");
6
6
  /**
7
7
  * Comment model class with helper methods.
8
+ *
9
+ * @category Comments
8
10
  */
9
11
  class Comment extends base_model_1.BaseModel {
10
- constructor(data) {
11
- super(data, schemas_1.commentSchema);
12
+ constructor(data, trusted) {
13
+ super(data, schemas_1.commentSchema, trusted);
12
14
  }
13
15
  /**
14
16
  * Returns "comment" - the object type.
@@ -1,16 +1,18 @@
1
- import { BaseModel } from './base.model';
1
+ import { BaseModel, type TRUSTED } from './base.model';
2
2
  import { type NotionCustomEmoji } from '../schemas';
3
3
  /**
4
4
  * Custom Emoji model class with helper methods.
5
+ *
6
+ * @category Custom Emoji & Icons
5
7
  */
6
8
  export declare class CustomEmoji extends BaseModel<NotionCustomEmoji> {
7
- constructor(data: NotionCustomEmoji);
9
+ constructor(data: NotionCustomEmoji, trusted?: typeof TRUSTED);
8
10
  /**
9
11
  * Returns "custom_emoji" - the object type.
10
12
  *
11
- * Note: individual custom emoji list items have no `object` field of their own in
12
- * the API response (only the paginated list wrapper does) -- this getter is
13
- * synthetic, not sourced from the payload, to satisfy {@link BaseModel}'s contract.
13
+ * Note: A custom emoji list item has no `object` field in the API response. Only
14
+ * the paginated list wrapper has that field. This getter returns a synthetic
15
+ * value, not data from the payload, to meet the {@link BaseModel} contract.
14
16
  */
15
17
  get object(): 'custom_emoji';
16
18
  /**
@@ -5,17 +5,19 @@ const base_model_1 = require("./base.model");
5
5
  const schemas_1 = require("../schemas");
6
6
  /**
7
7
  * Custom Emoji model class with helper methods.
8
+ *
9
+ * @category Custom Emoji & Icons
8
10
  */
9
11
  class CustomEmoji extends base_model_1.BaseModel {
10
- constructor(data) {
11
- super(data, schemas_1.customEmojiSchema);
12
+ constructor(data, trusted) {
13
+ super(data, schemas_1.customEmojiSchema, trusted);
12
14
  }
13
15
  /**
14
16
  * Returns "custom_emoji" - the object type.
15
17
  *
16
- * Note: individual custom emoji list items have no `object` field of their own in
17
- * the API response (only the paginated list wrapper does) -- this getter is
18
- * synthetic, not sourced from the payload, to satisfy {@link BaseModel}'s contract.
18
+ * Note: A custom emoji list item has no `object` field in the API response. Only
19
+ * the paginated list wrapper has that field. This getter returns a synthetic
20
+ * value, not data from the payload, to meet the {@link BaseModel} contract.
19
21
  */
20
22
  get object() {
21
23
  return 'custom_emoji';