meca 1.0.4 → 1.0.5
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 +124 -5
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/validate.d.ts +1 -0
- package/dist/cli/validate.d.ts.map +1 -0
- package/dist/cli/validate.js +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -1
- package/dist/{MECA_manifest.dtd → manifest-1.0.dtd} +2 -4
- package/dist/manifest.d.ts +55 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +194 -0
- package/dist/meca.cjs +3185 -2736
- package/dist/transfer-1.0.dtd +44 -0
- package/dist/transfer.d.ts +71 -0
- package/dist/transfer.d.ts.map +1 -0
- package/dist/transfer.js +276 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +30 -0
- package/dist/{validate/dtd.d.ts → validate.d.ts} +1 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +163 -0
- package/dist/version.d.ts +2 -1
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +1 -1
- package/package.json +9 -8
- package/dist/validate/dtd.js +0 -175
- package/dist/validate/index.d.ts +0 -1
- package/dist/validate/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# meca
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/meca)
|
|
4
|
-
[](https://github.com/curvenote/
|
|
5
|
-
[](https://github.com/curvenote/jats/blob/main/LICENSE)
|
|
5
|
+
[](https://github.com/curvenote/jats/actions)
|
|
6
6
|
|
|
7
7
|
Types and utilities for working with MECA bundles documents in Node and Typescript.
|
|
8
8
|
|
|
@@ -17,11 +17,130 @@ meca -v
|
|
|
17
17
|
|
|
18
18
|
## What is MECA?
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Manuscript Exchange Common Approach (MECA) is a [NISO standard](https://www.niso.org/standards-committees/meca) for transferring scientific manuscripts between vendors. It is a ZIP file with a `manifest.xml`, which contains a JATS file as the `article-metadata` and other source materials.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
## From the command line
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Commands available:
|
|
25
|
+
|
|
26
|
+
`validate`: validate the MECA zip file, including the JATS
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
meca validate my-meca-file.zip
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## From Typescript
|
|
33
|
+
|
|
34
|
+
The `manifest.xml` can be read and written as follows.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import fs from 'fs';
|
|
38
|
+
import { ManifestXml, createManifestXml } from 'meca';
|
|
39
|
+
|
|
40
|
+
const data = fs.readFileSync('manifest.xml').toString();
|
|
41
|
+
const manifest = new ManifestXml(data);
|
|
42
|
+
console.log(manifest.items);
|
|
43
|
+
|
|
44
|
+
// Write a manifest file
|
|
45
|
+
const roundTrip = createManifestXml(manifest.items);
|
|
46
|
+
fs.writeFileSync('manifest.xml', roundTrip);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The `ManifestItem` has the following shape:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
type ManifestItem = {
|
|
53
|
+
id?: string;
|
|
54
|
+
itemType?: string;
|
|
55
|
+
version?: string;
|
|
56
|
+
title?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
href: string;
|
|
59
|
+
mediaType?: string;
|
|
60
|
+
fileOrder?: string;
|
|
61
|
+
metadata?: Record<string, string>;
|
|
62
|
+
};
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
which translates to the following XML, for example, from the NISO spec:
|
|
66
|
+
|
|
67
|
+
```xml
|
|
68
|
+
<item id="b-456" item-type="figure" item-version="0">
|
|
69
|
+
<item-description>Figure</item-description>
|
|
70
|
+
<file-order>3</file-order>
|
|
71
|
+
<item-metadata>
|
|
72
|
+
<metadata metadata-name="Figure Number">1</metadata>
|
|
73
|
+
<metadata metadata-name="Caption"
|
|
74
|
+
>This is the caption for Figure 1</metadata>
|
|
75
|
+
</item-metadata>
|
|
76
|
+
<instance media-type="image/jpeg" xlink:href="wrist_scaphoidvx_diagnosis.jpg" />
|
|
77
|
+
</item>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
We assume that there is only one instance for each `item` and will warn if that is not the case.
|
|
81
|
+
|
|
82
|
+
### transfer.xml
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import fs from 'fs';
|
|
86
|
+
import { TransferXml, createTransferXml } from 'meca';
|
|
87
|
+
|
|
88
|
+
const data = fs.readFileSync('manifest.xml').toString();
|
|
89
|
+
const transfer = new TransferXml(data);
|
|
90
|
+
console.log(transfer.source);
|
|
91
|
+
|
|
92
|
+
// Write a transfer file
|
|
93
|
+
const roundTrip = createTransferXml({ source, destination, instructions });
|
|
94
|
+
fs.writeFileSync('transfer.xml', roundTrip);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The `source` has the following structure:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const source = {
|
|
101
|
+
provider: {
|
|
102
|
+
name: 'Aries Systems',
|
|
103
|
+
contact: {
|
|
104
|
+
name: { given: 'Mary', surname: 'Smith' },
|
|
105
|
+
email: 'MarySmith@sample.email',
|
|
106
|
+
phone: '444-555-0101',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
publication: {
|
|
110
|
+
type: 'journal',
|
|
111
|
+
title: 'The Journal of the American Medical Association',
|
|
112
|
+
acronym: 'JAMA',
|
|
113
|
+
contact: {
|
|
114
|
+
email: 'MyJournal@ariessys.com',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Which creates the following XML:
|
|
121
|
+
|
|
122
|
+
```xml
|
|
123
|
+
<transfer-source>
|
|
124
|
+
<service-provider>
|
|
125
|
+
<provider-name>Aries Systems</provider-name>
|
|
126
|
+
<contact>
|
|
127
|
+
<contact-name>
|
|
128
|
+
<surname>Smith</surname>
|
|
129
|
+
<given-names>Mary</given-names>
|
|
130
|
+
</contact-name>
|
|
131
|
+
<email>MarySmith@sample.email</email>
|
|
132
|
+
<phone>444-555-0101</phone>
|
|
133
|
+
</contact>
|
|
134
|
+
</service-provider>
|
|
135
|
+
<publication type="journal">
|
|
136
|
+
<publication-title>The Journal of the American Medical Association</publication-title>
|
|
137
|
+
<acronym>JAMA</acronym>
|
|
138
|
+
<contact>
|
|
139
|
+
<email>MyJournal@ariessys.com</email>
|
|
140
|
+
</contact>
|
|
141
|
+
</publication>
|
|
142
|
+
</transfer-source>
|
|
143
|
+
```
|
|
25
144
|
|
|
26
145
|
---
|
|
27
146
|
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
package/dist/cli/index.js
CHANGED
|
@@ -4,6 +4,6 @@ import version from '../version.js';
|
|
|
4
4
|
import { addValidateCLI } from './validate.js';
|
|
5
5
|
const program = new Command();
|
|
6
6
|
addValidateCLI(program);
|
|
7
|
-
program.version(`v${version}`, '-v, --version', 'Print the current version of
|
|
7
|
+
program.version(`v${version}`, '-v, --version', 'Print the current version of meca');
|
|
8
8
|
program.option('-d, --debug', 'Log out any errors to the console.');
|
|
9
9
|
program.parse(process.argv);
|
package/dist/cli/validate.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AA8C5C,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,QAE9C"}
|
package/dist/cli/validate.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, Option } from 'commander';
|
|
2
2
|
import { clirun } from 'myst-cli-utils';
|
|
3
3
|
import { getSession } from 'jats-xml';
|
|
4
|
-
import { validateMecaWrapper } from '../validate
|
|
4
|
+
import { validateMecaWrapper } from '../validate.js';
|
|
5
5
|
function makeValidateCLI(program) {
|
|
6
6
|
const command = new Command('validate')
|
|
7
7
|
.description(`
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
<!-- DOCTYPE manifest PUBLIC “-//MECA//DTD Manifest v1.0//en"
|
|
2
|
-
"https://www.manuscriptexchange.org/schema/manifest-1.0.dtd"
|
|
3
|
-
-->
|
|
1
|
+
<!-- DOCTYPE manifest PUBLIC “-//MECA//DTD Manifest v1.0//en" "https://meca.zip/manifest-1.0.dtd" -->
|
|
4
2
|
<!-- ============================================================= -->
|
|
5
3
|
<!-- SPECIAL CHARACTER MODULES -->
|
|
6
4
|
<!-- ============================================================= -->
|
|
@@ -40,4 +38,4 @@
|
|
|
40
38
|
<!ATTLIST instance media-type CDATA #IMPLIED>
|
|
41
39
|
<!ATTLIST instance origin CDATA #IMPLIED>
|
|
42
40
|
<!ATTLIST instance conversion CDATA #IMPLIED>
|
|
43
|
-
<!ATTLIST instance composition CDATA #IMPLIED>
|
|
41
|
+
<!ATTLIST instance composition CDATA #IMPLIED>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { GenericParent } from 'myst-common';
|
|
2
|
+
import type { Element, DeclarationAttributes } from 'xml-js';
|
|
3
|
+
import type { Logger } from 'myst-cli-utils';
|
|
4
|
+
export declare const MANIFEST = "manifest.xml";
|
|
5
|
+
export declare const MANIFEST_DTD = "manifest-1.0.dtd";
|
|
6
|
+
type Options = {
|
|
7
|
+
log?: Logger;
|
|
8
|
+
source?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare enum ItemTypes {
|
|
11
|
+
articleMetadata = "article-metadata",
|
|
12
|
+
articleSupportingFile = "article-supporting-file",
|
|
13
|
+
manuscript = "manuscript",
|
|
14
|
+
manuscriptSupportingFile = "manuscript-supporting-file",
|
|
15
|
+
articleSource = "article-source",
|
|
16
|
+
articleSourceEnvironment = "article-source-environment",
|
|
17
|
+
articleSourceDirectory = "article-source-directory",
|
|
18
|
+
transferMetadata = "transfer-metadata"
|
|
19
|
+
}
|
|
20
|
+
export type ManifestItem = {
|
|
21
|
+
id?: string;
|
|
22
|
+
itemType?: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
href: string;
|
|
27
|
+
mediaType?: string;
|
|
28
|
+
fileOrder?: string;
|
|
29
|
+
metadata?: Record<string, string>;
|
|
30
|
+
};
|
|
31
|
+
export declare class ManifestXml {
|
|
32
|
+
declaration?: DeclarationAttributes;
|
|
33
|
+
doctype?: string;
|
|
34
|
+
rawXML: string;
|
|
35
|
+
raw: Element;
|
|
36
|
+
log: Logger;
|
|
37
|
+
tree: GenericParent;
|
|
38
|
+
source?: string;
|
|
39
|
+
constructor(data: string, opts?: Options);
|
|
40
|
+
get localDtd(): string;
|
|
41
|
+
validateXml(remoteDtd?: string): Promise<boolean | undefined>;
|
|
42
|
+
get version(): string;
|
|
43
|
+
get items(): ManifestItem[];
|
|
44
|
+
get itemTypes(): string[];
|
|
45
|
+
get articleMetadata(): ManifestItem | undefined;
|
|
46
|
+
get transferMetadata(): ManifestItem[];
|
|
47
|
+
}
|
|
48
|
+
type WriteOptions = {
|
|
49
|
+
/** Some publishers prefer `href` instead of `xlink:href`, which is in the spec */
|
|
50
|
+
noXLink?: boolean;
|
|
51
|
+
dtdUrl?: string;
|
|
52
|
+
};
|
|
53
|
+
export declare function createManifestXml(manifestItems: ManifestItem[], opts?: WriteOptions): string;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAI7C,eAAO,MAAM,QAAQ,iBAAiB,CAAC;AACvC,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAE/C,KAAK,OAAO,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,oBAAY,SAAS;IACnB,eAAe,qBAAqB;IACpC,qBAAqB,4BAA4B;IACjD,UAAU,eAAe;IACzB,wBAAwB,+BAA+B;IACvD,aAAa,mBAAmB;IAChC,wBAAwB,+BAA+B;IACvD,sBAAsB,6BAA6B;IACnD,gBAAgB,sBAAsB;CACvC;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,qBAAa,WAAW;IACtB,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEJ,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAuBxC,IAAI,QAAQ,IAAI,MAAM,CAOrB;IAEK,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM;IAqBpC,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,KAAK,IAAI,YAAY,EAAE,CAmC1B;IAED,IAAI,SAAS,IAAI,MAAM,EAAE,CAMxB;IAED,IAAI,eAAe,IAAI,YAAY,GAAG,SAAS,CAI9C;IAED,IAAI,gBAAgB,IAAI,YAAY,EAAE,CAErC;CACF;AAED,KAAK,YAAY,GAAG;IAClB,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAuCF,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,YAAY,EAAE,EAAE,IAAI,CAAC,EAAE,YAAY,UA4BnF"}
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { js2xml, xml2js } from 'xml-js';
|
|
13
|
+
import { convertToUnist, xmllintValidate } from 'jats-xml';
|
|
14
|
+
import { tic } from 'myst-cli-utils';
|
|
15
|
+
import { createTempFolder, elementWithText, removeTempFolder, select, selectAll } from './utils.js';
|
|
16
|
+
export const MANIFEST = 'manifest.xml';
|
|
17
|
+
export const MANIFEST_DTD = 'manifest-1.0.dtd';
|
|
18
|
+
export var ItemTypes;
|
|
19
|
+
(function (ItemTypes) {
|
|
20
|
+
ItemTypes["articleMetadata"] = "article-metadata";
|
|
21
|
+
ItemTypes["articleSupportingFile"] = "article-supporting-file";
|
|
22
|
+
ItemTypes["manuscript"] = "manuscript";
|
|
23
|
+
ItemTypes["manuscriptSupportingFile"] = "manuscript-supporting-file";
|
|
24
|
+
ItemTypes["articleSource"] = "article-source";
|
|
25
|
+
ItemTypes["articleSourceEnvironment"] = "article-source-environment";
|
|
26
|
+
ItemTypes["articleSourceDirectory"] = "article-source-directory";
|
|
27
|
+
ItemTypes["transferMetadata"] = "transfer-metadata";
|
|
28
|
+
})(ItemTypes || (ItemTypes = {}));
|
|
29
|
+
export class ManifestXml {
|
|
30
|
+
constructor(data, opts) {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const toc = tic();
|
|
33
|
+
this.log = (_a = opts === null || opts === void 0 ? void 0 : opts.log) !== null && _a !== void 0 ? _a : console;
|
|
34
|
+
this.rawXML = data;
|
|
35
|
+
if (opts === null || opts === void 0 ? void 0 : opts.source)
|
|
36
|
+
this.source = opts.source;
|
|
37
|
+
try {
|
|
38
|
+
this.raw = xml2js(data, { compact: false });
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new Error('Problem parsing the TransferXML document, please ensure it is XML');
|
|
42
|
+
}
|
|
43
|
+
const { declaration, elements } = this.raw;
|
|
44
|
+
this.declaration = declaration === null || declaration === void 0 ? void 0 : declaration.attributes;
|
|
45
|
+
if (!((elements === null || elements === void 0 ? void 0 : elements.length) === 2 && elements[0].type === 'doctype' && elements[1].name === 'manifest')) {
|
|
46
|
+
throw new Error('Element <manifest> is not the only element of the manifest.xml');
|
|
47
|
+
}
|
|
48
|
+
this.doctype = elements[0].doctype;
|
|
49
|
+
const converted = convertToUnist(elements[1]);
|
|
50
|
+
this.tree = select('manifest', converted);
|
|
51
|
+
(_b = this.log) === null || _b === void 0 ? void 0 : _b.debug(toc('Parsed and converted manifest.xml to unist tree in %s'));
|
|
52
|
+
}
|
|
53
|
+
get localDtd() {
|
|
54
|
+
// This works both compiled and in tests
|
|
55
|
+
const dtd = fs.existsSync(path.join(__dirname, MANIFEST_DTD))
|
|
56
|
+
? path.join(__dirname, MANIFEST_DTD)
|
|
57
|
+
: path.join(__dirname, '..', 'static', MANIFEST_DTD);
|
|
58
|
+
if (fs.existsSync(dtd))
|
|
59
|
+
return dtd;
|
|
60
|
+
throw new Error(`Unable to locate manifest DTD file ${MANIFEST_DTD} in meca lib distribution`);
|
|
61
|
+
}
|
|
62
|
+
validateXml(remoteDtd) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
const tempFolder = createTempFolder();
|
|
65
|
+
fs.writeFileSync(path.join(tempFolder, MANIFEST), this.rawXML);
|
|
66
|
+
let dtdFile = this.localDtd;
|
|
67
|
+
if (remoteDtd) {
|
|
68
|
+
const data = yield (yield fetch(remoteDtd)).text();
|
|
69
|
+
dtdFile = path.join(tempFolder, MANIFEST_DTD);
|
|
70
|
+
fs.writeFileSync(dtdFile, data);
|
|
71
|
+
}
|
|
72
|
+
const manifestIsValid = yield xmllintValidate(this, path.join(tempFolder, MANIFEST), dtdFile).catch(() => {
|
|
73
|
+
this.log.error(`${MANIFEST} DTD validation failed`);
|
|
74
|
+
return false;
|
|
75
|
+
});
|
|
76
|
+
removeTempFolder(tempFolder);
|
|
77
|
+
return manifestIsValid;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
get version() {
|
|
81
|
+
return this.tree['manifest-version'] || this.tree.version;
|
|
82
|
+
}
|
|
83
|
+
get items() {
|
|
84
|
+
const items = selectAll(`item`, this.tree)
|
|
85
|
+
.map((item) => {
|
|
86
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
87
|
+
const instances = selectAll(`instance`, item);
|
|
88
|
+
if (instances.length === 0) {
|
|
89
|
+
this.log.warn('Item without an instance');
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
if (instances.length > 1) {
|
|
93
|
+
this.log.warn('Item has multiple instances, only the first is used.');
|
|
94
|
+
}
|
|
95
|
+
const instance = instances[0];
|
|
96
|
+
const title = (_b = (_a = select(`item-title`, item)) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b[0].value;
|
|
97
|
+
const description = (_d = (_c = select(`item-description`, item)) === null || _c === void 0 ? void 0 : _c.children) === null || _d === void 0 ? void 0 : _d[0].value;
|
|
98
|
+
const fileOrder = (_f = (_e = select(`file-order`, item)) === null || _e === void 0 ? void 0 : _e.children) === null || _f === void 0 ? void 0 : _f[0].value;
|
|
99
|
+
const metadata = Object.fromEntries((_h = (_g = selectAll('metadata', item)) === null || _g === void 0 ? void 0 : _g.map((n) => {
|
|
100
|
+
var _a;
|
|
101
|
+
return [
|
|
102
|
+
n['metadata-name'] || n.name,
|
|
103
|
+
(_a = n === null || n === void 0 ? void 0 : n.children) === null || _a === void 0 ? void 0 : _a[0].value,
|
|
104
|
+
];
|
|
105
|
+
})) !== null && _h !== void 0 ? _h : []);
|
|
106
|
+
return {
|
|
107
|
+
id: item.id,
|
|
108
|
+
itemType: item['item-type'],
|
|
109
|
+
version: item['item-version'] || item['version'],
|
|
110
|
+
title,
|
|
111
|
+
description,
|
|
112
|
+
href: instance['xlink:href'] || instance.href,
|
|
113
|
+
mediaType: instance['media-type'],
|
|
114
|
+
fileOrder,
|
|
115
|
+
metadata,
|
|
116
|
+
};
|
|
117
|
+
})
|
|
118
|
+
.filter((item) => !!item);
|
|
119
|
+
return items;
|
|
120
|
+
}
|
|
121
|
+
get itemTypes() {
|
|
122
|
+
const itemTypes = new Set();
|
|
123
|
+
this.items.forEach((item) => {
|
|
124
|
+
if (item.itemType)
|
|
125
|
+
itemTypes.add(item.itemType);
|
|
126
|
+
});
|
|
127
|
+
return [...itemTypes];
|
|
128
|
+
}
|
|
129
|
+
get articleMetadata() {
|
|
130
|
+
const items = this.items.filter((item) => item.itemType === ItemTypes.articleMetadata);
|
|
131
|
+
if (items.length > 1)
|
|
132
|
+
this.log.warn('More than 1 article metadata found');
|
|
133
|
+
return items[0];
|
|
134
|
+
}
|
|
135
|
+
get transferMetadata() {
|
|
136
|
+
return this.items.filter((item) => item.itemType === ItemTypes.transferMetadata);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function writeManifestItem(item, opts) {
|
|
140
|
+
const { id, version, href, itemType, mediaType, title, description, fileOrder, metadata } = item;
|
|
141
|
+
return {
|
|
142
|
+
type: 'element',
|
|
143
|
+
name: 'item',
|
|
144
|
+
attributes: {
|
|
145
|
+
id,
|
|
146
|
+
'item-type': itemType,
|
|
147
|
+
'item-version': version,
|
|
148
|
+
},
|
|
149
|
+
elements: [
|
|
150
|
+
title ? elementWithText('item-title', title) : undefined,
|
|
151
|
+
description ? elementWithText('item-description', description) : undefined,
|
|
152
|
+
fileOrder ? elementWithText('file-order', fileOrder) : undefined,
|
|
153
|
+
metadata && Object.keys(metadata !== null && metadata !== void 0 ? metadata : {}).length > 0
|
|
154
|
+
? {
|
|
155
|
+
type: 'element',
|
|
156
|
+
name: 'item-metadata',
|
|
157
|
+
elements: Object.entries(metadata).map(([k, v]) => elementWithText('metadata', v, { 'metadata-name': k })),
|
|
158
|
+
}
|
|
159
|
+
: undefined,
|
|
160
|
+
{
|
|
161
|
+
type: 'element',
|
|
162
|
+
name: 'instance',
|
|
163
|
+
attributes: {
|
|
164
|
+
[(opts === null || opts === void 0 ? void 0 : opts.noXLink) ? 'href' : 'xlink:href']: href,
|
|
165
|
+
'media-type': mediaType,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
].filter((e) => !!e),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
export function createManifestXml(manifestItems, opts) {
|
|
172
|
+
var _a;
|
|
173
|
+
const element = {
|
|
174
|
+
type: 'element',
|
|
175
|
+
elements: [
|
|
176
|
+
{
|
|
177
|
+
type: 'doctype',
|
|
178
|
+
doctype: `manifest PUBLIC "-//MECA//DTD Manifest v1.0//en" "${(_a = opts === null || opts === void 0 ? void 0 : opts.dtdUrl) !== null && _a !== void 0 ? _a : 'https://meca.zip/manifest-1.0.dtd'}"`,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
type: 'element',
|
|
182
|
+
name: 'manifest',
|
|
183
|
+
attributes: Object.assign({ 'manifest-version': '1', xmlns: 'https://manuscriptexchange.org/schema/manifest' }, ((opts === null || opts === void 0 ? void 0 : opts.noXLink) ? {} : { 'xmlns:xlink': 'http://www.w3.org/1999/xlink' })),
|
|
184
|
+
elements: manifestItems.map((item) => writeManifestItem(item, opts)),
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
declaration: { attributes: { version: '1.0', encoding: 'UTF-8' } },
|
|
188
|
+
};
|
|
189
|
+
const manifest = js2xml(element, {
|
|
190
|
+
compact: false,
|
|
191
|
+
spaces: 2,
|
|
192
|
+
});
|
|
193
|
+
return manifest;
|
|
194
|
+
}
|