From 6b43833387341975fc0cef65288e4b9f293e6c21 Mon Sep 17 00:00:00 2001 From: Federico Grandi Date: Tue, 17 May 2022 17:13:20 +0200 Subject: [PATCH 1/4] fix: add children on manual sync too --- src/action.ts | 4 +++- src/sync.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/action.ts b/src/action.ts index 9446bdc..ed6ad8d 100644 --- a/src/action.ts +++ b/src/action.ts @@ -109,7 +109,9 @@ export function parseBodyRichText(body: string) { } } -function getBodyChildrenBlocks(body: string): Exclude { +export function getBodyChildrenBlocks( + body: string +): Exclude { // We're currently using only one paragraph block, but this could be extended to multiple kinds of blocks. return [ { diff --git a/src/sync.ts b/src/sync.ts index d0c4799..3fd44ed 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -3,7 +3,7 @@ import {Issue} from '@octokit/webhooks-types/schema'; import * as core from '@actions/core'; import {Octokit} from 'octokit'; import {CustomValueMap, properties} from './properties'; -import {getProjectData} from './action'; +import {getBodyChildrenBlocks, getProjectData} from './action'; import {QueryDatabaseResponse} from '@notionhq/client/build/src/api-endpoints'; import {CustomTypes} from './api-types'; import {parseBodyRichText} from './action'; @@ -123,6 +123,7 @@ async function createPages( notion.pages.create({ parent: {database_id: databaseId}, properties: await getPropertiesFromIssue(issue, octokit), + children: getBodyChildrenBlocks(issue.body || ''), }) ) ); From 3576d89baee6138c438f96839bd43bff8bff36be Mon Sep 17 00:00:00 2001 From: Federico Grandi Date: Tue, 17 May 2022 17:32:13 +0200 Subject: [PATCH 2/4] chore: bump deps --- package-lock.json | 32 ++++++++++++++++---------------- package.json | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index a9b4dfe..7b05963 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,9 @@ "dependencies": { "@actions/core": "^1.4.0", "@actions/github": "^5.0.0", - "@notionhq/client": "^0.4.13", + "@notionhq/client": "^1.0.4", "@octokit/webhooks-definitions": "^3.67.3", - "@tryfabric/martian": "^1.1.1", + "@tryfabric/martian": "^1.2.0", "octokit": "^1.1.0" }, "devDependencies": { @@ -1009,9 +1009,9 @@ } }, "node_modules/@notionhq/client": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/@notionhq/client/-/client-0.4.13.tgz", - "integrity": "sha512-tHC95h4JZYteHmIL49xdta0Yb9q0peXySqo9cqTQEVzpPwUdcPNgWQljMqfrSVKqlpGNX+DhXztY0LR6f3Iw6A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@notionhq/client/-/client-1.0.4.tgz", + "integrity": "sha512-m7zZ5l3RUktayf1lRBV1XMb8HSKsmWTv/LZPqP7UGC1NMzOlc+bbTOPNQ4CP/c1P4cP61VWLb/zBq7a3c0nMaw==", "dependencies": { "@types/node-fetch": "^2.5.10", "node-fetch": "^2.6.1" @@ -1353,11 +1353,11 @@ } }, "node_modules/@tryfabric/martian": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@tryfabric/martian/-/martian-1.1.1.tgz", - "integrity": "sha512-7EC6np65doCeaJHubyoJzYa8dykKw069QQwV1AdRce0Epw4+eOfXQcYmmXnNHpvJYCctst/Nkjo0lQA6H1UPqQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@tryfabric/martian/-/martian-1.2.0.tgz", + "integrity": "sha512-q3grnGgwfujNZelpK6uMswObYKSy1dY+yKypgjl7EPxpSvSHlJb1f0gIfghGUWf1gVxZfHfSZDe+k9KCzaLbwQ==", "dependencies": { - "@notionhq/client": "^0.4.5", + "@notionhq/client": "^1.0.4", "remark-gfm": "^1.0.0", "remark-parse": "^9.0.0", "unified": "^9.2.1" @@ -9610,9 +9610,9 @@ } }, "@notionhq/client": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/@notionhq/client/-/client-0.4.13.tgz", - "integrity": "sha512-tHC95h4JZYteHmIL49xdta0Yb9q0peXySqo9cqTQEVzpPwUdcPNgWQljMqfrSVKqlpGNX+DhXztY0LR6f3Iw6A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@notionhq/client/-/client-1.0.4.tgz", + "integrity": "sha512-m7zZ5l3RUktayf1lRBV1XMb8HSKsmWTv/LZPqP7UGC1NMzOlc+bbTOPNQ4CP/c1P4cP61VWLb/zBq7a3c0nMaw==", "requires": { "@types/node-fetch": "^2.5.10", "node-fetch": "^2.6.1" @@ -9927,11 +9927,11 @@ "dev": true }, "@tryfabric/martian": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@tryfabric/martian/-/martian-1.1.1.tgz", - "integrity": "sha512-7EC6np65doCeaJHubyoJzYa8dykKw069QQwV1AdRce0Epw4+eOfXQcYmmXnNHpvJYCctst/Nkjo0lQA6H1UPqQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@tryfabric/martian/-/martian-1.2.0.tgz", + "integrity": "sha512-q3grnGgwfujNZelpK6uMswObYKSy1dY+yKypgjl7EPxpSvSHlJb1f0gIfghGUWf1gVxZfHfSZDe+k9KCzaLbwQ==", "requires": { - "@notionhq/client": "^0.4.5", + "@notionhq/client": "^1.0.4", "remark-gfm": "^1.0.0", "remark-parse": "^9.0.0", "unified": "^9.2.1" diff --git a/package.json b/package.json index 8351734..4d450fd 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,9 @@ "dependencies": { "@actions/core": "^1.4.0", "@actions/github": "^5.0.0", - "@notionhq/client": "^0.4.13", + "@notionhq/client": "^1.0.4", "@octokit/webhooks-definitions": "^3.67.3", - "@tryfabric/martian": "^1.1.1", + "@tryfabric/martian": "^1.2.0", "octokit": "^1.1.0" }, "devDependencies": { From 6989d99e9b68089cdf6e1f1d4a01d3f6877f7b07 Mon Sep 17 00:00:00 2001 From: Federico Grandi Date: Tue, 17 May 2022 17:35:36 +0200 Subject: [PATCH 3/4] feat: fill item body with parsed blocks instead of rich text --- src/action.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/action.ts b/src/action.ts index ed6ad8d..c5024e2 100644 --- a/src/action.ts +++ b/src/action.ts @@ -5,7 +5,7 @@ import type {WebhookPayload} from '@actions/github/lib/interfaces'; import {CustomValueMap, properties} from './properties'; import {createIssueMapping, syncNotionDBWithGitHub} from './sync'; import {Octokit} from 'octokit'; -import {markdownToRichText} from '@tryfabric/martian'; +import {markdownToRichText, markdownToBlocks} from '@tryfabric/martian'; import {CustomTypes, RichTextItemResponse} from './api-types'; import {CreatePageParameters} from '@notionhq/client/build/src/api-endpoints'; @@ -112,15 +112,7 @@ export function parseBodyRichText(body: string) { export function getBodyChildrenBlocks( body: string ): Exclude { - // We're currently using only one paragraph block, but this could be extended to multiple kinds of blocks. - return [ - { - type: 'paragraph', - paragraph: { - text: parseBodyRichText(body), - }, - }, - ]; + return markdownToBlocks(body); } interface IssueOpenedOptions { From 711c387facd873362a29521979361e6bc390eec1 Mon Sep 17 00:00:00 2001 From: Federico Grandi Date: Tue, 17 May 2022 17:35:59 +0200 Subject: [PATCH 4/4] chore: commit build --- dist/index.js | 1441 ++++++++++++++++++++++++++++--------------------- 1 file changed, 811 insertions(+), 630 deletions(-) diff --git a/dist/index.js b/dist/index.js index 388753b..d957161 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5,7 +5,15 @@ /***/ ((module) => { "use strict"; -module.exports = JSON.parse('{"name":"@notionhq/client","version":"0.4.13","description":"A simple and easy to use client for the Notion API","engines":{"node":">=12"},"homepage":"https://developers.notion.com/docs/getting-started","bugs":{"url":"https://github.com/makenotion/notion-sdk-js/issues"},"repository":{"type":"git","url":"https://github.com/makenotion/notion-sdk-js/"},"keywords":["notion","notionapi","rest","notion-api"],"main":"./build/src","scripts":{"prepare":"npm run build","prepublishOnly":"npm run checkLoggedIn && npm run lint && npm run test","build":"tsc","prettier":"prettier --write .","lint":"prettier --check . && eslint . --ext .ts && cspell \'**/*\' ","test":"ava","check-links":"git ls-files | grep md$ | xargs -n 1 markdown-link-check","prebuild":"npm run clean","clean":"rm -rf ./build","checkLoggedIn":"./scripts/verifyLoggedIn.sh"},"author":"","license":"MIT","files":["build/package.json","build/src/**"],"dependencies":{"@types/node-fetch":"^2.5.10","node-fetch":"^2.6.1"},"devDependencies":{"@ava/typescript":"^2.0.0","@typescript-eslint/eslint-plugin":"^4.22.0","@typescript-eslint/parser":"^4.22.0","ava":"^3.15.0","cspell":"^5.4.1","eslint":"^7.24.0","markdown-link-check":"^3.8.7","prettier":"^2.3.0","typescript":"^4.2.4"}}'); +module.exports = JSON.parse('{"name":"@notionhq/client","version":"1.0.4","description":"A simple and easy to use client for the Notion API","engines":{"node":">=12"},"homepage":"https://developers.notion.com/docs/getting-started","bugs":{"url":"https://github.com/makenotion/notion-sdk-js/issues"},"repository":{"type":"git","url":"https://github.com/makenotion/notion-sdk-js/"},"keywords":["notion","notionapi","rest","notion-api"],"main":"./build/src","types":"./build/src/index.d.ts","scripts":{"prepare":"npm run build","prepublishOnly":"npm run checkLoggedIn && npm run lint && npm run test","build":"tsc","prettier":"prettier --write .","lint":"prettier --check . && eslint . --ext .ts && cspell \'**/*\' ","test":"ava","check-links":"git ls-files | grep md$ | xargs -n 1 markdown-link-check","prebuild":"npm run clean","clean":"rm -rf ./build","checkLoggedIn":"./scripts/verifyLoggedIn.sh"},"author":"","license":"MIT","files":["build/package.json","build/src/**"],"dependencies":{"@types/node-fetch":"^2.5.10","node-fetch":"^2.6.1"},"devDependencies":{"@ava/typescript":"^2.0.0","@typescript-eslint/eslint-plugin":"^4.22.0","@typescript-eslint/parser":"^4.22.0","ava":"^3.15.0","cspell":"^5.4.1","eslint":"^7.24.0","markdown-link-check":"^3.8.7","prettier":"^2.3.0","typescript":"^4.2.4"}}'); + +/***/ }), + +/***/ 1796: +/***/ ((module) => { + +"use strict"; +module.exports = JSON.parse('{"abap":"abap","sh":"shell","shell-script":"shell","bash":"shell","zsh":"shell","text":"vb.net","c_cpp":"c++","clojure":"clojure","coffee":"coffeescript","coffee-script":"coffeescript","cpp":"c++","csharp":"c#","cake":"c#","cakescript":"c#","css":"css","dart":"dart","diff":"diff","udiff":"diff","dockerfile":"docker","elixir":"elixir","elm":"elm","erlang":"erlang","fsharp":"f#","cucumber":"gherkin","glsl":"glsl","golang":"go","groovy":"groovy","haskell":"haskell","html":"html","xhtml":"html","java":"java/c/c++/c#","javascript":"javascript","js":"javascript","node":"javascript","json":"json","julia":"julia","tex":"latex","latex":"latex","less":"less","lisp":"webassembly","livescript":"livescript","live-script":"livescript","ls":"livescript","lua":"lua","makefile":"makefile","bsdmake":"makefile","make":"makefile","mf":"makefile","markdown":"markdown","pandoc":"markdown","matlab":"matlab","octave":"matlab","nix":"nix","nixos":"nix","objectivec":"objective-c","obj-c":"objective-c","objc":"objective-c","ocaml":"ocaml","pascal":"pascal","delphi":"pascal","objectpascal":"pascal","perl":"perl","cperl":"perl","php":"php","inc":"php","powershell":"powershell","posh":"powershell","pwsh":"powershell","prolog":"prolog","protobuf":"protobuf","Protocol Buffers":"protobuf","python":"python","python3":"python","rusthon":"python","r":"r","R":"r","Rscript":"r","splus":"r","rust":"rust","ruby":"ruby","jruby":"ruby","macruby":"ruby","rake":"ruby","rb":"ruby","rbx":"ruby","rs":"rust","sass":"sass","scala":"scala","scheme":"scheme","scss":"scss","sql":"sql","typescript":"typescript","ts":"typescript","visual basic":"vb.net","vbnet":"vb.net","vb .net":"vb.net","vb.net":"vb.net","verilog":"verilog","vhdl":"vhdl","wast":"webassembly","wasm":"webassembly","xml":"xml","rss":"xml","xsd":"xml","wsdl":"xml","yaml":"yaml","yml":"yaml"}'); /***/ }), @@ -1684,7 +1692,7 @@ class Client { } exports.default = Client; _Client_auth = new WeakMap(), _Client_logLevel = new WeakMap(), _Client_logger = new WeakMap(), _Client_prefixUrl = new WeakMap(), _Client_timeoutMs = new WeakMap(), _Client_notionVersion = new WeakMap(), _Client_fetch = new WeakMap(), _Client_agent = new WeakMap(), _Client_userAgent = new WeakMap(); -Client.defaultNotionVersion = "2021-08-16"; +Client.defaultNotionVersion = "2022-02-22"; //# sourceMappingURL=Client.js.map /***/ }), @@ -1823,7 +1831,7 @@ exports.updateDatabase = { method: "patch", pathParams: ["database_id"], queryParams: [], - bodyParams: ["title", "icon", "cover", "properties"], + bodyParams: ["title", "icon", "cover", "properties", "archived"], path: (p) => `databases/${p.database_id}`, }; exports.queryDatabase = { @@ -8400,11 +8408,12 @@ const remark_gfm_1 = __importDefault(__nccwpck_require__(5772)); * * Supports GitHub-flavoured Markdown. * - * @param body any Markdown or GFM content + * @param body Any Markdown or GFM content + * @param options Any additional option */ -function markdownToBlocks(body, allowUnsupportedObjectType = false) { +function markdownToBlocks(body, options) { const root = (0, unified_1.default)().use(remark_parse_1.default).use(remark_gfm_1.default).parse(body); - return (0, internal_1.parseBlocks)(root, allowUnsupportedObjectType); + return (0, internal_1.parseBlocks)(root, options); } exports.markdownToBlocks = markdownToBlocks; /** @@ -8412,10 +8421,11 @@ exports.markdownToBlocks = markdownToBlocks; * Only supports plain text, italics, bold, strikethrough, inline code, and hyperlinks. * * @param text any inline Markdown or GFM content + * @param options Any additional option */ -function markdownToRichText(text) { +function markdownToRichText(text, options) { const root = (0, unified_1.default)().use(remark_parse_1.default).use(remark_gfm_1.default).parse(text); - return (0, internal_1.parseRichText)(root); + return (0, internal_1.parseRichText)(root, options); } exports.markdownToRichText = markdownToRichText; //# sourceMappingURL=index.js.map @@ -8428,24 +8438,24 @@ exports.markdownToRichText = markdownToRichText; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.tableCell = exports.tableRow = exports.table = exports.toDo = exports.numberedListItem = exports.bulletedListItem = exports.headingThree = exports.headingTwo = exports.headingOne = exports.table_of_contents = exports.image = exports.blockquote = exports.code = exports.paragraph = void 0; +exports.tableRow = exports.table = exports.toDo = exports.numberedListItem = exports.bulletedListItem = exports.headingThree = exports.headingTwo = exports.headingOne = exports.table_of_contents = exports.image = exports.blockquote = exports.code = exports.paragraph = void 0; function paragraph(text) { return { object: 'block', type: 'paragraph', paragraph: { - text: text, + rich_text: text, }, }; } exports.paragraph = paragraph; -function code(text) { +function code(text, lang = 'plain text') { return { object: 'block', type: 'code', code: { - text: text, - language: 'javascript', + rich_text: text, + language: lang, }, }; } @@ -8455,7 +8465,7 @@ function blockquote(text) { object: 'block', type: 'quote', quote: { - text: text, + rich_text: text, }, }; } @@ -8486,7 +8496,7 @@ function headingOne(text) { object: 'block', type: 'heading_1', heading_1: { - text: text, + rich_text: text, }, }; } @@ -8496,7 +8506,7 @@ function headingTwo(text) { object: 'block', type: 'heading_2', heading_2: { - text: text, + rich_text: text, }, }; } @@ -8506,7 +8516,7 @@ function headingThree(text) { object: 'block', type: 'heading_3', heading_3: { - text: text, + rich_text: text, }, }; } @@ -8516,7 +8526,7 @@ function bulletedListItem(text, children = []) { object: 'block', type: 'bulleted_list_item', bulleted_list_item: { - text: text, + rich_text: text, children: children.length ? children : undefined, }, }; @@ -8527,7 +8537,7 @@ function numberedListItem(text, children = []) { object: 'block', type: 'numbered_list_item', numbered_list_item: { - text: text, + rich_text: text, children: children.length ? children : undefined, }, }; @@ -8538,43 +8548,35 @@ function toDo(checked, text, children = []) { object: 'block', type: 'to_do', to_do: { - text: text, + rich_text: text, checked: checked, children: children.length ? children : undefined, }, }; } exports.toDo = toDo; -function table(children = []) { +function table(children, tableWidth) { return { - object: 'unsupported', + object: 'block', type: 'table', table: { - children: children.length ? children : undefined, + table_width: tableWidth, + has_row_header: true, + children: (children === null || children === void 0 ? void 0 : children.length) ? children : [], }, }; } exports.table = table; -function tableRow(children = []) { +function tableRow(cells = []) { return { - object: 'unsupported', + object: 'block', type: 'table_row', table_row: { - children: children.length ? children : undefined, + cells: cells.length ? cells : [], }, }; } exports.tableRow = tableRow; -function tableCell(children = []) { - return { - object: 'unsupported', - type: 'table_cell', - table_cell: { - children: children.length ? children : undefined, - }, - }; -} -exports.tableCell = tableCell; //# sourceMappingURL=blocks.js.map /***/ }), @@ -8585,7 +8587,20 @@ exports.tableCell = tableCell; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.richText = void 0; +exports.isSupportedCodeLang = exports.SUPPORTED_CODE_BLOCK_LANGUAGES = exports.richText = exports.LIMITS = void 0; +/** + * The limits that the Notion API uses for property values. + * @see https://developers.notion.com/reference/request-limits#limits-for-property-values + */ +exports.LIMITS = { + PAYLOAD_BLOCKS: 1000, + RICH_TEXT_ARRAYS: 100, + RICH_TEXT: { + TEXT_CONTENT: 2000, + LINK_URL: 1000, + EQUATION_EXPRESSION: 1000, + }, +}; function richText(content, options = {}) { var _a; const annotations = (_a = options.annotations) !== null && _a !== void 0 ? _a : {}; @@ -8612,6 +8627,84 @@ function richText(content, options = {}) { }; } exports.richText = richText; +exports.SUPPORTED_CODE_BLOCK_LANGUAGES = [ + 'abap', + 'arduino', + 'bash', + 'basic', + 'c', + 'clojure', + 'coffeescript', + 'c++', + 'c#', + 'css', + 'dart', + 'diff', + 'docker', + 'elixir', + 'elm', + 'erlang', + 'flow', + 'fortran', + 'f#', + 'gherkin', + 'glsl', + 'go', + 'graphql', + 'groovy', + 'haskell', + 'html', + 'java', + 'javascript', + 'json', + 'julia', + 'kotlin', + 'latex', + 'less', + 'lisp', + 'livescript', + 'lua', + 'makefile', + 'markdown', + 'markup', + 'matlab', + 'mermaid', + 'nix', + 'objective-c', + 'ocaml', + 'pascal', + 'perl', + 'php', + 'plain text', + 'powershell', + 'prolog', + 'protobuf', + 'python', + 'r', + 'reason', + 'ruby', + 'rust', + 'sass', + 'scala', + 'scheme', + 'scss', + 'shell', + 'sql', + 'swift', + 'typescript', + 'vb.net', + 'verilog', + 'vhdl', + 'visual basic', + 'webassembly', + 'xml', + 'yaml', + 'java/c/c++/c#', +]; +function isSupportedCodeLang(lang) { + return exports.SUPPORTED_CODE_BLOCK_LANGUAGES.includes(lang); +} +exports.isSupportedCodeLang = isSupportedCodeLang; //# sourceMappingURL=common.js.map /***/ }), @@ -8631,9 +8724,20 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.parseCodeLanguage = void 0; +const languageMap_json_1 = __importDefault(__nccwpck_require__(1796)); __exportStar(__nccwpck_require__(951), exports); __exportStar(__nccwpck_require__(3679), exports); +function parseCodeLanguage(lang) { + return lang + ? languageMap_json_1.default[lang.toLowerCase()] + : undefined; +} +exports.parseCodeLanguage = parseCodeLanguage; //# sourceMappingURL=index.js.map /***/ }), @@ -8662,14 +8766,26 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.parseRichText = exports.parseBlocks = void 0; const notion = __importStar(__nccwpck_require__(7849)); +const path_1 = __importDefault(__nccwpck_require__(5622)); const url_1 = __nccwpck_require__(8835); +const notion_1 = __nccwpck_require__(7849); function ensureLength(text, copy) { const chunks = text.match(/[^]{1,2000}/g) || []; return chunks.flatMap((item) => notion.richText(item, copy)); } +function ensureCodeBlockLanguage(lang) { + if (lang) { + lang = lang.toLowerCase(); + return (0, notion_1.isSupportedCodeLang)(lang) ? lang : notion.parseCodeLanguage(lang); + } + return undefined; +} function parseInline(element, options) { var _a; const copy = { @@ -8700,21 +8816,44 @@ function parseInline(element, options) { return []; } } -function parseParagraph(element) { - // If a paragraph containts an image element as its first element - // Lets assume it is an image, and parse it as only that (discard remaining content) - const isImage = element.children[0].type === 'image'; - if (isImage) { - const image = element.children[0]; - try { - new url_1.URL(image.url); - return notion.image(image.url); +function parseImage(image, options) { + var _a; + // https://developers.notion.com/reference/block#image-blocks + const allowedTypes = [ + '.png', + '.jpg', + '.jpeg', + '.gif', + '.tif', + '.tiff', + '.bmp', + '.svg', + '.heic', + ]; + function dealWithError() { + return notion.paragraph([notion.richText(image.url)]); + } + try { + if ((_a = options.strictImageUrls) !== null && _a !== void 0 ? _a : true) { + const parsedUrl = new url_1.URL(image.url); + const fileType = path_1.default.extname(parsedUrl.pathname); + if (allowedTypes.includes(fileType)) { + return notion.image(image.url); + } + else { + return dealWithError(); + } } - catch (error) { - console.log(`${error.input} is not a valid url, I will process this as text for you to fix later`); + else { + return notion.image(image.url); } } - // Paragraphs can also be legacy 'TOC' from some markdown + catch (error) { + return dealWithError(); + } +} +function parseParagraph(element, options) { + // Paragraphs can also be legacy 'TOC' from some markdown, so we check first const mightBeToc = element.children.length > 2 && element.children[0].type === 'text' && element.children[0].value === '[[' && @@ -8723,29 +8862,48 @@ function parseParagraph(element) { const emphasisItem = element.children[1]; const emphasisTextItem = emphasisItem.children[0]; if (emphasisTextItem.value === 'TOC') { - return notion.table_of_contents(); + return [notion.table_of_contents()]; } } - const text = element.children.flatMap(child => parseInline(child)); - return notion.paragraph(text); + // Notion doesn't deal with inline images, so we need to parse them all out + // of the paragraph into individual blocks + const images = []; + const paragraphs = []; + element.children.forEach(item => { + if (item.type === 'image') { + images.push(parseImage(item, options)); + } + else { + const richText = parseInline(item); + if (richText.length) { + paragraphs.push(richText); + } + } + }); + if (paragraphs.length) { + return [notion.paragraph(paragraphs.flat()), ...images]; + } + else { + return images; + } } -function parseBlockquote(element) { +function parseBlockquote(element, options) { // Quotes can only contain RichText[], but come through as Block[] // This code collects and flattens the common ones - const blocks = element.children.flatMap(child => parseNode(child)); + const blocks = element.children.flatMap(child => parseNode(child, options)); const paragraphs = blocks.flatMap(child => child); const richtext = paragraphs.flatMap(child => { - if (child.paragraph) { - return child.paragraph.text; + if (child.type === 'paragraph') { + return child.paragraph.rich_text; } - if (child.heading_1) { - return child.heading_1.text; + if (child.type === 'heading_1') { + return child.heading_1.rich_text; } - if (child.heading_2) { - return child.heading_2.text; + if (child.type === 'heading_2') { + return child.heading_2.rich_text; } - if (child.heading_3) { - return child.heading_3.text; + if (child.type === 'heading_3') { + return child.heading_3.rich_text; } return []; }); @@ -8764,9 +8922,10 @@ function parseHeading(element) { } function parseCode(element) { const text = ensureLength(element.value); - return notion.code(text); + const lang = ensureCodeBlockLanguage(element.lang); + return notion.code(text, lang); } -function parseList(element) { +function parseList(element, options) { return element.children.flatMap(item => { const paragraph = item.children.shift(); if (paragraph === undefined || paragraph.type !== 'paragraph') { @@ -8774,7 +8933,7 @@ function parseList(element) { } const text = paragraph.children.flatMap(child => parseInline(child)); // Now process any of the children - const parsedChildren = item.children.flatMap(child => parseNode(child)); + const parsedChildren = item.children.flatMap(child => parseNode(child, options)); if (element.start !== null && element.start !== undefined) { return [notion.numberedListItem(text, parsedChildren)]; } @@ -8787,31 +8946,35 @@ function parseList(element) { }); } function parseTableCell(node) { - const text = node.children.flatMap(child => parseInline(child)); - return [notion.tableCell(text)]; + return [node.children.flatMap(child => parseInline(child))]; } function parseTableRow(node) { const tableCells = node.children.flatMap(child => parseTableCell(child)); return [notion.tableRow(tableCells)]; } function parseTable(node) { + var _a; + // The width of the table is the amount of cells in the first row, as all rows must have the same number of cells + const tableWidth = ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length) + ? node.children[0].children.length + : 0; const tableRows = node.children.flatMap(child => parseTableRow(child)); - return [notion.table(tableRows)]; + return [notion.table(tableRows, tableWidth)]; } -function parseNode(node, unsupported = false) { +function parseNode(node, options) { switch (node.type) { case 'heading': return [parseHeading(node)]; case 'paragraph': - return [parseParagraph(node)]; + return parseParagraph(node, options); case 'code': return [parseCode(node)]; case 'blockquote': - return [parseBlockquote(node)]; + return [parseBlockquote(node, options)]; case 'list': - return parseList(node); + return parseList(node, options); case 'table': - if (unsupported) { + if (options.allowUnsupported) { return parseTable(node); } else { @@ -8821,11 +8984,17 @@ function parseNode(node, unsupported = false) { return []; } } -function parseBlocks(root, unsupported = false) { - return root.children.flatMap(item => parseNode(item, unsupported)); +function parseBlocks(root, options) { + var _a, _b, _c, _d; + const parsed = root.children.flatMap(item => parseNode(item, options || {})); + const truncate = !!((_b = (_a = options === null || options === void 0 ? void 0 : options.notionLimits) === null || _a === void 0 ? void 0 : _a.truncate) !== null && _b !== void 0 ? _b : true), limitCallback = (_d = (_c = options === null || options === void 0 ? void 0 : options.notionLimits) === null || _c === void 0 ? void 0 : _c.onError) !== null && _d !== void 0 ? _d : (() => { }); + if (parsed.length > notion_1.LIMITS.PAYLOAD_BLOCKS) + limitCallback(new Error(`Resulting blocks array exceeds Notion limit (${notion_1.LIMITS.PAYLOAD_BLOCKS})`)); + return truncate ? parsed.slice(0, notion_1.LIMITS.PAYLOAD_BLOCKS) : parsed; } exports.parseBlocks = parseBlocks; -function parseRichText(root) { +function parseRichText(root, options) { + var _a, _b, _c, _d; if (root.children[0].type !== 'paragraph') { throw new Error(`Unsupported markdown element: ${JSON.stringify(root)}`); } @@ -8835,7 +9004,26 @@ function parseRichText(root) { paragraph.children.forEach(child => richTexts.push(...parseInline(child))); } }); - return richTexts; + const truncate = !!((_b = (_a = options === null || options === void 0 ? void 0 : options.notionLimits) === null || _a === void 0 ? void 0 : _a.truncate) !== null && _b !== void 0 ? _b : true), limitCallback = (_d = (_c = options === null || options === void 0 ? void 0 : options.notionLimits) === null || _c === void 0 ? void 0 : _c.onError) !== null && _d !== void 0 ? _d : (() => { }); + if (richTexts.length > notion_1.LIMITS.RICH_TEXT_ARRAYS) + limitCallback(new Error(`Resulting richTexts array exceeds Notion limit (${notion_1.LIMITS.RICH_TEXT_ARRAYS})`)); + return (truncate ? richTexts.slice(0, notion_1.LIMITS.RICH_TEXT_ARRAYS) : richTexts).map(rt => { + var _a; + if (rt.type !== 'text') + return rt; + if (rt.text.content.length > notion_1.LIMITS.RICH_TEXT.TEXT_CONTENT) { + limitCallback(new Error(`Resulting text content exceeds Notion limit (${notion_1.LIMITS.RICH_TEXT.TEXT_CONTENT})`)); + if (truncate) + rt.text.content = + rt.text.content.slice(0, notion_1.LIMITS.RICH_TEXT.TEXT_CONTENT - 3) + '...'; + } + if (((_a = rt.text.link) === null || _a === void 0 ? void 0 : _a.url) && + rt.text.link.url.length > notion_1.LIMITS.RICH_TEXT.LINK_URL) + // There's no point in truncating URLs + limitCallback(new Error(`Resulting text URL exceeds Notion limit (${notion_1.LIMITS.RICH_TEXT.LINK_URL})`)); + // Notion equations are not supported by this library, since they don't exist in Markdown + return rt; + }); } exports.parseRichText = parseRichText; //# sourceMappingURL=internal.js.map @@ -32366,571 +32554,564 @@ var github = __nccwpck_require__(5438); // EXTERNAL MODULE: ./node_modules/@notionhq/client/build/src/index.js var src = __nccwpck_require__(324); ;// CONCATENATED MODULE: ./src/common.ts -// https://developers.notion.com/reference/errors#limits-for-property-values -const RICH_TEXT_CONTENT_CHARACTERS_LIMIT = 1000; -function truncateTextContent(text) { - return text.length > RICH_TEXT_CONTENT_CHARACTERS_LIMIT - ? text.substring(0, RICH_TEXT_CONTENT_CHARACTERS_LIMIT - 1) + '…' - : text; -} -var common; -(function (common) { - function richText(content, options = {}) { - var _a; - const annotations = (_a = options.annotations) !== null && _a !== void 0 ? _a : {}; - const truncated = truncateTextContent(content); - return [ - { - type: 'text', - annotations: Object.assign({ bold: false, strikethrough: false, underline: false, italic: false, code: false, color: 'default' }, annotations), - text: { - content: truncated, - link: options.url ? { url: options.url } : undefined, - }, - }, - ]; - } - common.richText = richText; -})(common || (common = {})); +// https://developers.notion.com/reference/errors#limits-for-property-values +const RICH_TEXT_CONTENT_CHARACTERS_LIMIT = 1000; +function truncateTextContent(text) { + return text.length > RICH_TEXT_CONTENT_CHARACTERS_LIMIT + ? text.substring(0, RICH_TEXT_CONTENT_CHARACTERS_LIMIT - 1) + '…' + : text; +} +var common; +(function (common) { + function richText(content, options = {}) { + var _a; + const annotations = (_a = options.annotations) !== null && _a !== void 0 ? _a : {}; + const truncated = truncateTextContent(content); + return [ + { + type: 'text', + annotations: Object.assign({ bold: false, strikethrough: false, underline: false, italic: false, code: false, color: 'default' }, annotations), + text: { + content: truncated, + link: options.url ? { url: options.url } : undefined, + }, + }, + ]; + } + common.richText = richText; +})(common || (common = {})); ;// CONCATENATED MODULE: ./src/properties.ts - -var properties; -(function (properties) { - function text(text) { - return { - type: 'rich_text', - rich_text: text ? common.richText(text) : [], - }; - } - properties.text = text; - function richText(text) { - return { - type: 'rich_text', - rich_text: text, - }; - } - properties.richText = richText; - function title(text) { - return { - type: 'title', - title: [ - { - type: 'text', - text: { - content: text, - }, - }, - ], - }; - } - properties.title = title; - function number(number) { - return { - type: 'number', - number: number, - }; - } - properties.number = number; - function date(time) { - return { - type: 'date', - date: { - start: time, - }, - }; - } - properties.date = date; - function getStatusSelectOption(state) { - switch (state) { - case 'open': - return select('Open', 'green'); - case 'closed': - return select('Closed', 'red'); - } - } - properties.getStatusSelectOption = getStatusSelectOption; - function select(name, color = 'default') { - return { - type: 'select', - select: { - name: name, - color: color, - }, - }; - } - properties.select = select; - function multiSelect(names) { - return { - type: 'multi_select', - multi_select: names.map(name => { - return { - name: name, - }; - }), - }; - } - properties.multiSelect = multiSelect; - function url(url) { - return { - type: 'url', - url, - }; - } - properties.url = url; -})(properties || (properties = {})); + +var properties; +(function (properties) { + function text(text) { + return { + type: 'rich_text', + rich_text: text ? common.richText(text) : [], + }; + } + properties.text = text; + function richText(text) { + return { + type: 'rich_text', + rich_text: text, + }; + } + properties.richText = richText; + function title(text) { + return { + type: 'title', + title: [ + { + type: 'text', + text: { + content: text, + }, + }, + ], + }; + } + properties.title = title; + function number(number) { + return { + type: 'number', + number: number, + }; + } + properties.number = number; + function date(time) { + return { + type: 'date', + date: { + start: time, + }, + }; + } + properties.date = date; + function getStatusSelectOption(state) { + switch (state) { + case 'open': + return select('Open', 'green'); + case 'closed': + return select('Closed', 'red'); + } + } + properties.getStatusSelectOption = getStatusSelectOption; + function select(name, color = 'default') { + return { + type: 'select', + select: { + name: name, + color: color, + }, + }; + } + properties.select = select; + function multiSelect(names) { + return { + type: 'multi_select', + multi_select: names.map(name => { + return { + name: name, + }; + }), + }; + } + properties.multiSelect = multiSelect; + function url(url) { + return { + type: 'url', + url, + }; + } + properties.url = url; +})(properties || (properties = {})); ;// CONCATENATED MODULE: ./src/sync.ts -var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __asyncValues = (undefined && undefined.__asyncValues) || function (o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); - function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } - function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } -}; - - - - -function createIssueMapping(notion, databaseId) { - return __awaiter(this, void 0, void 0, function* () { - const issuePageIds = new Map(); - const issuesAlreadyInNotion = yield getIssuesAlreadyInNotion(notion, databaseId); - for (const { pageId, issueNumber } of issuesAlreadyInNotion) { - issuePageIds.set(issueNumber, pageId); - } - return issuePageIds; - }); -} -function syncNotionDBWithGitHub(issuePageIds, octokit, notion, databaseId, githubRepo) { - return __awaiter(this, void 0, void 0, function* () { - const issues = yield getGitHubIssues(octokit, githubRepo); - const pagesToCreate = getIssuesNotInNotion(issuePageIds, issues); - yield createPages(notion, databaseId, pagesToCreate, octokit); - }); -} -// Notion SDK for JS: https://developers.notion.com/reference/post-database-query -function getIssuesAlreadyInNotion(notion, databaseId) { - return __awaiter(this, void 0, void 0, function* () { - core.info('Checking for issues already in the database...'); - const pages = []; - let cursor = undefined; - let next_cursor = 'true'; - while (next_cursor) { - const response = yield notion.databases.query({ - database_id: databaseId, - start_cursor: cursor, - }); - next_cursor = response.next_cursor; - const results = response.results; - pages.push(...results); - if (!next_cursor) { - break; - } - cursor = next_cursor; - } - const res = []; - pages.forEach(page => { - if ('properties' in page) { - let num = null; - num = page.properties['Number'].number; - if (typeof num !== 'undefined') - res.push({ - pageId: page.id, - issueNumber: num, - }); - } - }); - return res; - }); -} -// https://docs.github.com/en/rest/reference/issues#list-repository-issues -function getGitHubIssues(octokit, githubRepo) { - var e_1, _a; - return __awaiter(this, void 0, void 0, function* () { - core.info('Finding Github Issues...'); - const issues = []; - const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, { - owner: githubRepo.split('/')[0], - repo: githubRepo.split('/')[1], - state: 'all', - per_page: 100, - }); - try { - for (var iterator_1 = __asyncValues(iterator), iterator_1_1; iterator_1_1 = yield iterator_1.next(), !iterator_1_1.done;) { - const { data } = iterator_1_1.value; - for (const issue of data) { - if (!issue.pull_request) { - issues.push(issue); - } - } - } - } - catch (e_1_1) { e_1 = { error: e_1_1 }; } - finally { - try { - if (iterator_1_1 && !iterator_1_1.done && (_a = iterator_1.return)) yield _a.call(iterator_1); - } - finally { if (e_1) throw e_1.error; } - } - return issues; - }); -} -function getIssuesNotInNotion(issuePageIds, issues) { - const pagesToCreate = []; - for (const issue of issues) { - if (!issuePageIds.has(issue.number)) { - pagesToCreate.push(issue); - } - } - return pagesToCreate; -} -// Notion SDK for JS: https://developers.notion.com/reference/post-page -function createPages(notion, databaseId, pagesToCreate, octokit) { - return __awaiter(this, void 0, void 0, function* () { - core.info('Adding Github Issues to Notion...'); - yield Promise.all(pagesToCreate.map((issue) => __awaiter(this, void 0, void 0, function* () { - return notion.pages.create({ - parent: { database_id: databaseId }, - properties: yield getPropertiesFromIssue(issue, octokit), - }); - }))); - }); -} -/* - * For the `Assignees` field in the Notion DB we want to send only issues.assignees.login - * For the `Labels` field in the Notion DB we want to send only issues.labels.name - */ -function createMultiSelectObjects(issue) { - var _a; - const assigneesObject = issue.assignees.map((assignee) => assignee.login); - const labelsObject = (_a = issue.labels) === null || _a === void 0 ? void 0 : _a.map((label) => label.name); - return { assigneesObject, labelsObject }; -} -function getPropertiesFromIssue(issue, octokit) { - return __awaiter(this, void 0, void 0, function* () { - const { number, title, state, id, milestone, created_at, updated_at, body, repository_url, user, html_url, } = issue; - const author = user === null || user === void 0 ? void 0 : user.login; - const { assigneesObject, labelsObject } = createMultiSelectObjects(issue); - const urlComponents = repository_url.split('/'); - const org = urlComponents[urlComponents.length - 2]; - const repo = urlComponents[urlComponents.length - 1]; - const projectData = yield getProjectData({ - octokit, - githubRepo: `${org}/${repo}`, - issueNumber: issue.number, - }); - // These properties are specific to the template DB referenced in the README. - return { - Name: properties.title(title), - Status: properties.getStatusSelectOption(state), - Organization: properties.text(org), - Repository: properties.text(repo), - Body: properties.richText(parseBodyRichText(body || '')), - Number: properties.number(number), - Assignees: properties.multiSelect(assigneesObject), - Milestone: properties.text(milestone ? milestone.title : ''), - Labels: properties.multiSelect(labelsObject ? labelsObject : []), - Author: properties.text(author), - Created: properties.date(created_at), - Updated: properties.date(updated_at), - ID: properties.number(id), - Link: properties.url(html_url), - Project: properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.name) || ''), - 'Project Column': properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.columnName) || ''), - }; - }); -} +var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __asyncValues = (undefined && undefined.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +}; + + + + +function createIssueMapping(notion, databaseId) { + return __awaiter(this, void 0, void 0, function* () { + const issuePageIds = new Map(); + const issuesAlreadyInNotion = yield getIssuesAlreadyInNotion(notion, databaseId); + for (const { pageId, issueNumber } of issuesAlreadyInNotion) { + issuePageIds.set(issueNumber, pageId); + } + return issuePageIds; + }); +} +function syncNotionDBWithGitHub(issuePageIds, octokit, notion, databaseId, githubRepo) { + return __awaiter(this, void 0, void 0, function* () { + const issues = yield getGitHubIssues(octokit, githubRepo); + const pagesToCreate = getIssuesNotInNotion(issuePageIds, issues); + yield createPages(notion, databaseId, pagesToCreate, octokit); + }); +} +// Notion SDK for JS: https://developers.notion.com/reference/post-database-query +function getIssuesAlreadyInNotion(notion, databaseId) { + return __awaiter(this, void 0, void 0, function* () { + core.info('Checking for issues already in the database...'); + const pages = []; + let cursor = undefined; + let next_cursor = 'true'; + while (next_cursor) { + const response = yield notion.databases.query({ + database_id: databaseId, + start_cursor: cursor, + }); + next_cursor = response.next_cursor; + const results = response.results; + pages.push(...results); + if (!next_cursor) { + break; + } + cursor = next_cursor; + } + const res = []; + pages.forEach(page => { + if ('properties' in page) { + let num = null; + num = page.properties['Number'].number; + if (typeof num !== 'undefined') + res.push({ + pageId: page.id, + issueNumber: num, + }); + } + }); + return res; + }); +} +// https://docs.github.com/en/rest/reference/issues#list-repository-issues +function getGitHubIssues(octokit, githubRepo) { + var e_1, _a; + return __awaiter(this, void 0, void 0, function* () { + core.info('Finding Github Issues...'); + const issues = []; + const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, { + owner: githubRepo.split('/')[0], + repo: githubRepo.split('/')[1], + state: 'all', + per_page: 100, + }); + try { + for (var iterator_1 = __asyncValues(iterator), iterator_1_1; iterator_1_1 = yield iterator_1.next(), !iterator_1_1.done;) { + const { data } = iterator_1_1.value; + for (const issue of data) { + if (!issue.pull_request) { + issues.push(issue); + } + } + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (iterator_1_1 && !iterator_1_1.done && (_a = iterator_1.return)) yield _a.call(iterator_1); + } + finally { if (e_1) throw e_1.error; } + } + return issues; + }); +} +function getIssuesNotInNotion(issuePageIds, issues) { + const pagesToCreate = []; + for (const issue of issues) { + if (!issuePageIds.has(issue.number)) { + pagesToCreate.push(issue); + } + } + return pagesToCreate; +} +// Notion SDK for JS: https://developers.notion.com/reference/post-page +function createPages(notion, databaseId, pagesToCreate, octokit) { + return __awaiter(this, void 0, void 0, function* () { + core.info('Adding Github Issues to Notion...'); + yield Promise.all(pagesToCreate.map((issue) => __awaiter(this, void 0, void 0, function* () { + return notion.pages.create({ + parent: { database_id: databaseId }, + properties: yield getPropertiesFromIssue(issue, octokit), + children: getBodyChildrenBlocks(issue.body || ''), + }); + }))); + }); +} +/* + * For the `Assignees` field in the Notion DB we want to send only issues.assignees.login + * For the `Labels` field in the Notion DB we want to send only issues.labels.name + */ +function createMultiSelectObjects(issue) { + var _a; + const assigneesObject = issue.assignees.map((assignee) => assignee.login); + const labelsObject = (_a = issue.labels) === null || _a === void 0 ? void 0 : _a.map((label) => label.name); + return { assigneesObject, labelsObject }; +} +function getPropertiesFromIssue(issue, octokit) { + return __awaiter(this, void 0, void 0, function* () { + const { number, title, state, id, milestone, created_at, updated_at, body, repository_url, user, html_url, } = issue; + const author = user === null || user === void 0 ? void 0 : user.login; + const { assigneesObject, labelsObject } = createMultiSelectObjects(issue); + const urlComponents = repository_url.split('/'); + const org = urlComponents[urlComponents.length - 2]; + const repo = urlComponents[urlComponents.length - 1]; + const projectData = yield getProjectData({ + octokit, + githubRepo: `${org}/${repo}`, + issueNumber: issue.number, + }); + // These properties are specific to the template DB referenced in the README. + return { + Name: properties.title(title), + Status: properties.getStatusSelectOption(state), + Organization: properties.text(org), + Repository: properties.text(repo), + Body: properties.richText(parseBodyRichText(body || '')), + Number: properties.number(number), + Assignees: properties.multiSelect(assigneesObject), + Milestone: properties.text(milestone ? milestone.title : ''), + Labels: properties.multiSelect(labelsObject ? labelsObject : []), + Author: properties.text(author), + Created: properties.date(created_at), + Updated: properties.date(updated_at), + ID: properties.number(id), + Link: properties.url(html_url), + Project: properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.name) || ''), + 'Project Column': properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.columnName) || ''), + }; + }); +} // EXTERNAL MODULE: ./node_modules/octokit/dist-node/index.js var dist_node = __nccwpck_require__(7467); // EXTERNAL MODULE: ./node_modules/@tryfabric/martian/build/src/index.js var build_src = __nccwpck_require__(6615); ;// CONCATENATED MODULE: ./src/action.ts -var action_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; - - - - - - -function removeHTML(text) { - var _a; - return (_a = text === null || text === void 0 ? void 0 : text.replace(/<.*>.*<\/.*>/g, '')) !== null && _a !== void 0 ? _a : ''; -} -function parsePropertiesFromPayload(options) { - var _a, _b, _c, _d, _e, _f, _g; - return action_awaiter(this, void 0, void 0, function* () { - const { payload, octokit, possibleProject } = options; - (_a = payload.issue.labels) === null || _a === void 0 ? void 0 : _a.map(label => label.color); - const projectData = yield getProjectData({ - octokit, - githubRepo: payload.repository.full_name, - issueNumber: payload.issue.number, - possible: possibleProject, - }); - core.debug(`Current project data: ${JSON.stringify(projectData, null, 2)}`); - const result = { - Name: properties.title(payload.issue.title), - Status: properties.getStatusSelectOption(payload.issue.state), - Organization: properties.text((_c = (_b = payload.organization) === null || _b === void 0 ? void 0 : _b.login) !== null && _c !== void 0 ? _c : ''), - Repository: properties.text(payload.repository.name), - Number: properties.number(payload.issue.number), - Body: properties.richText(parseBodyRichText(payload.issue.body)), - Assignees: properties.multiSelect(payload.issue.assignees.map(assignee => assignee.login)), - Milestone: properties.text((_e = (_d = payload.issue.milestone) === null || _d === void 0 ? void 0 : _d.title) !== null && _e !== void 0 ? _e : ''), - Labels: properties.multiSelect((_g = (_f = payload.issue.labels) === null || _f === void 0 ? void 0 : _f.map(label => label.name)) !== null && _g !== void 0 ? _g : []), - Author: properties.text(payload.issue.user.login), - Created: properties.date(payload.issue.created_at), - Updated: properties.date(payload.issue.updated_at), - ID: properties.number(payload.issue.id), - Link: properties.url(payload.issue.html_url), - Project: properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.name) || ''), - 'Project Column': properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.columnName) || ''), - }; - return result; - }); -} -function getProjectData(options) { - return action_awaiter(this, void 0, void 0, function* () { - const { octokit, githubRepo, issueNumber, possible } = options; - const projects = (yield octokit.rest.projects.listForRepo({ - owner: githubRepo.split('/')[0], - repo: githubRepo.split('/')[1], - })).data || []; - projects.sort(p => (p.name === (possible === null || possible === void 0 ? void 0 : possible.name) ? -1 : 1)); - core.debug(`Found ${projects.length} projects.`); - for (const project of projects) { - const columns = (yield octokit.rest.projects.listColumns({ project_id: project.id })).data || []; - if ((possible === null || possible === void 0 ? void 0 : possible.name) === project.name) - columns.sort(c => (c.name === possible.columnName ? -1 : 1)); - for (const column of columns) { - const cards = (yield octokit.rest.projects.listCards({ column_id: column.id })).data, card = cards && cards.find(c => { var _a; return Number((_a = c.content_url) === null || _a === void 0 ? void 0 : _a.split('/issues/')[1]) === issueNumber; }); - if (card) - return { - name: project.name, - columnName: column.name, - }; - } - } - return undefined; - }); -} -function parseBodyRichText(body) { - try { - return (0,build_src.markdownToRichText)(removeHTML(body)); - } - catch (_a) { - return []; - } -} -function getBodyChildrenBlocks(body) { - // We're currently using only one paragraph block, but this could be extended to multiple kinds of blocks. - return [ - { - type: 'paragraph', - paragraph: { - text: parseBodyRichText(body), - }, - }, - ]; -} -function handleIssueOpened(options) { - return action_awaiter(this, void 0, void 0, function* () { - const { notion, payload } = options; - core.info(`Creating page for issue #${payload.issue.number}`); - yield notion.client.pages.create({ - parent: { - database_id: notion.databaseId, - }, - properties: yield parsePropertiesFromPayload({ - payload, - octokit: options.octokit, - }), - children: getBodyChildrenBlocks(payload.issue.body), - }); - }); -} -function handleIssueEdited(options) { - var _a, _b; - return action_awaiter(this, void 0, void 0, function* () { - const { notion, payload, octokit } = options; - core.info(`Querying database for page with github id ${payload.issue.id}`); - const query = yield notion.client.databases.query({ - database_id: notion.databaseId, - filter: { - property: 'ID', - number: { - equals: payload.issue.id, - }, - }, - page_size: 1, - }); - const bodyBlocks = getBodyChildrenBlocks(payload.issue.body); - if (query.results.length > 0) { - const pageId = query.results[0].id; - core.info(`Query successful: Page ${pageId}`); - core.info(`Updating page for issue #${payload.issue.number}`); - yield notion.client.pages.update({ - page_id: pageId, - properties: yield parsePropertiesFromPayload({ payload, octokit }), - }); - const existingBlocks = (yield notion.client.blocks.children.list({ - block_id: pageId, - })).results; - const overlap = Math.min(bodyBlocks.length, existingBlocks.length); - yield Promise.all(bodyBlocks.slice(0, overlap).map((block, index) => notion.client.blocks.update(Object.assign({ block_id: existingBlocks[index].id }, block)))); - if (bodyBlocks.length > existingBlocks.length) { - yield notion.client.blocks.children.append({ - block_id: pageId, - children: bodyBlocks.slice(overlap), - }); - } - else if (bodyBlocks.length < existingBlocks.length) { - yield Promise.all(existingBlocks - .slice(overlap) - .map(block => notion.client.blocks.delete({ block_id: block.id }))); - } - } - else { - core.warning(`Could not find page with github id ${payload.issue.id}, creating a new one`); - yield notion.client.pages.create({ - parent: { - database_id: notion.databaseId, - }, - properties: yield parsePropertiesFromPayload({ payload, octokit }), - children: bodyBlocks, - }); - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const result = query.results[0], pageId = result.id, possible = result - ? { - name: (_a = result.properties.Project.rich_text[0]) === null || _a === void 0 ? void 0 : _a.plain_text, - columnName: (_b = result.properties['Project Column'] - .rich_text[0]) === null || _b === void 0 ? void 0 : _b.plain_text, - } - : undefined; - core.info(`Query successful: Page ${pageId}`); - core.info(`Updating page for issue #${payload.issue.number}`); - yield notion.client.pages.update({ - page_id: pageId, - properties: yield parsePropertiesFromPayload({ - payload, - octokit: options.octokit, - possibleProject: possible, - }), - }); - }); -} -function run(options) { - var _a; - return action_awaiter(this, void 0, void 0, function* () { - const { notion, github } = options; - core.info('Starting...'); - const notionClient = new src/* Client */.KU({ - auth: notion.token, - logLevel: core.isDebug() ? src/* LogLevel.DEBUG */.in.DEBUG : src/* LogLevel.WARN */.in.WARN, - }); - const octokit = new dist_node/* Octokit */.vd({ auth: github.token }); - if (github.payload.action === 'opened') { - yield handleIssueOpened({ - notion: { - client: notionClient, - databaseId: notion.databaseId, - }, - payload: github.payload, - octokit, - }); - } - else if (github.eventName === 'workflow_dispatch') { - const notion = new src/* Client */.KU({ auth: options.notion.token }); - const { databaseId } = options.notion; - const issuePageIds = yield createIssueMapping(notion, databaseId); - if (!((_a = github.payload.repository) === null || _a === void 0 ? void 0 : _a.full_name)) { - throw new Error('Unable to find repository name in github webhook context'); - } - const githubRepo = github.payload.repository.full_name; - yield syncNotionDBWithGitHub(issuePageIds, octokit, notion, databaseId, githubRepo); - } - else { - yield handleIssueEdited({ - notion: { - client: notionClient, - databaseId: notion.databaseId, - }, - payload: github.payload, - octokit, - }); - } - core.info('Complete!'); - }); -} +var action_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; + + + + + + +function removeHTML(text) { + var _a; + return (_a = text === null || text === void 0 ? void 0 : text.replace(/<.*>.*<\/.*>/g, '')) !== null && _a !== void 0 ? _a : ''; +} +function parsePropertiesFromPayload(options) { + var _a, _b, _c, _d, _e, _f, _g; + return action_awaiter(this, void 0, void 0, function* () { + const { payload, octokit, possibleProject } = options; + (_a = payload.issue.labels) === null || _a === void 0 ? void 0 : _a.map(label => label.color); + const projectData = yield getProjectData({ + octokit, + githubRepo: payload.repository.full_name, + issueNumber: payload.issue.number, + possible: possibleProject, + }); + core.debug(`Current project data: ${JSON.stringify(projectData, null, 2)}`); + const result = { + Name: properties.title(payload.issue.title), + Status: properties.getStatusSelectOption(payload.issue.state), + Organization: properties.text((_c = (_b = payload.organization) === null || _b === void 0 ? void 0 : _b.login) !== null && _c !== void 0 ? _c : ''), + Repository: properties.text(payload.repository.name), + Number: properties.number(payload.issue.number), + Body: properties.richText(parseBodyRichText(payload.issue.body)), + Assignees: properties.multiSelect(payload.issue.assignees.map(assignee => assignee.login)), + Milestone: properties.text((_e = (_d = payload.issue.milestone) === null || _d === void 0 ? void 0 : _d.title) !== null && _e !== void 0 ? _e : ''), + Labels: properties.multiSelect((_g = (_f = payload.issue.labels) === null || _f === void 0 ? void 0 : _f.map(label => label.name)) !== null && _g !== void 0 ? _g : []), + Author: properties.text(payload.issue.user.login), + Created: properties.date(payload.issue.created_at), + Updated: properties.date(payload.issue.updated_at), + ID: properties.number(payload.issue.id), + Link: properties.url(payload.issue.html_url), + Project: properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.name) || ''), + 'Project Column': properties.text((projectData === null || projectData === void 0 ? void 0 : projectData.columnName) || ''), + }; + return result; + }); +} +function getProjectData(options) { + return action_awaiter(this, void 0, void 0, function* () { + const { octokit, githubRepo, issueNumber, possible } = options; + const projects = (yield octokit.rest.projects.listForRepo({ + owner: githubRepo.split('/')[0], + repo: githubRepo.split('/')[1], + })).data || []; + projects.sort(p => (p.name === (possible === null || possible === void 0 ? void 0 : possible.name) ? -1 : 1)); + core.debug(`Found ${projects.length} projects.`); + for (const project of projects) { + const columns = (yield octokit.rest.projects.listColumns({ project_id: project.id })).data || []; + if ((possible === null || possible === void 0 ? void 0 : possible.name) === project.name) + columns.sort(c => (c.name === possible.columnName ? -1 : 1)); + for (const column of columns) { + const cards = (yield octokit.rest.projects.listCards({ column_id: column.id })).data, card = cards && cards.find(c => { var _a; return Number((_a = c.content_url) === null || _a === void 0 ? void 0 : _a.split('/issues/')[1]) === issueNumber; }); + if (card) + return { + name: project.name, + columnName: column.name, + }; + } + } + return undefined; + }); +} +function parseBodyRichText(body) { + try { + return (0,build_src.markdownToRichText)(removeHTML(body)); + } + catch (_a) { + return []; + } +} +function getBodyChildrenBlocks(body) { + return (0,build_src.markdownToBlocks)(body); +} +function handleIssueOpened(options) { + return action_awaiter(this, void 0, void 0, function* () { + const { notion, payload } = options; + core.info(`Creating page for issue #${payload.issue.number}`); + yield notion.client.pages.create({ + parent: { + database_id: notion.databaseId, + }, + properties: yield parsePropertiesFromPayload({ + payload, + octokit: options.octokit, + }), + children: getBodyChildrenBlocks(payload.issue.body), + }); + }); +} +function handleIssueEdited(options) { + var _a, _b; + return action_awaiter(this, void 0, void 0, function* () { + const { notion, payload, octokit } = options; + core.info(`Querying database for page with github id ${payload.issue.id}`); + const query = yield notion.client.databases.query({ + database_id: notion.databaseId, + filter: { + property: 'ID', + number: { + equals: payload.issue.id, + }, + }, + page_size: 1, + }); + const bodyBlocks = getBodyChildrenBlocks(payload.issue.body); + if (query.results.length > 0) { + const pageId = query.results[0].id; + core.info(`Query successful: Page ${pageId}`); + core.info(`Updating page for issue #${payload.issue.number}`); + yield notion.client.pages.update({ + page_id: pageId, + properties: yield parsePropertiesFromPayload({ payload, octokit }), + }); + const existingBlocks = (yield notion.client.blocks.children.list({ + block_id: pageId, + })).results; + const overlap = Math.min(bodyBlocks.length, existingBlocks.length); + yield Promise.all(bodyBlocks.slice(0, overlap).map((block, index) => notion.client.blocks.update(Object.assign({ block_id: existingBlocks[index].id }, block)))); + if (bodyBlocks.length > existingBlocks.length) { + yield notion.client.blocks.children.append({ + block_id: pageId, + children: bodyBlocks.slice(overlap), + }); + } + else if (bodyBlocks.length < existingBlocks.length) { + yield Promise.all(existingBlocks + .slice(overlap) + .map(block => notion.client.blocks.delete({ block_id: block.id }))); + } + } + else { + core.warning(`Could not find page with github id ${payload.issue.id}, creating a new one`); + yield notion.client.pages.create({ + parent: { + database_id: notion.databaseId, + }, + properties: yield parsePropertiesFromPayload({ payload, octokit }), + children: bodyBlocks, + }); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const result = query.results[0], pageId = result.id, possible = result + ? { + name: (_a = result.properties.Project.rich_text[0]) === null || _a === void 0 ? void 0 : _a.plain_text, + columnName: (_b = result.properties['Project Column'] + .rich_text[0]) === null || _b === void 0 ? void 0 : _b.plain_text, + } + : undefined; + core.info(`Query successful: Page ${pageId}`); + core.info(`Updating page for issue #${payload.issue.number}`); + yield notion.client.pages.update({ + page_id: pageId, + properties: yield parsePropertiesFromPayload({ + payload, + octokit: options.octokit, + possibleProject: possible, + }), + }); + }); +} +function run(options) { + var _a; + return action_awaiter(this, void 0, void 0, function* () { + const { notion, github } = options; + core.info('Starting...'); + const notionClient = new src/* Client */.KU({ + auth: notion.token, + logLevel: core.isDebug() ? src/* LogLevel.DEBUG */.in.DEBUG : src/* LogLevel.WARN */.in.WARN, + }); + const octokit = new dist_node/* Octokit */.vd({ auth: github.token }); + if (github.payload.action === 'opened') { + yield handleIssueOpened({ + notion: { + client: notionClient, + databaseId: notion.databaseId, + }, + payload: github.payload, + octokit, + }); + } + else if (github.eventName === 'workflow_dispatch') { + const notion = new src/* Client */.KU({ auth: options.notion.token }); + const { databaseId } = options.notion; + const issuePageIds = yield createIssueMapping(notion, databaseId); + if (!((_a = github.payload.repository) === null || _a === void 0 ? void 0 : _a.full_name)) { + throw new Error('Unable to find repository name in github webhook context'); + } + const githubRepo = github.payload.repository.full_name; + yield syncNotionDBWithGitHub(issuePageIds, octokit, notion, databaseId, githubRepo); + } + else { + yield handleIssueEdited({ + notion: { + client: notionClient, + databaseId: notion.databaseId, + }, + payload: github.payload, + octokit, + }); + } + core.info('Complete!'); + }); +} ;// CONCATENATED MODULE: ./src/index.ts -var src_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; - - - -const INPUTS = { - NOTION_TOKEN: 'notion-token', - NOTION_DB: 'notion-db', - GITHUB_TOKEN: 'github-token', -}; -function start() { - return src_awaiter(this, void 0, void 0, function* () { - try { - const notionToken = core.getInput(INPUTS.NOTION_TOKEN, { required: true }); - const notionDb = core.getInput(INPUTS.NOTION_DB, { required: true }); - const githubToken = core.getInput(INPUTS.GITHUB_TOKEN, { required: true }); - core.info(`context event: ${github.context.eventName}`); - core.info(`context action: ${github.context.action}`); - core.info(`payload action: ${github.context.payload.action}`); - const options = { - notion: { - token: notionToken, - databaseId: notionDb, - }, - github: { - payload: github.context.payload, - eventName: github.context.eventName, - token: githubToken, - }, - }; - yield run(options); - } - catch (e) { - core.setFailed(e instanceof Error ? e.message : e + ''); - } - }); -} -(() => src_awaiter(void 0, void 0, void 0, function* () { - yield start(); -}))(); +var src_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; + + + +const INPUTS = { + NOTION_TOKEN: 'notion-token', + NOTION_DB: 'notion-db', + GITHUB_TOKEN: 'github-token', +}; +function start() { + return src_awaiter(this, void 0, void 0, function* () { + try { + const notionToken = core.getInput(INPUTS.NOTION_TOKEN, { required: true }); + const notionDb = core.getInput(INPUTS.NOTION_DB, { required: true }); + const githubToken = core.getInput(INPUTS.GITHUB_TOKEN, { required: true }); + core.info(`context event: ${github.context.eventName}`); + core.info(`context action: ${github.context.action}`); + core.info(`payload action: ${github.context.payload.action}`); + const options = { + notion: { + token: notionToken, + databaseId: notionDb, + }, + github: { + payload: github.context.payload, + eventName: github.context.eventName, + token: githubToken, + }, + }; + yield run(options); + } + catch (e) { + core.setFailed(e instanceof Error ? e.message : e + ''); + } + }); +} +(() => src_awaiter(void 0, void 0, void 0, function* () { + yield start(); +}))(); })();