@storyteller-platform/epub 0.6.3 → 0.7.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.
package/dist/upgrade.cjs CHANGED
@@ -41,6 +41,7 @@ __export(upgrade_exports, {
41
41
  });
42
42
  module.exports = __toCommonJS(upgrade_exports);
43
43
  var import_nanoid = require("nanoid");
44
+ var import_media_types = require("@storyteller-platform/media-types");
44
45
  var import_index = require("./index.cjs");
45
46
  const GUIDE_TO_EPUBTYPE = {
46
47
  acknowledgements: "acknowledgments",
@@ -88,31 +89,7 @@ const GUIDE_TO_EPUBTYPE = {
88
89
  "other.volume": "volume",
89
90
  "other.warning": "warning"
90
91
  };
91
- const XHTML_MEDIA_TYPES = /* @__PURE__ */ new Set([
92
- "application/xhtml+xml",
93
- "application/vnd.adobe-page-template+xml",
94
- "text/html"
95
- ]);
96
- const OEB_FONTS = /* @__PURE__ */ new Set([
97
- "application/vnd.ms-opentype",
98
- "application/x-font-ttf",
99
- "application/x-font-otf",
100
- "application/x-font-truetype",
101
- "application/font-sfnt",
102
- "application/font-woff",
103
- "application/font-woff2",
104
- "font/woff",
105
- "font/woff2",
106
- "font/otf",
107
- "font/ttf",
108
- "font/sfnt"
109
- ]);
110
- const FONT_MIME_BY_EXT = {
111
- ".ttf": "application/font-sfnt",
112
- ".otf": "application/font-sfnt",
113
- ".woff": "application/font-woff",
114
- ".woff2": "font/woff2"
115
- };
92
+ const XHTML_MEDIA_TYPES = /* @__PURE__ */ new Set([import_media_types.MediaType.XHTML, import_media_types.MediaType.HTML]);
116
93
  function getMetadataElement(pkg) {
117
94
  return import_index.Epub.findXmlChildByName("metadata", import_index.Epub.getXmlChildren(pkg));
118
95
  }
@@ -389,11 +366,10 @@ function removeSpineTocRef(pkg) {
389
366
  delete spine[":@"]["@_toc"];
390
367
  }
391
368
  async function collectManifestProperties(epub) {
392
- var _a;
393
369
  const manifest = await epub.getManifest();
394
370
  for (const item of Object.values(manifest)) {
395
- const mediaType = ((_a = item.mediaType) == null ? void 0 : _a.toLowerCase()) ?? "";
396
- if (!XHTML_MEDIA_TYPES.has(mediaType)) continue;
371
+ const mediaType = import_media_types.MediaType.fromMime(item.mediaType ?? "");
372
+ if (!mediaType || !XHTML_MEDIA_TYPES.has(mediaType)) continue;
397
373
  let xml;
398
374
  try {
399
375
  xml = await epub.readXhtmlItemContents(item.id);
@@ -414,21 +390,16 @@ async function collectManifestProperties(epub) {
414
390
  }
415
391
  }
416
392
  function fixFontMimeTypes(pkg) {
417
- var _a, _b;
393
+ var _a, _b, _c;
418
394
  const manifest = getManifestElement(pkg);
419
395
  if (!manifest) return;
420
396
  for (const item of findAllByName("item", manifest.manifest)) {
421
- const mt = (((_a = item[":@"]) == null ? void 0 : _a["@_media-type"]) ?? "").toLowerCase();
422
- if (!OEB_FONTS.has(mt)) continue;
423
- const href = ((_b = item[":@"]) == null ? void 0 : _b["@_href"]) ?? "";
424
- const dotIdx = href.lastIndexOf(".");
425
- if (dotIdx === -1) continue;
426
- const ext = href.slice(dotIdx).toLowerCase();
427
- const corrected = FONT_MIME_BY_EXT[ext];
428
- if (corrected && corrected !== mt) {
429
- item[":@"] ??= {};
430
- item[":@"]["@_media-type"] = corrected;
431
- }
397
+ const declared = ((_a = item[":@"]) == null ? void 0 : _a["@_media-type"]) ?? "";
398
+ if (!((_b = import_media_types.MediaType.fromMime(declared)) == null ? void 0 : _b.is("font"))) continue;
399
+ const corrected = import_media_types.MediaType.fromPath(((_c = item[":@"]) == null ? void 0 : _c["@_href"]) ?? "");
400
+ if (!(corrected == null ? void 0 : corrected.is("font")) || corrected.mime === declared) continue;
401
+ item[":@"] ??= {};
402
+ item[":@"]["@_media-type"] = corrected.mime;
432
403
  }
433
404
  }
434
405
  function buildTocOl(entries) {
@@ -521,10 +492,7 @@ async function chooseNavHref(epub) {
521
492
  async function removeNcx(epub) {
522
493
  const manifest = await epub.getManifest();
523
494
  const ncxItem = Object.values(manifest).find(
524
- (item) => {
525
- var _a;
526
- return ((_a = item.mediaType) == null ? void 0 : _a.toLowerCase()) === "application/x-dtbncx+xml";
527
- }
495
+ (item) => import_media_types.MediaType.fromMime(item.mediaType ?? "") === import_media_types.MediaType.NCX
528
496
  );
529
497
  if (ncxItem) {
530
498
  await epub.removeManifestItem(ncxItem.id);
@@ -87,6 +87,31 @@ interface DcSubject {
87
87
  authority: string;
88
88
  term: string;
89
89
  }
90
+ interface EpubIdentifier {
91
+ value: string;
92
+ id?: string | undefined;
93
+ /** the value of a refining `identifier-type` meta, if present */
94
+ identifierType?: string | undefined;
95
+ /** the `scheme` of a refining `identifier-type` meta, or a legacy `opf:scheme` attribute */
96
+ scheme?: string | undefined;
97
+ }
98
+ interface EpubSource {
99
+ value: string;
100
+ id?: string | undefined;
101
+ /** the value of a refining `identifier-type` meta, if present */
102
+ identifierType?: string | undefined;
103
+ /** the `scheme` of a refining `identifier-type` meta, or a legacy `opf:scheme` attribute */
104
+ scheme?: string | undefined;
105
+ /**
106
+ * whether this source has a `source-of="pagination"` refinement
107
+ * or of a `<meta property="pageBreakSource">` element
108
+ *
109
+ * as of EPUB 3.4 `source-of` is advised-deprecated in favour of the
110
+ * publication-level `pageBreakSource` property. if you want to
111
+ * be sure to get the source of pagination, use {@link Epub.getPageBreakSource}
112
+ */
113
+ isPageBreakSource?: boolean | undefined;
114
+ }
90
115
  interface AlternateScript {
91
116
  name: string;
92
117
  locale: Intl.Locale;
@@ -140,7 +165,7 @@ interface FromOptions {
140
165
  * Read-only view of an EPUB
141
166
  * Returned by Epub.using(MemoryAdapter).from(...) and by Epub.from(path, { readonly: true })
142
167
  */
143
- type EpubReader = Pick<Epub, "storage" | "getManifest" | "getVersion" | "getLayout" | "getBaseDirection" | "getMetadata" | "findMetadataItem" | "findAllMetadataItems" | "getIdentifier" | "getTitle" | "getSubtitle" | "getTitles" | "getLanguage" | "getPublicationDate" | "getModifiedDate" | "getDescription" | "getType" | "getCreators" | "getContributors" | "getSubjects" | "getCollections" | "getPackageVocabularyPrefixes" | "getCoverImageItem" | "getCoverImage" | "getSpineItems" | "getNcxTableOfContents" | "getGuideEntries" | "getTableOfContents" | "getLandmarks" | "getPageList" | "resolveHref" | "readFileContents" | "readItemContents" | "readXhtmlItemContents" | "getItemArchiveLength" | "discardAndClose"> & Disposable;
168
+ type EpubReader = Pick<Epub, "storage" | "findMetadataItem" | "findAllMetadataItems" | "resolveHref" | "readFileContents" | "readItemContents" | "readXhtmlItemContents" | "discardAndClose" | Extract<keyof Epub, `get${string}`>> & Disposable;
144
169
  /**
145
170
  * Readonly Epub-instance backed by an in-memory zip handle
146
171
  * Returned by `Epub.using(MemoryAdapter).from(...)`
@@ -314,10 +339,6 @@ declare class Epub {
314
339
  static assertEpub3(epub: Epub): Promise<void>;
315
340
  copy(path?: string): Promise<Epub>;
316
341
  private removeEntry;
317
- /**
318
- * Read raw bytes (or utf-8 text) from the underlying adapter
319
- */
320
- private getFileData;
321
342
  /**
322
343
  * Length of the underlying archive entry for a manifest item, in bytes
323
344
  * Necessary to compute the readium page count which is for COMPRESSED content
@@ -366,7 +387,7 @@ declare class Epub {
366
387
  */
367
388
  findMetadataItem(predicate: (entry: MetadataEntry) => boolean): Promise<{
368
389
  id: string | undefined;
369
- type: `?${string}` | `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}`;
390
+ type: `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}` | `?${string}`;
370
391
  properties: {
371
392
  [k: string]: string;
372
393
  };
@@ -378,7 +399,7 @@ declare class Epub {
378
399
  */
379
400
  findAllMetadataItems(predicate: (entry: MetadataEntry) => boolean): Promise<{
380
401
  id: string | undefined;
381
- type: `?${string}` | `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}`;
402
+ type: `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}` | `?${string}`;
382
403
  properties: {
383
404
  [k: string]: string;
384
405
  };
@@ -398,12 +419,15 @@ declare class Epub {
398
419
  */
399
420
  getMetadata(): Promise<EpubMetadata>;
400
421
  /**
401
- * Retrieve the identifier from the dc:identifier element
422
+ * Retrieve the first identifier from the dc:identifier element
402
423
  * in the EPUB metadata.
403
424
  *
404
425
  * If there is no dc:identifier element, returns null.
405
426
  *
406
427
  * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
428
+ *
429
+ * @deprecated Use {@link getUniqueIdentifier} instead to get the unique identifier,
430
+ * or {@link getIdentifiers} to get all identifiers.
407
431
  */
408
432
  getIdentifier(): Promise<string | null>;
409
433
  /**
@@ -413,8 +437,130 @@ declare class Epub {
413
437
  * Otherwise creates a new element
414
438
  *
415
439
  * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
440
+ *
441
+ * @deprecated Use {@link setUniqueIdentifier} instead.
416
442
  */
417
443
  setIdentifier(identifier: string): Promise<void>;
444
+ /**
445
+ * Retrieve the identifier with the unique identifier id
446
+ * in the EPUB metadata.
447
+ *
448
+ * If there is no unique identifier id, returns the first dc:identifier element.
449
+ *
450
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
451
+ */
452
+ getUniqueIdentifier(): Promise<string | null>;
453
+ /**
454
+ * Set the unique identifier id for the EPUB.
455
+ *
456
+ * Updates the existing dc:identifier element referenced by the unique identifier id if one exists.
457
+ * Otherwise creates a new element with the provided identifier, and sets the unique identifier id to the new element's id.
458
+ *
459
+ * Note: you likely shouldn't change the unique identifier id unless you are producing a new EPUB.
460
+ *
461
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
462
+ */
463
+ setUniqueIdentifier(identifier: string): Promise<void>;
464
+ /**
465
+ * Retrieve the id of the publication's unique identifier, as declared by the
466
+ * package element's `unique-identifier` attribute.
467
+ *
468
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
469
+ */
470
+ getUniqueIdentifierId(): Promise<string | null>;
471
+ /**
472
+ * Collect `dc:identifier` or `dc:source` entries, attaching the value and
473
+ * scheme of any refining `identifier-type` meta (spec D.3.8) and a legacy
474
+ * `opf:scheme` attribute. Values are not interpreted.
475
+ *
476
+ * `onRefinement` is invoked for every other meta refining a collected entry,
477
+ * so callers can surface element-specific refinements (e.g. `source-of` on a
478
+ * `dc:source`).
479
+ */
480
+ private static collectDcEntries;
481
+ /**
482
+ * Retrieve every `dc:identifier` entry, returned as found.
483
+ *
484
+ * Values are not interpreted. Any refining `identifier-type` meta (spec
485
+ * D.3.8) or legacy `opf:scheme` attribute is surfaced on the entry, but no
486
+ * parsing of the value itself is attempted. To read `dc:source` entries, use
487
+ * {@link getSources}.
488
+ *
489
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
490
+ */
491
+ getIdentifiers(): Promise<EpubIdentifier[]>;
492
+ /**
493
+ * Retrieve every `dc:source` entry, returned as found.
494
+ *
495
+ * Like {@link getIdentifiers}, values are not interpreted. In addition to a
496
+ * refining `identifier-type`, a refining `source-of` meta (spec D.3.11) is
497
+ * surfaced as `sourceOf`.
498
+ *
499
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcsource
500
+ */
501
+ getSources(): Promise<EpubSource[]>;
502
+ /**
503
+ * Retrieve the `pageBreakSource` property (EPUB 3.4, spec D.2.9), the
504
+ * publication-level source for the source of its page break markers.
505
+ *
506
+ * This property replaces the refining `source-of="pagination"` meta (spec
507
+ * D.3.11), see {@link EpubSource.sourceOf}. If no `pageBreakSource` property is found,
508
+ * we fall back to finding a `dc:source` with a `source-of="pagination"` refinement.
509
+ *
510
+ * @link https://www.w3.org/TR/epub/#pageBreakSource
511
+ */
512
+ getPageBreakSource(): Promise<EpubSource | null>;
513
+ /**
514
+ * Set the `pageBreakSource` property (EPUB 3.4, spec D.2.9), or remove it when
515
+ * passed null. Replaces an existing `pageBreakSource` meta if present.
516
+ *
517
+ * Pass `none` to indicate the pagination is unique to this publication.
518
+ *
519
+ * @link https://www.w3.org/TR/epub/#pageBreakSource
520
+ */
521
+ setPageBreakSource(value: string | null): Promise<void>;
522
+ /**
523
+ * Replace the publication's `dc:identifier` entries.
524
+ *
525
+ * This replaces ALL existing `dc:identifier` elements except the publication's
526
+ * unique identifier (the one referenced by the package element's
527
+ * `unique-identifier` attribute), which is always preserved and must not be
528
+ * included in the provided list. If included anyway, it is ignored. See
529
+ * {@link setUniqueIdentifier} to change it.
530
+ *
531
+ * Identifiers are placed in the order they are provided.
532
+ *
533
+ * `dc:source` entries are not touched, use {@link setSources} for those.
534
+ *
535
+ * When an entry has an `identifierType`, it is written in the refining form
536
+ * (a `meta` with `property="identifier-type"`, carrying the `scheme`
537
+ * attribute when provided). An entry with only a `scheme` is written using
538
+ * the legacy `opf:scheme` attribute.
539
+ *
540
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
541
+ */
542
+ setIdentifiers(identifiers: EpubIdentifier[]): Promise<void>;
543
+ /**
544
+ * Remove `meta` refinements pointing at any of the given ids,
545
+ * restricted to the given `property` values as a cleanup step
546
+ * Mutates `children` in place.
547
+ */
548
+ private static removeRefiningMetas;
549
+ /**
550
+ * Replace the publication's `dc:source` entries.
551
+ *
552
+ * This replaces ALL existing `dc:source` elements (and their refining
553
+ * `identifier-type` / `source-of` metas). `dc:identifier` entries are not
554
+ * touched; use {@link setIdentifiers} for those. Pass an empty array to
555
+ * remove all sources.
556
+ *
557
+ * When an entry has an `identifierType`, it is written in the refining form.
558
+ * A `sourceOf` value is written as a refining `source-of` meta (spec D.3.11).
559
+ * An entry with only a `scheme` uses the legacy `opf:scheme` attribute.
560
+ *
561
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcsource
562
+ */
563
+ setSources(sources: EpubSource[]): Promise<void>;
418
564
  /**
419
565
  * Even "EPUB 3" publications sometimes still only use the
420
566
  * EPUB 2 specification for identifying the cover image.
@@ -772,13 +918,31 @@ declare class Epub {
772
918
  resolveToRoot?: boolean;
773
919
  }): Promise<Navigation | null>;
774
920
  /**
775
- * Returns a Zip Entry path for an HREF
921
+ * Name the entry a resolved URL addresses.
922
+ *
923
+ * A correctly authored publication percent-encodes its hrefs, so the
924
+ * decoded reading is the one the spec calls for and the one we prefer.
925
+ * Some publications instead write the entry name verbatim, so when the two
926
+ * readings differ we ask the archive which one it holds. A verbatim name
927
+ * carrying a bare `%`, as `100%.xhtml` does, is not a valid encoding at all
928
+ * and can only be its own answer.
929
+ */
930
+ private entryForUrl;
931
+ /**
932
+ * Resolve an href to the name of the archive entry it addresses.
933
+ *
934
+ * @param from The entry the href appears in; it resolves against that
935
+ * entry's directory
936
+ * @throws when the href addresses something outside the publication
776
937
  */
777
- private resolveInternalHref;
938
+ private resolveEntry;
778
939
  /**
779
940
  * Returns a path-relative-scheme-less URL, relative to the
780
941
  * container root.
781
942
  *
943
+ * An href that points outside the publication, such as an external link in
944
+ * a navigation document, is handed back unchanged.
945
+ *
782
946
  * @param href The href to resolve
783
947
  * @param [relativeTo] Optional - The href to resolve this href relative to.
784
948
  Use if resolving a relative href from a file other than the package document.
@@ -1029,4 +1193,4 @@ declare class EpubFactory<A extends EpubStorageAdapterClass> {
1029
1193
  upgrade(path: string, options?: Epub2UpgradeOptions): Promise<EpubInstanceFor<A>>;
1030
1194
  }
1031
1195
 
1032
- export { type AlternateScript as A, type Collection as C, type DcSubject as D, type ElementName as E, type Epub2UpgradeOptions, type FromOptions as F, type InMemoryEpubReader as I, type Landmark, type ManifestItem as M, type NavigationItem as N, type ParsedXml as P, type XmlElement as X, type XmlTextNode as a, type XmlNode as b, buildNavDocument, buildTocOl, type MetadataEntry as c, chooseNavHref, collectManifestProperties, type EpubMetadata as d, type DcCreator as e, extractGuideLandmarks, type DublinCore as f, fixFontMimeTypes, type NavigationList as g, type Navigation as h, type PackageElement as i, type EpubReader as j, EpubVersionError as k, EpubReadOnlyError as l, Epub as m, type EpubInstanceFor as n, EpubFactory as o, removeGuide, removeInvalidDcAttrs, removeNcx, removeSpineTocRef, setLastModified, setPackageVersion, upgradeAuthors, upgradeCover, upgradeDate, upgradeIdentifiers, upgradeLanguages, upgradeMeta, upgradePackageMetadata, upgradeTitle };
1196
+ export { type AlternateScript as A, type Collection as C, type DcSubject as D, type ElementName as E, type Epub2UpgradeOptions, type FromOptions as F, type InMemoryEpubReader as I, type Landmark, type ManifestItem as M, type NavigationItem as N, type ParsedXml as P, type XmlElement as X, type XmlTextNode as a, type XmlNode as b, buildNavDocument, buildTocOl, type MetadataEntry as c, chooseNavHref, collectManifestProperties, type EpubMetadata as d, type EpubIdentifier as e, extractGuideLandmarks, type EpubSource as f, fixFontMimeTypes, type DcCreator as g, type DublinCore as h, type NavigationList as i, type Navigation as j, type PackageElement as k, type EpubReader as l, EpubVersionError as m, EpubReadOnlyError as n, Epub as o, type EpubInstanceFor as p, EpubFactory as q, removeGuide, removeInvalidDcAttrs, removeNcx, removeSpineTocRef, setLastModified, setPackageVersion, upgradeAuthors, upgradeCover, upgradeDate, upgradeIdentifiers, upgradeLanguages, upgradeMeta, upgradePackageMetadata, upgradeTitle };
package/dist/upgrade.d.ts CHANGED
@@ -87,6 +87,31 @@ interface DcSubject {
87
87
  authority: string;
88
88
  term: string;
89
89
  }
90
+ interface EpubIdentifier {
91
+ value: string;
92
+ id?: string | undefined;
93
+ /** the value of a refining `identifier-type` meta, if present */
94
+ identifierType?: string | undefined;
95
+ /** the `scheme` of a refining `identifier-type` meta, or a legacy `opf:scheme` attribute */
96
+ scheme?: string | undefined;
97
+ }
98
+ interface EpubSource {
99
+ value: string;
100
+ id?: string | undefined;
101
+ /** the value of a refining `identifier-type` meta, if present */
102
+ identifierType?: string | undefined;
103
+ /** the `scheme` of a refining `identifier-type` meta, or a legacy `opf:scheme` attribute */
104
+ scheme?: string | undefined;
105
+ /**
106
+ * whether this source has a `source-of="pagination"` refinement
107
+ * or of a `<meta property="pageBreakSource">` element
108
+ *
109
+ * as of EPUB 3.4 `source-of` is advised-deprecated in favour of the
110
+ * publication-level `pageBreakSource` property. if you want to
111
+ * be sure to get the source of pagination, use {@link Epub.getPageBreakSource}
112
+ */
113
+ isPageBreakSource?: boolean | undefined;
114
+ }
90
115
  interface AlternateScript {
91
116
  name: string;
92
117
  locale: Intl.Locale;
@@ -140,7 +165,7 @@ interface FromOptions {
140
165
  * Read-only view of an EPUB
141
166
  * Returned by Epub.using(MemoryAdapter).from(...) and by Epub.from(path, { readonly: true })
142
167
  */
143
- type EpubReader = Pick<Epub, "storage" | "getManifest" | "getVersion" | "getLayout" | "getBaseDirection" | "getMetadata" | "findMetadataItem" | "findAllMetadataItems" | "getIdentifier" | "getTitle" | "getSubtitle" | "getTitles" | "getLanguage" | "getPublicationDate" | "getModifiedDate" | "getDescription" | "getType" | "getCreators" | "getContributors" | "getSubjects" | "getCollections" | "getPackageVocabularyPrefixes" | "getCoverImageItem" | "getCoverImage" | "getSpineItems" | "getNcxTableOfContents" | "getGuideEntries" | "getTableOfContents" | "getLandmarks" | "getPageList" | "resolveHref" | "readFileContents" | "readItemContents" | "readXhtmlItemContents" | "getItemArchiveLength" | "discardAndClose"> & Disposable;
168
+ type EpubReader = Pick<Epub, "storage" | "findMetadataItem" | "findAllMetadataItems" | "resolveHref" | "readFileContents" | "readItemContents" | "readXhtmlItemContents" | "discardAndClose" | Extract<keyof Epub, `get${string}`>> & Disposable;
144
169
  /**
145
170
  * Readonly Epub-instance backed by an in-memory zip handle
146
171
  * Returned by `Epub.using(MemoryAdapter).from(...)`
@@ -314,10 +339,6 @@ declare class Epub {
314
339
  static assertEpub3(epub: Epub): Promise<void>;
315
340
  copy(path?: string): Promise<Epub>;
316
341
  private removeEntry;
317
- /**
318
- * Read raw bytes (or utf-8 text) from the underlying adapter
319
- */
320
- private getFileData;
321
342
  /**
322
343
  * Length of the underlying archive entry for a manifest item, in bytes
323
344
  * Necessary to compute the readium page count which is for COMPRESSED content
@@ -366,7 +387,7 @@ declare class Epub {
366
387
  */
367
388
  findMetadataItem(predicate: (entry: MetadataEntry) => boolean): Promise<{
368
389
  id: string | undefined;
369
- type: `?${string}` | `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}`;
390
+ type: `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}` | `?${string}`;
370
391
  properties: {
371
392
  [k: string]: string;
372
393
  };
@@ -378,7 +399,7 @@ declare class Epub {
378
399
  */
379
400
  findAllMetadataItems(predicate: (entry: MetadataEntry) => boolean): Promise<{
380
401
  id: string | undefined;
381
- type: `?${string}` | `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}`;
402
+ type: `a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}` | `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}` | `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}` | `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}` | `y${string}` | `z${string}` | `A${string}` | `B${string}` | `C${string}` | `D${string}` | `E${string}` | `F${string}` | `G${string}` | `H${string}` | `I${string}` | `J${string}` | `K${string}` | `L${string}` | `M${string}` | `N${string}` | `O${string}` | `P${string}` | `Q${string}` | `R${string}` | `S${string}` | `T${string}` | `U${string}` | `V${string}` | `W${string}` | `X${string}` | `Y${string}` | `Z${string}` | `?${string}`;
382
403
  properties: {
383
404
  [k: string]: string;
384
405
  };
@@ -398,12 +419,15 @@ declare class Epub {
398
419
  */
399
420
  getMetadata(): Promise<EpubMetadata>;
400
421
  /**
401
- * Retrieve the identifier from the dc:identifier element
422
+ * Retrieve the first identifier from the dc:identifier element
402
423
  * in the EPUB metadata.
403
424
  *
404
425
  * If there is no dc:identifier element, returns null.
405
426
  *
406
427
  * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
428
+ *
429
+ * @deprecated Use {@link getUniqueIdentifier} instead to get the unique identifier,
430
+ * or {@link getIdentifiers} to get all identifiers.
407
431
  */
408
432
  getIdentifier(): Promise<string | null>;
409
433
  /**
@@ -413,8 +437,130 @@ declare class Epub {
413
437
  * Otherwise creates a new element
414
438
  *
415
439
  * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
440
+ *
441
+ * @deprecated Use {@link setUniqueIdentifier} instead.
416
442
  */
417
443
  setIdentifier(identifier: string): Promise<void>;
444
+ /**
445
+ * Retrieve the identifier with the unique identifier id
446
+ * in the EPUB metadata.
447
+ *
448
+ * If there is no unique identifier id, returns the first dc:identifier element.
449
+ *
450
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
451
+ */
452
+ getUniqueIdentifier(): Promise<string | null>;
453
+ /**
454
+ * Set the unique identifier id for the EPUB.
455
+ *
456
+ * Updates the existing dc:identifier element referenced by the unique identifier id if one exists.
457
+ * Otherwise creates a new element with the provided identifier, and sets the unique identifier id to the new element's id.
458
+ *
459
+ * Note: you likely shouldn't change the unique identifier id unless you are producing a new EPUB.
460
+ *
461
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
462
+ */
463
+ setUniqueIdentifier(identifier: string): Promise<void>;
464
+ /**
465
+ * Retrieve the id of the publication's unique identifier, as declared by the
466
+ * package element's `unique-identifier` attribute.
467
+ *
468
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
469
+ */
470
+ getUniqueIdentifierId(): Promise<string | null>;
471
+ /**
472
+ * Collect `dc:identifier` or `dc:source` entries, attaching the value and
473
+ * scheme of any refining `identifier-type` meta (spec D.3.8) and a legacy
474
+ * `opf:scheme` attribute. Values are not interpreted.
475
+ *
476
+ * `onRefinement` is invoked for every other meta refining a collected entry,
477
+ * so callers can surface element-specific refinements (e.g. `source-of` on a
478
+ * `dc:source`).
479
+ */
480
+ private static collectDcEntries;
481
+ /**
482
+ * Retrieve every `dc:identifier` entry, returned as found.
483
+ *
484
+ * Values are not interpreted. Any refining `identifier-type` meta (spec
485
+ * D.3.8) or legacy `opf:scheme` attribute is surfaced on the entry, but no
486
+ * parsing of the value itself is attempted. To read `dc:source` entries, use
487
+ * {@link getSources}.
488
+ *
489
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
490
+ */
491
+ getIdentifiers(): Promise<EpubIdentifier[]>;
492
+ /**
493
+ * Retrieve every `dc:source` entry, returned as found.
494
+ *
495
+ * Like {@link getIdentifiers}, values are not interpreted. In addition to a
496
+ * refining `identifier-type`, a refining `source-of` meta (spec D.3.11) is
497
+ * surfaced as `sourceOf`.
498
+ *
499
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcsource
500
+ */
501
+ getSources(): Promise<EpubSource[]>;
502
+ /**
503
+ * Retrieve the `pageBreakSource` property (EPUB 3.4, spec D.2.9), the
504
+ * publication-level source for the source of its page break markers.
505
+ *
506
+ * This property replaces the refining `source-of="pagination"` meta (spec
507
+ * D.3.11), see {@link EpubSource.sourceOf}. If no `pageBreakSource` property is found,
508
+ * we fall back to finding a `dc:source` with a `source-of="pagination"` refinement.
509
+ *
510
+ * @link https://www.w3.org/TR/epub/#pageBreakSource
511
+ */
512
+ getPageBreakSource(): Promise<EpubSource | null>;
513
+ /**
514
+ * Set the `pageBreakSource` property (EPUB 3.4, spec D.2.9), or remove it when
515
+ * passed null. Replaces an existing `pageBreakSource` meta if present.
516
+ *
517
+ * Pass `none` to indicate the pagination is unique to this publication.
518
+ *
519
+ * @link https://www.w3.org/TR/epub/#pageBreakSource
520
+ */
521
+ setPageBreakSource(value: string | null): Promise<void>;
522
+ /**
523
+ * Replace the publication's `dc:identifier` entries.
524
+ *
525
+ * This replaces ALL existing `dc:identifier` elements except the publication's
526
+ * unique identifier (the one referenced by the package element's
527
+ * `unique-identifier` attribute), which is always preserved and must not be
528
+ * included in the provided list. If included anyway, it is ignored. See
529
+ * {@link setUniqueIdentifier} to change it.
530
+ *
531
+ * Identifiers are placed in the order they are provided.
532
+ *
533
+ * `dc:source` entries are not touched, use {@link setSources} for those.
534
+ *
535
+ * When an entry has an `identifierType`, it is written in the refining form
536
+ * (a `meta` with `property="identifier-type"`, carrying the `scheme`
537
+ * attribute when provided). An entry with only a `scheme` is written using
538
+ * the legacy `opf:scheme` attribute.
539
+ *
540
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcidentifier
541
+ */
542
+ setIdentifiers(identifiers: EpubIdentifier[]): Promise<void>;
543
+ /**
544
+ * Remove `meta` refinements pointing at any of the given ids,
545
+ * restricted to the given `property` values as a cleanup step
546
+ * Mutates `children` in place.
547
+ */
548
+ private static removeRefiningMetas;
549
+ /**
550
+ * Replace the publication's `dc:source` entries.
551
+ *
552
+ * This replaces ALL existing `dc:source` elements (and their refining
553
+ * `identifier-type` / `source-of` metas). `dc:identifier` entries are not
554
+ * touched; use {@link setIdentifiers} for those. Pass an empty array to
555
+ * remove all sources.
556
+ *
557
+ * When an entry has an `identifierType`, it is written in the refining form.
558
+ * A `sourceOf` value is written as a refining `source-of` meta (spec D.3.11).
559
+ * An entry with only a `scheme` uses the legacy `opf:scheme` attribute.
560
+ *
561
+ * @link https://www.w3.org/TR/epub-33/#sec-opf-dcsource
562
+ */
563
+ setSources(sources: EpubSource[]): Promise<void>;
418
564
  /**
419
565
  * Even "EPUB 3" publications sometimes still only use the
420
566
  * EPUB 2 specification for identifying the cover image.
@@ -772,13 +918,31 @@ declare class Epub {
772
918
  resolveToRoot?: boolean;
773
919
  }): Promise<Navigation | null>;
774
920
  /**
775
- * Returns a Zip Entry path for an HREF
921
+ * Name the entry a resolved URL addresses.
922
+ *
923
+ * A correctly authored publication percent-encodes its hrefs, so the
924
+ * decoded reading is the one the spec calls for and the one we prefer.
925
+ * Some publications instead write the entry name verbatim, so when the two
926
+ * readings differ we ask the archive which one it holds. A verbatim name
927
+ * carrying a bare `%`, as `100%.xhtml` does, is not a valid encoding at all
928
+ * and can only be its own answer.
929
+ */
930
+ private entryForUrl;
931
+ /**
932
+ * Resolve an href to the name of the archive entry it addresses.
933
+ *
934
+ * @param from The entry the href appears in; it resolves against that
935
+ * entry's directory
936
+ * @throws when the href addresses something outside the publication
776
937
  */
777
- private resolveInternalHref;
938
+ private resolveEntry;
778
939
  /**
779
940
  * Returns a path-relative-scheme-less URL, relative to the
780
941
  * container root.
781
942
  *
943
+ * An href that points outside the publication, such as an external link in
944
+ * a navigation document, is handed back unchanged.
945
+ *
782
946
  * @param href The href to resolve
783
947
  * @param [relativeTo] Optional - The href to resolve this href relative to.
784
948
  Use if resolving a relative href from a file other than the package document.
@@ -1029,4 +1193,4 @@ declare class EpubFactory<A extends EpubStorageAdapterClass> {
1029
1193
  upgrade(path: string, options?: Epub2UpgradeOptions): Promise<EpubInstanceFor<A>>;
1030
1194
  }
1031
1195
 
1032
- export { type AlternateScript as A, type Collection as C, type DcSubject as D, type ElementName as E, type Epub2UpgradeOptions, type FromOptions as F, type InMemoryEpubReader as I, type Landmark, type ManifestItem as M, type NavigationItem as N, type ParsedXml as P, type XmlElement as X, type XmlTextNode as a, type XmlNode as b, buildNavDocument, buildTocOl, type MetadataEntry as c, chooseNavHref, collectManifestProperties, type EpubMetadata as d, type DcCreator as e, extractGuideLandmarks, type DublinCore as f, fixFontMimeTypes, type NavigationList as g, type Navigation as h, type PackageElement as i, type EpubReader as j, EpubVersionError as k, EpubReadOnlyError as l, Epub as m, type EpubInstanceFor as n, EpubFactory as o, removeGuide, removeInvalidDcAttrs, removeNcx, removeSpineTocRef, setLastModified, setPackageVersion, upgradeAuthors, upgradeCover, upgradeDate, upgradeIdentifiers, upgradeLanguages, upgradeMeta, upgradePackageMetadata, upgradeTitle };
1196
+ export { type AlternateScript as A, type Collection as C, type DcSubject as D, type ElementName as E, type Epub2UpgradeOptions, type FromOptions as F, type InMemoryEpubReader as I, type Landmark, type ManifestItem as M, type NavigationItem as N, type ParsedXml as P, type XmlElement as X, type XmlTextNode as a, type XmlNode as b, buildNavDocument, buildTocOl, type MetadataEntry as c, chooseNavHref, collectManifestProperties, type EpubMetadata as d, type EpubIdentifier as e, extractGuideLandmarks, type EpubSource as f, fixFontMimeTypes, type DcCreator as g, type DublinCore as h, type NavigationList as i, type Navigation as j, type PackageElement as k, type EpubReader as l, EpubVersionError as m, EpubReadOnlyError as n, Epub as o, type EpubInstanceFor as p, EpubFactory as q, removeGuide, removeInvalidDcAttrs, removeNcx, removeSpineTocRef, setLastModified, setPackageVersion, upgradeAuthors, upgradeCover, upgradeDate, upgradeIdentifiers, upgradeLanguages, upgradeMeta, upgradePackageMetadata, upgradeTitle };