@sillsdev/docu-notion 0.12.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.
Files changed (74) 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 +44 -0
  14. package/dist/NotionPage.js +194 -0
  15. package/dist/config/configuration.d.ts +5 -0
  16. package/dist/config/configuration.js +86 -0
  17. package/dist/config/default.docunotion.config.d.ts +3 -0
  18. package/dist/config/default.docunotion.config.js +37 -0
  19. package/dist/images.d.ts +24 -0
  20. package/dist/images.js +230 -0
  21. package/dist/index.d.ts +7 -0
  22. package/dist/index.js +37 -0
  23. package/dist/log.d.ts +11 -0
  24. package/dist/log.js +61 -0
  25. package/dist/makeImagePersistencePlan.spec.d.ts +1 -0
  26. package/dist/makeImagePersistencePlan.spec.js +35 -0
  27. package/dist/notion-styles.css +58 -0
  28. package/dist/plugins/CalloutTransformer.d.ts +24 -0
  29. package/dist/plugins/CalloutTransformer.js +88 -0
  30. package/dist/plugins/CalloutTransformer.spec.d.ts +1 -0
  31. package/dist/plugins/CalloutTransformer.spec.js +199 -0
  32. package/dist/plugins/ColumnListTransformer.d.ts +2 -0
  33. package/dist/plugins/ColumnListTransformer.js +34 -0
  34. package/dist/plugins/ColumnTransformer.d.ts +2 -0
  35. package/dist/plugins/ColumnTransformer.js +67 -0
  36. package/dist/plugins/EscapeHtmlBlockModifier.d.ts +2 -0
  37. package/dist/plugins/EscapeHtmlBlockModifier.js +41 -0
  38. package/dist/plugins/EscapeHtmlBlockModifier.spec.d.ts +1 -0
  39. package/dist/plugins/EscapeHtmlBlockModifier.spec.js +130 -0
  40. package/dist/plugins/HeadingTranformer.spec.d.ts +1 -0
  41. package/dist/plugins/HeadingTranformer.spec.js +46 -0
  42. package/dist/plugins/HeadingTransformer.d.ts +2 -0
  43. package/dist/plugins/HeadingTransformer.js +63 -0
  44. package/dist/plugins/NumberedListTransformer.d.ts +2 -0
  45. package/dist/plugins/NumberedListTransformer.js +55 -0
  46. package/dist/plugins/NumberedListTransformer.spec.d.ts +1 -0
  47. package/dist/plugins/NumberedListTransformer.spec.js +86 -0
  48. package/dist/plugins/TableTransformer.d.ts +5 -0
  49. package/dist/plugins/TableTransformer.js +70 -0
  50. package/dist/plugins/embedTweaks.d.ts +5 -0
  51. package/dist/plugins/embedTweaks.js +46 -0
  52. package/dist/plugins/embedTweaks.spec.d.ts +1 -0
  53. package/dist/plugins/embedTweaks.spec.js +230 -0
  54. package/dist/plugins/externalLinks.d.ts +2 -0
  55. package/dist/plugins/externalLinks.js +26 -0
  56. package/dist/plugins/externalLinks.spec.d.ts +1 -0
  57. package/dist/plugins/externalLinks.spec.js +132 -0
  58. package/dist/plugins/internalLinks.d.ts +6 -0
  59. package/dist/plugins/internalLinks.js +78 -0
  60. package/dist/plugins/internalLinks.spec.d.ts +1 -0
  61. package/dist/plugins/internalLinks.spec.js +442 -0
  62. package/dist/plugins/pluginTestRun.d.ts +10 -0
  63. package/dist/plugins/pluginTestRun.js +248 -0
  64. package/dist/plugins/pluginTypes.d.ts +42 -0
  65. package/dist/plugins/pluginTypes.js +2 -0
  66. package/dist/pull.d.ts +12 -0
  67. package/dist/pull.js +253 -0
  68. package/dist/run.d.ts +1 -0
  69. package/dist/run.js +35 -0
  70. package/dist/transform.d.ts +6 -0
  71. package/dist/transform.js +195 -0
  72. package/dist/types.d.ts +8 -0
  73. package/dist/types.js +2 -0
  74. package/package.json +96 -0
@@ -0,0 +1,233 @@
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 images_1 = require("./images");
13
+ const kPrimaryImageUrl = "https://s3.us-west-2.amazonaws.com/primaryImage.png?Blah=foo";
14
+ /* didn't work?
15
+ beforeAll(async () => {
16
+ console.log("before");
17
+ await initImageHandling("", "", []);
18
+ console.log("azfter");
19
+ });
20
+ */
21
+ /* eslint-disable @typescript-eslint/require-await */
22
+ test("finds primary image url", () => __awaiter(void 0, void 0, void 0, function* () {
23
+ yield (0, images_1.initImageHandling)("", "", []);
24
+ const img = (0, images_1.parseImageBlock)(kImageBlockWithTwoLocalizedImages.image);
25
+ expect(img.primaryUrl).toBe(kPrimaryImageUrl);
26
+ }));
27
+ test("primary caption content after image links are removed", () => __awaiter(void 0, void 0, void 0, function* () {
28
+ yield (0, images_1.initImageHandling)("", "", []);
29
+ const img = (0, images_1.parseImageBlock)(kImageBlockWithTwoLocalizedImagesWrappedWithActualCaptionText.image);
30
+ // carriage returns seem to mess up the markdown, so should be removed
31
+ expect(img.caption).toBe("Caption before images. Caption after images.");
32
+ }));
33
+ test("gets localized image links", () => __awaiter(void 0, void 0, void 0, function* () {
34
+ yield (0, images_1.initImageHandling)("", "", []);
35
+ const img = (0, images_1.parseImageBlock)(kImageBlockWithTwoLocalizedImagesWrappedWithActualCaptionText.image);
36
+ expect(img.localizedUrls.length).toBe(2);
37
+ expect(img.localizedUrls[0].iso632Code).toBe("fr");
38
+ expect(img.localizedUrls[1].iso632Code).toBe("es");
39
+ expect(img.localizedUrls[0].url).toBe("https://i.imgur.com/pYmE7OJ.png");
40
+ expect(img.localizedUrls[1].url).toBe("https://i.imgur.com/8paSZ0i.png");
41
+ }));
42
+ const kImageBlockWithTwoLocalizedImagesWrappedWithActualCaptionText = {
43
+ object: "block",
44
+ id: "20b821b4-7c5b-41dc-8e30-92c23c125580",
45
+ parent: { type: "page_id", page_id: "9dd05134-0401-47f6-b159-1e6b76b9aad3" },
46
+ created_time: "2022-07-25T23:05:00.000Z",
47
+ last_edited_time: "2022-07-26T15:31:00.000Z",
48
+ created_by: { object: "user", id: "11fb7f16-0560-4aee-ab88-ed75a850cfc4" },
49
+ last_edited_by: {
50
+ object: "user",
51
+ id: "11fb7f16-0560-4aee-ab88-ed75a850cfc4",
52
+ },
53
+ has_children: false,
54
+ archived: false,
55
+ type: "image",
56
+ image: {
57
+ caption: [
58
+ {
59
+ type: "text",
60
+ text: { content: "Caption before images. fr-", link: null },
61
+ annotations: {
62
+ bold: false,
63
+ italic: false,
64
+ strikethrough: false,
65
+ underline: false,
66
+ code: false,
67
+ color: "default",
68
+ },
69
+ plain_text: "Caption before images.\nfr ",
70
+ href: null,
71
+ },
72
+ {
73
+ type: "text",
74
+ text: {
75
+ content: "https://i.imgur.com/pYmE7OJ.png",
76
+ link: { url: "https://i.imgur.com/pYmE7OJ.png" },
77
+ },
78
+ annotations: {
79
+ bold: false,
80
+ italic: false,
81
+ strikethrough: false,
82
+ underline: false,
83
+ code: false,
84
+ color: "default",
85
+ },
86
+ plain_text: "https://i.imgur.com/pYmE7OJ.png",
87
+ href: "https://i.imgur.com/pYmE7OJ.png",
88
+ },
89
+ {
90
+ type: "text",
91
+ text: { content: " es-", link: null },
92
+ annotations: {
93
+ bold: false,
94
+ italic: false,
95
+ strikethrough: false,
96
+ underline: false,
97
+ code: false,
98
+ color: "default",
99
+ },
100
+ plain_text: "\nES ",
101
+ href: null,
102
+ },
103
+ {
104
+ type: "text",
105
+ text: {
106
+ content: "https://i.imgur.com/8paSZ0i.png",
107
+ link: { url: "https://i.imgur.com/8paSZ0i.png" },
108
+ },
109
+ annotations: {
110
+ bold: false,
111
+ italic: false,
112
+ strikethrough: false,
113
+ underline: false,
114
+ code: false,
115
+ color: "default",
116
+ },
117
+ plain_text: "https://i.imgur.com/8paSZ0i.png",
118
+ href: "https://i.imgur.com/8paSZ0i.png",
119
+ },
120
+ {
121
+ type: "text",
122
+ text: { content: "\nCaption after images", link: null },
123
+ annotations: {
124
+ bold: false,
125
+ italic: false,
126
+ strikethrough: false,
127
+ underline: false,
128
+ code: false,
129
+ color: "default",
130
+ },
131
+ plain_text: "\nCaption after images.",
132
+ href: null,
133
+ },
134
+ ],
135
+ type: "file",
136
+ file: {
137
+ url: kPrimaryImageUrl,
138
+ expiry_time: "2022-07-26T16:35:44.029Z",
139
+ },
140
+ },
141
+ };
142
+ const kImageBlockWithTwoLocalizedImages = {
143
+ object: "block",
144
+ id: "20b821b4-7c5b-41dc-8e30-92c23c125580",
145
+ parent: {
146
+ type: "page_id",
147
+ page_id: "9dd05134-0401-47f6-b159-1e6b76b9aad3",
148
+ },
149
+ created_time: "2022-07-25T23:05:00.000Z",
150
+ last_edited_time: "2022-07-25T23:07:00.000Z",
151
+ created_by: {
152
+ object: "user",
153
+ id: "11fb7f16-0560-4aee-ab88-ed75a850cfc4",
154
+ },
155
+ last_edited_by: {
156
+ object: "user",
157
+ id: "11fb7f16-0560-4aee-ab88-ed75a850cfc4",
158
+ },
159
+ has_children: false,
160
+ archived: false,
161
+ type: "image",
162
+ image: {
163
+ caption: [
164
+ {
165
+ type: "text",
166
+ text: { content: "fr-", link: null },
167
+ annotations: {
168
+ bold: false,
169
+ italic: false,
170
+ strikethrough: false,
171
+ underline: false,
172
+ code: false,
173
+ color: "default",
174
+ },
175
+ plain_text: "fr-",
176
+ href: null,
177
+ },
178
+ {
179
+ type: "text",
180
+ text: {
181
+ content: "https://i.imgur.com/pYmE7OJ.png",
182
+ link: { url: "https://i.imgur.com/pYmE7OJ.png" },
183
+ },
184
+ annotations: {
185
+ bold: false,
186
+ italic: false,
187
+ strikethrough: false,
188
+ underline: false,
189
+ code: false,
190
+ color: "default",
191
+ },
192
+ plain_text: "https://i.imgur.com/pYmE7OJ.png",
193
+ href: "https://i.imgur.com/pYmE7OJ.png",
194
+ },
195
+ {
196
+ type: "text",
197
+ text: { content: " es-", link: null },
198
+ annotations: {
199
+ bold: false,
200
+ italic: false,
201
+ strikethrough: false,
202
+ underline: false,
203
+ code: false,
204
+ color: "default",
205
+ },
206
+ plain_text: " es-",
207
+ href: null,
208
+ },
209
+ {
210
+ type: "text",
211
+ text: {
212
+ content: "https://i.imgur.com/8paSZ0i.png",
213
+ link: { url: "https://i.imgur.com/8paSZ0i.png" },
214
+ },
215
+ annotations: {
216
+ bold: false,
217
+ italic: false,
218
+ strikethrough: false,
219
+ underline: false,
220
+ code: false,
221
+ color: "default",
222
+ },
223
+ plain_text: "https://i.imgur.com/8paSZ0i.png",
224
+ href: "https://i.imgur.com/8paSZ0i.png",
225
+ },
226
+ ],
227
+ type: "file",
228
+ file: {
229
+ url: kPrimaryImageUrl,
230
+ expiry_time: "2022-07-26T00:19:09.096Z",
231
+ },
232
+ },
233
+ };
@@ -0,0 +1,44 @@
1
+ import { GetPageResponse } from "@notionhq/client/build/src/api-endpoints";
2
+ import { ListBlockChildrenResponseResults } from "notion-to-md/build/types";
3
+ export declare enum PageType {
4
+ DatabasePage = 0,
5
+ Simple = 1
6
+ }
7
+ export declare class NotionPage {
8
+ metadata: GetPageResponse;
9
+ pageId: string;
10
+ order: number;
11
+ layoutContext: string;
12
+ foundDirectlyInOutline: boolean;
13
+ constructor(args: {
14
+ layoutContext: string;
15
+ pageId: string;
16
+ order: number;
17
+ metadata: GetPageResponse;
18
+ foundDirectlyInOutline: boolean;
19
+ });
20
+ matchesLinkId(id: string): boolean;
21
+ get type(): PageType;
22
+ get nameOrTitle(): string;
23
+ nameForFile(): string;
24
+ private get title();
25
+ private get name();
26
+ private explicitSlug;
27
+ get slug(): string;
28
+ get hasExplicitSlug(): boolean;
29
+ get keywords(): string | undefined;
30
+ get status(): string | undefined;
31
+ getPlainTextProperty(property: string, defaultIfEmpty: string): string;
32
+ getSelectProperty(property: string): string | undefined;
33
+ getContentInfo(children: ListBlockChildrenResponseResults): Promise<{
34
+ childPageIdsAndOrder: {
35
+ id: string;
36
+ order: number;
37
+ }[];
38
+ linksPageIdsAndOrder: {
39
+ id: string;
40
+ order: number;
41
+ }[];
42
+ hasParagraphs: boolean;
43
+ }>;
44
+ }
@@ -0,0 +1,194 @@
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
+ exports.NotionPage = exports.PageType = void 0;
13
+ const internalLinks_1 = require("./plugins/internalLinks");
14
+ // Notion has 2 kinds of pages: a normal one which is just content, and what I'm calling a "database page", which has whatever properties you put on it.
15
+ // docu-notion supports the later via links from outline pages. That is, you put the database pages in a database, then separately, in the outline, you
16
+ // create pages for each node of the outline and then add links from those to the database pages. In this way, we get the benefits of database
17
+ // pages (metadata, workflow, etc) and also normal pages (order, position in the outline).
18
+ var PageType;
19
+ (function (PageType) {
20
+ PageType[PageType["DatabasePage"] = 0] = "DatabasePage";
21
+ PageType[PageType["Simple"] = 1] = "Simple";
22
+ })(PageType = exports.PageType || (exports.PageType = {}));
23
+ class NotionPage {
24
+ constructor(args) {
25
+ this.layoutContext = args.layoutContext;
26
+ this.pageId = args.pageId;
27
+ this.order = args.order;
28
+ this.metadata = args.metadata;
29
+ this.foundDirectlyInOutline = args.foundDirectlyInOutline;
30
+ // review: this is expensive to learn as it takes another api call... I
31
+ // think? We can tell if it's a database because it has a "Name" instead of a
32
+ // "tile" and "parent": "type": "database_id". But do we need to differentiate
33
+ //this.type = PageType.Unknown;
34
+ }
35
+ matchesLinkId(id) {
36
+ const { baseLinkId } = (0, internalLinks_1.parseLinkId)(id);
37
+ const match = baseLinkId === this.pageId || // from a link_to_page.pageId, which still has the dashes
38
+ baseLinkId === this.pageId.replaceAll("-", ""); // from inline links, which are lacking the dashes
39
+ // logDebug(
40
+ // `matchedLinkId`,
41
+ // `comparing pageId:${this.pageId} to id ${id} --> ${match.toString()}`
42
+ // );
43
+ return match;
44
+ }
45
+ get type() {
46
+ /*
47
+ {
48
+ "object": "page",
49
+ "parent": {
50
+ "type": "page_id",
51
+ or
52
+ "type": "database_id",
53
+ ...
54
+ },
55
+ */
56
+ return this.metadata.parent.type === "database_id"
57
+ ? PageType.DatabasePage
58
+ : PageType.Simple;
59
+ }
60
+ // In Notion, pages from the Database have names and simple pages have titles.
61
+ get nameOrTitle() {
62
+ return this.type === PageType.DatabasePage ? this.name : this.title;
63
+ }
64
+ nameForFile() {
65
+ var _a;
66
+ // In Notion, pages from the Database have names and simple pages have titles.
67
+ return this.type === PageType.Simple
68
+ ? this.title
69
+ : // if it's a Database page, then we'll use the slug unless there is none, then we'd rather have the
70
+ // page name than an ugly id for the file name
71
+ ((_a = this.explicitSlug()) === null || _a === void 0 ? void 0 : _a.replace(/^\//, "")) || this.name;
72
+ }
73
+ // TODO: let's go farther in hiding this separate title vs name stuff. This seems like an implementation detail on the Notion side.
74
+ // In Notion, pages from the Outline have "title"'s.
75
+ get title() {
76
+ return this.getPlainTextProperty("title", "title missing");
77
+ }
78
+ // In Notion, pages from the Database have "Name"s.
79
+ get name() {
80
+ return this.getPlainTextProperty("Name", "name missing");
81
+ }
82
+ explicitSlug() {
83
+ const explicitSlug = this.getPlainTextProperty("Slug", "");
84
+ if (explicitSlug) {
85
+ if (explicitSlug === "/")
86
+ return explicitSlug; // the root page
87
+ else
88
+ return ("/" +
89
+ encodeURIComponent(explicitSlug
90
+ .replace(/^\//, "")
91
+ // If for some reason someone types in a slug with special characters,
92
+ //we really don't want to see ugly entities in the URL, so first
93
+ // we replace a bunch of likely suspects with dashes. This will not
94
+ // adequately handle the case where there is one pag with slug:"foo-bar"
95
+ // and another with "foo?bar". Both will come out "foo-bar"
96
+ .replaceAll(" ", "-")
97
+ .replaceAll("?", "-")
98
+ .replaceAll("/", "-")
99
+ .replaceAll("#", "-")
100
+ .replaceAll("&", "-")
101
+ .replaceAll("%", "-")
102
+ // remove consecutive dashes
103
+ .replaceAll("--", "-")));
104
+ return undefined; // this page has no slug property
105
+ }
106
+ }
107
+ get slug() {
108
+ var _a;
109
+ return (_a = this.explicitSlug()) !== null && _a !== void 0 ? _a : "/" + this.pageId;
110
+ }
111
+ get hasExplicitSlug() {
112
+ return this.explicitSlug() !== undefined;
113
+ }
114
+ get keywords() {
115
+ return this.getPlainTextProperty("Keywords", "");
116
+ }
117
+ get status() {
118
+ return this.getSelectProperty("Status");
119
+ }
120
+ getPlainTextProperty(property, defaultIfEmpty) {
121
+ /* Notion strings look like this
122
+ "properties": {
123
+ "slug": {
124
+ "type": "rich_text",
125
+ ...
126
+ "rich_text": [
127
+ {
128
+ ...
129
+ "plain_text": "/",
130
+ }
131
+ ]
132
+ },
133
+ "Name": {
134
+ "type": "title",
135
+ "title": [
136
+ {
137
+ ...
138
+ "plain_text": "Intro",
139
+ }
140
+ ]
141
+ */
142
+ var _a;
143
+ //console.log("metadata:\n" + JSON.stringify(this.metadata, null, 2));
144
+ const p = (_a = this.metadata.properties) === null || _a === void 0 ? void 0 : _a[property];
145
+ //console.log(`prop ${property} = ${JSON.stringify(p)}`);
146
+ if (!p)
147
+ return defaultIfEmpty;
148
+ const textArray = p[p.type];
149
+ //console.log("textarray:" + JSON.stringify(textArray, null, 2));
150
+ return textArray && textArray.length
151
+ ? textArray[0].plain_text
152
+ : defaultIfEmpty;
153
+ }
154
+ getSelectProperty(property) {
155
+ /* Notion select values look like this
156
+ "properties": {
157
+ "Status": {
158
+ "id": "oB~%3D",
159
+ "type": "select",
160
+ "select": {
161
+ "id": "1",
162
+ "name": "Ready For Review",
163
+ "color": "red"
164
+ }
165
+ },
166
+ */
167
+ var _a, _b;
168
+ const p = (_a = this.metadata.properties) === null || _a === void 0 ? void 0 : _a[property];
169
+ if (!p) {
170
+ throw new Error(`missing ${property} in ${JSON.stringify(this.metadata, null, 2)}`);
171
+ return undefined;
172
+ }
173
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
174
+ return ((_b = p.select) === null || _b === void 0 ? void 0 : _b.name) || undefined;
175
+ }
176
+ getContentInfo(children) {
177
+ return __awaiter(this, void 0, void 0, function* () {
178
+ for (let i = 0; i < children.length; i++) {
179
+ children[i].order = i;
180
+ }
181
+ return {
182
+ childPageIdsAndOrder: children
183
+ .filter((b) => b.type === "child_page")
184
+ .map((b) => ({ id: b.id, order: b.order })),
185
+ linksPageIdsAndOrder: children
186
+ .filter((b) => b.type === "link_to_page")
187
+ .map((b) => ({ id: b.link_to_page.page_id, order: b.order })),
188
+ hasParagraphs: children.some(b => b.type === "paragraph" &&
189
+ b.paragraph.rich_text.length > 0),
190
+ };
191
+ });
192
+ }
193
+ }
194
+ exports.NotionPage = NotionPage;
@@ -0,0 +1,5 @@
1
+ import { IPlugin } from "../plugins/pluginTypes";
2
+ export type IDocuNotionConfig = {
3
+ plugins: IPlugin[];
4
+ };
5
+ export declare function loadConfigAsync(): Promise<IDocuNotionConfig>;
@@ -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>;