@sillsdev/docu-notion 0.11.1

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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +135 -0
  3. package/dist/FlatGuidLayoutStrategy.d.ts +6 -0
  4. package/dist/FlatGuidLayoutStrategy.js +25 -0
  5. package/dist/HierarchicalNamedLayoutStrategy.d.ts +7 -0
  6. package/dist/HierarchicalNamedLayoutStrategy.js +80 -0
  7. package/dist/LayoutStrategy.d.ts +12 -0
  8. package/dist/LayoutStrategy.js +83 -0
  9. package/dist/MakeImagePersistencePlan.d.ts +2 -0
  10. package/dist/MakeImagePersistencePlan.js +66 -0
  11. package/dist/NotionImage-CaptionReading.spec.d.ts +1 -0
  12. package/dist/NotionImage-CaptionReading.spec.js +233 -0
  13. package/dist/NotionPage.d.ts +45 -0
  14. package/dist/NotionPage.js +229 -0
  15. package/dist/NotionPage.spec.d.ts +1 -0
  16. package/dist/NotionPage.spec.js +143 -0
  17. package/dist/config/configuration.d.ts +5 -0
  18. package/dist/config/configuration.js +86 -0
  19. package/dist/config/default.docunotion.config.d.ts +3 -0
  20. package/dist/config/default.docunotion.config.js +37 -0
  21. package/dist/images.d.ts +24 -0
  22. package/dist/images.js +230 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.js +37 -0
  25. package/dist/log.d.ts +11 -0
  26. package/dist/log.js +61 -0
  27. package/dist/makeImagePersistencePlan.spec.d.ts +1 -0
  28. package/dist/makeImagePersistencePlan.spec.js +35 -0
  29. package/dist/notion-styles.css +58 -0
  30. package/dist/plugins/CalloutTransformer.d.ts +24 -0
  31. package/dist/plugins/CalloutTransformer.js +88 -0
  32. package/dist/plugins/CalloutTransformer.spec.d.ts +1 -0
  33. package/dist/plugins/CalloutTransformer.spec.js +199 -0
  34. package/dist/plugins/ColumnListTransformer.d.ts +2 -0
  35. package/dist/plugins/ColumnListTransformer.js +34 -0
  36. package/dist/plugins/ColumnTransformer.d.ts +2 -0
  37. package/dist/plugins/ColumnTransformer.js +67 -0
  38. package/dist/plugins/EscapeHtmlBlockModifier.d.ts +2 -0
  39. package/dist/plugins/EscapeHtmlBlockModifier.js +41 -0
  40. package/dist/plugins/EscapeHtmlBlockModifier.spec.d.ts +1 -0
  41. package/dist/plugins/EscapeHtmlBlockModifier.spec.js +130 -0
  42. package/dist/plugins/HeadingTranformer.spec.d.ts +1 -0
  43. package/dist/plugins/HeadingTranformer.spec.js +46 -0
  44. package/dist/plugins/HeadingTransformer.d.ts +2 -0
  45. package/dist/plugins/HeadingTransformer.js +63 -0
  46. package/dist/plugins/NumberedListTransformer.d.ts +2 -0
  47. package/dist/plugins/NumberedListTransformer.js +55 -0
  48. package/dist/plugins/NumberedListTransformer.spec.d.ts +1 -0
  49. package/dist/plugins/NumberedListTransformer.spec.js +86 -0
  50. package/dist/plugins/TableTransformer.d.ts +5 -0
  51. package/dist/plugins/TableTransformer.js +70 -0
  52. package/dist/plugins/embedTweaks.d.ts +5 -0
  53. package/dist/plugins/embedTweaks.js +46 -0
  54. package/dist/plugins/embedTweaks.spec.d.ts +1 -0
  55. package/dist/plugins/embedTweaks.spec.js +230 -0
  56. package/dist/plugins/externalLinks.d.ts +2 -0
  57. package/dist/plugins/externalLinks.js +26 -0
  58. package/dist/plugins/externalLinks.spec.d.ts +1 -0
  59. package/dist/plugins/externalLinks.spec.js +132 -0
  60. package/dist/plugins/internalLinks.d.ts +7 -0
  61. package/dist/plugins/internalLinks.js +102 -0
  62. package/dist/plugins/internalLinks.spec.d.ts +1 -0
  63. package/dist/plugins/internalLinks.spec.js +505 -0
  64. package/dist/plugins/mermaidLinkPlugin.spec.d.ts +1 -0
  65. package/dist/plugins/mermaidLinkPlugin.spec.js +77 -0
  66. package/dist/plugins/pluginTestRun.d.ts +10 -0
  67. package/dist/plugins/pluginTestRun.js +252 -0
  68. package/dist/plugins/pluginTypes.d.ts +44 -0
  69. package/dist/plugins/pluginTypes.js +2 -0
  70. package/dist/pull.d.ts +12 -0
  71. package/dist/pull.js +255 -0
  72. package/dist/run.d.ts +1 -0
  73. package/dist/run.js +35 -0
  74. package/dist/transform.d.ts +6 -0
  75. package/dist/transform.js +200 -0
  76. package/dist/types.d.ts +8 -0
  77. package/dist/types.js +2 -0
  78. package/package.json +103 -0
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.loadConfigAsync = void 0;
39
+ const Cosmic = __importStar(require("cosmiconfig"));
40
+ const default_docunotion_config_1 = __importDefault(require("./default.docunotion.config"));
41
+ const log_1 = require("../log");
42
+ const cosmiconfig_typescript_loader_1 = require("cosmiconfig-typescript-loader");
43
+ const process_1 = require("process");
44
+ // read the plugins from the config file
45
+ // and add them to the map
46
+ function loadConfigAsync() {
47
+ var _a, _b, _c, _d, _e;
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ let config = default_docunotion_config_1.default;
50
+ try {
51
+ const cosmic = Cosmic.cosmiconfig("docu-notion", {
52
+ loaders: {
53
+ ".ts": (0, cosmiconfig_typescript_loader_1.TypeScriptLoader)(),
54
+ },
55
+ searchPlaces: [`docu-notion.config.ts`],
56
+ });
57
+ const found = yield cosmic.search();
58
+ if (found) {
59
+ (0, log_1.verbose)(`Loading config from ${found.filepath}`);
60
+ }
61
+ else {
62
+ (0, log_1.verbose)(`Did not find configuration file, using defaults.`);
63
+ }
64
+ const pluginsWithInitializers = (_b = (_a = found === null || found === void 0 ? void 0 : found.config) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.filter((p) => p.init !== undefined);
65
+ const initializers = pluginsWithInitializers === null || pluginsWithInitializers === void 0 ? void 0 : pluginsWithInitializers.map((p) => () => p.init(p));
66
+ yield Promise.all(initializers || []);
67
+ (_d = (_c = found === null || found === void 0 ? void 0 : found.config) === null || _c === void 0 ? void 0 : _c.plugins) === null || _d === void 0 ? void 0 : _d.forEach((plugin) => __awaiter(this, void 0, void 0, function* () {
68
+ if (plugin.init !== undefined) {
69
+ (0, log_1.verbose)(`Initializing plugin ${plugin.name}...`);
70
+ yield plugin.init(plugin);
71
+ }
72
+ }));
73
+ // for now, all we have is plugins
74
+ config = {
75
+ plugins: default_docunotion_config_1.default.plugins.concat(((_e = found === null || found === void 0 ? void 0 : found.config) === null || _e === void 0 ? void 0 : _e.plugins) || []),
76
+ };
77
+ }
78
+ catch (e) {
79
+ (0, log_1.error)(e.message);
80
+ (0, process_1.exit)(1);
81
+ }
82
+ (0, log_1.verbose)(`Active plugins: [${config.plugins.map(p => p.name).join(", ")}]`);
83
+ return config;
84
+ });
85
+ }
86
+ exports.loadConfigAsync = loadConfigAsync;
@@ -0,0 +1,3 @@
1
+ import { IDocuNotionConfig } from "./configuration";
2
+ declare const defaultConfig: IDocuNotionConfig;
3
+ export default defaultConfig;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const embedTweaks_1 = require("../plugins/embedTweaks");
4
+ const images_1 = require("../images");
5
+ const internalLinks_1 = require("../plugins/internalLinks");
6
+ const CalloutTransformer_1 = require("../plugins/CalloutTransformer");
7
+ const ColumnListTransformer_1 = require("../plugins/ColumnListTransformer");
8
+ const ColumnTransformer_1 = require("../plugins/ColumnTransformer");
9
+ const EscapeHtmlBlockModifier_1 = require("../plugins/EscapeHtmlBlockModifier");
10
+ const HeadingTransformer_1 = require("../plugins/HeadingTransformer");
11
+ const NumberedListTransformer_1 = require("../plugins/NumberedListTransformer");
12
+ const TableTransformer_1 = require("../plugins/TableTransformer");
13
+ const externalLinks_1 = require("../plugins/externalLinks");
14
+ const defaultConfig = {
15
+ plugins: [
16
+ // Notion "Block" JSON modifiers
17
+ EscapeHtmlBlockModifier_1.standardEscapeHtmlBlockModifier,
18
+ HeadingTransformer_1.standardHeadingTransformer,
19
+ // Notion to Markdown transformers. Most things get transformed correctly by the notion-to-markdown library,
20
+ // but some things need special handling.
21
+ ColumnTransformer_1.standardColumnTransformer,
22
+ ColumnListTransformer_1.standardColumnListTransformer,
23
+ images_1.standardImageTransformer,
24
+ CalloutTransformer_1.standardCalloutTransformer,
25
+ TableTransformer_1.standardTableTransformer,
26
+ NumberedListTransformer_1.standardNumberedListTransformer,
27
+ // Link modifiers, which are special because they can read metadata from all the pages in order to figure out the correct url
28
+ internalLinks_1.standardInternalLinkConversion,
29
+ externalLinks_1.standardExternalLinkConversion,
30
+ // Regexps plus javascript `import`s that operate on the Markdown output
31
+ embedTweaks_1.imgurGifEmbed,
32
+ embedTweaks_1.gifEmbed,
33
+ embedTweaks_1.youtubeEmbed,
34
+ embedTweaks_1.vimeoEmbed,
35
+ ],
36
+ };
37
+ exports.default = defaultConfig;
@@ -0,0 +1,24 @@
1
+ /// <reference types="node" />
2
+ import { FileTypeResult } from "file-type";
3
+ import { ListBlockChildrenResponseResult } from "notion-to-md/build/types";
4
+ import { IPlugin } from "./plugins/pluginTypes";
5
+ export type ImageSet = {
6
+ primaryUrl: string;
7
+ caption?: string;
8
+ localizedUrls: Array<{
9
+ iso632Code: string;
10
+ url: string;
11
+ }>;
12
+ pathToParentDocument?: string;
13
+ relativePathToParentDocument?: string;
14
+ primaryBuffer?: Buffer;
15
+ fileType?: FileTypeResult;
16
+ primaryFileOutputPath?: string;
17
+ outputFileName?: string;
18
+ filePathToUseInMarkdown?: string;
19
+ };
20
+ export declare function initImageHandling(prefix: string, outputPath: string, incomingLocales: string[]): Promise<void>;
21
+ export declare const standardImageTransformer: IPlugin;
22
+ export declare function markdownToMDImageTransformer(block: ListBlockChildrenResponseResult, fullPathToDirectoryContainingMarkdown: string, relativePathToThisPage: string): Promise<string>;
23
+ export declare function parseImageBlock(image: any): ImageSet;
24
+ export declare function cleanupOldImages(): Promise<void>;
package/dist/images.js ADDED
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.cleanupOldImages = exports.parseImageBlock = exports.markdownToMDImageTransformer = exports.standardImageTransformer = exports.initImageHandling = void 0;
39
+ const fs = __importStar(require("fs-extra"));
40
+ const file_type_1 = __importDefault(require("file-type"));
41
+ const node_fetch_1 = __importDefault(require("node-fetch"));
42
+ const Path = __importStar(require("path"));
43
+ const MakeImagePersistencePlan_1 = require("./MakeImagePersistencePlan");
44
+ const log_1 = require("./log");
45
+ // We several things here:
46
+ // 1) copy images locally instead of leaving them in Notion
47
+ // 2) change the links to point here
48
+ // 3) read the caption and if there are localized images, get those too
49
+ // 4) prepare for localized documents, which need a copy of every image
50
+ let existingImagesNotSeenYetInPull = [];
51
+ let imageOutputPath = ""; // default to putting in the same directory as the document referring to it.
52
+ let imagePrefix = ""; // default to "./"
53
+ let locales;
54
+ function initImageHandling(prefix, outputPath, incomingLocales) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ // If they gave us a trailing slash, remove it because we add it back later.
57
+ // Note that it's up to the caller to have a *leading* slash or not.
58
+ imagePrefix = prefix.replace(/\/$/, "");
59
+ imageOutputPath = outputPath;
60
+ locales = incomingLocales;
61
+ // Currently we don't delete the image directory, because if an image
62
+ // changes, it gets a new id. This way can then prevent downloading
63
+ // and image after the 1st time. The downside is currently we don't
64
+ // have the smarts to remove unused images.
65
+ if (imageOutputPath) {
66
+ yield fs.mkdir(imageOutputPath, { recursive: true });
67
+ }
68
+ });
69
+ }
70
+ exports.initImageHandling = initImageHandling;
71
+ exports.standardImageTransformer = {
72
+ name: "DownloadImagesToRepo",
73
+ notionToMarkdownTransforms: [
74
+ {
75
+ type: "image",
76
+ // we have to set this one up for each page because we need to
77
+ // give it two extra parameters that are context for each page
78
+ getStringFromBlock: (context, block) => markdownToMDImageTransformer(block, context.directoryContainingMarkdown, context.relativeFilePathToFolderContainingPage),
79
+ },
80
+ ],
81
+ };
82
+ // This is a "custom transformer" function passed to notion-to-markdown
83
+ // eslint-disable-next-line @typescript-eslint/require-await
84
+ function markdownToMDImageTransformer(block, fullPathToDirectoryContainingMarkdown, relativePathToThisPage) {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ const image = block.image;
87
+ yield processImageBlock(image, fullPathToDirectoryContainingMarkdown, relativePathToThisPage);
88
+ // just concatenate the caption text parts together
89
+ const altText = image.caption
90
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
91
+ .map((item) => item.plain_text)
92
+ .join("");
93
+ const href = image.type === "external" ? image.external.url : image.file.url;
94
+ return `![${altText}](${href})`;
95
+ });
96
+ }
97
+ exports.markdownToMDImageTransformer = markdownToMDImageTransformer;
98
+ function processImageBlock(imageBlock, pathToParentDocument, relativePathToThisPage) {
99
+ return __awaiter(this, void 0, void 0, function* () {
100
+ (0, log_1.logDebug)("processImageBlock", JSON.stringify(imageBlock));
101
+ const imageSet = parseImageBlock(imageBlock);
102
+ imageSet.pathToParentDocument = pathToParentDocument;
103
+ imageSet.relativePathToParentDocument = relativePathToThisPage;
104
+ // enhance: it would much better if we could split the changes to markdown separately from actual reading/writing,
105
+ // so that this wasn't part of the markdown-creation loop. It's already almost there; we just need to
106
+ // save the imageSets somewhere and then do the actual reading/writing later.
107
+ yield readPrimaryImage(imageSet);
108
+ (0, MakeImagePersistencePlan_1.makeImagePersistencePlan)(imageSet, imageOutputPath, imagePrefix);
109
+ yield saveImage(imageSet);
110
+ // change the src to point to our copy of the image
111
+ if ("file" in imageBlock) {
112
+ imageBlock.file.url = imageSet.filePathToUseInMarkdown;
113
+ }
114
+ else {
115
+ imageBlock.external.url = imageSet.filePathToUseInMarkdown;
116
+ }
117
+ // put back the simplified caption, stripped of the meta information
118
+ if (imageSet.caption) {
119
+ imageBlock.caption = [
120
+ {
121
+ type: "text",
122
+ text: { content: imageSet.caption, link: null },
123
+ plain_text: imageSet.caption,
124
+ },
125
+ ];
126
+ }
127
+ else {
128
+ imageBlock.caption = [];
129
+ }
130
+ });
131
+ }
132
+ function readPrimaryImage(imageSet) {
133
+ return __awaiter(this, void 0, void 0, function* () {
134
+ const response = yield (0, node_fetch_1.default)(imageSet.primaryUrl);
135
+ const arrayBuffer = yield response.arrayBuffer();
136
+ imageSet.primaryBuffer = Buffer.from(arrayBuffer);
137
+ imageSet.fileType = yield file_type_1.default.fromBuffer(imageSet.primaryBuffer);
138
+ });
139
+ }
140
+ function saveImage(imageSet) {
141
+ return __awaiter(this, void 0, void 0, function* () {
142
+ writeImageIfNew(imageSet.primaryFileOutputPath, imageSet.primaryBuffer);
143
+ for (const localizedImage of imageSet.localizedUrls) {
144
+ let buffer = imageSet.primaryBuffer;
145
+ // if we have a urls for the localized screenshot, download it
146
+ if ((localizedImage === null || localizedImage === void 0 ? void 0 : localizedImage.url.length) > 0) {
147
+ (0, log_1.verbose)(`Retrieving ${localizedImage.iso632Code} version...`);
148
+ const response = yield (0, node_fetch_1.default)(localizedImage.url);
149
+ const arrayBuffer = yield response.arrayBuffer();
150
+ buffer = Buffer.from(arrayBuffer);
151
+ }
152
+ else {
153
+ (0, log_1.verbose)(`No localized image specified for ${localizedImage.iso632Code}, will use primary image.`);
154
+ // otherwise, we're going to fall back to outputting the primary image here
155
+ }
156
+ const directory = `./i18n/${localizedImage.iso632Code}/docusaurus-plugin-content-docs/current/${imageSet.relativePathToParentDocument}`;
157
+ writeImageIfNew((directory + "/" + imageSet.outputFileName).replaceAll("//", "/"), buffer);
158
+ }
159
+ });
160
+ }
161
+ function writeImageIfNew(path, buffer) {
162
+ imageWasSeen(path);
163
+ // Note: it's tempting to not spend time writing this out if we already have
164
+ // it from a previous run. But we don't really know it's the same. A) it
165
+ // could just have the same name, B) it could have been previously
166
+ // unlocalized and thus filled with a copy of the primary language image
167
+ // while and now is localized.
168
+ if (fs.pathExistsSync(path)) {
169
+ (0, log_1.verbose)("Replacing image " + path);
170
+ }
171
+ else {
172
+ (0, log_1.verbose)("Adding image " + path);
173
+ fs.mkdirsSync(Path.dirname(path));
174
+ }
175
+ fs.createWriteStream(path).write(buffer); // async but we're not waiting
176
+ }
177
+ function parseImageBlock(image) {
178
+ var _a;
179
+ if (!locales)
180
+ throw Error("Did you call initImageHandling()?");
181
+ const imageSet = {
182
+ primaryUrl: "",
183
+ caption: "",
184
+ localizedUrls: locales.map(l => ({ iso632Code: l, url: "" })),
185
+ };
186
+ if ("file" in image) {
187
+ imageSet.primaryUrl = image.file.url; // image saved on notion (actually AWS)
188
+ }
189
+ else {
190
+ imageSet.primaryUrl = image.external.url; // image still pointing somewhere else. I've see this happen when copying a Google Doc into Notion. Notion kep pointing at the google doc.
191
+ }
192
+ const mergedCaption = image.caption
193
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
194
+ .map((c) => c.plain_text)
195
+ .join("");
196
+ const lines = mergedCaption.split("\n");
197
+ // Example:
198
+ // Caption before images.\nfr https://i.imgur.com/pYmE7OJ.png\nES https://i.imgur.com/8paSZ0i.png\nCaption after images
199
+ lines.forEach(l => {
200
+ const match = /\s*(..)\s*(https:\/\/.*)/.exec(l);
201
+ if (match) {
202
+ imageSet.localizedUrls.push({
203
+ iso632Code: match[1].toLowerCase(),
204
+ url: match[2],
205
+ });
206
+ }
207
+ else {
208
+ // NB: carriage returns seem to mess up the markdown, so should be removed
209
+ imageSet.caption += l + " ";
210
+ }
211
+ });
212
+ // NB: currently notion-md puts the caption in Alt, which noone sees (unless the image isn't found)
213
+ // We could inject a custom element handler to emit a <figure> in order to show the caption.
214
+ imageSet.caption = (_a = imageSet.caption) === null || _a === void 0 ? void 0 : _a.trim();
215
+ //console.log(JSON.stringify(imageSet, null, 2));
216
+ return imageSet;
217
+ }
218
+ exports.parseImageBlock = parseImageBlock;
219
+ function imageWasSeen(path) {
220
+ existingImagesNotSeenYetInPull = existingImagesNotSeenYetInPull.filter(p => p !== path);
221
+ }
222
+ function cleanupOldImages() {
223
+ return __awaiter(this, void 0, void 0, function* () {
224
+ for (const p of existingImagesNotSeenYetInPull) {
225
+ (0, log_1.verbose)(`Removing old image: ${p}`);
226
+ yield fs.rm(p);
227
+ }
228
+ });
229
+ }
230
+ exports.cleanupOldImages = cleanupOldImages;
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ export * as Log from "./log";
3
+ export * from "./types";
4
+ export * from "./config/configuration";
5
+ export * from "./plugins/pluginTypes";
6
+ import type { IDocuNotionConfig } from "./config/configuration";
7
+ export type { IDocuNotionConfig };
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
27
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.Log = void 0;
31
+ const run_1 = require("./run");
32
+ (0, run_1.run)();
33
+ // for plugins to import
34
+ exports.Log = __importStar(require("./log"));
35
+ __exportStar(require("./types"), exports);
36
+ __exportStar(require("./config/configuration"), exports);
37
+ __exportStar(require("./plugins/pluginTypes"), exports);
package/dist/log.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ type levels = "info" | "verbose" | "debug";
2
+ export declare function setLogLevel(l: levels): void;
3
+ export declare function error(s: string): void;
4
+ export declare function warning(s: string): void;
5
+ export declare function info(s: string): void;
6
+ export declare function group(s: string): void;
7
+ export declare function endGroup(): void;
8
+ export declare function verbose(s: string): void;
9
+ export declare function logDebugFn(label: string, runIfLoggingDebug: () => string): void;
10
+ export declare function logDebug(label: string, info: string): void;
11
+ export {};
package/dist/log.js ADDED
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logDebug = exports.logDebugFn = exports.verbose = exports.endGroup = exports.group = exports.info = exports.warning = exports.error = exports.setLogLevel = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ chalk_1.default;
9
+ let logLevel;
10
+ function setLogLevel(l) {
11
+ logLevel = l;
12
+ }
13
+ exports.setLogLevel = setLogLevel;
14
+ function error(s) {
15
+ console.error(chalk_1.default.red(wrapForCI(s, "error")));
16
+ }
17
+ exports.error = error;
18
+ function warning(s) {
19
+ console.log(chalk_1.default.hex("#FFA500")(wrapForCI(s, "warning")));
20
+ }
21
+ exports.warning = warning;
22
+ function info(s) {
23
+ console.log(s);
24
+ }
25
+ exports.info = info;
26
+ // make sure to call endGroup(), eventually, after calling this
27
+ function group(s) {
28
+ console.log(chalk_1.default.blue(wrapForCI(s, "group")));
29
+ }
30
+ exports.group = group;
31
+ // github actions needs an ::endgroup:: to end a group
32
+ function endGroup() {
33
+ console.log(wrapForCI("", "endgroup"));
34
+ }
35
+ exports.endGroup = endGroup;
36
+ function verbose(s) {
37
+ if (logLevel === "verbose" || logLevel === "debug")
38
+ console.log(chalk_1.default.green(s));
39
+ }
40
+ exports.verbose = verbose;
41
+ // use this one if the debug info would take time to construct,
42
+ // so you want to skip doing it if not in debug mode
43
+ function logDebugFn(label, runIfLoggingDebug) {
44
+ if (logLevel === "debug") {
45
+ logDebug(label, runIfLoggingDebug());
46
+ }
47
+ }
48
+ exports.logDebugFn = logDebugFn;
49
+ function logDebug(label, info) {
50
+ if (logLevel === "debug") {
51
+ console.log(chalk_1.default.dim(wrapForCI(`[${label}]`, "debug")));
52
+ console.log(chalk_1.default.dim(wrapForCI(info, "debug")));
53
+ }
54
+ }
55
+ exports.logDebug = logDebug;
56
+ function wrapForCI(s, githubActionsPrefix) {
57
+ // for now, we only know about github actions, but submit a PR if you want to add more
58
+ return process.env["GITHUB_ACTIONS"] === "true"
59
+ ? `::${githubActionsPrefix}::${s}`
60
+ : s;
61
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const MakeImagePersistencePlan_1 = require("./MakeImagePersistencePlan");
4
+ test("primary file with explicit file output path and prefix", () => {
5
+ const imageSet = {
6
+ primaryUrl: "https://s3.us-west-2.amazonaws.com/primaryImage?Blah=foo",
7
+ localizedUrls: [],
8
+ pathToParentDocument: "/pathToParentSomewhere/",
9
+ fileType: { ext: "png", mime: "image/png" },
10
+ };
11
+ (0, MakeImagePersistencePlan_1.makeImagePersistencePlan)(imageSet, "./static/notion_imgs", "/notion_imgs");
12
+ expect(imageSet.outputFileName).toBe("463556435.png");
13
+ expect(imageSet.primaryFileOutputPath).toBe("static/notion_imgs/463556435.png");
14
+ expect(imageSet.filePathToUseInMarkdown).toBe("/notion_imgs/463556435.png");
15
+ });
16
+ test("primary file with defaults for image output path and prefix", () => {
17
+ const imageSet = {
18
+ primaryUrl: "https://s3.us-west-2.amazonaws.com/primaryImage?Blah=foo",
19
+ localizedUrls: [],
20
+ pathToParentDocument: "/pathToParentSomewhere/",
21
+ fileType: { ext: "png", mime: "image/png" },
22
+ };
23
+ (0, MakeImagePersistencePlan_1.makeImagePersistencePlan)(imageSet, "", "");
24
+ expect(imageSet.outputFileName).toBe("463556435.png");
25
+ // the default behavior is to put the image next to the markdown file
26
+ expect(imageSet.primaryFileOutputPath).toBe("/pathToParentSomewhere/463556435.png");
27
+ expect(imageSet.filePathToUseInMarkdown).toBe("./463556435.png");
28
+ });
29
+ // In order to make image fallback work with other languages, we have to have
30
+ // a file for each image, in each Docusaurus language directory. This is true
31
+ // whether we have a localized version of the image or not.
32
+ // The imageSet is initially populated with placeholders for each language.
33
+ // This test ensures that these placeholders are replaced with actual urls
34
+ // when localized versions of the image are listed.
35
+ // TODO write this test
@@ -0,0 +1,58 @@
1
+ /* Note, I haven't figure out how a Docusaurus app can actually include this, yet.
2
+ So currently this has to be duplicated by the client.
3
+ */
4
+
5
+ /* Copied from
6
+ https://github1s.com/NotionX/react-notion-x/blob/master/packages/react-notion-x/src/styles.css#L934
7
+ and
8
+ https://github1s.com/NotionX/react-notion-x/blob/master/packages/react-notion-x/src/styles.css#L1063
9
+ */
10
+ .notion-column {
11
+ display: flex;
12
+ flex-direction: column;
13
+ padding-top: 12px;
14
+ padding-bottom: 12px;
15
+ }
16
+
17
+ .notion-column > *:first-child {
18
+ margin-top: 0;
19
+ margin-left: 0;
20
+ margin-right: 0;
21
+ }
22
+
23
+ .notion-column > *:last-child {
24
+ margin-left: 0;
25
+ margin-right: 0;
26
+ margin-bottom: 0;
27
+ }
28
+
29
+ .notion-row {
30
+ display: flex;
31
+ overflow: hidden;
32
+ width: 100%;
33
+ max-width: 100%;
34
+ }
35
+
36
+ @media (max-width: 640px) {
37
+ .notion-row {
38
+ flex-direction: column;
39
+ }
40
+
41
+ .notion-row .notion-column {
42
+ width: 100% !important;
43
+ }
44
+
45
+ .notion-row .notion-spacer {
46
+ display: none;
47
+ }
48
+ }
49
+
50
+ .notion-spacer {
51
+ /* This matches the value in ColumnTransformer.ts */
52
+ width: calc(min(32px, 4vw));
53
+ }
54
+
55
+ .notion-spacer:last-child {
56
+ display: none;
57
+ }
58
+ /* End copied from NotionX */
@@ -0,0 +1,24 @@
1
+ import { IPlugin } from "./pluginTypes";
2
+ type TextRequest = string;
3
+ type Annotations = {
4
+ bold: boolean;
5
+ italic: boolean;
6
+ strikethrough: boolean;
7
+ underline: boolean;
8
+ code: boolean;
9
+ color: "default" | "gray" | "brown" | "orange" | "yellow" | "green" | "blue" | "purple" | "pink" | "red" | "gray_background" | "brown_background" | "orange_background" | "yellow_background" | "green_background" | "blue_background" | "purple_background" | "pink_background" | "red_background";
10
+ };
11
+ export type Text = {
12
+ type: "text";
13
+ text: {
14
+ content: string;
15
+ link: {
16
+ url: TextRequest;
17
+ } | null;
18
+ };
19
+ annotations: Annotations;
20
+ plain_text: string;
21
+ href: string | null;
22
+ };
23
+ export declare const standardCalloutTransformer: IPlugin;
24
+ export {};