@getguru/import-engine 0.1.1 → 0.1.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.
- package/docx-import-cli.js +127 -6
- package/package.json +1 -1
package/docx-import-cli.js
CHANGED
|
@@ -114320,7 +114320,7 @@ var import_jszip5 = __toESM(require_lib3());
|
|
|
114320
114320
|
var import_url_join6 = __toESM(require_url_join());
|
|
114321
114321
|
|
|
114322
114322
|
// packages/import-engine/package.json
|
|
114323
|
-
var version = "0.1.
|
|
114323
|
+
var version = "0.1.2";
|
|
114324
114324
|
|
|
114325
114325
|
// src/docx-import/detectors.js
|
|
114326
114326
|
function isGoogleSitesDoc(div) {
|
|
@@ -114344,7 +114344,7 @@ var showError;
|
|
|
114344
114344
|
var updateLoader;
|
|
114345
114345
|
var showReport;
|
|
114346
114346
|
var docLinkIndex = /* @__PURE__ */ new Map();
|
|
114347
|
-
var toolVersion = true ? `${version}+${"
|
|
114347
|
+
var toolVersion = true ? `${version}+${"4d61d22"}` : version;
|
|
114348
114348
|
var pendingUpload = null;
|
|
114349
114349
|
function confirmPendingUpload() {
|
|
114350
114350
|
const upload = pendingUpload;
|
|
@@ -115155,6 +115155,91 @@ function setSubtract(a, b) {
|
|
|
115155
115155
|
return !b.includes(value);
|
|
115156
115156
|
});
|
|
115157
115157
|
}
|
|
115158
|
+
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
115159
|
+
var EXTERNAL_MANIFEST_MAX_BYTES = 1048576;
|
|
115160
|
+
var EXTERNAL_MAX_ENTRIES = 500;
|
|
115161
|
+
var EXTERNAL_NAME_RE = /^[\p{L}\p{N}._-]{1,128}$/u;
|
|
115162
|
+
var EXTERNAL_REFUSED = "the server won't fetch this image; the card will link to the original URL";
|
|
115163
|
+
function checkExternalImages(zip, task, report) {
|
|
115164
|
+
var state = { enabled: false, names: /* @__PURE__ */ new Set(), referenced: [] };
|
|
115165
|
+
report.externalImages = state;
|
|
115166
|
+
var collectionFile = zip.file("collection.yaml");
|
|
115167
|
+
var manifestFile = zip.file("resources/external.json");
|
|
115168
|
+
function readCollection() {
|
|
115169
|
+
if (!collectionFile) {
|
|
115170
|
+
return Promise.resolve();
|
|
115171
|
+
}
|
|
115172
|
+
return collectionFile.async("string").then(function(yamlString) {
|
|
115173
|
+
try {
|
|
115174
|
+
var collection = yaml.load(yamlString);
|
|
115175
|
+
state.enabled = !!collection && typeof collection == "object" && collection.FetchExternalImages === true;
|
|
115176
|
+
} catch (e) {
|
|
115177
|
+
}
|
|
115178
|
+
}, function() {
|
|
115179
|
+
});
|
|
115180
|
+
}
|
|
115181
|
+
function readManifest() {
|
|
115182
|
+
if (!manifestFile) {
|
|
115183
|
+
return Promise.resolve();
|
|
115184
|
+
}
|
|
115185
|
+
return manifestFile.async("string").then(function(text2) {
|
|
115186
|
+
var size2 = manifestFile._data && manifestFile._data.uncompressedSize || text2.length;
|
|
115187
|
+
var dropped = "The server will ignore the whole manifest, so no external images will be fetched";
|
|
115188
|
+
if (size2 > EXTERNAL_MANIFEST_MAX_BYTES) {
|
|
115189
|
+
report.error(`resources/external.json is larger than ${EXTERNAL_MANIFEST_MAX_BYTES} bytes. ${dropped}.`);
|
|
115190
|
+
return;
|
|
115191
|
+
}
|
|
115192
|
+
var manifest;
|
|
115193
|
+
try {
|
|
115194
|
+
manifest = JSON.parse(text2);
|
|
115195
|
+
} catch (e) {
|
|
115196
|
+
report.error(`resources/external.json is not valid JSON (${e.message}). ${dropped}.`);
|
|
115197
|
+
return;
|
|
115198
|
+
}
|
|
115199
|
+
if (!manifest || typeof manifest != "object" || Array.isArray(manifest)) {
|
|
115200
|
+
report.error(`resources/external.json must be a JSON object mapping file names to URLs. ${dropped}.`);
|
|
115201
|
+
return;
|
|
115202
|
+
}
|
|
115203
|
+
var keys2 = Object.keys(manifest);
|
|
115204
|
+
if (keys2.some(function(key) {
|
|
115205
|
+
return typeof manifest[key] != "string";
|
|
115206
|
+
})) {
|
|
115207
|
+
report.error(`resources/external.json must map every file name to a URL string. ${dropped}.`);
|
|
115208
|
+
return;
|
|
115209
|
+
}
|
|
115210
|
+
keys2.forEach(function(name, index) {
|
|
115211
|
+
state.names.add(name);
|
|
115212
|
+
var url = manifest[name];
|
|
115213
|
+
var label = `resources/external.json entry "${escapeQuotes(name)}"`;
|
|
115214
|
+
if (index >= EXTERNAL_MAX_ENTRIES) {
|
|
115215
|
+
report.warn(`${label} is past the first ${EXTERNAL_MAX_ENTRIES} entries: ${EXTERNAL_REFUSED}.`);
|
|
115216
|
+
} else if (!EXTERNAL_NAME_RE.test(name) || name.includes("..")) {
|
|
115217
|
+
report.warn(`${label} has an invalid file name: ${EXTERNAL_REFUSED}.`);
|
|
115218
|
+
} else if (url.trim() === "") {
|
|
115219
|
+
report.warn(`${label} has a blank URL: ${EXTERNAL_REFUSED}.`);
|
|
115220
|
+
} else if (!/^https:\/\//i.test(url.trim())) {
|
|
115221
|
+
report.warn(`${label} is not an https URL: ${EXTERNAL_REFUSED}.`);
|
|
115222
|
+
}
|
|
115223
|
+
if (zip.file("resources/" + name)) {
|
|
115224
|
+
report.info(`${label} also exists as resources/${escapeQuotes(name)} in the zip, so the server skips the fetch.`);
|
|
115225
|
+
}
|
|
115226
|
+
});
|
|
115227
|
+
}, function() {
|
|
115228
|
+
});
|
|
115229
|
+
}
|
|
115230
|
+
return readCollection().then(readManifest).then(function() {
|
|
115231
|
+
if (manifestFile && !state.enabled) {
|
|
115232
|
+
report.warn(`resources/external.json is included but collection.yaml doesn't set FetchExternalImages: true, so the server ignores it.`);
|
|
115233
|
+
}
|
|
115234
|
+
if (state.enabled && !manifestFile) {
|
|
115235
|
+
report.warn(`collection.yaml sets FetchExternalImages: true but the zip has no resources/external.json.`);
|
|
115236
|
+
}
|
|
115237
|
+
if (state.enabled) {
|
|
115238
|
+
report.syncError(`If this is a sync, FetchExternalImages is ignored (external images are only fetched on imports).`);
|
|
115239
|
+
}
|
|
115240
|
+
report.next();
|
|
115241
|
+
});
|
|
115242
|
+
}
|
|
115158
115243
|
function escapeQuotes(value) {
|
|
115159
115244
|
value = value || "";
|
|
115160
115245
|
return value.replace(/"/g, `\\"`);
|
|
@@ -115189,11 +115274,18 @@ function checkCardYaml(zip, task, report) {
|
|
|
115189
115274
|
return zip.file(task.filename).async("string").then(function(yamlString) {
|
|
115190
115275
|
try {
|
|
115191
115276
|
var card = yaml.load(yamlString);
|
|
115192
|
-
var possibleKeys = ["ExternalId", "ExternalUrl", "Title", "Tags", "externalLastUpdated"];
|
|
115277
|
+
var possibleKeys = ["ExternalId", "ExternalUrl", "Title", "Tags", "externalLastUpdated", "ID"];
|
|
115193
115278
|
var otherKeys = setSubtract(Object.keys(card), possibleKeys);
|
|
115194
115279
|
otherKeys.forEach(function(key) {
|
|
115195
115280
|
report.warn(`Unexpected property "${key}" in the card's yaml.`);
|
|
115196
115281
|
});
|
|
115282
|
+
if (card.ID !== void 0 && card.ID !== null) {
|
|
115283
|
+
if (typeof card.ID != "string" || !UUID_RE2.test(card.ID)) {
|
|
115284
|
+
report.error(`The card's ID property must be a UUID string (e.g. ID: "123e4567-e89b-12d3-a456-426614174000"), but it was: ${escapeHtml3(String(card.ID))}`);
|
|
115285
|
+
} else {
|
|
115286
|
+
report.info(`The card has an ID, so it updates the existing card with that ID in the same collection if one exists, otherwise a new card is created.`);
|
|
115287
|
+
}
|
|
115288
|
+
}
|
|
115197
115289
|
if (!card.Title) {
|
|
115198
115290
|
report.error(`A "Title" property is required in the card's yaml.`);
|
|
115199
115291
|
} else {
|
|
@@ -115258,7 +115350,17 @@ function checkCardHtml(zip, task, report) {
|
|
|
115258
115350
|
report.resourceReferences.push(reference2);
|
|
115259
115351
|
}
|
|
115260
115352
|
} else {
|
|
115261
|
-
report.
|
|
115353
|
+
var ext = report.externalImages || { enabled: false, names: /* @__PURE__ */ new Set(), referenced: [] };
|
|
115354
|
+
var extName = reference2.slice("resources/".length);
|
|
115355
|
+
if (ext.names.has(extName) && ext.enabled) {
|
|
115356
|
+
if (!ext.referenced.includes(extName)) {
|
|
115357
|
+
ext.referenced.push(extName);
|
|
115358
|
+
}
|
|
115359
|
+
} else if (ext.names.has(extName)) {
|
|
115360
|
+
report.error(`The referenced resource "${reference2}" is listed in resources/external.json but collection.yaml doesn't set FetchExternalImages: true, so it won't be fetched.`);
|
|
115361
|
+
} else {
|
|
115362
|
+
report.error(`The referenced resource "${reference2}" does not exist in the zip.`);
|
|
115363
|
+
}
|
|
115262
115364
|
}
|
|
115263
115365
|
} else if (reference2.startsWith("cards/")) {
|
|
115264
115366
|
if (zip.file(reference2 + ".yaml")) {
|
|
@@ -115515,7 +115617,7 @@ function checkCollectionYaml(zip, task, report) {
|
|
|
115515
115617
|
}
|
|
115516
115618
|
try {
|
|
115517
115619
|
var collection = yaml.load(yamlString);
|
|
115518
|
-
var possibleKeys = ["Items", "Tags", "Title", "Version"];
|
|
115620
|
+
var possibleKeys = ["Items", "Tags", "Title", "Version", "FetchExternalImages", "ReuseFolders"];
|
|
115519
115621
|
var otherKeys = setSubtract(Object.keys(collection), possibleKeys);
|
|
115520
115622
|
otherKeys.forEach(function(key) {
|
|
115521
115623
|
report.warn(`Unexpected property "${key}" in collection.yaml.`);
|
|
@@ -115532,6 +115634,14 @@ function checkCollectionYaml(zip, task, report) {
|
|
|
115532
115634
|
}
|
|
115533
115635
|
}
|
|
115534
115636
|
var isV2 = collection.Version == 2;
|
|
115637
|
+
["FetchExternalImages", "ReuseFolders"].forEach(function(key) {
|
|
115638
|
+
if (collection[key] !== void 0 && collection[key] !== null && typeof collection[key] != "boolean") {
|
|
115639
|
+
report.warn(`The collection's ${key} property must be true or false (${key} = ${escapeHtml3(String(collection[key]))}).`);
|
|
115640
|
+
}
|
|
115641
|
+
});
|
|
115642
|
+
if (collection.ReuseFolders === true && !isV2) {
|
|
115643
|
+
report.warn(`ReuseFolders is ignored unless the collection has "Version: 2" (it applies only to Version 2 non-sync imports).`);
|
|
115644
|
+
}
|
|
115535
115645
|
if (collection.Items) {
|
|
115536
115646
|
if (!Array.isArray(collection.Items)) {
|
|
115537
115647
|
report.error(`The collection's Items list is optional, but if provided it must be a list.`);
|
|
@@ -115635,7 +115745,16 @@ function checkResource(zip, task, report) {
|
|
|
115635
115745
|
} else {
|
|
115636
115746
|
report.resources += 1;
|
|
115637
115747
|
}
|
|
115638
|
-
if (
|
|
115748
|
+
if (task.filename == "resources/external.json") {
|
|
115749
|
+
var ext = report.externalImages;
|
|
115750
|
+
if (ext) {
|
|
115751
|
+
ext.names.forEach(function(name) {
|
|
115752
|
+
if (!ext.referenced.includes(name) && !report.resourceReferences.includes("resources/" + name)) {
|
|
115753
|
+
report.warn(`resources/external.json entry "${escapeQuotes(name)}" isn't referenced by any cards.`);
|
|
115754
|
+
}
|
|
115755
|
+
});
|
|
115756
|
+
}
|
|
115757
|
+
} else if (!report.resourceReferences.includes(task.filename)) {
|
|
115639
115758
|
report.warn(`Resource ${task.filename} is included in the zip but isn't referenced by any cards.`);
|
|
115640
115759
|
}
|
|
115641
115760
|
if (zip.file(task.filename)._data.uncompressedSize > 2e9) {
|
|
@@ -115732,6 +115851,7 @@ function checkZip(zip) {
|
|
|
115732
115851
|
collectionRoots: [],
|
|
115733
115852
|
tags: [],
|
|
115734
115853
|
resourceReferences: [],
|
|
115854
|
+
externalImages: { enabled: false, names: /* @__PURE__ */ new Set(), referenced: [] },
|
|
115735
115855
|
cardLinks: 0,
|
|
115736
115856
|
boardLinks: 0,
|
|
115737
115857
|
checkCount: 0,
|
|
@@ -115805,6 +115925,7 @@ function checkZip(zip) {
|
|
|
115805
115925
|
info(`Unexpected file ${fullPath}`);
|
|
115806
115926
|
}
|
|
115807
115927
|
}
|
|
115928
|
+
tasks.push({ func: checkExternalImages, context: "resources/external.json", checks: 3, priority: 0 });
|
|
115808
115929
|
tasks.push({ func: checkFolderTree, checks: 5, priority: 6 });
|
|
115809
115930
|
tasks.push({ func: checkStats, checks: 3, priority: 10 });
|
|
115810
115931
|
tasks.sort(function(a, b) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getguru/import-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Command-line engine that turns Notion, Confluence, Google, Word, PDF, Markdown and spreadsheet exports into Guru import zips.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"guru-import-engine": "docx-import-cli.js"
|