@notionhq/client 5.25.2 → 5.27.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.
- package/README.md +130 -129
- package/build/package.json +4 -3
- package/build/src/Client.d.ts +1901 -96
- package/build/src/Client.d.ts.map +1 -1
- package/build/src/Client.js +271 -427
- package/build/src/Client.js.map +1 -1
- package/build/src/api-endpoint-methods.d.ts +920 -0
- package/build/src/api-endpoint-methods.d.ts.map +1 -0
- package/build/src/api-endpoint-methods.js +171 -0
- package/build/src/api-endpoint-methods.js.map +1 -0
- package/build/src/api-endpoints/agent-skills.d.ts +68 -0
- package/build/src/api-endpoints/agent-skills.d.ts.map +1 -0
- package/build/src/api-endpoints/agent-skills.js +36 -0
- package/build/src/api-endpoints/agent-skills.js.map +1 -0
- package/build/src/api-endpoints/agents.d.ts +3268 -0
- package/build/src/api-endpoints/agents.d.ts.map +1 -0
- package/build/src/api-endpoints/agents.js +336 -0
- package/build/src/api-endpoints/agents.js.map +1 -0
- package/build/src/api-endpoints/data-sources.d.ts +1 -0
- package/build/src/api-endpoints/data-sources.d.ts.map +1 -1
- package/build/src/api-endpoints/data-sources.js.map +1 -1
- package/build/src/api-endpoints/databases.d.ts +3 -1
- package/build/src/api-endpoints/databases.d.ts.map +1 -1
- package/build/src/api-endpoints/databases.js +1 -0
- package/build/src/api-endpoints/databases.js.map +1 -1
- package/build/src/api-endpoints/file-uploads.d.ts.map +1 -1
- package/build/src/api-endpoints/file-uploads.js.map +1 -1
- package/build/src/api-endpoints/pages.d.ts.map +1 -1
- package/build/src/api-endpoints/pages.js.map +1 -1
- package/build/src/api-endpoints/users.d.ts.map +1 -1
- package/build/src/api-endpoints/users.js.map +1 -1
- package/build/src/api-endpoints.d.ts +2 -0
- package/build/src/api-endpoints.d.ts.map +1 -1
- package/build/src/api-endpoints.js +2 -0
- package/build/src/api-endpoints.js.map +1 -1
- package/build/src/errors.d.ts +11 -0
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +20 -1
- package/build/src/errors.js.map +1 -1
- package/build/src/fetch-types.d.ts +11 -0
- package/build/src/fetch-types.d.ts.map +1 -1
- package/build/src/fetch-types.js.map +1 -1
- package/build/src/helpers.d.ts +4 -4
- package/build/src/helpers.d.ts.map +1 -1
- package/build/src/helpers.js.map +1 -1
- package/build/src/index.d.ts +2 -2
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +2 -1
- package/build/src/index.js.map +1 -1
- package/build/src/webhooks.d.ts +12 -19
- package/build/src/webhooks.d.ts.map +1 -1
- package/build/src/webhooks.js +27 -35
- package/build/src/webhooks.js.map +1 -1
- package/package.json +4 -3
package/build/src/webhooks.js
CHANGED
|
@@ -2,19 +2,13 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Helpers for receiving and verifying Notion webhook deliveries.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the
|
|
8
|
-
*
|
|
9
|
-
* **exactly as it arrived over the wire** — any JSON re-serialization
|
|
10
|
-
* will change the bytes and invalidate the signature.
|
|
5
|
+
* Event signatures use HMAC-SHA256 with the subscription's verification
|
|
6
|
+
* token. The `X-Notion-Signature` header contains `sha256=<hex>`.
|
|
7
|
+
* Pass the raw body as received. Parsing and re-serializing JSON can change
|
|
8
|
+
* its bytes and invalidate the signature.
|
|
11
9
|
*
|
|
12
|
-
* The helpers
|
|
13
|
-
*
|
|
14
|
-
* transparently fall back to `node:crypto`'s `webcrypto.subtle` on older
|
|
15
|
-
* Node.js 18 builds where `globalThis.crypto` is not yet enabled by
|
|
16
|
-
* default. They work without configuration in Node.js, Bun, Deno,
|
|
17
|
-
* Vercel Edge Functions, Cloudflare Workers, and modern browsers.
|
|
10
|
+
* The helpers use `globalThis.crypto.subtle` when available, then fall
|
|
11
|
+
* back to the Web Crypto API in Node's crypto module.
|
|
18
12
|
*/
|
|
19
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
14
|
exports.verifyWebhookSignature = verifyWebhookSignature;
|
|
@@ -25,29 +19,32 @@ const SHA256_HEX_LENGTH = 64;
|
|
|
25
19
|
* Verify that a webhook delivery came from Notion and has not been
|
|
26
20
|
* tampered with.
|
|
27
21
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* malformed input so the caller can respond with a single 401/403 path.
|
|
22
|
+
* Returns `true` if the signature matches HMAC-SHA256 of the body using
|
|
23
|
+
* the verification token. Returns `false` for a missing or malformed
|
|
24
|
+
* signature. Crypto errors may throw.
|
|
32
25
|
*/
|
|
33
26
|
async function verifyWebhookSignature(args) {
|
|
34
27
|
const { body, signature, verificationToken } = args;
|
|
35
|
-
if (typeof signature !== "string")
|
|
28
|
+
if (typeof signature !== "string") {
|
|
36
29
|
return false;
|
|
37
|
-
|
|
30
|
+
}
|
|
31
|
+
if (!signature.startsWith(SIGNATURE_PREFIX)) {
|
|
38
32
|
return false;
|
|
33
|
+
}
|
|
39
34
|
const providedHex = signature.slice(SIGNATURE_PREFIX.length).toLowerCase();
|
|
40
|
-
if (providedHex.length !== SHA256_HEX_LENGTH)
|
|
35
|
+
if (providedHex.length !== SHA256_HEX_LENGTH) {
|
|
41
36
|
return false;
|
|
42
|
-
|
|
37
|
+
}
|
|
38
|
+
if (!/^[0-9a-f]+$/.test(providedHex)) {
|
|
43
39
|
return false;
|
|
40
|
+
}
|
|
44
41
|
const computedHex = await computeHmacSha256Hex(verificationToken, body);
|
|
45
42
|
return timingSafeEqualHex(providedHex, computedHex);
|
|
46
43
|
}
|
|
47
44
|
/**
|
|
48
45
|
* Compute the value Notion would send in `X-Notion-Signature` for a
|
|
49
|
-
* given body and verification token.
|
|
50
|
-
*
|
|
46
|
+
* given body and verification token. Use this to test webhook handlers
|
|
47
|
+
* without a live subscription.
|
|
51
48
|
*/
|
|
52
49
|
async function signWebhookPayload(args) {
|
|
53
50
|
const hex = await computeHmacSha256Hex(args.verificationToken, args.body);
|
|
@@ -68,23 +65,17 @@ async function computeHmacSha256Hex(key, body) {
|
|
|
68
65
|
let cachedSubtle;
|
|
69
66
|
async function getSubtle() {
|
|
70
67
|
var _a, _b;
|
|
71
|
-
if (cachedSubtle)
|
|
68
|
+
if (cachedSubtle) {
|
|
72
69
|
return cachedSubtle;
|
|
73
|
-
|
|
74
|
-
// global object. This includes browsers, Vercel Edge, Cloudflare
|
|
75
|
-
// Workers, Deno, Bun, and Node.js >= 18.19 (which backported the
|
|
76
|
-
// change from Node.js 19).
|
|
70
|
+
}
|
|
77
71
|
const fromGlobal = (_a = globalThis
|
|
78
72
|
.crypto) === null || _a === void 0 ? void 0 : _a.subtle;
|
|
79
73
|
if (fromGlobal) {
|
|
80
74
|
cachedSubtle = fromGlobal;
|
|
81
75
|
return cachedSubtle;
|
|
82
76
|
}
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
// Using `require` (rather than a static `import`) keeps the
|
|
86
|
-
// node:crypto reference off the dependency graph of browser bundlers
|
|
87
|
-
// that would otherwise fail to resolve it.
|
|
77
|
+
// Load Node's fallback only when needed so browser callers can use the
|
|
78
|
+
// global API without loading a Node module.
|
|
88
79
|
try {
|
|
89
80
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
90
81
|
const nodeCrypto = require("crypto");
|
|
@@ -104,8 +95,8 @@ async function getSubtle() {
|
|
|
104
95
|
}
|
|
105
96
|
function bytesToHex(bytes) {
|
|
106
97
|
let hex = "";
|
|
107
|
-
for (
|
|
108
|
-
hex +=
|
|
98
|
+
for (const byte of bytes) {
|
|
99
|
+
hex += byte.toString(16).padStart(2, "0");
|
|
109
100
|
}
|
|
110
101
|
return hex;
|
|
111
102
|
}
|
|
@@ -113,8 +104,9 @@ function bytesToHex(bytes) {
|
|
|
113
104
|
// the same length (callers enforce SHA256_HEX_LENGTH), so this purely
|
|
114
105
|
// avoids early-exit on the first differing character.
|
|
115
106
|
function timingSafeEqualHex(a, b) {
|
|
116
|
-
if (a.length !== b.length)
|
|
107
|
+
if (a.length !== b.length) {
|
|
117
108
|
return false;
|
|
109
|
+
}
|
|
118
110
|
let diff = 0;
|
|
119
111
|
for (let i = 0; i < a.length; i++) {
|
|
120
112
|
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Helpers for receiving and verifying Notion webhook deliveries.\n *\n * Event signatures use HMAC-SHA256 with the subscription's verification\n * token. The `X-Notion-Signature` header contains `sha256=<hex>`.\n * Pass the raw body as received. Parsing and re-serializing JSON can change\n * its bytes and invalidate the signature.\n *\n * The helpers use `globalThis.crypto.subtle` when available, then fall\n * back to the Web Crypto API in Node's crypto module.\n */\n\nconst SIGNATURE_PREFIX = \"sha256=\"\nconst SHA256_HEX_LENGTH = 64\n\nexport type VerifyWebhookSignatureArgs = {\n /**\n * The raw HTTP request body, before any parsing.\n * Pass a string for text bodies or a Uint8Array/Buffer for binary-safe\n * access. Re-serialized JSON will not verify.\n */\n body: string | Uint8Array\n /**\n * The value of the `X-Notion-Signature` request header. Verification\n * fails (returns false) if this is missing or malformed.\n */\n signature: string | null | undefined\n /**\n * The verification token configured for this webhook subscription\n * (returned by Notion when the subscription was created and surfaced\n * during the initial handshake).\n */\n verificationToken: string\n}\n\n/**\n * Verify that a webhook delivery came from Notion and has not been\n * tampered with.\n *\n * Returns `true` if the signature matches HMAC-SHA256 of the body using\n * the verification token. Returns `false` for a missing or malformed\n * signature. Crypto errors may throw.\n */\nexport async function verifyWebhookSignature(\n args: VerifyWebhookSignatureArgs\n): Promise<boolean> {\n const { body, signature, verificationToken } = args\n\n if (typeof signature !== \"string\") {\n return false\n }\n if (!signature.startsWith(SIGNATURE_PREFIX)) {\n return false\n }\n\n const providedHex = signature.slice(SIGNATURE_PREFIX.length).toLowerCase()\n if (providedHex.length !== SHA256_HEX_LENGTH) {\n return false\n }\n if (!/^[0-9a-f]+$/.test(providedHex)) {\n return false\n }\n\n const computedHex = await computeHmacSha256Hex(verificationToken, body)\n return timingSafeEqualHex(providedHex, computedHex)\n}\n\n/**\n * Compute the value Notion would send in `X-Notion-Signature` for a\n * given body and verification token. Use this to test webhook handlers\n * without a live subscription.\n */\nexport async function signWebhookPayload(args: {\n body: string | Uint8Array\n verificationToken: string\n}): Promise<string> {\n const hex = await computeHmacSha256Hex(args.verificationToken, args.body)\n return `${SIGNATURE_PREFIX}${hex}`\n}\n\nasync function computeHmacSha256Hex(\n key: string,\n body: string | Uint8Array\n): Promise<string> {\n const subtle = await getSubtle()\n\n const encoder = new TextEncoder()\n const keyBytes = encoder.encode(key)\n // Copy any Uint8Array input into a fresh ArrayBuffer-backed view so\n // subtle.sign (which forbids SharedArrayBuffer-backed views) is\n // satisfied regardless of where the caller's buffer came from.\n const bodyBytes =\n typeof body === \"string\" ? encoder.encode(body) : Uint8Array.from(body)\n\n const cryptoKey = await subtle.importKey(\n \"raw\",\n keyBytes,\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n )\n const signatureBuffer = await subtle.sign(\"HMAC\", cryptoKey, bodyBytes)\n return bytesToHex(new Uint8Array(signatureBuffer))\n}\n\nlet cachedSubtle: SubtleCrypto | undefined\n\nasync function getSubtle(): Promise<SubtleCrypto> {\n if (cachedSubtle) {\n return cachedSubtle\n }\n\n const fromGlobal = (globalThis as { crypto?: { subtle?: SubtleCrypto } })\n .crypto?.subtle\n if (fromGlobal) {\n cachedSubtle = fromGlobal\n return cachedSubtle\n }\n\n // Load Node's fallback only when needed so browser callers can use the\n // global API without loading a Node module.\n try {\n /* eslint-disable @typescript-eslint/no-var-requires */\n const nodeCrypto = require(\"crypto\") as {\n webcrypto?: { subtle?: SubtleCrypto }\n }\n /* eslint-enable @typescript-eslint/no-var-requires */\n if (nodeCrypto.webcrypto?.subtle) {\n cachedSubtle = nodeCrypto.webcrypto.subtle\n return cachedSubtle\n }\n } catch {\n // node:crypto unavailable (e.g. a browser bundle that stubbed it).\n // Fall through to the error below.\n }\n\n throw new Error(\n \"verifyWebhookSignature requires Web Crypto support \" +\n \"(globalThis.crypto.subtle or node:crypto.webcrypto). Upgrade to \" +\n \"a runtime that provides one of them.\"\n )\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let hex = \"\"\n for (const byte of bytes) {\n hex += byte.toString(16).padStart(2, \"0\")\n }\n return hex\n}\n\n// Constant-time string comparison. The inputs are already known to be\n// the same length (callers enforce SHA256_HEX_LENGTH), so this purely\n// avoids early-exit on the first differing character.\nfunction timingSafeEqualHex(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false\n }\n let diff = 0\n for (let i = 0; i < a.length; i++) {\n diff |= a.charCodeAt(i) ^ b.charCodeAt(i)\n }\n return diff === 0\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@notionhq/client",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.27.0",
|
|
4
4
|
"description": "A simple and easy to use client for the Notion API",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18"
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
"prepublishOnly": "npm run checkLoggedIn && npm run lint && npm run test",
|
|
27
27
|
"build": "tsc",
|
|
28
28
|
"prettier": "prettier --write .",
|
|
29
|
-
"lint": "prettier --check . && eslint . --ext .ts && cspell '**/*'
|
|
29
|
+
"lint": "prettier --check . && eslint . --ext .ts,.js && cspell '**/*'",
|
|
30
30
|
"test": "jest ./test",
|
|
31
|
+
"check:compatibility": "node build/test/checkCompatibility.js",
|
|
31
32
|
"check-links": "git ls-files | grep md$ | xargs -n 1 markdown-link-check",
|
|
32
33
|
"prebuild": "npm run clean",
|
|
33
34
|
"clean": "rm -rf ./build",
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
},
|
|
36
37
|
"lint-staged": {
|
|
37
38
|
"*.{ts,js,json,md}": "prettier --write",
|
|
38
|
-
"*.ts": "eslint --fix"
|
|
39
|
+
"*.{ts,js}": "eslint --fix"
|
|
39
40
|
},
|
|
40
41
|
"author": "",
|
|
41
42
|
"license": "MIT",
|