notion-helper
Version:
A library of functions for working more easily with the Notion API
1,551 lines (1,547 loc) • 149 kB
JavaScript
// src/constants.mjs
var CONSTANTS = {
MAX_TEXT_LENGTH: 2e3,
MAX_BLOCKS: 100,
MAX_BLOCKS_REQEST: 999,
MAX_CHILD_ARRAY_DEPTH: 2,
MAX_PAYLOAD_SIZE: 45e4,
// 450kb
IMAGE_SUPPORT: {
FORMATS: [
"bmp",
"gif",
"heic",
"jpeg",
"jpg",
"png",
"svg",
"tif",
"tiff"
]
},
VIDEO_SUPPORT: {
FORMATS: [
"amv",
"asf",
"avi",
"f4v",
"flv",
"gifv",
"mkv",
"mov",
"mpg",
"mpeg",
"mpv",
"mp4",
"m4v",
"qt",
"wmv"
],
SITES: [
"youtube.com"
]
},
AUDIO_SUPPORT: {
FORMATS: [
"mp3",
"wav",
"ogg",
"mid",
"midi",
"wma",
"aac",
"m4a",
"m4b"
]
},
DOCUMENT_SUPPORT: {
FORMATS: [
"pdf",
"json",
"txt"
]
}
};
var constants_default = CONSTANTS;
// src/utils.mjs
function isSingleEmoji(string) {
const trimmedString = string.trim();
const regex = /^(?:\p{Emoji_Presentation}|\p{Emoji}\uFE0F)(?:\p{Emoji_Modifier})?$/u;
return regex.test(trimmedString);
}
function isValidURL(string) {
try {
const url2 = new URL(string);
return url2.protocol === "http:" || url2.protocol === "https:";
} catch (e) {
return false;
}
}
function isValidUUID(string) {
const regex = /^[0-9a-fA-F]{8}(-?[0-9a-fA-F]{4}){3}-?[0-9a-fA-F]{12}$/;
return regex.test(string);
}
function validateImageURL(url2) {
try {
const supportedFormats = constants_default.IMAGE_SUPPORT.FORMATS.join("|");
const formatRegex = new RegExp(`\\.(${supportedFormats})$`, "i");
return formatRegex.test(url2) && isValidURL(url2);
} catch (e) {
return false;
}
}
function validateVideoURL(url2) {
try {
const supportedFormats = constants_default.VIDEO_SUPPORT.FORMATS.join("|");
const formatRegex = new RegExp(`\\.(${supportedFormats})$`, "i");
const supportedSites = constants_default.VIDEO_SUPPORT.SITES.join("|");
const siteRegex = new RegExp(`(${supportedSites})`, "i");
return (formatRegex.test(url2) || siteRegex.test(url2)) && isValidURL(url2);
} catch (e) {
return false;
}
}
function validateAudioURL(url2) {
try {
const supportedFormats = constants_default.AUDIO_SUPPORT.FORMATS.join("|");
const formatRegex = new RegExp(`\\.(${supportedFormats})$`, "i");
return formatRegex.test(url2) && isValidURL(url2);
} catch (e) {
return false;
}
}
function validatePDFURL(url2) {
try {
const formatRegex = new RegExp(`\\.pdf$`, "i");
return formatRegex.test(url2) && isValidURL(url2);
} catch (e) {
return false;
}
}
function enforceStringLength(string, limit) {
if (typeof string !== "string") {
console.error(
"Invalid input sent to enforceStringLength(). Expected a string, got: ",
string,
typeof string
);
throw new Error("Invalid input: Expected a string.");
}
const charLimit = constants_default.MAX_TEXT_LENGTH;
const softLimit = limit && limit > 0 ? limit : charLimit * 0.8;
if (string.length < charLimit) {
return [string];
} else {
let chunks = [];
let currentIndex = 0;
while (currentIndex < string.length) {
let nextCutIndex = Math.min(
currentIndex + softLimit,
string.length
);
let nextSpaceIndex = string.indexOf(" ", nextCutIndex);
if (nextSpaceIndex === -1 || nextSpaceIndex - currentIndex > softLimit) {
nextSpaceIndex = nextCutIndex;
}
while (nextSpaceIndex > 0 && string.charCodeAt(nextSpaceIndex - 1) >= 55296 && string.charCodeAt(nextSpaceIndex - 1) <= 56319) {
nextSpaceIndex--;
}
chunks.push(string.substring(currentIndex, nextSpaceIndex));
currentIndex = nextSpaceIndex + 1;
}
return chunks;
}
}
function validateDate(dateInput) {
let date2;
if (dateInput === null) {
return null;
}
if (dateInput instanceof Date) {
date2 = dateInput;
} else if (typeof dateInput === "string") {
date2 = new Date(dateInput);
} else {
console.warn(`Invalid input: Expected a Date object or string representing a date. Returning null.`);
return null;
}
if (!isNaN(date2.getTime())) {
const isoString = date2.toISOString();
if (typeof dateInput === "string" && !dateInput.includes(":") && !dateInput.includes("T")) {
return isoString.split("T")[0];
} else {
return isoString;
}
} else {
console.warn(`Invalid date string or Date object provided. Returning null.`);
return null;
}
}
function getDepth(arr, level = 0) {
if (!Array.isArray(arr) || arr.length === 0) {
return level;
}
let maxDepth = level;
for (let block2 of arr) {
if (block2[block2.type].children) {
const depth = getDepth(block2[block2.type].children, level + 1);
maxDepth = Math.max(maxDepth, depth);
}
}
return maxDepth;
}
function getTotalCount(arr) {
if (!arr || arr?.length === 0) return 0;
return arr.reduce(
(acc, child) => {
if (child[child.type].children) {
return acc + 1 + getTotalCount(child[child.type].children);
}
return acc;
},
0
);
}
function getLongestArray(arr, count = 0) {
if (!Array.isArray(arr) || arr.length === 0) {
return count;
}
let maxLength = Math.max(count, arr.length);
for (let block2 of arr) {
if (block2[block2.type].children) {
const count2 = getLongestArray(block2[block2.type].children, maxLength);
maxLength = Math.max(count2, maxLength);
}
}
return maxLength;
}
function getPayloadSize(arr) {
if (!arr || !Array.isArray(arr)) return 0;
const size = arr.reduce((acc, block2) => {
return acc + new TextEncoder().encode(JSON.stringify(block2)).length;
}, 0);
return size;
}
// src/rich-text.mjs
function buildRichTextObj(input, options = {}) {
if (arguments.length > 1 && !options.url && !options.type && !options.annotations) {
options = {
annotations: arguments[1],
url: arguments[2],
type: arguments[3] || "text"
};
}
const { annotations = {}, url: url2, type = "text" } = options;
if (typeof input === "string") {
switch (type) {
case "text":
return [
{
type: "text",
text: {
content: input,
link: url2 ? { url: url2 } : null
},
annotations: {
...annotations
}
}
];
case "equation":
return [
{
type: "equation",
equation: {
expression: input
}
}
];
}
}
if (typeof input === "object") {
if (type === "text" || !type) {
return [
{
type: "text",
text: input
}
];
} else {
switch (type) {
case "equation":
return [
{
type: "equation",
equation: input,
annotations: {
...annotations
}
}
];
case "mention":
return [
{
type: "mention",
mention: input,
annotations: {
...annotations
}
}
];
default:
const error2 = `Unsupported rich text type: ${input.type}`;
console.error(error2);
throw new Error(error2);
}
}
}
const error = `Invalid input send to buildRichTextObj()`;
console.error(error);
throw new Error(error);
}
function enforceRichText(content) {
if (!content) {
return [];
}
if (Array.isArray(content)) {
return content.flatMap(
(item) => typeof item === "string" ? enforceRichText(item) : enforceRichTextObject(item)
);
}
if (typeof content === "string") {
const strings = enforceStringLength(content);
const richTextObjects = strings.flatMap((string) => {
const isURL = isValidURL(string);
const isBold = /^\*{2}[\s\S]*?\*{2}$/.test(string);
const isItalic = /^[\*_]{1}[^\*_]{1}[\s\S]*?[^\*_]{1}[\*_]{1}$/.test(string);
const isBoldItalic = /^\*{3}[\s\S]*?\*{3}$/.test(string);
let plainString = string;
if (isBold || isItalic || isBoldItalic) {
plainString = string.replace(/^(\*|_)+|(\*|_)+$/g, "");
}
return buildRichTextObj(
plainString,
{
annotations: {
bold: isBold || isBoldItalic,
italic: isItalic || isBoldItalic
},
url: isURL ? plainString : null
}
);
});
return richTextObjects;
}
if (typeof content === "number") {
return buildRichTextObj(content.toString());
}
if (typeof content === "object") {
return [enforceRichTextObject(content)];
}
console.warn(`Invalid input for rich text. Returning empty array.`);
return [];
}
function enforceRichTextObject(obj) {
if (typeof obj === "string") {
return buildRichTextObj(obj)[0];
}
if (obj.type && obj.text && typeof obj.text.content === "string") {
return obj;
}
console.warn(`Invalid rich text object. Returning empty rich text object.`);
return buildRichTextObj("")[0];
}
// src/emoji-and-files.mjs
function setIcon(value) {
if (typeof value !== "string") {
return {};
}
const isEmoji = isSingleEmoji(value);
const isImageURL = validateImageURL(value);
const isUUID = isValidUUID(value);
if (isImageURL) {
return createExternal(value);
} else if (isEmoji) {
return createEmoji(value);
} else if (isUUID) {
return createFile(value);
} else {
return void 0;
}
}
function createExternal(url2) {
return {
type: "external",
external: {
url: url2
}
};
}
function createEmoji(emoji) {
return {
type: "emoji",
emoji
};
}
function createFile(id) {
return {
type: "file_upload",
file_upload: {
id
}
};
}
// src/blocks.mjs
var block = {
/**
* Methods for audio blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
audio: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates an audio block.
*
* @function
* @param {string|Object} options - A string representing the audio URL, a file upload ID, or an options object.
* @param {string} options.url - The URL for the audio.
* @param {string} options.id - The ID of the file upload.
* @param {string|string[]|Array<Object>} [options.caption=[]] - The caption as a string, an array of strings, or an array of rich text objects.
* @returns {Object|null} An audio block object compatible with Notion's API, or null if the URL/ID is invalid.
* @example
* // Use with an external URL
* const externalAudio = block.audio.createBlock("https://thomasjfrank.com/wp-content/uploads/2025/05/output3.mp3");
*
* // Use with a file upload ID
* const fileUploadAudio = block.audio.createBlock("123e4567-e89b-12d3-a456-426614174000");
*
* // Use with options object for external audio
* const externalAudio = block.audio.createBlock({
* url: "https://thomasjfrank.com/wp-content/uploads/2025/05/output3.mp3",
* caption: "Check out my mixtape, man."
* });
*
* // Use with options object for file upload
* const fileUploadAudio = block.audio.createBlock({
* id: "123e4567-e89b-12d3-a456-426614174000",
* caption: "Check out my mixtape, man."
* });
*/
createBlock: (options) => {
let url2, id, caption;
if (typeof options === "string") {
url2 = options;
caption = [];
} else {
({ url: url2, id, caption = [] } = options);
}
let urlOrId = url2 || id;
const isValidAudio = validateAudioURL(urlOrId) || isValidUUID(urlOrId);
const isFileUpload = isValidUUID(urlOrId);
const isExternal = isValidURL(urlOrId);
const audioType = isFileUpload ? "file_upload" : isExternal ? "external" : "file";
if (!isValidAudio) {
console.warn(`${urlOrId} is not a valid audio URL or file upload ID.`);
}
return isValidAudio ? {
type: "audio",
audio: {
type: audioType,
[audioType]: {
[audioType === "file_upload" ? "id" : "url"]: urlOrId
},
caption: enforceRichText(caption)
}
} : null;
}
},
/**
* Methods for bookmark blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
bookmark: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates a bookmark block.
*
* @function
* @param {string|Object} options - A string representing the URL, or an options object.
* @param {string} options.url - The URL to be bookmarked.
* @param {string|string[]|Array<Object>} [options.caption=[]] - The caption as a string, an array of strings, or an array of rich text objects.
* @returns {Object} A bookmark block object compatible with Notion's API.
* @example
* // Use with just a URL
* const simpleBookmark = block.bookmark.createBlock("https://www.flylighter.com");
*
* // Use with options object
* const complexBookmark = block.bookmark.createBlock({
* url: "https://www.flylighter.com",
* caption: "Flylighter is a super-rad web clipper for Notion."
* });
*
* // Use with options object and array of strings for caption
* const multiLineBookmark = block.bookmark.createBlock({
* url: "https://www.flylighter.com",
* caption: ["Flylighter is a web clipper for Notion...", "...and Obsidian, too."]
* });
*/
createBlock: (options) => {
let url2, caption;
if (typeof options === "string") {
url2 = options;
caption = [];
} else {
({ url: url2, caption = [] } = options);
}
return {
type: "bookmark",
bookmark: {
url: url2,
caption: enforceRichText(caption)
}
};
}
},
/**
* Methods for breadcrumb blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
breadcrumb: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates a breadcrumb block.
*
* @returns {Object} A breadcrumb block object.
*
* @example
* // Create a breadcrumb block
* const breadcrumbBlock = block.breadcrumb.createBlock();
*/
createBlock: () => {
return {
type: "breadcrumb",
breadcrumb: {}
};
}
},
/**
* Methods for bulleted list item blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
bulleted_list_item: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a bulleted list item block.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the list item content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The item's content as a string, an array of strings, or an array of rich text objects.
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @param {string} [options.color="default"] - Color for the text.
* @returns {Object} A bulleted list item block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleItem = block.bulleted_list_item.createBlock("Simple list item");
*
* // Use with an array of strings
* const multiLineItem = block.bulleted_list_item.createBlock(["Line 1", "Line 2"]);
*
* // Use with options object
* const complexItem = block.bulleted_list_item.createBlock({
* rich_text: "Complex item",
* color: "red",
* children: [
* // Child blocks would go here
* ]
* });
*/
createBlock: (options) => {
let rich_text, children, color;
if (typeof options === "string" || Array.isArray(options)) {
rich_text = options;
children = [];
color = "default";
} else {
({
rich_text = [],
children = [],
color = "default"
} = options);
}
return {
type: "bulleted_list_item",
bulleted_list_item: {
rich_text: enforceRichText(rich_text),
color,
...children.length > 0 && { children }
}
};
}
},
/**
* Methods for callout blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
callout: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a callout block.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the callout content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The content as a string, an array of strings, or an array of rich text objects.
* @param {string} [options.icon=""] - An optional icon value (URL for "external" or emoji character for "emoji").
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @param {string} [options.color="default"] - Color for the callout background.
* @returns {Object} A callout block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleCallout = block.callout.createBlock("I though I told you never to come in here, McFly!");
*
* // Use with options object
* const complexCallout = block.callout.createBlock({
* rich_text: "Now make like a tree and get outta here.",
* icon: "💡",
* color: "blue_background",
* children: [
* // Child blocks would go here
* ]
* });
*/
createBlock: (options) => {
let rich_text, icon2, children, color;
if (typeof options === "string" || Array.isArray(options)) {
rich_text = options;
icon2 = "";
children = [];
color = "default";
} else {
({
rich_text = [],
icon: icon2 = "",
children = [],
color = "default"
} = options);
}
return {
type: "callout",
callout: {
rich_text: enforceRichText(rich_text),
icon: setIcon(icon2),
color,
...children.length > 0 && { children }
}
};
}
},
/**
* Methods for code blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
code: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates a code block.
*
* @function
* @param {string|Object} options - A string representing the code content, or an options object.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The code content as a string, an array of strings, or an array of rich text objects.
* @param {string|string[]|Array<Object>} [options.caption=[]] - The caption as a string, an array of strings, or an array of rich text objects.
* @param {string} [options.language="plain text"] - Programming language of the code block.
* @returns {Object} A code block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleCode = block.code.createBlock("console.log('Give me all the bacon and eggs you have.');");
*
* // Use with options object
* const complexCode = block.code.createBlock({
* rich_text: "const name = 'Monkey D. Luffy'\n console.log(`My name is ${name} and I will be king of the pirates!`)",
* language: "JavaScript",
* caption: "A simple JavaScript greeting function"
* });
*/
createBlock: (options) => {
let rich_text, caption, language;
if (typeof options === "string") {
rich_text = options;
caption = [];
language = "plain text";
} else {
({
rich_text = [],
caption = [],
language = "plain text"
} = options);
}
return {
type: "code",
code: {
rich_text: enforceRichText(rich_text),
caption: enforceRichText(caption),
language
}
};
}
},
/**
* Methods for column list blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
column_list: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a column list block. Column list blocks must have at least two column child blocks, each of which must have at least one child block - otherwise, the Notion API will throw an error.
*
* @see https://developers.notion.com/reference/block#column-list-and-column
*
* @param {(number|Array|undefined)} options - The options for creating the column list block.
* @param {number} [options] - The number of columns to create. Each will contain an empty paragraph block.
* @param {Array} [options] - An array where each element represents a column. Each element can be:
* - A column object (will be added to the final column list's children array directly)
* - A string (will create a column object containing a paragraph block with the string's value)
* - An array (will create a column object containing the elements as children. Each element should be a string or a valid block object. Strings will be converted to paragraph blocks.)
*
* @returns {Object|null} The created column list block object, or null if invalid input is provided.
*
* @example
* // Create a column list with 3 empty columns
* const emptyColumns = block.column_list.createBlock(3);
*
* @example
* // Create a column list with 2 columns, each containing a paragraph
* const twoColumnList = block.column_list.createBlock(["First column", "Second column"]);
*
* @example
* // Create a column list with mixed content
* const mixedColumnList = block.column_list.createBlock([
* "Text in first column",
* ["Paragraph 1 in second column", "Paragraph 2 in second column"],
* {
* type: "column",
* column: {},
* children: [block.heading_2.createBlock("Custom heading in third column")]
* }
* ]);
*
* @example
* // Create an empty column list
* const emptyColumnList = block.column_list.createBlock();
*/
createBlock: (options) => {
if (typeof options === "string" || typeof options === "function") {
return null;
}
if (!options || Array.isArray(options) && options.length === 0 || typeof options === "object" && Object.keys(options).length < 1) {
return {
type: "column_list",
column_list: {}
};
}
if (typeof options === "number") {
let columns = [];
for (let i = 0; i < options; i++) {
const column2 = {
type: "column",
column: {
children: [block.paragraph.createBlock("")]
}
};
columns.push(column2);
}
return {
type: "column_list",
column_list: {
children: columns
}
};
}
if (Array.isArray(options)) {
let columns = [];
for (let option of options) {
if (typeof option === "object" && option.hasOwnProperty("column")) {
columns.push(option);
}
if (Array.isArray(option)) {
let blocks = [];
for (let singleBlock of option) {
if (typeof singleBlock === "string") {
const paragraph2 = block.paragraph.createBlock(singleBlock);
blocks.push(paragraph2);
} else if (typeof singleBlock === "object" && singleBlock !== null && !singleBlock.hasOwnProperty("column")) {
blocks.push(singleBlock);
}
}
const column2 = {
type: "column",
column: {
children: blocks
}
};
columns.push(column2);
}
if (typeof option === "string") {
const column2 = {
type: "column",
column: {
children: [block.paragraph.createBlock(option)]
}
};
columns.push(column2);
}
if (!Array.isArray(option) && typeof option === "object" && !option.hasOwnProperty("column")) {
const column2 = {
type: "column",
column: {
children: [option]
}
};
columns.push(column2);
}
}
return {
type: "column_list",
column_list: {
children: columns
}
};
}
}
},
/**
* Methods for column blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
column: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a column block. A column block must have at least one non-column block in its children array, and the column block itself must be appended as a child block to a column_list block.
*
* @see https://developers.notion.com/reference/block#column-list-and-column
*
* @param {(Array|string|undefined)} options - The options for creating the column block.
* @param {Array} [options] - An array where each element becomes a child block of the column. Each element should be:
* - A block object (will be added directly to the column's children array)
* - A string (will be converted to a paragraph block)
* @param {string} [options] - A string that will be converted into a paragraph block within the column.
*
* @returns {Object} The created column block object.
*
* @example
* // Create an empty column
* const emptyColumn = block.column.createBlock();
*
* @example
* // Create a column with a single paragraph
* const singleParagraphColumn = block.column.createBlock("This is a paragraph in a column");
*
* @example
* // Create a column with multiple blocks
* const multiBlockColumn = block.column.createBlock([
* "First paragraph",
* block.heading_2.createBlock("Heading in column"),
* "Another paragraph"
* ]);
*
* @example
* // Create a column with custom blocks
* const customBlocksColumn = block.column.createBlock([
* block.paragraph.createBlock("Custom paragraph"),
* block.bulleted_list_item.createBlock("Bullet point in column"),
* block.image.createBlock({ url: "https://example.com/image.jpg" })
* ]);
*/
createBlock: (options) => {
if (!options || Array.isArray(options) && options.length === 0 || typeof options === "object" && Object.keys(options).length < 1) {
return {
type: "column",
column: {
children: []
}
};
}
if (typeof options === "string") {
return {
type: "column",
column: {
children: [block.paragraph.createBlock(options)]
}
};
}
if (Array.isArray(options)) {
let blocks = [];
for (let singleBlock of options) {
if (typeof singleBlock === "string") {
const paragraph2 = block.paragraph.createBlock(singleBlock);
blocks.push(paragraph2);
} else if (typeof singleBlock === "object" && singleBlock !== null && !singleBlock.hasOwnProperty("column")) {
blocks.push(singleBlock);
}
}
return {
type: "column",
column: {
children: blocks
}
};
}
}
},
/**
* Methods for divider blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
divider: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates a divider block.
*
* @function
* @returns {Object} A divider block object compatible with Notion's API.
* @example
* const divider = block.divider.createBlock();
*/
createBlock: () => ({
type: "divider",
divider: {}
})
},
/**
* Methods for embed blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
embed: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates an embed block.
*
* @function
* @param {string|Object} options - A string representing the URL to be embedded, or an options object.
* @param {string} options.url - The URL to be embedded.
* @returns {Object} An embed block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleEmbed = block.embed.createBlock("https://www.youtube.com/watch?v=ec5m6t77eYM");
*
* // Use with options object
* const complexEmbed = block.embed.createBlock({
* url: "https://www.youtube.com/watch?v=ec5m6t77eYM"
* });
*/
createBlock: (options) => {
const url2 = typeof options === "string" ? options : options.url;
return {
type: "embed",
embed: {
url: url2
}
};
}
},
/**
* Methods for file blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
file: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates a file block.
*
* @function
* @param {string|Object} options - A string representing the file URL, a file upload ID, or an options object.
* @param {string} options.url - The URL for the file.
* @param {string} options.id - The ID of the file upload.
* @param {string} [options.name] - The name of the file.
* @param {string|string[]|Array<Object>} [options.caption=[]] - The caption as a string, an array of strings, or an array of rich text objects.
* @returns {Object|null} A file block object compatible with Notion's API, or null if the URL/ID is invalid.
* @example
* // Use with a file URL
* const externalFile = block.file.createBlock("https://collegeinfogeek.com/wp-content/uploads/2015/01/10steps-reddit.pdf");
*
* // Use with a file upload ID
* const fileUploadFile = block.file.createBlock("123e4567-e89b-12d3-a456-426614174000");
*
* // Use with options object for external file
* const externalFile = block.file.createBlock({
* url: "https://collegeinfogeek.com/wp-content/uploads/2015/01/10steps-reddit.pdf",
* name: "10 Steps to Earning Awesome Grades (preview)",
* caption: "The Reddit preview of the 10 Steps to Earning Awesome Grades book."
* });
*
* // Use with options object for file upload
* const fileUploadFile = block.file.createBlock({
* id: "123e4567-e89b-12d3-a456-426614174000",
* name: "10 Steps to Earning Awesome Grades (preview)",
* caption: "The Reddit preview of the 10 Steps to Earning Awesome Grades book."
* });
*/
createBlock: (options) => {
let url2, id, name, caption;
if (typeof options === "string") {
url2 = options;
name = "";
caption = [];
} else {
({ url: url2, id, name = "", caption = [] } = options);
}
let urlOrId = url2 || id;
const isValid = isValidURL(urlOrId) || isValidUUID(urlOrId);
const isFileUpload = isValidUUID(urlOrId);
const isExternal = isValidURL(urlOrId);
const fileType = isFileUpload ? "file_upload" : isExternal ? "external" : "file";
if (!isValid) {
console.warn(`${urlOrId} is not a valid file URL or file upload ID.`);
}
return isValid ? {
type: "file",
file: {
type: fileType,
[fileType]: {
[fileType === "file_upload" ? "id" : "url"]: urlOrId
},
caption: enforceRichText(caption),
name: name && name !== "" ? name : void 0
}
} : null;
}
},
/**
* Methods for heading_1 blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
heading_1: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a heading_1 block.
*
* Adding children will coerce headings to toggle headings.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the heading content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The content as a string, an array of strings, or an array of rich text objects.
* @param {string} [options.color="default"] - Color for the heading text.
* @param {boolean} [options.is_toggleable=false] - Whether the heading is toggleable.
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @returns {Object} A heading_1 block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleHeading = block.heading_1.createBlock("Simple Heading");
*
* // Use with options object
* const complexHeading = block.heading_1.createBlock({
* rich_text: "Complex Heading",
* color: "red",
* is_toggleable: true,
* children: [
* // Child blocks would go here
* ]
* });
*/
createBlock: (options) => {
let rich_text, color, is_toggleable, children;
if (typeof options === "string" || Array.isArray(options)) {
rich_text = options;
color = "default";
is_toggleable = false;
children = [];
} else {
({
rich_text = [],
color = "default",
is_toggleable = false,
children = []
} = options);
}
return {
type: "heading_1",
heading_1: {
rich_text: enforceRichText(rich_text),
color,
is_toggleable,
...children.length > 0 && { children }
}
};
}
},
/**
* Methods for heading_2 blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
heading_2: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a heading_2 block.
*
* Adding children will coerce headings to toggle headings.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the heading content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The content as a string, an array of strings, or an array of rich text objects.
* @param {string} [options.color="default"] - Color for the heading text.
* @param {boolean} [options.is_toggleable=false] - Whether the heading is toggleable.
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @returns {Object} A heading_2 block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleHeading = block.heading_2.createBlock("Simple Heading");
*
* // Use with options object
* const complexHeading = block.heading_2.createBlock({
* rich_text: "Complex Heading",
* color: "red",
* is_toggleable: true,
* children: [
* // Child blocks would go here
* ]
* });
*/
createBlock: (options) => {
let rich_text, color, is_toggleable, children;
if (typeof options === "string" || Array.isArray(options)) {
rich_text = options;
color = "default";
is_toggleable = false;
children = [];
} else {
({
rich_text = [],
color = "default",
is_toggleable = false,
children = []
} = options);
}
return {
type: "heading_2",
heading_2: {
rich_text: enforceRichText(rich_text),
color,
is_toggleable,
...children.length > 0 && { children }
}
};
}
},
/**
* Methods for heading_3 blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
heading_3: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a heading_3 block.
*
* Adding children will coerce headings to toggle headings.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the heading content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The content as a string, an array of strings, or an array of rich text objects.
* @param {string} [options.color="default"] - Color for the heading text.
* @param {boolean} [options.is_toggleable=false] - Whether the heading is toggleable.
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @returns {Object} A heading_3 block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleHeading = block.heading_3.createBlock("Simple Heading");
*
* // Use with options object
* const complexHeading = block.heading_3.createBlock({
* rich_text: "Complex Heading",
* color: "red",
* is_toggleable: true,
* children: [
* // Child blocks would go here
* ]
* });
*/
createBlock: (options) => {
let rich_text, color, is_toggleable, children;
if (typeof options === "string" || Array.isArray(options)) {
rich_text = options;
color = "default";
is_toggleable = false;
children = [];
} else {
({
rich_text = [],
color = "default",
is_toggleable = false,
children = []
} = options);
}
return {
type: "heading_3",
heading_3: {
rich_text: enforceRichText(rich_text),
color,
is_toggleable,
...children.length > 0 && { children }
}
};
}
},
/**
* Methods for image blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
image: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates an image block.
*
* @function
* @param {string|Object} options - A string representing the image URL, a file upload ID, or an options object.
* @param {string} options.url - The URL for the image.
* @param {string} options.id - The ID of the file upload.
* @param {string|string[]|Array<Object>} [options.caption=[]] - The caption as a string, an array of strings, or an array of rich text objects.
* @returns {Object|null} An image block object compatible with Notion's API, or null if the URL/ID is invalid.
* @example
* // Use with a string
* const simpleImage = block.image.createBlock("https://i.imgur.com/5vSShIw.jpeg");
*
* // Use with a file upload ID
* const fileUploadImage = block.image.createBlock("123e4567-e89b-12d3-a456-426614174000");
*
* // Use with options object for external image
* const complexImage = block.image.createBlock({
* url: "https://i.imgur.com/5vSShIw.jpeg",
* caption: "A beautiful landscape"
* });
*
* // Use with options object for file upload
* const fileUploadImage = block.image.createBlock({
* id: "123e4567-e89b-12d3-a456-426614174000",
* caption: "A beautiful landscape"
* });
*/
createBlock: (options) => {
let url2, id, caption;
if (typeof options === "string") {
url2 = options;
caption = [];
} else {
({ url: url2, id, caption = [] } = options);
}
let urlOrId = url2 || id;
const isValidImage = validateImageURL(urlOrId) || isValidUUID(urlOrId);
const isFileUpload = isValidUUID(urlOrId);
const isExternal = isValidURL(urlOrId);
const imageType = isFileUpload ? "file_upload" : isExternal ? "external" : "file";
if (!isValidImage) {
console.warn(`${urlOrId} is not a valid image URL or file upload ID.`);
}
return isValidImage ? {
type: "image",
image: {
type: imageType,
[imageType]: {
[imageType === "file_upload" ? "id" : "url"]: urlOrId
},
caption: enforceRichText(caption)
}
} : null;
}
},
/**
* Methods for numbered list item blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
numbered_list_item: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a numbered list item block.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the list item content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The content as a string, an array of strings, or an array of rich text objects.
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @param {string} [options.color="default"] - Color for the text.
* @returns {Object} A numbered list item block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleItem = block.numbered_list_item.createBlock("Simple list item");
*
* // Use with an array of strings
* const multiLineItem = block.numbered_list_item.createBlock(["Line 1", "Line 2"]);
*
* // Use with options object
* const complexItem = block.numbered_list_item.createBlock({
* rich_text: "Complex item",
* color: "red",
* children: [
* // Child blocks would go here
* ]
* });
*/
createBlock: (options) => {
let rich_text, children, color;
if (typeof options === "string" || Array.isArray(options)) {
rich_text = options;
children = [];
color = "default";
} else {
({
rich_text = [],
children = [],
color = "default"
} = options);
}
return {
type: "numbered_list_item",
numbered_list_item: {
rich_text: enforceRichText(rich_text),
color,
...children.length > 0 && { children }
}
};
}
},
/**
* Methods for paragraph blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
paragraph: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a paragraph block.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the paragraph content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The content as a string, an array of strings, or an array of rich text objects.
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @param {string} [options.color="default"] - Color for the text.
* @returns {Object} A paragraph block object compatible with Notion's API.
* @example
* // Direct use with a string
* const paragraphBlock = block.paragraph.createBlock("Hello, World!");
*
* // Direct use with an array of strings
* const multiLineParagraph = block.paragraph.createBlock(["I'm a line", "I'm also a line!"]);
*
* // Usage with options object
* const complexParagraph = block.paragraph.createBlock({
* rich_text: "Complex paragraph",
* color: "red",
* children: [
* // Child blocks would go here
* ]
* });
*/
createBlock: (options) => {
let rich_text, children, color;
if (typeof options === "string" || Array.isArray(options)) {
rich_text = options;
children = [];
color = "default";
} else {
({
rich_text = [],
children = [],
color = "default"
} = options);
}
return {
type: "paragraph",
paragraph: {
rich_text: rich_text === "" ? buildRichTextObj("") : enforceRichText(rich_text),
color,
...children.length > 0 && { children }
}
};
}
},
/**
* Methods for PDF blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
pdf: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: false,
/**
* Creates a PDF block.
*
* @function
* @param {string|Object} options - A string representing the PDF URL, a file upload ID, or an options object.
* @param {string} options.url - The URL for the PDF.
* @param {string} options.id - The ID of the file upload.
* @param {string|string[]|Array<Object>} [options.caption=[]] - The caption as a string, an array of strings, or an array of rich text objects.
* @returns {Object|null} A PDF block object compatible with Notion's API, or null if the URL/ID is invalid.
* @example
* // Use with a PDF URL
* const externalPDF = block.pdf.createBlock("https://collegeinfogeek.com/wp-content/uploads/2015/01/10steps-reddit.pdf");
*
* // Use with a file upload ID
* const fileUploadPDF = block.pdf.createBlock("123e4567-e89b-12d3-a456-426614174000");
*
* // Use with options object for external PDF
* const externalPDF = block.pdf.createBlock({
* url: "https://collegeinfogeek.com/wp-content/uploads/2015/01/10steps-reddit.pdf",
* caption: "The Reddit preview of the 10 Steps to Earning Awesome Grades book."
* });
*
* // Use with options object for file upload
* const fileUploadPDF = block.pdf.createBlock({
* id: "123e4567-e89b-12d3-a456-426614174000",
* caption: "The Reddit preview of the 10 Steps to Earning Awesome Grades book."
* });
*/
createBlock: (options) => {
let url2, id, caption;
if (typeof options === "string") {
url2 = options;
caption = [];
} else {
({ url: url2, id, caption = [] } = options);
}
let urlOrId = url2 || id;
const isValidPDF = validatePDFURL(urlOrId) || isValidUUID(urlOrId);
const isFileUpload = isValidUUID(urlOrId);
const isExternal = isValidURL(urlOrId);
const pdfType = isFileUpload ? "file_upload" : isExternal ? "external" : "file";
if (!isValidPDF) {
console.warn(`${urlOrId} is not a valid PDF URL or file upload ID.`);
}
return isValidPDF ? {
type: "pdf",
pdf: {
type: pdfType,
[pdfType]: {
[pdfType === "file_upload" ? "id" : "url"]: urlOrId
},
caption: enforceRichText(caption)
}
} : null;
}
},
/**
* Methods for quote blocks.
*
* @namespace
* @property {boolean} supports_children - Indicates if the block supports child blocks.
*/
quote: {
/**
* Indicates if the block supports child blocks.
* @type {boolean}
*/
supports_children: true,
/**
* Creates a quote block.
*
* @function
* @param {string|string[]|Object} options - A string, an array of strings, or an options object representing the quote content.
* @param {string|string[]|Array<Object>} [options.rich_text=[]] - The content as a string, an array of strings, or an array of rich text objects.
* @param {Array<Object>} [options.children=[]] - An array of child block objects.
* @param {string} [options.color="default"] - Color for the text.
* @returns {Object} A quote block object compatible with Notion's API.
* @example
* // Use with a string
* const simpleQuote = block.quote.createBlock("Simple quote");
*
* // Use with an array of strings
* const mul