@sillsdev/docu-notion 0.13.3 → 0.14.0-alpha.2

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.
@@ -10,6 +10,7 @@ const EscapeHtmlBlockModifier_1 = require("../plugins/EscapeHtmlBlockModifier");
10
10
  const HeadingTransformer_1 = require("../plugins/HeadingTransformer");
11
11
  const NumberedListTransformer_1 = require("../plugins/NumberedListTransformer");
12
12
  const TableTransformer_1 = require("../plugins/TableTransformer");
13
+ const VideoTransformer_1 = require("../plugins/VideoTransformer");
13
14
  const externalLinks_1 = require("../plugins/externalLinks");
14
15
  const defaultConfig = {
15
16
  plugins: [
@@ -24,14 +25,13 @@ const defaultConfig = {
24
25
  CalloutTransformer_1.standardCalloutTransformer,
25
26
  TableTransformer_1.standardTableTransformer,
26
27
  NumberedListTransformer_1.standardNumberedListTransformer,
28
+ VideoTransformer_1.standardVideoTransformer,
27
29
  // Link modifiers, which are special because they can read metadata from all the pages in order to figure out the correct url
28
30
  internalLinks_1.standardInternalLinkConversion,
29
31
  externalLinks_1.standardExternalLinkConversion,
30
32
  // Regexps plus javascript `import`s that operate on the Markdown output
31
33
  embedTweaks_1.imgurGifEmbed,
32
34
  embedTweaks_1.gifEmbed,
33
- embedTweaks_1.youtubeEmbed,
34
- embedTweaks_1.vimeoEmbed,
35
35
  ],
36
36
  };
37
37
  exports.default = defaultConfig;
@@ -37,7 +37,7 @@ function notionColumnToMarkdown(notionToMarkdown, getBlockChildren, block) {
37
37
  return (`<div class='notion-column' style={{width: '${columnWidth}'}}>\n\n${childrenStrings.join("\n\n")}\n\n</div>` +
38
38
  // Spacer between columns. CSS takes care of hiding this for the last column
39
39
  // and when the screen is too narrow for multiple columns.
40
- `<div className='notion-spacer' />`);
40
+ `<div className='notion-spacer'></div>`);
41
41
  });
42
42
  }
43
43
  // The official API doesn't give us access to the format information, including column_ratio.
@@ -0,0 +1,2 @@
1
+ import { IPlugin } from "./pluginTypes";
2
+ export declare const standardVideoTransformer: IPlugin;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.standardVideoTransformer = void 0;
4
+ const log_1 = require("../log");
5
+ exports.standardVideoTransformer = {
6
+ name: "video",
7
+ notionToMarkdownTransforms: [
8
+ {
9
+ type: "video",
10
+ getStringFromBlock: (context, block) => {
11
+ const video = block.video;
12
+ let url = "";
13
+ switch (video.type) {
14
+ case "external":
15
+ url = video.external.url;
16
+ break;
17
+ case "file":
18
+ url = video.file.url;
19
+ break;
20
+ default:
21
+ // video.type can only be "external" or "file" as of the writing of this code, so typescript
22
+ // isn't happy trying to turn video.type into a string. But this default in our switch is
23
+ // just attempting some future-proofing. Thus the strange typing/stringifying below.
24
+ (0, log_1.warning)(`[standardVideoTransformer] Found Notion "video" block with type ${JSON.stringify(video.type)}. The best docu-notion can do for now is ignore it.`);
25
+ return "";
26
+ break;
27
+ }
28
+ context.imports.push(`import ReactPlayer from "react-player";`);
29
+ return `<ReactPlayer controls url="${url}" />`;
30
+ },
31
+ },
32
+ ],
33
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,112 @@
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 VideoTransformer_1 = require("./VideoTransformer");
14
+ const pluginTestRun_1 = require("./pluginTestRun");
15
+ test("youtube embedded", () => __awaiter(void 0, void 0, void 0, function* () {
16
+ const config = { plugins: [VideoTransformer_1.standardVideoTransformer] };
17
+ const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
18
+ {
19
+ object: "block",
20
+ type: "video",
21
+ video: {
22
+ caption: [
23
+ {
24
+ type: "text",
25
+ text: {
26
+ content: "A video about editing in Notion",
27
+ link: null,
28
+ },
29
+ plain_text: "A video about editing in Notion",
30
+ href: null,
31
+ },
32
+ ],
33
+ type: "external",
34
+ external: { url: "https://www.youtube.com/watch?v=FXIrojSK3Jo" },
35
+ },
36
+ },
37
+ ]);
38
+ expect(result).toContain(`import ReactPlayer from "react-player";`);
39
+ expect(result).toContain(`<ReactPlayer controls url="https://www.youtube.com/watch?v=FXIrojSK3Jo" />`);
40
+ }));
41
+ test("vimeo embedded", () => __awaiter(void 0, void 0, void 0, function* () {
42
+ (0, log_1.setLogLevel)("verbose");
43
+ const config = { plugins: [VideoTransformer_1.standardVideoTransformer] };
44
+ const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
45
+ {
46
+ object: "block",
47
+ type: "video",
48
+ video: {
49
+ caption: [],
50
+ type: "external",
51
+ external: { url: "https://vimeo.com/4613611xx" },
52
+ },
53
+ },
54
+ ]);
55
+ expect(result).toContain(`import ReactPlayer from "react-player";`);
56
+ expect(result).toContain(`<ReactPlayer controls url="https://vimeo.com/4613611xx" />`);
57
+ }));
58
+ test("video link, not embedded", () => __awaiter(void 0, void 0, void 0, function* () {
59
+ (0, log_1.setLogLevel)("verbose");
60
+ const config = { plugins: [VideoTransformer_1.standardVideoTransformer] };
61
+ const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
62
+ {
63
+ object: "block",
64
+ type: "paragraph",
65
+ paragraph: {
66
+ rich_text: [
67
+ {
68
+ type: "text",
69
+ text: {
70
+ content: "https://vimeo.com/4613611xx",
71
+ link: {
72
+ url: "https://vimeo.com/4613611xx",
73
+ },
74
+ },
75
+ annotations: {
76
+ code: false,
77
+ },
78
+ plain_text: "https://vimeo.com/4613611xx",
79
+ href: "https://vimeo.com/4613611xx",
80
+ },
81
+ ],
82
+ color: "default",
83
+ },
84
+ },
85
+ ]);
86
+ expect(result).toContain("[https://vimeo.com/4613611xx](https://vimeo.com/4613611xx)");
87
+ expect(result).not.toContain(`import`);
88
+ }));
89
+ test("direct upload to to Notion (embedded)", () => __awaiter(void 0, void 0, void 0, function* () {
90
+ (0, log_1.setLogLevel)("verbose");
91
+ const config = { plugins: [VideoTransformer_1.standardVideoTransformer] };
92
+ const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
93
+ {
94
+ object: "block",
95
+ id: "12f7db3b-4412-4be9-a3f7-6ac423fee94a",
96
+ parent: {
97
+ type: "page_id",
98
+ page_id: "edaffeb2-ece8-4d44-976f-351e6b5757bb",
99
+ },
100
+ type: "video",
101
+ video: {
102
+ caption: [],
103
+ type: "file",
104
+ file: {
105
+ url: "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/f6bc4746-011e-2124-86ca-ed4337d70891/people_fre_motionAsset_p3.mp4?X-Blah-blah",
106
+ },
107
+ },
108
+ },
109
+ ]);
110
+ expect(result).toContain(`import ReactPlayer from "react-player";`);
111
+ expect(result).toContain(`<ReactPlayer controls url="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/f6bc4746-011e-2124-86ca-ed4337d70891/people_fre_motionAsset_p3.mp4?X-Blah-blah" />`);
112
+ }));
@@ -1,5 +1,3 @@
1
1
  import { IPlugin } from "./pluginTypes";
2
2
  export declare const gifEmbed: IPlugin;
3
3
  export declare const imgurGifEmbed: IPlugin;
4
- export declare const youtubeEmbed: IPlugin;
5
- export declare const vimeoEmbed: IPlugin;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.vimeoEmbed = exports.youtubeEmbed = exports.imgurGifEmbed = exports.gifEmbed = void 0;
3
+ exports.imgurGifEmbed = exports.gifEmbed = void 0;
4
4
  exports.gifEmbed = {
5
5
  name: "gif",
6
6
  regexMarkdownModifications: [
@@ -22,25 +22,3 @@ exports.imgurGifEmbed = {
22
22
  },
23
23
  ],
24
24
  };
25
- exports.youtubeEmbed = {
26
- name: "youtube",
27
- regexMarkdownModifications: [
28
- {
29
- regex: /\[.*\]\((.*youtube\.com\/watch.*)\)/,
30
- imports: [`import ReactPlayer from "react-player";`],
31
- replacementPattern: `<ReactPlayer controls url="$1" />`,
32
- },
33
- ],
34
- };
35
- exports.vimeoEmbed = {
36
- name: "vimeo",
37
- regexMarkdownModifications: [
38
- {
39
- regex: /\[.*\]\((https:\/\/.*vimeo.*)\)/,
40
- // we use to have the following, but the above should handle both the player an not-player urls.
41
- //regex: /\[.*\]\((.*player\.vimeo.*)\)/gm, // player.vimeo
42
- imports: [`import ReactPlayer from "react-player";`],
43
- replacementPattern: `<ReactPlayer controls url="$1" />`,
44
- },
45
- ],
46
- };
@@ -12,53 +12,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const log_1 = require("../log");
13
13
  const pluginTestRun_1 = require("./pluginTestRun");
14
14
  const embedTweaks_1 = require("./embedTweaks");
15
- test("youtube", () => __awaiter(void 0, void 0, void 0, function* () {
16
- const config = { plugins: [embedTweaks_1.youtubeEmbed] };
17
- const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
18
- {
19
- object: "block",
20
- id: "e6ddd1d4-36d4-4925-94c1-5dff4662c1f3",
21
- has_children: false,
22
- archived: false,
23
- type: "video",
24
- video: {
25
- caption: [
26
- {
27
- type: "text",
28
- text: {
29
- content: "A video about editing in Notion",
30
- link: null,
31
- },
32
- plain_text: "A video about editing in Notion",
33
- href: null,
34
- },
35
- ],
36
- type: "external",
37
- external: { url: "https://www.youtube.com/watch?v=FXIrojSK3Jo" },
38
- },
39
- },
40
- ]);
41
- expect(result).toContain(`import ReactPlayer from "react-player";`);
42
- expect(result).toContain(`<ReactPlayer controls url="https://www.youtube.com/watch?v=FXIrojSK3Jo" />`);
43
- }));
44
- test("vimeo", () => __awaiter(void 0, void 0, void 0, function* () {
45
- (0, log_1.setLogLevel)("verbose");
46
- const config = { plugins: [embedTweaks_1.vimeoEmbed] };
47
- const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
48
- {
49
- object: "block",
50
- id: "39ff83a3-2fb5-4411-a715-960656a177ff",
51
- type: "video",
52
- video: {
53
- caption: [],
54
- type: "external",
55
- external: { url: "https://vimeo.com/4613611xx" },
56
- },
57
- },
58
- ]);
59
- expect(result).toContain(`import ReactPlayer from "react-player";`);
60
- expect(result).toContain(`<ReactPlayer controls url="https://vimeo.com/4613611xx" />`);
61
- }));
62
15
  test("imgur", () => __awaiter(void 0, void 0, void 0, function* () {
63
16
  (0, log_1.setLogLevel)("verbose");
64
17
  const config = { plugins: [embedTweaks_1.imgurGifEmbed] };
@@ -23,6 +23,19 @@ test("links turned into bookmarks", () => __awaiter(void 0, void 0, void 0, func
23
23
  });
24
24
  expect(results.trim()).toBe("[https://github.com](https://github.com)");
25
25
  }));
26
+ test("video links turned into bookmarks", () => __awaiter(void 0, void 0, void 0, function* () {
27
+ (0, log_1.setLogLevel)("debug");
28
+ const results = yield getMarkdown({
29
+ object: "block",
30
+ type: "bookmark",
31
+ bookmark: {
32
+ caption: [],
33
+ url: "https://vimeo.com/4613611xx",
34
+ },
35
+ });
36
+ expect(results).toContain("[https://vimeo.com/4613611xx](https://vimeo.com/4613611xx)");
37
+ expect(results).not.toContain(`import`);
38
+ }));
26
39
  test("external link inside callout", () => __awaiter(void 0, void 0, void 0, function* () {
27
40
  const results = yield getMarkdown({
28
41
  type: "callout",
@@ -39,6 +39,7 @@ function blocksToMarkdown(config, blocks, pages) {
39
39
  convertNotionLinkToLocalDocusaurusLink: (url) => {
40
40
  return (0, internalLinks_1.convertInternalUrl)(docunotionContext, url);
41
41
  },
42
+ imports: [],
42
43
  //TODO might be needed for some tests, e.g. the image transformer...
43
44
  directoryContainingMarkdown: "not yet",
44
45
  relativeFilePathToFolderContainingPage: "not yet",
@@ -40,5 +40,6 @@ export type IDocuNotionContext = {
40
40
  convertNotionLinkToLocalDocusaurusLink: (url: string) => string | undefined;
41
41
  pages: NotionPage[];
42
42
  counts: ICounts;
43
+ imports: string[];
43
44
  };
44
45
  export {};
package/dist/pull.js CHANGED
@@ -99,6 +99,7 @@ function outputPages(options, config, pages) {
99
99
  options: options,
100
100
  pages: pages,
101
101
  counts: counts,
102
+ imports: [],
102
103
  convertNotionLinkToLocalDocusaurusLink: (url) => (0, internalLinks_1.convertInternalUrl)(context, url),
103
104
  };
104
105
  for (const page of pages) {
package/dist/transform.js CHANGED
@@ -44,9 +44,12 @@ 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(context, config, markdown);
47
+ const body = yield doTransformsOnMarkdown(context, config, markdown);
48
48
  // console.log("markdown after regex fixes", markdown);
49
49
  // console.log("body after regex", body);
50
+ const uniqueImports = [...new Set(context.imports)];
51
+ const imports = uniqueImports.join("\n");
52
+ context.imports = []; // reset for next page
50
53
  return `${imports}\n${body}`;
51
54
  });
52
55
  }
@@ -65,7 +68,6 @@ function doNotionBlockTransforms(blocks, config) {
65
68
  }
66
69
  }
67
70
  function doTransformsOnMarkdown(context, config, input) {
68
- var _a;
69
71
  return __awaiter(this, void 0, void 0, function* () {
70
72
  const regexMods = config.plugins
71
73
  .filter(plugin => !!plugin.regexMarkdownModifications)
@@ -81,7 +83,6 @@ function doTransformsOnMarkdown(context, config, input) {
81
83
  let body = input;
82
84
  //console.log("body before regex: " + body);
83
85
  let match;
84
- const imports = new Set();
85
86
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
86
87
  for (const mod of regexMods) {
87
88
  let replacement = undefined;
@@ -113,14 +114,15 @@ function doTransformsOnMarkdown(context, config, input) {
113
114
  precedingPart +
114
115
  partStartingFromThisMatch.replace(original, replacement);
115
116
  // add any library imports
116
- (_a = mod.imports) === null || _a === void 0 ? void 0 : _a.forEach(imp => imports.add(imp));
117
+ if (!context.imports)
118
+ context.imports = [];
119
+ context.imports.push(...(mod.imports || []));
117
120
  }
118
121
  }
119
122
  }
120
123
  }
121
124
  (0, log_1.logDebug)("doTransformsOnMarkdown", "body after regex: " + body);
122
- const uniqueImports = [...new Set(imports)];
123
- return { body, imports: [...uniqueImports].join("\n") };
125
+ return body;
124
126
  });
125
127
  }
126
128
  function doNotionToMarkdown(docunotionContext, blocks) {
package/package.json CHANGED
@@ -90,5 +90,5 @@
90
90
  "volta": {
91
91
  "node": "18.16.0"
92
92
  },
93
- "version": "0.13.3"
93
+ "version": "0.14.0-alpha.2"
94
94
  }