@ocfl/ocfl 0.3.0 → 1.0.0-beta.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 (138) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +24 -9
  3. package/dist/constants.d.ts +15 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +14 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/digest.d.ts +58 -0
  8. package/dist/digest.d.ts.map +1 -0
  9. package/dist/digest.js +204 -0
  10. package/dist/digest.js.map +1 -0
  11. package/dist/error.d.ts +5 -0
  12. package/dist/error.d.ts.map +1 -0
  13. package/dist/error.js +9 -0
  14. package/dist/error.js.map +1 -0
  15. package/dist/extension.d.ts +83 -0
  16. package/dist/extension.d.ts.map +1 -0
  17. package/dist/extension.js +170 -0
  18. package/dist/extension.js.map +1 -0
  19. package/dist/extensions/0002-flat-direct-storage-layout.d.ts +12 -0
  20. package/dist/extensions/0002-flat-direct-storage-layout.d.ts.map +1 -0
  21. package/dist/extensions/0002-flat-direct-storage-layout.js +34 -0
  22. package/dist/extensions/0002-flat-direct-storage-layout.js.map +1 -0
  23. package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.d.ts +15 -0
  24. package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.d.ts.map +1 -0
  25. package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.js +49 -0
  26. package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.js.map +1 -0
  27. package/dist/extensions/0004-hashed-n-tuple-storage-layout.d.ts +17 -0
  28. package/dist/extensions/0004-hashed-n-tuple-storage-layout.d.ts.map +1 -0
  29. package/dist/extensions/0004-hashed-n-tuple-storage-layout.js +54 -0
  30. package/dist/extensions/0004-hashed-n-tuple-storage-layout.js.map +1 -0
  31. package/dist/extensions/0006-flat-omit-prefix-storage-layout.d.ts +6 -0
  32. package/dist/extensions/0006-flat-omit-prefix-storage-layout.d.ts.map +1 -0
  33. package/dist/extensions/0006-flat-omit-prefix-storage-layout.js +8 -0
  34. package/dist/extensions/0006-flat-omit-prefix-storage-layout.js.map +1 -0
  35. package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.d.ts +6 -0
  36. package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.d.ts.map +1 -0
  37. package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.js +8 -0
  38. package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.js.map +1 -0
  39. package/dist/extensions/0009-digest-algorithms.d.ts +9 -0
  40. package/dist/extensions/0009-digest-algorithms.d.ts.map +1 -0
  41. package/dist/extensions/0009-digest-algorithms.js +11 -0
  42. package/dist/extensions/0009-digest-algorithms.js.map +1 -0
  43. package/dist/extensions/000N-path-direct-storage-layout.d.ts +16 -0
  44. package/dist/extensions/000N-path-direct-storage-layout.d.ts.map +1 -0
  45. package/dist/extensions/000N-path-direct-storage-layout.js +46 -0
  46. package/dist/extensions/000N-path-direct-storage-layout.js.map +1 -0
  47. package/dist/extensions/index.d.ts +23 -0
  48. package/dist/extensions/index.d.ts.map +1 -0
  49. package/dist/extensions/index.js +8 -0
  50. package/dist/extensions/index.js.map +1 -0
  51. package/dist/file.d.ts +87 -0
  52. package/dist/file.d.ts.map +1 -0
  53. package/dist/file.js +118 -0
  54. package/dist/file.js.map +1 -0
  55. package/dist/index.d.ts +61 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +73 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/inventory.d.ts +155 -0
  60. package/dist/inventory.d.ts.map +1 -0
  61. package/dist/inventory.js +591 -0
  62. package/dist/inventory.js.map +1 -0
  63. package/dist/object.d.ts +188 -0
  64. package/dist/object.d.ts.map +1 -0
  65. package/dist/object.js +425 -0
  66. package/dist/object.js.map +1 -0
  67. package/dist/storage.d.ts +94 -0
  68. package/dist/storage.d.ts.map +1 -0
  69. package/dist/storage.js +302 -0
  70. package/dist/storage.js.map +1 -0
  71. package/dist/store.d.ts +100 -0
  72. package/dist/store.d.ts.map +1 -0
  73. package/dist/store.js +157 -0
  74. package/dist/store.js.map +1 -0
  75. package/dist/transaction.d.ts +155 -0
  76. package/dist/transaction.d.ts.map +1 -0
  77. package/dist/transaction.js +395 -0
  78. package/dist/transaction.js.map +1 -0
  79. package/dist/types.d.ts +107 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +2 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/utils.d.ts +24 -0
  84. package/dist/utils.d.ts.map +1 -0
  85. package/dist/utils.js +85 -0
  86. package/dist/utils.js.map +1 -0
  87. package/dist/validation.d.ts +32 -0
  88. package/dist/validation.d.ts.map +1 -0
  89. package/dist/validation.js +31 -0
  90. package/dist/validation.js.map +1 -0
  91. package/package.json +31 -50
  92. package/src/constants.ts +16 -0
  93. package/src/digest.ts +258 -0
  94. package/src/error.ts +9 -0
  95. package/src/extension.ts +206 -0
  96. package/{lib/extensions/0002-flat-direct-storage-layout.js → src/extensions/0002-flat-direct-storage-layout.ts} +15 -22
  97. package/src/extensions/0003-hash-and-id-n-tuple-storage-layout.ts +56 -0
  98. package/src/extensions/0004-hashed-n-tuple-storage-layout.ts +59 -0
  99. package/src/extensions/0006-flat-omit-prefix-storage-layout.ts +9 -0
  100. package/src/extensions/0007-n-tuple-omit-prefix-storage-layout.ts +9 -0
  101. package/src/extensions/0009-digest-algorithms.ts +12 -0
  102. package/src/extensions/000N-path-direct-storage-layout.ts +51 -0
  103. package/src/extensions/index.ts +24 -0
  104. package/src/file.ts +161 -0
  105. package/src/index.ts +92 -0
  106. package/src/inventory.ts +634 -0
  107. package/src/object.ts +473 -0
  108. package/src/storage.ts +342 -0
  109. package/src/store.ts +199 -0
  110. package/src/transaction.ts +456 -0
  111. package/{lib/types.d.ts → src/types.ts} +28 -74
  112. package/src/utils.ts +94 -0
  113. package/src/validation.ts +46 -0
  114. package/index.js +0 -129
  115. package/index.mjs +0 -18
  116. package/lib/constants.js +0 -24
  117. package/lib/digest.js +0 -307
  118. package/lib/enum.js +0 -90
  119. package/lib/error.js +0 -19
  120. package/lib/extension.js +0 -194
  121. package/lib/extensions/0003-hash-and-id-n-tuple-storage-layout.js +0 -60
  122. package/lib/extensions/0004-hashed-n-tuple-storage-layout.js +0 -63
  123. package/lib/extensions/0005-mutable-head.js +0 -0
  124. package/lib/extensions/0006-flat-omit-prefix-storage-layout.js +0 -7
  125. package/lib/extensions/0007-n-tuple-omit-prefix-storage-layout.js +0 -7
  126. package/lib/extensions/0008-schema-registry.js +0 -0
  127. package/lib/extensions/0009-digest-algorithms.js +0 -18
  128. package/lib/extensions/000N-path-direct-storage-layout.js +0 -61
  129. package/lib/extensions/index.js +0 -13
  130. package/lib/file.js +0 -129
  131. package/lib/index.js +0 -13
  132. package/lib/inventory.js +0 -564
  133. package/lib/object.js +0 -451
  134. package/lib/storage.js +0 -338
  135. package/lib/store.js +0 -191
  136. package/lib/transaction.js +0 -448
  137. package/lib/utils.js +0 -123
  138. package/lib/validation.js +0 -174
package/README.md CHANGED
@@ -1,21 +1,36 @@
1
- # ocfl-js - Common modules
2
- This is JavaScript/Node.js library to create and interact with Oxford Common File Layout (OCFL) storage and objects within it.
1
+ # @ocfl/ocfl - Common modules
2
+
3
+ TypeScript library to create and interact with Oxford Common File Layout (OCFL) storage and objects within it.
3
4
  This package contains abstract classes definition. Do not use this package directly. To work with an actual OCFL storage and object, use the following concrete implementation:
4
5
 
5
- * ocfl-fs - File system backend
6
+ - `@ocfl/ocfl-fs` - File system backend
6
7
 
7
8
  ## Extensions
8
- This library by default includes all the community extensions defined in the [OCFL Community Extensions page](https://github.com/OCFL/extensions). The implementation is organised in the ocfl-extensions package.
9
9
 
10
- To implement a local extension in this library, first follow the description in that page, then create a function like in the following example:
10
+ This library by default includes all the community extensions defined in the [OCFL Community Extensions page](https://github.com/OCFL/extensions).
11
+
12
+ To implement a local extension, first follow the description in that page, then extend `OcflExtension` (or `OcflStorageLayout` for a storage layout) and register it. For example, a storage layout:
11
13
 
12
- const ocfl = require(ocfl-fs);
13
- ocfl.extensions['9999-local-test'] = function (Storage, Object) {
14
+ import { OcflStorageLayout } from '@ocfl/ocfl';
15
+ import { storage } from '@ocfl/ocfl-fs';
14
16
 
15
-
17
+ class UppercaseLayout extends OcflStorageLayout {
18
+ static get NAME() {
19
+ return '9999-uppercase-layout';
20
+ }
21
+ static get DESCRIPTION() {
22
+ return 'Maps an object id to an uppercase directory name';
23
+ }
24
+
25
+ map(id: string): string {
26
+ return id.toUpperCase();
27
+ }
16
28
  }
17
29
 
30
+ UppercaseLayout.register();
31
+
32
+ const s = storage({ root: '/var/data/ocfl', layout: '9999-uppercase-layout' });
18
33
 
19
34
  ## Implementation
20
35
 
21
- A new data store backend can be implemented by creating a new package with a store class that extends the `OcflStore` class and implements its methods. Please see the source code of ocfl-fs as an example implementation
36
+ A new data store backend can be implemented by creating a new package with a store class that extends the `OcflStore` class and implements its methods. Please see the source code of `@ocfl/ocfl-fs` as an example implementation.
@@ -0,0 +1,15 @@
1
+ import type { OcflVersion } from './types.ts';
2
+ declare const OcflConstants: {
3
+ OCFL_VERSION: OcflVersion;
4
+ OCFL_VERSIONS: readonly ["1.1", "1.0"];
5
+ OCFL_LAYOUT: string;
6
+ NAMASTE_T: string;
7
+ NAMASTE_PREFIX_OBJECT: string;
8
+ NAMASTE_PREFIX_STORAGE: string;
9
+ INVENTORY_NAME: string;
10
+ EXTENSIONS_DIR: string;
11
+ EXTENSION_CONFIG: string;
12
+ DIGEST_ALGORITHM: string;
13
+ };
14
+ export { OcflConstants };
15
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,QAAA,MAAM,aAAa;IACjB,YAAY,EAAW,WAAW;IAClC,aAAa;IACb,WAAW;IACX,SAAS;IACT,qBAAqB;IACrB,sBAAsB;IACtB,cAAc;IACd,cAAc;IACd,gBAAgB;IAChB,gBAAgB;CACjB,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ const OcflConstants = {
2
+ OCFL_VERSION: '1.1',
3
+ OCFL_VERSIONS: Object.freeze(['1.1', '1.0']),
4
+ OCFL_LAYOUT: 'ocfl_layout.json',
5
+ NAMASTE_T: '0=',
6
+ NAMASTE_PREFIX_OBJECT: 'ocfl_object_',
7
+ NAMASTE_PREFIX_STORAGE: 'ocfl_',
8
+ INVENTORY_NAME: 'inventory.json',
9
+ EXTENSIONS_DIR: 'extensions',
10
+ EXTENSION_CONFIG: 'config.json',
11
+ DIGEST_ALGORITHM: 'sha512',
12
+ };
13
+ export { OcflConstants };
14
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG;IACpB,YAAY,EAAE,KAAoB;IAClC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC;IACrD,WAAW,EAAE,kBAAkB;IAC/B,SAAS,EAAE,IAAI;IACf,qBAAqB,EAAE,cAAc;IACrC,sBAAsB,EAAE,OAAO;IAC/B,cAAc,EAAE,gBAAgB;IAChC,cAAc,EAAE,YAAY;IAC5B,gBAAgB,EAAE,aAAa;IAC/B,gBAAgB,EAAE,QAAQ;CAC3B,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,58 @@
1
+ import type { CommonHasher, IDataType, MultiHasher } from './types.ts';
2
+ declare const CONTENT: readonly ['sha256', 'sha512'];
3
+ type ContentAlgorithm = (typeof CONTENT)[number];
4
+ type Digest = CommonHasher['digest'];
5
+ type MultiDigest = MultiHasher['digest'];
6
+ type WritableStreamHasher = WritableStream & {
7
+ update(data: IDataType): void;
8
+ digest: Digest;
9
+ };
10
+ type WritableStreamMultiHasher = WritableStream & {
11
+ update(data: IDataType): void;
12
+ digest: MultiDigest;
13
+ };
14
+ type StreamThroughHash = TransformStream & {
15
+ digest: MultiDigest;
16
+ };
17
+ type StreamThroughOptions = {
18
+ writableStrategy?: QueuingStrategy;
19
+ readableStrategy?: QueuingStrategy;
20
+ };
21
+ /**
22
+ * Register a hash algorithm and it's factory function.
23
+ */
24
+ declare function registerHasherFactory(name: string, factory: () => Promise<CommonHasher>): void;
25
+ declare function hasAlgorithm(name: string): boolean;
26
+ /**
27
+ * Create a hash instance that implements WritableStream.
28
+ * @param algorithm One or more digest algorithm names
29
+ */
30
+ declare function createStream(algorithm?: string): Promise<WritableStreamHasher>;
31
+ declare function createStream(algorithm: string[]): Promise<WritableStreamMultiHasher>;
32
+ /**
33
+ * Create a pass through stream that pass data as it is and calculate the digest as data pass through.
34
+ */
35
+ declare function createStreamThrough(algorithm?: string | string[], options?: StreamThroughOptions): Promise<StreamThroughHash>;
36
+ declare function digest(algorithm: string[], input: IDataType | ReadableStream): Promise<{
37
+ [key: string]: string;
38
+ }>;
39
+ declare function digest(algorithm: string, input: IDataType | ReadableStream): Promise<string>;
40
+ declare function initSync(algorithm: string): Promise<void>;
41
+ /**
42
+ * For this sync function to work correctly, it requires a call to initSync() to be awaited for each algorithm before calling this function.
43
+ */
44
+ declare function digestSync(algorithm: string, input: IDataType): string;
45
+ declare function getHexDigestLength(algorithm: string): number;
46
+ declare const OcflDigest: {
47
+ CONTENT: readonly ["sha256", "sha512"];
48
+ createStream: typeof createStream;
49
+ createStreamThrough: typeof createStreamThrough;
50
+ digest: typeof digest;
51
+ registerHasherFactory: typeof registerHasherFactory;
52
+ hasAlgorithm: typeof hasAlgorithm;
53
+ getHexDigestLength: typeof getHexDigestLength;
54
+ digestSync: typeof digestSync;
55
+ initSync: typeof initSync;
56
+ };
57
+ export { type ContentAlgorithm, OcflDigest };
58
+ //# sourceMappingURL=digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvE,QAAA,MAAM,OAAO,YAAI,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAC9C,KAAK,gBAAgB,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAYjD,KAAK,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AACrC,KAAK,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;AACzC,KAAK,oBAAoB,GAAG,cAAc,GAAG;IAAE,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/F,KAAK,yBAAyB,GAAG,cAAc,GAAG;IAAE,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AACzG,KAAK,iBAAiB,GAAG,eAAe,GAAG;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AACnE,KAAK,oBAAoB,GAAG;IAAE,gBAAgB,CAAC,EAAE,eAAe,CAAC;IAAC,gBAAgB,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC;AAqCvG;;GAEG;AACH,iBAAS,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,QAIhF;AAED,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,WAEjC;AAuFD;;;GAGG;AACH,iBAAe,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAC/E,iBAAe,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAerF;;GAEG;AACH,iBAAe,mBAAmB,CAAC,SAAS,GAAE,MAAM,GAAG,MAAM,EAAa,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAetI;AAED,iBAAe,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,cAAc,GAAG,OAAO,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,CAAC;AAClH,iBAAe,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAW7F,iBAAe,QAAQ,CAAC,SAAS,EAAE,MAAM,iBAQxC;AAED;;GAEG;AACH,iBAAS,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAM/D;AAaD,iBAAS,kBAAkB,CAAC,SAAS,EAAE,MAAM,UAE5C;AAED,QAAA,MAAM,UAAU;;;;;;;;;;CAUf,CAAC;AAEF,OAAO,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,CAAC"}
package/dist/digest.js ADDED
@@ -0,0 +1,204 @@
1
+ import crypto from 'node:crypto';
2
+ import zlib from 'node:zlib';
3
+ const CONTENT = ['sha256', 'sha512'];
4
+ /** OCFL algorithm name to node:crypto name */
5
+ const NATIVE = {
6
+ md5: 'md5',
7
+ sha1: 'sha1',
8
+ sha256: 'sha256',
9
+ sha512: 'sha512',
10
+ 'sha512/256': 'sha512-256',
11
+ 'blake2b-512': 'blake2b512',
12
+ };
13
+ function toBytes(data) {
14
+ if (typeof data === 'string' || data instanceof Uint8Array) {
15
+ return data;
16
+ }
17
+ if (ArrayBuffer.isView(data)) {
18
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
19
+ }
20
+ return new Uint8Array(data);
21
+ }
22
+ function hasher(digestSize, start) {
23
+ let state = start();
24
+ return {
25
+ digestSize,
26
+ init() {
27
+ state = start();
28
+ return this;
29
+ },
30
+ update(data) {
31
+ state.update(toBytes(data));
32
+ return this;
33
+ },
34
+ digest: ((encoding) => (encoding === 'binary' ? state.digest() : state.hex())),
35
+ };
36
+ }
37
+ const hasherFactory = {};
38
+ const hasherSyncCache = {};
39
+ /**
40
+ * Register a hash algorithm and it's factory function.
41
+ */
42
+ function registerHasherFactory(name, factory) {
43
+ if (typeof factory === 'function') {
44
+ hasherFactory[name] = factory;
45
+ }
46
+ }
47
+ function hasAlgorithm(name) {
48
+ return name in hasherFactory;
49
+ }
50
+ for (const [algo, nativeName] of Object.entries(NATIVE)) {
51
+ const digestSize = crypto.createHash(nativeName).digest().length;
52
+ registerHasherFactory(algo, async () => hasher(digestSize, () => {
53
+ const h = crypto.createHash(nativeName);
54
+ let result;
55
+ const final = () => {
56
+ result ??= h.digest();
57
+ return result;
58
+ };
59
+ return { update: (d) => h.update(d), digest: () => new Uint8Array(final()), hex: () => final().toString('hex') };
60
+ }));
61
+ }
62
+ registerHasherFactory('crc32', async () => hasher(4, () => {
63
+ let crc = 0;
64
+ return {
65
+ update: (d) => {
66
+ crc = zlib.crc32(d, crc);
67
+ },
68
+ digest: () => {
69
+ const b = new Uint8Array(4);
70
+ new DataView(b.buffer).setUint32(0, crc);
71
+ return b;
72
+ },
73
+ hex: () => crc.toString(16).padStart(8, '0'),
74
+ };
75
+ }));
76
+ registerHasherFactory('size', async () => hasher(8, () => {
77
+ let size = 0;
78
+ return {
79
+ update: (d) => {
80
+ size += typeof d === 'string' ? Buffer.byteLength(d) : d.byteLength;
81
+ },
82
+ digest: () => new Uint8Array(new BigUint64Array([BigInt(size)]).buffer),
83
+ hex: () => `${size}`,
84
+ };
85
+ }));
86
+ /**
87
+ * Create a hasher instance for the given algorithm.
88
+ */
89
+ async function createHasher(algorithm) {
90
+ const factory = hasherFactory[algorithm];
91
+ if (!factory) {
92
+ throw new Error(`Unsupported digest algorithm: ${algorithm}`);
93
+ }
94
+ return (await factory()).init();
95
+ }
96
+ /**
97
+ * Create a hasher instance for calculating multiple types of digest in one go.
98
+ */
99
+ async function createMultiHasher(algorithms) {
100
+ const algoNames = Array.isArray(algorithms) ? (algorithms.length ? [...new Set(algorithms)] : ['sha512']) : [algorithms];
101
+ const hashers = await Promise.all(algoNames.map(async (name) => [name, await createHasher(name)]));
102
+ const multiHasher = {
103
+ multi: true,
104
+ update(data) {
105
+ for (const [, hash] of hashers) {
106
+ hash.update(data);
107
+ }
108
+ return this;
109
+ },
110
+ digest: ((encoding) => {
111
+ const result = {};
112
+ for (const [name, hash] of hashers) {
113
+ result[name] = hash.digest(encoding);
114
+ }
115
+ return result;
116
+ }),
117
+ };
118
+ return multiHasher;
119
+ }
120
+ function createAnyHasher(algorithm) {
121
+ return Array.isArray(algorithm) ? createMultiHasher(algorithm) : createHasher(algorithm);
122
+ }
123
+ async function createStream(algorithm = 'sha512') {
124
+ const hash = await createAnyHasher(algorithm);
125
+ const ws = new WritableStream({
126
+ write(chunk) {
127
+ hash.update(chunk);
128
+ },
129
+ });
130
+ ws.update = (data) => {
131
+ hash.update(data);
132
+ };
133
+ ws.digest = ((encoding) => hash.digest(encoding));
134
+ return ws;
135
+ }
136
+ /**
137
+ * Create a pass through stream that pass data as it is and calculate the digest as data pass through.
138
+ */
139
+ async function createStreamThrough(algorithm = 'sha512', options) {
140
+ const hash = await createAnyHasher(algorithm);
141
+ const { writableStrategy, readableStrategy } = options || {};
142
+ const ts = new TransformStream({
143
+ transform(chunk, controller) {
144
+ controller.enqueue(chunk);
145
+ hash.update(chunk);
146
+ },
147
+ }, writableStrategy, readableStrategy);
148
+ ts.digest = ((encoding) => hash.digest(encoding));
149
+ return ts;
150
+ }
151
+ async function digest(algorithm, input) {
152
+ if (input instanceof ReadableStream) {
153
+ const hash = await createStream(algorithm);
154
+ await input.pipeTo(hash);
155
+ return hash.digest();
156
+ }
157
+ const hash = await createAnyHasher(algorithm);
158
+ return hash.update(input).digest();
159
+ }
160
+ async function initSync(algorithm) {
161
+ if (!hasherSyncCache[algorithm]) {
162
+ const factory = hasherFactory[algorithm];
163
+ if (!factory) {
164
+ throw new Error(`Unsupported digest algorithm: ${algorithm}`);
165
+ }
166
+ hasherSyncCache[algorithm] = await factory();
167
+ }
168
+ }
169
+ /**
170
+ * For this sync function to work correctly, it requires a call to initSync() to be awaited for each algorithm before calling this function.
171
+ */
172
+ function digestSync(algorithm, input) {
173
+ const hasher = hasherSyncCache[algorithm];
174
+ if (!hasher) {
175
+ throw new Error(`Hasher for algorithm ${algorithm} is not initialized. Please call and await initSync('${algorithm}') before calling this function.`);
176
+ }
177
+ return hasher.init().update(input).digest();
178
+ }
179
+ const HEX_DIGEST_LENGTH = {
180
+ md5: 32,
181
+ sha1: 40,
182
+ sha256: 64,
183
+ 'sha512/256': 64,
184
+ sha512: 128,
185
+ 'blake2b-512': 128,
186
+ crc32: 8,
187
+ size: 1,
188
+ };
189
+ function getHexDigestLength(algorithm) {
190
+ return HEX_DIGEST_LENGTH[algorithm] || 0;
191
+ }
192
+ const OcflDigest = {
193
+ CONTENT,
194
+ createStream,
195
+ createStreamThrough,
196
+ digest,
197
+ registerHasherFactory,
198
+ hasAlgorithm,
199
+ getHexDigestLength,
200
+ digestSync,
201
+ initSync,
202
+ };
203
+ export { OcflDigest };
204
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ declare class NotImplementedError extends Error {
2
+ constructor(methodName?: string);
3
+ }
4
+ export { NotImplementedError };
5
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,cAAM,mBAAoB,SAAQ,KAAK;IACrC,YAAY,UAAU,CAAC,EAAE,MAAM,EAI9B;CACF;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
package/dist/error.js ADDED
@@ -0,0 +1,9 @@
1
+ class NotImplementedError extends Error {
2
+ constructor(methodName) {
3
+ const msg = methodName ? `Method ${methodName} has not been implemented` : '';
4
+ super(msg);
5
+ this.name = 'NotImplementedError';
6
+ }
7
+ }
8
+ export { NotImplementedError };
9
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,MAAM,mBAAoB,SAAQ,KAAK;IACrC,YAAY,UAAmB;QAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,UAAU,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,83 @@
1
+ import type { StorageLayout } from './extensions/index.ts';
2
+ import type { OcflExtensionConfig } from './types.ts';
3
+ type ExtensionConstructor<T> = new (config?: OcflExtensionConfig) => T;
4
+ declare class OcflExtension<C extends object = object> {
5
+ #private;
6
+ parameters: C;
7
+ /**
8
+ * Get an object-level extension
9
+ * @param name - A registered extension name
10
+ */
11
+ static object(name: string): typeof OcflExtension | undefined;
12
+ /**
13
+ * Get an storage-level extension
14
+ * @param name - A registered extension name
15
+ */
16
+ static storage(name: string): typeof OcflExtension | undefined;
17
+ /** List all registered extension classes */
18
+ static get classes(): (typeof OcflExtension)[];
19
+ /**
20
+ * Find a registered extension with the specified name
21
+ * @param name - extension class name or registered extension name
22
+ * @returns the extension class
23
+ */
24
+ static class(name: string): typeof OcflExtension | undefined;
25
+ /**
26
+ * Register an extension
27
+ */
28
+ static register(extensionClass?: typeof OcflExtension): void;
29
+ /**
30
+ * Create an instance of the extension
31
+ */
32
+ static create<T extends OcflExtension>(this: ExtensionConstructor<T>, config?: OcflExtensionConfig): T;
33
+ static get forObject(): boolean;
34
+ static get forStorage(): boolean;
35
+ static get NAME(): string;
36
+ static get DESCRIPTION(): string;
37
+ static setup(_ocfl: typeof import('./index.ts')): Promise<void>;
38
+ constructor(config?: OcflExtensionConfig, defaultConfig?: C);
39
+ /** Return all the parameters in which the value has been set to non-default value */
40
+ get config(): OcflExtensionConfig | undefined;
41
+ get p(): C;
42
+ /** Extension registered name */
43
+ get name(): string;
44
+ get description(): string;
45
+ get minOcflVersion(): string;
46
+ get version(): string;
47
+ /**
48
+ * Get the specified parameter value
49
+ * @param param - The extension parameter name
50
+ */
51
+ get(param: string): any;
52
+ /**
53
+ * Set the specified parameter value
54
+ * @param param - The extension parameter name
55
+ * @param value - The extension parameter value
56
+ */
57
+ set(param: string, value: unknown): void;
58
+ }
59
+ declare class OcflStorageLayout<C extends object = object> extends OcflExtension<C> {
60
+ static get layout(): StorageLayout;
61
+ static class(name: string): typeof OcflStorageLayout | undefined;
62
+ static get classes(): (typeof OcflStorageLayout)[];
63
+ /**
64
+ * Register a storage layout extension
65
+ */
66
+ static register(extensionClass?: typeof OcflStorageLayout): void;
67
+ static get forStorage(): boolean;
68
+ validate(): Promise<void>;
69
+ /**
70
+ * Map an object identifier to a path
71
+ * @param id - The identifier of the OCFL Object
72
+ */
73
+ map(_id: string): string;
74
+ }
75
+ type ExtensionRegistry<T> = {
76
+ class(name: string): {
77
+ create(config?: OcflExtensionConfig): T;
78
+ } | undefined;
79
+ };
80
+ /** Create an instance of the extension registered as `name`, or throw if `registry` has none */
81
+ declare function createByName<T extends OcflExtension>(registry: ExtensionRegistry<T>, kind: 'Extension' | 'Layout', name: string | undefined, config?: OcflExtensionConfig): T;
82
+ export { createByName, OcflExtension, OcflStorageLayout };
83
+ //# sourceMappingURL=extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ import { NotImplementedError } from './error.js';
2
+ /** Index by Registered extension name */
3
+ const extensionByName = {};
4
+ /** Index by extension class name */
5
+ const extensionByClassName = {};
6
+ const storageLayout = {};
7
+ class OcflExtension {
8
+ static #object = {};
9
+ static #storage = {};
10
+ parameters;
11
+ /**
12
+ * Get an object-level extension
13
+ * @param name - A registered extension name
14
+ */
15
+ static object(name) {
16
+ return OcflExtension.#object[name];
17
+ }
18
+ /**
19
+ * Get an storage-level extension
20
+ * @param name - A registered extension name
21
+ */
22
+ static storage(name) {
23
+ return OcflExtension.#storage[name];
24
+ }
25
+ /** List all registered extension classes */
26
+ static get classes() {
27
+ return Object.values(extensionByName);
28
+ }
29
+ /**
30
+ * Find a registered extension with the specified name
31
+ * @param name - extension class name or registered extension name
32
+ * @returns the extension class
33
+ */
34
+ static class(name) {
35
+ return extensionByName[name] || extensionByClassName[name];
36
+ }
37
+ /**
38
+ * Register an extension
39
+ */
40
+ // biome-ignore lint/complexity/noThisInStatic: defaults to the subclass register() is called on
41
+ static register(extensionClass = this) {
42
+ const name = extensionClass.NAME;
43
+ extensionByName[name] = extensionClass;
44
+ extensionByClassName[extensionClass.name] = extensionClass;
45
+ import('./index.js').then((ocfl) => extensionClass.setup(ocfl));
46
+ }
47
+ /**
48
+ * Create an instance of the extension
49
+ */
50
+ static create(config) {
51
+ const name = config?.extensionName;
52
+ // biome-ignore lint/complexity/noThisInStatic: must be the subclass create() is called on, or it recurses
53
+ if (!name || this.NAME === name) {
54
+ return new this(config);
55
+ }
56
+ return createByName(OcflExtension, 'Extension', name, config);
57
+ }
58
+ static get forObject() {
59
+ return false;
60
+ }
61
+ static get forStorage() {
62
+ return false;
63
+ }
64
+ static get NAME() {
65
+ return '0000-example-extension';
66
+ }
67
+ static get DESCRIPTION() {
68
+ return 'Example extension';
69
+ }
70
+ static async setup(_ocfl) { }
71
+ constructor(config, defaultConfig) {
72
+ this.parameters = typeof defaultConfig === 'object' ? Object.create(defaultConfig) : {};
73
+ if (typeof config === 'object' && defaultConfig) {
74
+ for (const k in config) {
75
+ if (k in defaultConfig) {
76
+ this.parameters[k] = config[k];
77
+ }
78
+ }
79
+ }
80
+ }
81
+ /** Return all the parameters in which the value has been set to non-default value */
82
+ get config() {
83
+ const paramNames = Object.keys(this.parameters);
84
+ if (paramNames.length === 0) {
85
+ return undefined;
86
+ }
87
+ const params = { extensionName: this.name };
88
+ for (const name of paramNames) {
89
+ params[name] = this.get(name);
90
+ }
91
+ return params;
92
+ }
93
+ get p() {
94
+ return this.parameters;
95
+ }
96
+ /** Extension registered name */
97
+ get name() {
98
+ return this.constructor.NAME;
99
+ }
100
+ get description() {
101
+ return this.constructor.DESCRIPTION;
102
+ }
103
+ get minOcflVersion() {
104
+ return '1.0';
105
+ }
106
+ get version() {
107
+ return '1.0';
108
+ }
109
+ /**
110
+ * Get the specified parameter value
111
+ * @param param - The extension parameter name
112
+ */
113
+ // biome-ignore lint/suspicious/noExplicitAny: parameter values are extension specific
114
+ get(param) {
115
+ return this.parameters[param];
116
+ }
117
+ /**
118
+ * Set the specified parameter value
119
+ * @param param - The extension parameter name
120
+ * @param value - The extension parameter value
121
+ */
122
+ set(param, value) {
123
+ if (param in this.parameters) {
124
+ this.parameters[param] = value;
125
+ }
126
+ }
127
+ }
128
+ class OcflStorageLayout extends OcflExtension {
129
+ static get layout() {
130
+ return storageLayout;
131
+ }
132
+ static class(name) {
133
+ const c = OcflExtension.class(name);
134
+ if (c && c.prototype instanceof OcflStorageLayout) {
135
+ return c;
136
+ }
137
+ }
138
+ static get classes() {
139
+ return Object.values(storageLayout);
140
+ }
141
+ /**
142
+ * Register a storage layout extension
143
+ */
144
+ // biome-ignore lint/complexity/noThisInStatic: defaults to the subclass register() is called on
145
+ static register(extensionClass = this) {
146
+ OcflExtension.register(extensionClass);
147
+ storageLayout[extensionClass.name] = extensionClass;
148
+ }
149
+ static get forStorage() {
150
+ return true;
151
+ }
152
+ async validate() { }
153
+ /**
154
+ * Map an object identifier to a path
155
+ * @param id - The identifier of the OCFL Object
156
+ */
157
+ map(_id) {
158
+ throw new NotImplementedError();
159
+ }
160
+ }
161
+ /** Create an instance of the extension registered as `name`, or throw if `registry` has none */
162
+ function createByName(registry, kind, name, config) {
163
+ const cls = name ? registry.class(name) : undefined;
164
+ if (!cls) {
165
+ throw new Error(`${kind} "${name}" is not supported.`);
166
+ }
167
+ return cls.create(config);
168
+ }
169
+ export { createByName, OcflExtension, OcflStorageLayout };
170
+ //# sourceMappingURL=extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}