@sillsdev/docu-notion 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,6 +30,7 @@ export declare class NotionPage {
30
30
  get status(): string | undefined;
31
31
  getPlainTextProperty(property: string, defaultIfEmpty: string): string;
32
32
  getSelectProperty(property: string): string | undefined;
33
+ getDateProperty(property: string, defaultIfEmpty: string, start?: boolean): string;
33
34
  getContentInfo(children: ListBlockChildrenResponseResults): Promise<{
34
35
  childPageIdsAndOrder: {
35
36
  id: string;
@@ -83,7 +83,8 @@ class NotionPage {
83
83
  const explicitSlug = this.getPlainTextProperty("Slug", "");
84
84
  if (explicitSlug) {
85
85
  if (explicitSlug === "/")
86
- return explicitSlug; // the root page
86
+ return explicitSlug;
87
+ // the root page
87
88
  else
88
89
  return ("/" +
89
90
  encodeURIComponent(explicitSlug
@@ -136,6 +137,10 @@ class NotionPage {
136
137
  {
137
138
  ...
138
139
  "plain_text": "Intro",
140
+ },
141
+ {
142
+ ...
143
+ "plain_text": " to Notion",
139
144
  }
140
145
  ]
141
146
  */
@@ -148,7 +153,9 @@ class NotionPage {
148
153
  const textArray = p[p.type];
149
154
  //console.log("textarray:" + JSON.stringify(textArray, null, 2));
150
155
  return textArray && textArray.length
151
- ? textArray[0].plain_text
156
+ ? textArray
157
+ .map((item) => item.plain_text)
158
+ .join("")
152
159
  : defaultIfEmpty;
153
160
  }
154
161
  getSelectProperty(property) {
@@ -173,6 +180,34 @@ class NotionPage {
173
180
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
174
181
  return ((_b = p.select) === null || _b === void 0 ? void 0 : _b.name) || undefined;
175
182
  }
183
+ getDateProperty(property, defaultIfEmpty, start = true) {
184
+ /* Notion dates look like this
185
+ "properties": {
186
+ "published_date":
187
+ {
188
+ "id":"a%3Cql",
189
+ "type":"date",
190
+ "date":{
191
+ "start":"2021-10-24",
192
+ "end":null,
193
+ "time_zone":null
194
+ }
195
+ }
196
+ }
197
+ */
198
+ var _a, _b, _c;
199
+ // console.log("metadata:\n" + JSON.stringify(this.metadata, null, 2));
200
+ const p = (_a = this.metadata.properties) === null || _a === void 0 ? void 0 : _a[property];
201
+ // console.log(`prop ${property} = ${JSON.stringify(p)}`);
202
+ if (!p)
203
+ return defaultIfEmpty;
204
+ if (start) {
205
+ return ((_b = p === null || p === void 0 ? void 0 : p.date) === null || _b === void 0 ? void 0 : _b.start) ? p.date.start : defaultIfEmpty;
206
+ }
207
+ else {
208
+ return ((_c = p === null || p === void 0 ? void 0 : p.date) === null || _c === void 0 ? void 0 : _c.end) ? p.date.end : defaultIfEmpty;
209
+ }
210
+ }
176
211
  getContentInfo(children) {
177
212
  return __awaiter(this, void 0, void 0, function* () {
178
213
  for (let i = 0; i < children.length; i++) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const NotionPage_1 = require("./NotionPage");
4
+ describe("NotionPage", () => {
5
+ const mockMetadata = {
6
+ object: "page",
7
+ id: "6e6921b9-b1f5-4614-ab3c-bf1a73358a1f",
8
+ created_time: "2023-04-11T10:17:00.000Z",
9
+ last_edited_time: "2023-04-13T20:24:00.000Z",
10
+ created_by: {
11
+ object: "user",
12
+ id: "USERID",
13
+ },
14
+ last_edited_by: {
15
+ object: "user",
16
+ id: "USERID",
17
+ },
18
+ cover: null,
19
+ icon: {
20
+ type: "file",
21
+ file: {
22
+ url: "https:/dummy_URL",
23
+ expiry_time: "2023-04-15T11:50:20.461Z",
24
+ },
25
+ },
26
+ parent: {
27
+ type: "workspace",
28
+ workspace: true,
29
+ },
30
+ archived: false,
31
+ properties: {
32
+ title: {
33
+ id: "title",
34
+ type: "title",
35
+ title: [
36
+ {
37
+ type: "text",
38
+ text: {
39
+ content: "Foo",
40
+ link: null,
41
+ },
42
+ annotations: {
43
+ bold: false,
44
+ italic: false,
45
+ strikethrough: false,
46
+ underline: false,
47
+ code: false,
48
+ color: "default",
49
+ },
50
+ plain_text: "Foo",
51
+ href: null,
52
+ },
53
+ {
54
+ type: "text",
55
+ text: {
56
+ content: "Bar",
57
+ link: null,
58
+ },
59
+ annotations: {
60
+ bold: false,
61
+ italic: false,
62
+ strikethrough: false,
63
+ underline: false,
64
+ code: false,
65
+ color: "default",
66
+ },
67
+ plain_text: "Bar",
68
+ href: null,
69
+ },
70
+ ],
71
+ },
72
+ date_property: {
73
+ id: "a%3Cql",
74
+ type: "date",
75
+ date: {
76
+ start: "2021-10-24",
77
+ end: "2021-10-28",
78
+ time_zone: null,
79
+ },
80
+ },
81
+ },
82
+ url: "https://www.notion.so/Site-docu-notion-PAGEID",
83
+ };
84
+ describe("getPlainTextProperty", () => {
85
+ it("should return the plain text value of a property", () => {
86
+ const page = new NotionPage_1.NotionPage({
87
+ layoutContext: "Test Context",
88
+ pageId: "123",
89
+ order: 1,
90
+ metadata: mockMetadata,
91
+ foundDirectlyInOutline: true,
92
+ });
93
+ const result = page.getPlainTextProperty("title", "");
94
+ expect(result).toBe("FooBar");
95
+ });
96
+ it("should return the default value if the property is not found", () => {
97
+ const page = new NotionPage_1.NotionPage({
98
+ layoutContext: "Test Context",
99
+ pageId: "123",
100
+ order: 1,
101
+ metadata: mockMetadata,
102
+ foundDirectlyInOutline: true,
103
+ });
104
+ const result = page.getPlainTextProperty("nonexistent", "Default Value");
105
+ expect(result).toBe("Default Value");
106
+ });
107
+ });
108
+ describe("getDateProperty", () => {
109
+ it("should return the start date property by default", () => {
110
+ const page = new NotionPage_1.NotionPage({
111
+ layoutContext: "Test Context",
112
+ pageId: "123",
113
+ order: 1,
114
+ metadata: mockMetadata,
115
+ foundDirectlyInOutline: true,
116
+ });
117
+ const result = page.getDateProperty("date_property", "");
118
+ expect(result).toBe("2021-10-24");
119
+ });
120
+ it("should return the end date if start is false", () => {
121
+ const page = new NotionPage_1.NotionPage({
122
+ layoutContext: "Test Context",
123
+ pageId: "123",
124
+ order: 1,
125
+ metadata: mockMetadata,
126
+ foundDirectlyInOutline: true,
127
+ });
128
+ const result = page.getDateProperty("date_property", "", false);
129
+ expect(result).toBe("2021-10-28");
130
+ });
131
+ it("should return the default value if the property is not found", () => {
132
+ const page = new NotionPage_1.NotionPage({
133
+ layoutContext: "Test Context",
134
+ pageId: "123",
135
+ order: 1,
136
+ metadata: mockMetadata,
137
+ foundDirectlyInOutline: true,
138
+ });
139
+ const result = page.getPlainTextProperty("nonexistent", "Default Value");
140
+ expect(result).toBe("Default Value");
141
+ });
142
+ });
143
+ });
@@ -1,4 +1,5 @@
1
- import { IPlugin } from "./pluginTypes";
1
+ import { IDocuNotionContext, IPlugin } from "./pluginTypes";
2
+ export declare function convertInternalUrl(context: IDocuNotionContext, url: string): string | undefined;
2
3
  export declare function parseLinkId(fullLinkId: string): {
3
4
  baseLinkId: string;
4
5
  fragmentId: string;
@@ -1,7 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.standardInternalLinkConversion = exports.parseLinkId = void 0;
3
+ exports.standardInternalLinkConversion = exports.parseLinkId = exports.convertInternalUrl = void 0;
4
4
  const log_1 = require("../log");
5
+ // converts a url to a local link, if it is a link to a page in the Notion site
6
+ // only here for plugins, notion won't normally be giving us raw urls (at least not that I've noticed)
7
+ // If it finds a URL but can't find the page it points to, it will return undefined.
8
+ // If it doesn't find a match at all, it returns undefined.
9
+ function convertInternalUrl(context, url) {
10
+ const kGetIDFromNotionURL = /https:\/\/www\.notion\.so\S+-([a-z,0-9]+)+.*/;
11
+ const match = kGetIDFromNotionURL.exec(url);
12
+ if (match === null) {
13
+ (0, log_1.warning)(`[standardInternalLinkConversion] Could not parse link ${url} as a Notion URL`);
14
+ return undefined;
15
+ }
16
+ const id = match[1];
17
+ const pages = context.pages;
18
+ // find the page where pageId matches hrefFromNotion
19
+ const targetPage = pages.find(p => {
20
+ return p.matchesLinkId(id);
21
+ });
22
+ if (!targetPage) {
23
+ // About this situation. See https://github.com/sillsdev/docu-notion/issues/9
24
+ (0, log_1.warning)(`[standardInternalLinkConversion] Could not find the target of this link. Note that links to outline sections are not supported. ${url}. https://github.com/sillsdev/docu-notion/issues/9`);
25
+ return undefined;
26
+ }
27
+ return convertLinkHref(context, targetPage, url);
28
+ }
29
+ exports.convertInternalUrl = convertInternalUrl;
30
+ // handles the whole markdown link, including the label
5
31
  function convertInternalLink(context, markdownLink) {
6
32
  const linkRegExp = /\[([^\]]+)?\]\(\/?([^),^/]+)\)/g;
7
33
  const match = linkRegExp.exec(markdownLink);
@@ -70,9 +96,7 @@ exports.standardInternalLinkConversion = {
70
96
  // (has some other text that's been turned into a link) or "raw".
71
97
  // Raw links come in without a leading slash, e.g. [link_to_page](4a6de8c0-b90b-444b-8a7b-d534d6ec71a4)
72
98
  // Inline links come in with a leading slash, e.g. [pointer to the introduction](/4a6de8c0b90b444b8a7bd534d6ec71a4)
73
- // we only want the inline ones for this plugin
74
- // review: currently we expect that internal links have an opening slash, but at one point it was optional.
75
- match: /\[([^\]]+)?\]\(\/([^),^/]+)\)/,
99
+ match: /\[([^\]]+)?\]\((?!mailto:)(\/?[^),^/]+)\)/,
76
100
  convert: convertInternalLink,
77
101
  },
78
102
  };
@@ -173,7 +173,8 @@ test("link to a heading block on a page", () => __awaiter(void 0, void 0, void 0
173
173
  const slugResults = yield getMarkdown(blocks, slugTargetPage);
174
174
  expect(slugResults.trim()).toBe(`(Inline [heading on some page](/hello-world#456) the end.)`);
175
175
  }));
176
- test("link to an existing page on this site uses slug", () => __awaiter(void 0, void 0, void 0, function* () {
176
+ // Text that has been selected and turned into a link to one of our pages
177
+ test("inline link to an existing page on this site uses slug", () => __awaiter(void 0, void 0, void 0, function* () {
177
178
  const targetPageId = "123";
178
179
  const targetPage = (0, pluginTestRun_1.makeSamplePageObject)({
179
180
  slug: "hello-world",
@@ -221,6 +222,33 @@ test("link to an existing page on this site uses slug", () => __awaiter(void 0,
221
222
  }, targetPage);
222
223
  expect(results.trim()).toBe("Inline [It’s good](/hello-world)");
223
224
  }));
225
+ // this is the kind of link you get if you just insert a "link to page" to Notion
226
+ test("raw link to an existing page on this site that has a slug", () => __awaiter(void 0, void 0, void 0, function* () {
227
+ const targetPageId = "123";
228
+ const targetPage = (0, pluginTestRun_1.makeSamplePageObject)({
229
+ slug: "point-to-me",
230
+ name: "Point to Me",
231
+ id: targetPageId,
232
+ });
233
+ const results = yield getMarkdown({
234
+ object: "block",
235
+ id: "2051d790-e527-4b4e-b145-ec0beee2addf",
236
+ parent: {
237
+ type: "page_id",
238
+ page_id: "333",
239
+ },
240
+ created_time: "2023-06-14T20:09:00.000Z",
241
+ last_edited_time: "2023-06-14T20:09:00.000Z",
242
+ has_children: false,
243
+ archived: false,
244
+ type: "link_to_page",
245
+ link_to_page: {
246
+ type: "page_id",
247
+ page_id: targetPageId,
248
+ },
249
+ }, targetPage);
250
+ expect(results.trim()).toBe("[Point to Me](/point-to-me)");
251
+ }));
224
252
  test("link in a bulleted list", () => __awaiter(void 0, void 0, void 0, function* () {
225
253
  const targetPageId = "123";
226
254
  const targetPage = (0, pluginTestRun_1.makeSamplePageObject)({
@@ -427,6 +455,41 @@ Callouts inline [great page](/hello-world).
427
455
 
428
456
  :::`);
429
457
  }));
458
+ test("internal link inside codeblock ignored", () => __awaiter(void 0, void 0, void 0, function* () {
459
+ const targetPageId = "123";
460
+ const targetPage = (0, pluginTestRun_1.makeSamplePageObject)({
461
+ slug: "hello-world",
462
+ name: "Hello World",
463
+ id: targetPageId,
464
+ });
465
+ const results = yield getMarkdown({
466
+ type: "code",
467
+ code: {
468
+ caption: [],
469
+ rich_text: [
470
+ {
471
+ type: "text",
472
+ text: {
473
+ content: "this should not change [link](https://www.notion.so/native/metapages/mypage)",
474
+ link: null,
475
+ },
476
+ annotations: {
477
+ bold: false,
478
+ italic: false,
479
+ strikethrough: false,
480
+ underline: false,
481
+ code: false,
482
+ color: "default",
483
+ },
484
+ plain_text: "this should not change [link](https://www.notion.so/native/metapages/mypage)",
485
+ href: null,
486
+ },
487
+ ],
488
+ language: "javascript", // notion assumed javascript in my test in which I didn't specify a language
489
+ },
490
+ }, targetPage);
491
+ expect(results.trim()).toContain("this should not change [link](https://www.notion.so/native/metapages/mypage)");
492
+ }));
430
493
  function getMarkdown(block, targetPage) {
431
494
  return __awaiter(this, void 0, void 0, function* () {
432
495
  const config = {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const log_1 = require("../log");
13
+ const pluginTestRun_1 = require("./pluginTestRun");
14
+ test("raw url inside a mermaid codeblock gets converted to path using slug of that page", () => __awaiter(void 0, void 0, void 0, function* () {
15
+ const targetPageId = "123";
16
+ const targetPage = (0, pluginTestRun_1.makeSamplePageObject)({
17
+ slug: "slug-of-target",
18
+ name: "My Target Page",
19
+ id: targetPageId,
20
+ });
21
+ const input = {
22
+ type: "code",
23
+ code: {
24
+ caption: [],
25
+ rich_text: [
26
+ {
27
+ type: "text",
28
+ text: {
29
+ content: `click A "https://www.notion.so/native/metapages/A-Page-${targetPageId}"`,
30
+ link: null,
31
+ },
32
+ annotations: {
33
+ bold: false,
34
+ italic: false,
35
+ strikethrough: false,
36
+ underline: false,
37
+ code: false,
38
+ color: "default",
39
+ },
40
+ plain_text: `click A "https://www.notion.so/native/metapages/A-Page-${targetPageId}"`,
41
+ href: null,
42
+ },
43
+ ],
44
+ language: "mermaid", // notion assumed javascript in my test in which I didn't specify a language
45
+ },
46
+ };
47
+ const mermaidLinks = {
48
+ name: "mermaidLinks",
49
+ regexMarkdownModifications: [
50
+ {
51
+ regex: /```mermaid\n.*"(https:\/\/www\.notion\.so\S+)"/,
52
+ includeCodeBlocks: true,
53
+ getReplacement: (context, match) => __awaiter(void 0, void 0, void 0, function* () {
54
+ const url = match[1];
55
+ const docusaurusUrl = context.convertNotionLinkToLocalDocusaurusLink(url);
56
+ if (docusaurusUrl) {
57
+ // eslint-disable-next-line @typescript-eslint/await-thenable
58
+ return yield match[0].replace(url, docusaurusUrl);
59
+ }
60
+ else {
61
+ (0, log_1.error)(`Could not convert link ${url} to a local docusaurus link`);
62
+ return match[0];
63
+ }
64
+ }),
65
+ },
66
+ ],
67
+ };
68
+ const config = {
69
+ plugins: [
70
+ // standardInternalLinkConversion,
71
+ // standardExternalLinkConversion,
72
+ mermaidLinks,
73
+ ],
74
+ };
75
+ const results = yield (0, pluginTestRun_1.oneBlockToMarkdown)(config, input, targetPage);
76
+ expect(results.trim()).toContain(`click A "/slug-of-target"`);
77
+ }));
@@ -15,6 +15,7 @@ const notion_to_md_1 = require("notion-to-md");
15
15
  const HierarchicalNamedLayoutStrategy_1 = require("../HierarchicalNamedLayoutStrategy");
16
16
  const NotionPage_1 = require("../NotionPage");
17
17
  const transform_1 = require("../transform");
18
+ const internalLinks_1 = require("./internalLinks");
18
19
  function blocksToMarkdown(config, blocks, pages) {
19
20
  return __awaiter(this, void 0, void 0, function* () {
20
21
  const notionClient = new client_1.Client({ auth: "unused" });
@@ -35,6 +36,9 @@ function blocksToMarkdown(config, blocks, pages) {
35
36
  resolve([]);
36
37
  });
37
38
  },
39
+ convertNotionLinkToLocalDocusaurusLink: (url) => {
40
+ return (0, internalLinks_1.convertInternalUrl)(docunotionContext, url);
41
+ },
38
42
  //TODO might be needed for some tests, e.g. the image transformer...
39
43
  directoryContainingMarkdown: "not yet",
40
44
  relativeFilePathToFolderContainingPage: "not yet",
@@ -24,7 +24,8 @@ export type IPlugin = {
24
24
  export type IRegexMarkdownModification = {
25
25
  regex: RegExp;
26
26
  replacementPattern?: string;
27
- getReplacement?(s: string): Promise<string>;
27
+ getReplacement?(context: IDocuNotionContext, match: RegExpExecArray): Promise<string>;
28
+ includeCodeBlocks?: boolean;
28
29
  imports?: string[];
29
30
  };
30
31
  export type ICustomNotionToMarkdownConversion = (block: ListBlockChildrenResponseResult, context: IDocuNotionContext) => () => Promise<string>;
@@ -36,6 +37,7 @@ export type IDocuNotionContext = {
36
37
  notionToMarkdown: NotionToMarkdown;
37
38
  directoryContainingMarkdown: string;
38
39
  relativeFilePathToFolderContainingPage: string;
40
+ convertNotionLinkToLocalDocusaurusLink: (url: string) => string | undefined;
39
41
  pages: NotionPage[];
40
42
  counts: ICounts;
41
43
  };
package/dist/pull.js CHANGED
@@ -45,6 +45,7 @@ const limiter_1 = require("limiter");
45
45
  const client_1 = require("@notionhq/client");
46
46
  const process_1 = require("process");
47
47
  const configuration_1 = require("./config/configuration");
48
+ const internalLinks_1 = require("./plugins/internalLinks");
48
49
  let layoutStrategy;
49
50
  let notionToMarkdown;
50
51
  const pages = new Array();
@@ -97,7 +98,8 @@ function outputPages(options, config, pages) {
97
98
  notionToMarkdown: notionToMarkdown,
98
99
  options: options,
99
100
  pages: pages,
100
- counts: counts, // review will this get copied or pointed to?
101
+ counts: counts,
102
+ convertNotionLinkToLocalDocusaurusLink: (url) => (0, internalLinks_1.convertInternalUrl)(context, url),
101
103
  };
102
104
  for (const page of pages) {
103
105
  layoutStrategy.pageWasSeen(page);
package/dist/transform.js CHANGED
@@ -44,7 +44,7 @@ function getMarkdownFromNotionBlocks(context, config, blocks) {
44
44
  markdown = doLinkFixes(context, markdown, config);
45
45
  //console.log("markdown after link fixes", markdown);
46
46
  // simple regex-based tweaks. These are usually related to docusaurus
47
- const { imports, body } = yield doTransformsOnMarkdown(config, markdown);
47
+ const { imports, body } = yield doTransformsOnMarkdown(context, config, markdown);
48
48
  // console.log("markdown after regex fixes", markdown);
49
49
  // console.log("body after regex", body);
50
50
  return `${imports}\n${body}`;
@@ -64,7 +64,7 @@ function doNotionBlockTransforms(blocks, config) {
64
64
  });
65
65
  }
66
66
  }
67
- function doTransformsOnMarkdown(config, input) {
67
+ function doTransformsOnMarkdown(context, config, input) {
68
68
  var _a;
69
69
  return __awaiter(this, void 0, void 0, function* () {
70
70
  const regexMods = config.plugins
@@ -88,15 +88,19 @@ function doTransformsOnMarkdown(config, input) {
88
88
  // regex.exec is stateful, so we don't want to mess up the plugin's use of its own regex, so we clone it.
89
89
  // we also add the "g" flag to make sure we get all matches
90
90
  const regex = new RegExp(`${codeBlocks.source}|(${mod.regex.source})`, "g");
91
- let count = 0;
92
91
  while ((match = regex.exec(input)) !== null) {
93
92
  if (match[0]) {
94
93
  const original = match[0];
95
- if (original.startsWith("```") && original.endsWith("```")) {
96
- continue; // code block
94
+ if (original.startsWith("```") &&
95
+ original.endsWith("```") &&
96
+ !mod.includeCodeBlocks) {
97
+ continue; // code block, and they didn't say to include them
97
98
  }
98
99
  if (mod.getReplacement) {
99
- replacement = yield mod.getReplacement(original);
100
+ // our match here has an extra group, which is an implementation detail
101
+ // that shouldn't be made visible to the plugin
102
+ const matchAsThePluginWouldExpectIt = mod.regex.exec(match[0]);
103
+ replacement = yield mod.getReplacement(context, matchAsThePluginWouldExpectIt);
100
104
  }
101
105
  else if (mod.replacementPattern) {
102
106
  console.log(`mod.replacementPattern.replace("$1", ${match[2]}`);
@@ -123,7 +127,7 @@ function doTransformsOnMarkdown(config, input) {
123
127
  function doNotionToMarkdown(docunotionContext, blocks) {
124
128
  return __awaiter(this, void 0, void 0, function* () {
125
129
  const mdBlocks = yield docunotionContext.notionToMarkdown.blocksToMarkdown(blocks);
126
- let markdown = docunotionContext.notionToMarkdown.toMarkdownString(mdBlocks);
130
+ const markdown = docunotionContext.notionToMarkdown.toMarkdownString(mdBlocks);
127
131
  return markdown;
128
132
  });
129
133
  }
@@ -151,6 +155,7 @@ function doLinkFixes(context, markdown, config) {
151
155
  if (!plugin.linkModifier)
152
156
  return false;
153
157
  if (plugin.linkModifier.match.exec(originalLinkMarkdown) === null) {
158
+ (0, log_1.verbose)(`plugin "${plugin.name}" did not match this url`);
154
159
  return false;
155
160
  }
156
161
  const newMarkdown = plugin.linkModifier.convert(context, originalLinkMarkdown);
package/package.json CHANGED
@@ -1,26 +1,27 @@
1
1
  {
2
2
  "scripts": {
3
- "test": "jest",
4
- "build": "yarn test && tsc && cp ./src/css/*.css dist/",
3
+ "test": "vitest",
4
+ "build": "npm run test -- --run && tsc && cp ./src/css/*.css dist/",
5
5
  "build-only": "tsc && cp ./src/css/*.css dist/",
6
6
  "clean": "rimraf ./dist/",
7
7
  "semantic-release": "semantic-release",
8
- "typecheck": "tsc --noEmit",
9
- "notion-download": "node dist/index.js",
10
8
  "cmdhelp": "ts-node src/index.ts",
11
9
  "// note that we're not using ts-node at the moment because of ": "https://github.com/Codex-/cosmiconfig-typescript-loader/issues/70",
12
- "ts": "yarn tsc && rimraf ./docs/ && cross-var node dist/index.js",
10
+ "ts": "tsc && rimraf ./docs/ && cross-var node dist/index.js",
11
+ "// typescript check": "",
12
+ "tsc": "tsc",
13
13
  "// test out with a private sample notion db": "",
14
- "pull-test-tagged": "yarn ts -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_TEST_ROOT_PAGE_ID --log-level debug --status-tag test",
15
- "pull-sample-site": "yarn ts -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_SAMPLE_ROOT_PAGE --log-level debug",
14
+ "pull-test-tagged": "npm run ts -- -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_TEST_ROOT_PAGE_ID --log-level debug --status-tag test",
15
+ "pull-sample-site": "npm run ts -- -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_SAMPLE_ROOT_PAGE --log-level debug",
16
16
  "// test with a semi-stable/public site:": "",
17
- "pull-sample": "yarn ts -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_SAMPLE_ROOT_PAGE -m ./sample --locales en,es,fr,de --log-level verbose",
18
- "pull-sample-with-paths": "yarn ts -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_SAMPLE_ROOT_PAGE -m ./sample --img-output-path ./sample_img"
17
+ "pull-sample": "npm run ts -- -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_SAMPLE_ROOT_PAGE -m ./sample --locales en,es,fr,de --log-level verbose",
18
+ "pull-sample-with-paths": "npm run ts -- -n $DOCU_NOTION_INTEGRATION_TOKEN -r $DOCU_NOTION_SAMPLE_ROOT_PAGE -m ./sample --img-output-path ./sample_img"
19
19
  },
20
20
  "//file-type": "have to use this version before they switched to ESM, which gives a compile error related to require()",
21
21
  "//node-fetch@2.6.6file-type": "have to use this version before they switched to ESM, which gives a compile error related to require()",
22
22
  "//chalk@4": "also ESM related problem",
23
23
  "//notion-client@4": "also ESM related problem",
24
+ "//note: ts-node": "really is a runtime dependency",
24
25
  "dependencies": {
25
26
  "@notionhq/client": "2.2.3",
26
27
  "chalk": "^4.1.2",
@@ -35,29 +36,29 @@
35
36
  "notion-client": "^4",
36
37
  "notion-to-md": "^2.5.5",
37
38
  "path": "^0.12.7",
39
+ "ts-node": "^10.2.1",
38
40
  "sanitize-filename": "^1.6.3"
39
41
  },
40
42
  "devDependencies": {
41
43
  "@types/fs-extra": "^9.0.13",
42
- "@types/jest": "^28.1.6",
43
44
  "@types/markdown-table": "^2.0.0",
44
- "@types/node": "^12.20.11",
45
+ "@types/node": "^18.15.11",
45
46
  "@typescript-eslint/eslint-plugin": "^4.22.0",
46
47
  "@typescript-eslint/parser": "^4.22.0",
48
+ "@vitest/ui": "^0.30.1",
47
49
  "cross-var": "^1.1.0",
48
50
  "cz-conventional-changelog": "^3.3.0",
49
51
  "eslint": "^7.25.0",
50
52
  "eslint-config-prettier": "^8.3.0",
51
53
  "eslint-plugin-node": "^11.1.0",
52
54
  "eslint-plugin-prettier": "^3.4.0",
53
- "jest": "^28.1.3",
54
55
  "lint-staged": "^10.5.4",
55
56
  "prettier": "^2.2.1",
56
57
  "rimraf": "^4.1.2",
57
58
  "semantic-release": "^19.0.2",
58
- "ts-jest": "^28.0.7",
59
- "ts-node": "^10.2.1",
60
- "typescript": "^4.6.4"
59
+ "typescript": "^4.6.4",
60
+ "vite": "^4.2.1",
61
+ "vitest": "^0.30.1"
61
62
  },
62
63
  "name": "@sillsdev/docu-notion",
63
64
  "description": "Download Notion pages as markdown and image files, preserving hierarchy and enabling workflow properties. Works with Docusaurus.",
@@ -77,20 +78,16 @@
77
78
  "url": "https://github.com/sillsdev/docu-notion/issues"
78
79
  },
79
80
  "homepage": "https://github.com/sillsdev/docu-notion#readme",
80
- "packageManager": "yarn@3.4.1",
81
81
  "main": "./dist/index.js",
82
82
  "bin": "dist/index.js",
83
83
  "files": [
84
84
  "dist/**/*"
85
85
  ],
86
- "release": {
87
- "branches": [
88
- "main",
89
- "release"
90
- ]
91
- },
92
86
  "publishConfig": {
93
87
  "access": "public"
94
88
  },
95
- "version": "0.12.0"
89
+ "volta": {
90
+ "node": "18.16.0"
91
+ },
92
+ "version": "0.13.0"
96
93
  }