create = async (
  { recordValue = {}, recordTable = 'block' } = {},
  {
    prepend = false,
    siblingID = undefined,
    parentID = getPageID(),
    parentTable = 'block',
    spaceID = getSpaceID(),
    userID = getUserID(),
  } = {}
) => {
  spaceID = standardiseUUID(await spaceID);
  parentID = standardiseUUID(parentID);
  siblingID = standardiseUUID(siblingID);
  const recordID = standardiseUUID(recordValue?.id ?? fmt.uuidv4()),
    path = [],
    args = {
      type: 'text',
      id: recordID,
      version: 0,
      created_time: new Date().getTime(),
      last_edited_time: new Date().getTime(),
      parent_id: parentID,
      parent_table: parentTable,
      alive: true,
      created_by_table: 'notion_user',
      created_by_id: userID,
      last_edited_by_table: 'notion_user',
      last_edited_by_id: userID,
      space_id: spaceID,
      permissions: [{ type: 'user_permission', role: 'editor', user_id: userID }],
    };
  if (parentTable === 'space') {
    parentID = spaceID;
    args.parent_id = spaceID;
    path.push('pages');
    args.type = 'page';
  } else if (parentTable === 'collection_view') {
    path.push('page_sort');
    args.type = 'page';
  } else {
    path.push('content');
  }
  const json = await fs.getJSON('https://www.notion.so/api/v3/saveTransactions', {
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      requestId: fmt.uuidv4(),
      transactions: [
        {
          id: fmt.uuidv4(),
          spaceId: spaceID,
          operations: [
            {
              pointer: {
                table: parentTable,
                id: parentID,
                spaceId: spaceID,
              },
              path,
              command: prepend ? 'listBefore' : 'listAfter',
              args: {
                ...(siblingID ? { after: siblingID } : {}),
                id: recordID,
              },
            },
            {
              pointer: {
                table: recordTable,
                id: recordID,
                spaceId: spaceID,
              },
              path: [],
              command: 'set',
              args: {
                ...args,
                ...recordValue,
              },
            },
          ],
        },
      ],
    }),
    method: 'POST',
  });
  return json.errorId ? json : recordID;
}
unofficial content api: create and add a new block to a page
(requires user to be signed in or content to be public).
TEST THIS THOROUGHLY. misuse can corrupt a record, leading the notion client
to be unable to parse and render content properly and throw errors.
why not use the official api?
1. cors blocking prevents use on the client
2. the majority of blocks are still 'unsupported'
@param {object} insert - the new record.
@param {object} pointer - where to insert the new block
for examples, use notion.get to fetch an existing block record.
type definitions can be found here: https://github.com/NotionX/react-notion-x/blob/master/packages/notion-types/src/block.ts
may also be 'collection', 'collection_view', 'space', 'notion_user', 'discussion', or 'comment'
@param {object=} insert.recordValue - the new raw data values to set to the record.
@param {object=} insert.recordTable - record type (default: 'block').
may also be 'collection', 'collection_view', 'space', 'notion_user', 'discussion', or 'comment'
@param {string=} pointer.prepend - insert before pointer.siblingID. if false, will be appended after
@param {string=} pointer.siblingID - uuidv4 sibling id. if unset, the record will be
inserted at the end of the page start (or the start if pointer.prepend is true)
@param {string=} pointer.parentID - uuidv4 parent id
@param {string=} pointer.parentTable - parent record type (default: 'block').
@param {string=} pointer.spaceID - uuidv4 space id
@param {string=} pointer.userID - uuidv4 user id
instead of the end
@returns {string|object} error object or uuidv4 of the new record