@storyteller-platform/epub 1.0.0 → 1.0.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/README.md +153 -970
- package/dist/index.d.ts +2 -3
- package/dist/index.js +10 -14
- package/dist/upgrade.js +2 -3
- package/dist/xml.d.ts +1 -0
- package/dist/xml.js +3 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -146,7 +146,7 @@ export declare class EpubReadOnlyError extends Error {
|
|
|
146
146
|
* ```ts
|
|
147
147
|
* import { Epub, getBody, findByName, textContent } from '@storyteller-platform/epub';
|
|
148
148
|
*
|
|
149
|
-
*
|
|
149
|
+
* using epub = await Epub.from('./path/to/book.epub');
|
|
150
150
|
* const title = await epub.getTitle();
|
|
151
151
|
* const spineItems = await epub.getSpineItems();
|
|
152
152
|
* const chptOne = spineItems[0];
|
|
@@ -157,8 +157,7 @@ export declare class EpubReadOnlyError extends Error {
|
|
|
157
157
|
* const headingText = textContent(h1);
|
|
158
158
|
*
|
|
159
159
|
* await epub.setTitle(headingText);
|
|
160
|
-
* await epub.
|
|
161
|
-
* await epub.close();
|
|
160
|
+
* await epub.saveAndClose();
|
|
162
161
|
* ```
|
|
163
162
|
*
|
|
164
163
|
* @link https://www.w3.org/TR/epub-33/
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@storyteller-platform/epub/jsx-runtime";
|
|
2
2
|
import { Mutex } from "async-mutex";
|
|
3
3
|
import memoize from "mem";
|
|
4
|
-
import { nanoid } from "nanoid";
|
|
5
4
|
import { MediaType } from "@storyteller-platform/media-types";
|
|
6
5
|
import { copyFile } from "#files";
|
|
7
6
|
import { TmpFsAdapter } from "#tmpfs";
|
|
8
7
|
import * as Upgrade from "./upgrade.js";
|
|
9
|
-
import { createDocument, createDocumentType, declareDefaultNamespace, findXmlChildByName, findXmlChildByNameNS, findXmlDescendantByName, getXhtmlBody, insert, isElement, isText, NS, parse, replace, serialize, text, x, } from "./xml.js";
|
|
8
|
+
import { createDocument, createDocumentType, declareDefaultNamespace, findXmlChildByName, findXmlChildByNameNS, findXmlDescendantByName, getXhtmlBody, insert, isElement, isText, NS, parse, replace, serialize, text, x, xmlId, } from "./xml.js";
|
|
10
9
|
export { TmpFsAdapter } from "#tmpfs";
|
|
11
10
|
export { MemoryAdapter } from "./adapters/memory.js";
|
|
12
11
|
/**
|
|
@@ -93,7 +92,7 @@ function spineReferenceable(manifest, item) {
|
|
|
93
92
|
* ```ts
|
|
94
93
|
* import { Epub, getBody, findByName, textContent } from '@storyteller-platform/epub';
|
|
95
94
|
*
|
|
96
|
-
*
|
|
95
|
+
* using epub = await Epub.from('./path/to/book.epub');
|
|
97
96
|
* const title = await epub.getTitle();
|
|
98
97
|
* const spineItems = await epub.getSpineItems();
|
|
99
98
|
* const chptOne = spineItems[0];
|
|
@@ -104,8 +103,7 @@ function spineReferenceable(manifest, item) {
|
|
|
104
103
|
* const headingText = textContent(h1);
|
|
105
104
|
*
|
|
106
105
|
* await epub.setTitle(headingText);
|
|
107
|
-
* await epub.
|
|
108
|
-
* await epub.close();
|
|
106
|
+
* await epub.saveAndClose();
|
|
109
107
|
* ```
|
|
110
108
|
*
|
|
111
109
|
* @link https://www.w3.org/TR/epub-33/
|
|
@@ -487,7 +485,7 @@ export class Epub {
|
|
|
487
485
|
let uniqueId = await this.getUniqueIdentifierId();
|
|
488
486
|
if (!uniqueId) {
|
|
489
487
|
// Create a new unique identifier id
|
|
490
|
-
const newUniqueId =
|
|
488
|
+
const newUniqueId = xmlId();
|
|
491
489
|
packageElement.setAttribute("unique-identifier", newUniqueId);
|
|
492
490
|
uniqueId = newUniqueId;
|
|
493
491
|
}
|
|
@@ -676,7 +674,7 @@ export class Epub {
|
|
|
676
674
|
if (identifier.id && identifier.id === uniqueId)
|
|
677
675
|
continue;
|
|
678
676
|
const id = identifier.id ??
|
|
679
|
-
(identifier.identifierType !== undefined ?
|
|
677
|
+
(identifier.identifierType !== undefined ? xmlId() : undefined);
|
|
680
678
|
insert(metadata, _jsx("dc:identifier", { ...(id && { id }), ...(identifier.scheme &&
|
|
681
679
|
identifier.id === undefined && {
|
|
682
680
|
"opf:scheme": identifier.scheme,
|
|
@@ -743,7 +741,7 @@ export class Epub {
|
|
|
743
741
|
]);
|
|
744
742
|
for (const source of sources) {
|
|
745
743
|
const needsId = source.identifierType !== undefined || source.isPageBreakSource;
|
|
746
|
-
const id = source.id ?? (needsId ?
|
|
744
|
+
const id = source.id ?? (needsId ? xmlId() : undefined);
|
|
747
745
|
insert(metadata, _jsx("dc:source", { ...(id && { id }), ...(source.scheme &&
|
|
748
746
|
source.identifierType === undefined && {
|
|
749
747
|
"opf:scheme": source.scheme,
|
|
@@ -943,7 +941,7 @@ export class Epub {
|
|
|
943
941
|
value: subject,
|
|
944
942
|
}
|
|
945
943
|
: subject;
|
|
946
|
-
const subjectId =
|
|
944
|
+
const subjectId = xmlId();
|
|
947
945
|
await this.addMetadata({
|
|
948
946
|
id: subjectId,
|
|
949
947
|
type: "dc:subject",
|
|
@@ -1243,7 +1241,7 @@ export class Epub {
|
|
|
1243
1241
|
for (let i = 0; i < entries.length; i++) {
|
|
1244
1242
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1245
1243
|
const entry = entries[i];
|
|
1246
|
-
const id =
|
|
1244
|
+
const id = xmlId();
|
|
1247
1245
|
insert(metadata, _jsx("dc:title", { id: id, children: entry.title }));
|
|
1248
1246
|
if (entry.type) {
|
|
1249
1247
|
insert(metadata, _jsx("meta", { refines: `#${id}`, property: "title-type", children: entry.type }));
|
|
@@ -1282,7 +1280,7 @@ export class Epub {
|
|
|
1282
1280
|
* will be added to the end of the list.
|
|
1283
1281
|
*/
|
|
1284
1282
|
async addCollection(collection, index) {
|
|
1285
|
-
const collectionId =
|
|
1283
|
+
const collectionId = xmlId();
|
|
1286
1284
|
// Order matters for creators and contributors,
|
|
1287
1285
|
// so we can't just append these to the end of the
|
|
1288
1286
|
// metadata element's children using `addMetadata`.
|
|
@@ -1426,7 +1424,7 @@ export class Epub {
|
|
|
1426
1424
|
* @link https://www.w3.org/TR/epub-33/#sec-opf-dccreator
|
|
1427
1425
|
*/
|
|
1428
1426
|
async addCreator(creator, index, type = "creator") {
|
|
1429
|
-
const creatorId =
|
|
1427
|
+
const creatorId = xmlId();
|
|
1430
1428
|
// Order matters for creators and contributors,
|
|
1431
1429
|
// so we can't just append these to the end of the
|
|
1432
1430
|
// metadata element's children using `addMetadata`.
|
|
@@ -1783,8 +1781,6 @@ export class Epub {
|
|
|
1783
1781
|
Use if resolving a relative href from a file other than the package document.
|
|
1784
1782
|
*/
|
|
1785
1783
|
async resolveHref(href, relativeTo, { toRoot } = {}) {
|
|
1786
|
-
if (href.startsWith("#"))
|
|
1787
|
-
return href;
|
|
1788
1784
|
const rootfile = await this.getRootfile();
|
|
1789
1785
|
const from = relativeTo
|
|
1790
1786
|
? await this.resolveEntry(rootfile, relativeTo)
|
package/dist/upgrade.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@storyteller-platform/epub/jsx-runtime";
|
|
2
|
-
import { nanoid } from "nanoid";
|
|
3
2
|
import { MediaType } from "@storyteller-platform/media-types";
|
|
4
|
-
import { findXmlChildByNameNS, findXmlDescendantByName, findXmlDescendantByNameNS, insert, NS, replace, serialize, text, x, } from "./xml.js";
|
|
3
|
+
import { findXmlChildByNameNS, findXmlDescendantByName, findXmlDescendantByNameNS, insert, NS, replace, serialize, text, x, xmlId, } from "./xml.js";
|
|
5
4
|
const GUIDE_TO_EPUBTYPE = {
|
|
6
5
|
acknowledgements: "acknowledgments",
|
|
7
6
|
"other.afterword": "afterword",
|
|
@@ -78,7 +77,7 @@ function ensureId(element) {
|
|
|
78
77
|
const existing = element.getAttribute("id");
|
|
79
78
|
if (existing)
|
|
80
79
|
return existing;
|
|
81
|
-
const id = `id-${
|
|
80
|
+
const id = `id-${xmlId(8)}`;
|
|
82
81
|
element.setAttribute("id", id);
|
|
83
82
|
return id;
|
|
84
83
|
}
|
package/dist/xml.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import xmldom, { type Document, type CharacterData, type Element, type Node, type Text, type DocumentType } from "@xmldom/xmldom";
|
|
2
|
+
export declare const xmlId: (size?: number) => string;
|
|
2
3
|
export declare const XMLSerializer: typeof xmldom.XMLSerializer;
|
|
3
4
|
export declare function isElement(n: Node): n is Element;
|
|
4
5
|
export declare function isText(n: Node): n is CharacterData;
|
package/dist/xml.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import xmldom from "@xmldom/xmldom";
|
|
2
|
+
import { customAlphabet } from "nanoid";
|
|
3
|
+
// XML IDs can't start with numbers or symbols. Only use characters for simplicity
|
|
4
|
+
export const xmlId = customAlphabet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 22);
|
|
2
5
|
const { DOMParser } = xmldom;
|
|
3
6
|
export const { XMLSerializer } = xmldom;
|
|
4
7
|
export function isElement(n) {
|