@frictionless-ts/dataset 1.0.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/README.md +3 -0
- package/build/file/copy.d.ts +4 -0
- package/build/file/copy.js +7 -0
- package/build/file/copy.spec.d.ts +1 -0
- package/build/file/copy.spec.js +104 -0
- package/build/file/describe.d.ts +7 -0
- package/build/file/describe.js +9 -0
- package/build/file/fetch.d.ts +2 -0
- package/build/file/fetch.js +21 -0
- package/build/file/index.d.ts +9 -0
- package/build/file/index.js +10 -0
- package/build/file/infer.d.ts +10 -0
- package/build/file/infer.js +48 -0
- package/build/file/infer.spec.d.ts +1 -0
- package/build/file/infer.spec.js +141 -0
- package/build/file/load.d.ts +3 -0
- package/build/file/load.js +7 -0
- package/build/file/path.d.ts +2 -0
- package/build/file/path.js +17 -0
- package/build/file/save.d.ts +3 -0
- package/build/file/save.js +7 -0
- package/build/file/temp.d.ts +11 -0
- package/build/file/temp.js +23 -0
- package/build/file/validate.d.ts +6 -0
- package/build/file/validate.js +47 -0
- package/build/file/validate.spec.d.ts +1 -0
- package/build/file/validate.spec.js +180 -0
- package/build/folder/create.d.ts +1 -0
- package/build/folder/create.js +5 -0
- package/build/folder/index.d.ts +2 -0
- package/build/folder/index.js +3 -0
- package/build/folder/temp.d.ts +3 -0
- package/build/folder/temp.js +16 -0
- package/build/index.d.ts +36 -0
- package/build/index.js +35 -0
- package/build/package/index.d.ts +2 -0
- package/build/package/index.js +3 -0
- package/build/package/merge.d.ts +23 -0
- package/build/package/merge.js +12 -0
- package/build/package/path.d.ts +3 -0
- package/build/package/path.js +43 -0
- package/build/package/path.spec.d.ts +1 -0
- package/build/package/path.spec.js +56 -0
- package/build/plugin.d.ts +11 -0
- package/build/plugin.js +2 -0
- package/build/plugins/ckan/ckan/index.d.ts +1 -0
- package/build/plugins/ckan/ckan/index.js +2 -0
- package/build/plugins/ckan/ckan/request.d.ts +11 -0
- package/build/plugins/ckan/ckan/request.js +35 -0
- package/build/plugins/ckan/index.d.ts +4 -0
- package/build/plugins/ckan/index.js +5 -0
- package/build/plugins/ckan/package/Organization.d.ts +21 -0
- package/build/plugins/ckan/package/Organization.js +2 -0
- package/build/plugins/ckan/package/Package.d.ts +76 -0
- package/build/plugins/ckan/package/Package.js +2 -0
- package/build/plugins/ckan/package/Tag.d.ts +17 -0
- package/build/plugins/ckan/package/Tag.js +2 -0
- package/build/plugins/ckan/package/convert/fromCkan.d.ts +3 -0
- package/build/plugins/ckan/package/convert/fromCkan.js +63 -0
- package/build/plugins/ckan/package/convert/fromCkan.spec.d.ts +1 -0
- package/build/plugins/ckan/package/convert/fromCkan.spec.js +80 -0
- package/build/plugins/ckan/package/convert/toCkan.d.ts +22 -0
- package/build/plugins/ckan/package/convert/toCkan.js +51 -0
- package/build/plugins/ckan/package/convert/toCkan.spec.d.ts +1 -0
- package/build/plugins/ckan/package/convert/toCkan.spec.js +153 -0
- package/build/plugins/ckan/package/fixtures/ckan-package.json +308 -0
- package/build/plugins/ckan/package/index.d.ts +7 -0
- package/build/plugins/ckan/package/index.js +5 -0
- package/build/plugins/ckan/package/load.d.ts +21 -0
- package/build/plugins/ckan/package/load.js +74 -0
- package/build/plugins/ckan/package/load.spec.d.ts +1 -0
- package/build/plugins/ckan/package/load.spec.js +11 -0
- package/build/plugins/ckan/package/save.d.ts +10 -0
- package/build/plugins/ckan/package/save.js +83 -0
- package/build/plugins/ckan/package/save.spec.d.ts +1 -0
- package/build/plugins/ckan/package/save.spec.js +319 -0
- package/build/plugins/ckan/plugin.d.ts +19 -0
- package/build/plugins/ckan/plugin.js +18 -0
- package/build/plugins/ckan/plugin.spec.d.ts +1 -0
- package/build/plugins/ckan/plugin.spec.js +83 -0
- package/build/plugins/ckan/resource/Resource.d.ts +56 -0
- package/build/plugins/ckan/resource/Resource.js +2 -0
- package/build/plugins/ckan/resource/convert/fromCkan.d.ts +3 -0
- package/build/plugins/ckan/resource/convert/fromCkan.js +39 -0
- package/build/plugins/ckan/resource/convert/toCkan.d.ts +3 -0
- package/build/plugins/ckan/resource/convert/toCkan.js +20 -0
- package/build/plugins/ckan/resource/index.d.ts +3 -0
- package/build/plugins/ckan/resource/index.js +3 -0
- package/build/plugins/ckan/schema/Field.d.ts +34 -0
- package/build/plugins/ckan/schema/Field.js +2 -0
- package/build/plugins/ckan/schema/Schema.d.ts +10 -0
- package/build/plugins/ckan/schema/Schema.js +2 -0
- package/build/plugins/ckan/schema/convert/fixtures/ckan-schema.json +115 -0
- package/build/plugins/ckan/schema/convert/fromCkan.d.ts +3 -0
- package/build/plugins/ckan/schema/convert/fromCkan.js +47 -0
- package/build/plugins/ckan/schema/convert/fromCkan.spec.d.ts +1 -0
- package/build/plugins/ckan/schema/convert/fromCkan.spec.js +157 -0
- package/build/plugins/ckan/schema/convert/toCkan.d.ts +3 -0
- package/build/plugins/ckan/schema/convert/toCkan.js +50 -0
- package/build/plugins/ckan/schema/convert/toCkan.spec.d.ts +1 -0
- package/build/plugins/ckan/schema/convert/toCkan.spec.js +278 -0
- package/build/plugins/ckan/schema/index.d.ts +4 -0
- package/build/plugins/ckan/schema/index.js +3 -0
- package/build/plugins/datahub/index.d.ts +2 -0
- package/build/plugins/datahub/index.js +3 -0
- package/build/plugins/datahub/package/index.d.ts +1 -0
- package/build/plugins/datahub/package/index.js +2 -0
- package/build/plugins/datahub/package/load.d.ts +1 -0
- package/build/plugins/datahub/package/load.js +9 -0
- package/build/plugins/datahub/package/load.spec.d.ts +1 -0
- package/build/plugins/datahub/package/load.spec.js +11 -0
- package/build/plugins/datahub/plugin.d.ts +4 -0
- package/build/plugins/datahub/plugin.js +18 -0
- package/build/plugins/datahub/plugin.spec.d.ts +1 -0
- package/build/plugins/datahub/plugin.spec.js +78 -0
- package/build/plugins/descriptor/index.d.ts +1 -0
- package/build/plugins/descriptor/index.js +2 -0
- package/build/plugins/descriptor/plugin.d.ts +11 -0
- package/build/plugins/descriptor/plugin.js +29 -0
- package/build/plugins/descriptor/plugin.spec.d.ts +1 -0
- package/build/plugins/descriptor/plugin.spec.js +169 -0
- package/build/plugins/folder/index.d.ts +2 -0
- package/build/plugins/folder/index.js +3 -0
- package/build/plugins/folder/package/index.d.ts +2 -0
- package/build/plugins/folder/package/index.js +3 -0
- package/build/plugins/folder/package/load.d.ts +1 -0
- package/build/plugins/folder/package/load.js +6 -0
- package/build/plugins/folder/package/load.spec.d.ts +1 -0
- package/build/plugins/folder/package/load.spec.js +175 -0
- package/build/plugins/folder/package/save.d.ts +7 -0
- package/build/plugins/folder/package/save.js +35 -0
- package/build/plugins/folder/package/save.spec.d.ts +1 -0
- package/build/plugins/folder/package/save.spec.js +328 -0
- package/build/plugins/folder/plugin.d.ts +4 -0
- package/build/plugins/folder/plugin.js +19 -0
- package/build/plugins/folder/plugin.spec.d.ts +1 -0
- package/build/plugins/folder/plugin.spec.js +53 -0
- package/build/plugins/github/github/index.d.ts +1 -0
- package/build/plugins/github/github/index.js +2 -0
- package/build/plugins/github/github/path.d.ts +1 -0
- package/build/plugins/github/github/path.js +4 -0
- package/build/plugins/github/github/request.d.ts +15 -0
- package/build/plugins/github/github/request.js +43 -0
- package/build/plugins/github/index.d.ts +3 -0
- package/build/plugins/github/index.js +4 -0
- package/build/plugins/github/package/License.d.ts +21 -0
- package/build/plugins/github/package/License.js +2 -0
- package/build/plugins/github/package/Owner.d.ts +25 -0
- package/build/plugins/github/package/Owner.js +2 -0
- package/build/plugins/github/package/Package.d.ts +87 -0
- package/build/plugins/github/package/Package.js +2 -0
- package/build/plugins/github/package/convert/fromGithub.d.ts +3 -0
- package/build/plugins/github/package/convert/fromGithub.js +50 -0
- package/build/plugins/github/package/index.d.ts +6 -0
- package/build/plugins/github/package/index.js +4 -0
- package/build/plugins/github/package/load.d.ts +23 -0
- package/build/plugins/github/package/load.js +48 -0
- package/build/plugins/github/package/load.spec.d.ts +1 -0
- package/build/plugins/github/package/load.spec.js +15 -0
- package/build/plugins/github/package/save.d.ts +14 -0
- package/build/plugins/github/package/save.js +69 -0
- package/build/plugins/github/package/save.spec.d.ts +1 -0
- package/build/plugins/github/package/save.spec.js +566 -0
- package/build/plugins/github/plugin.d.ts +19 -0
- package/build/plugins/github/plugin.js +18 -0
- package/build/plugins/github/plugin.spec.d.ts +1 -0
- package/build/plugins/github/plugin.spec.js +73 -0
- package/build/plugins/github/resource/Resource.d.ts +29 -0
- package/build/plugins/github/resource/Resource.js +2 -0
- package/build/plugins/github/resource/convert/fromGithub.d.ts +5 -0
- package/build/plugins/github/resource/convert/fromGithub.js +24 -0
- package/build/plugins/github/resource/convert/toGithub.d.ts +3 -0
- package/build/plugins/github/resource/convert/toGithub.js +10 -0
- package/build/plugins/github/resource/index.d.ts +3 -0
- package/build/plugins/github/resource/index.js +3 -0
- package/build/plugins/zenodo/index.d.ts +3 -0
- package/build/plugins/zenodo/index.js +4 -0
- package/build/plugins/zenodo/package/Creator.d.ts +20 -0
- package/build/plugins/zenodo/package/Creator.js +2 -0
- package/build/plugins/zenodo/package/Package.d.ts +94 -0
- package/build/plugins/zenodo/package/Package.js +2 -0
- package/build/plugins/zenodo/package/convert/fromZenodo.d.ts +3 -0
- package/build/plugins/zenodo/package/convert/fromZenodo.js +43 -0
- package/build/plugins/zenodo/package/convert/toZenodo.d.ts +3 -0
- package/build/plugins/zenodo/package/convert/toZenodo.js +79 -0
- package/build/plugins/zenodo/package/index.d.ts +6 -0
- package/build/plugins/zenodo/package/index.js +5 -0
- package/build/plugins/zenodo/package/load.d.ts +23 -0
- package/build/plugins/zenodo/package/load.js +45 -0
- package/build/plugins/zenodo/package/load.spec.d.ts +1 -0
- package/build/plugins/zenodo/package/load.spec.js +15 -0
- package/build/plugins/zenodo/package/save.d.ts +13 -0
- package/build/plugins/zenodo/package/save.js +74 -0
- package/build/plugins/zenodo/package/save.spec.d.ts +1 -0
- package/build/plugins/zenodo/package/save.spec.js +524 -0
- package/build/plugins/zenodo/plugin.d.ts +19 -0
- package/build/plugins/zenodo/plugin.js +18 -0
- package/build/plugins/zenodo/plugin.spec.d.ts +1 -0
- package/build/plugins/zenodo/plugin.spec.js +78 -0
- package/build/plugins/zenodo/resource/Resource.d.ts +27 -0
- package/build/plugins/zenodo/resource/Resource.js +2 -0
- package/build/plugins/zenodo/resource/convert/fromZenodo.d.ts +10 -0
- package/build/plugins/zenodo/resource/convert/fromZenodo.js +18 -0
- package/build/plugins/zenodo/resource/convert/toZenodo.d.ts +3 -0
- package/build/plugins/zenodo/resource/convert/toZenodo.js +13 -0
- package/build/plugins/zenodo/resource/index.d.ts +3 -0
- package/build/plugins/zenodo/resource/index.js +3 -0
- package/build/plugins/zenodo/zenodo/index.d.ts +1 -0
- package/build/plugins/zenodo/zenodo/index.js +2 -0
- package/build/plugins/zenodo/zenodo/request.d.ts +12 -0
- package/build/plugins/zenodo/zenodo/request.js +36 -0
- package/build/plugins/zip/index.d.ts +2 -0
- package/build/plugins/zip/index.js +3 -0
- package/build/plugins/zip/package/index.d.ts +2 -0
- package/build/plugins/zip/package/index.js +3 -0
- package/build/plugins/zip/package/load.d.ts +1 -0
- package/build/plugins/zip/package/load.js +30 -0
- package/build/plugins/zip/package/load.spec.d.ts +1 -0
- package/build/plugins/zip/package/load.spec.js +173 -0
- package/build/plugins/zip/package/save.d.ts +5 -0
- package/build/plugins/zip/package/save.js +50 -0
- package/build/plugins/zip/package/save.spec.d.ts +1 -0
- package/build/plugins/zip/package/save.spec.js +287 -0
- package/build/plugins/zip/plugin.d.ts +11 -0
- package/build/plugins/zip/plugin.js +24 -0
- package/build/plugins/zip/plugin.spec.d.ts +1 -0
- package/build/plugins/zip/plugin.spec.js +158 -0
- package/build/resource/index.d.ts +1 -0
- package/build/resource/index.js +2 -0
- package/build/resource/save.d.ts +13 -0
- package/build/resource/save.js +53 -0
- package/build/resource/save.spec.d.ts +1 -0
- package/build/resource/save.spec.js +107 -0
- package/build/stream/concat.d.ts +3 -0
- package/build/stream/concat.js +5 -0
- package/build/stream/index.d.ts +3 -0
- package/build/stream/index.js +4 -0
- package/build/stream/load.d.ts +5 -0
- package/build/stream/load.js +46 -0
- package/build/stream/save.d.ts +5 -0
- package/build/stream/save.js +13 -0
- package/package.json +48 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
import { relative } from "node:path";
|
|
2
|
+
import { loadPackageDescriptor } from "@frictionless-ts/metadata";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { savePackageToZenodo } from "./save.js";
|
|
5
|
+
describe("savePackageToZenodo", () => {
|
|
6
|
+
const getFixturePath = (name) => relative(process.cwd(), `${import.meta.dirname}/fixtures/${name}`);
|
|
7
|
+
const mockPackage = {
|
|
8
|
+
name: "test-package",
|
|
9
|
+
title: "Test Package",
|
|
10
|
+
description: "A test package",
|
|
11
|
+
version: "1.0.0",
|
|
12
|
+
resources: [
|
|
13
|
+
{
|
|
14
|
+
name: "test-resource",
|
|
15
|
+
path: getFixturePath("data.csv"),
|
|
16
|
+
format: "csv",
|
|
17
|
+
bytes: 100,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
const mockOptions = {
|
|
22
|
+
apiKey: "test-api-key",
|
|
23
|
+
sandbox: true,
|
|
24
|
+
};
|
|
25
|
+
const originalFetch = globalThis.fetch;
|
|
26
|
+
let fetchMock;
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
fetchMock = vi.fn();
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
globalThis.fetch = fetchMock;
|
|
31
|
+
});
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
globalThis.fetch = originalFetch;
|
|
34
|
+
vi.resetAllMocks();
|
|
35
|
+
});
|
|
36
|
+
it.skip("should save a package", async () => {
|
|
37
|
+
const dataPackage = await loadPackageDescriptor("core/package/fixtures/package.json");
|
|
38
|
+
const result = await savePackageToZenodo(dataPackage, {
|
|
39
|
+
apiKey: "<key>",
|
|
40
|
+
sandbox: true,
|
|
41
|
+
});
|
|
42
|
+
expect(result).toBeDefined();
|
|
43
|
+
});
|
|
44
|
+
it("creates a deposition in Zenodo with correct API calls", async () => {
|
|
45
|
+
fetchMock.mockResolvedValueOnce({
|
|
46
|
+
ok: true,
|
|
47
|
+
json: () => Promise.resolve({
|
|
48
|
+
id: 12345,
|
|
49
|
+
links: {
|
|
50
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
51
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
52
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
53
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
54
|
+
},
|
|
55
|
+
metadata: {
|
|
56
|
+
title: "Test Package",
|
|
57
|
+
description: "A test package",
|
|
58
|
+
upload_type: "dataset",
|
|
59
|
+
creators: [],
|
|
60
|
+
},
|
|
61
|
+
state: "unsubmitted",
|
|
62
|
+
submitted: false,
|
|
63
|
+
files: [],
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
fetchMock.mockResolvedValueOnce({
|
|
67
|
+
ok: true,
|
|
68
|
+
json: () => Promise.resolve({
|
|
69
|
+
id: "file-1",
|
|
70
|
+
filename: "data.csv",
|
|
71
|
+
filesize: 100,
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
fetchMock.mockResolvedValueOnce({
|
|
75
|
+
ok: true,
|
|
76
|
+
json: () => Promise.resolve({
|
|
77
|
+
id: "file-2",
|
|
78
|
+
filename: "datapackage.json",
|
|
79
|
+
filesize: 500,
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
const result = await savePackageToZenodo(mockPackage, mockOptions);
|
|
83
|
+
expect(fetchMock).toHaveBeenCalledTimes(3);
|
|
84
|
+
const depositionCreateCall = fetchMock.mock.calls[0];
|
|
85
|
+
expect(depositionCreateCall).toBeDefined();
|
|
86
|
+
if (!depositionCreateCall)
|
|
87
|
+
return;
|
|
88
|
+
expect(depositionCreateCall[0]).toContain("https://sandbox.zenodo.org/api/deposit/depositions");
|
|
89
|
+
expect(depositionCreateCall[0]).toContain("access_token=test-api-key");
|
|
90
|
+
expect(depositionCreateCall[1]).toMatchObject({
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: {
|
|
93
|
+
"Content-Type": "application/json",
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
const depositionPayload = JSON.parse(depositionCreateCall[1].body);
|
|
97
|
+
expect(depositionPayload.metadata.title).toEqual("Test Package");
|
|
98
|
+
expect(depositionPayload.metadata.description).toEqual("A test package");
|
|
99
|
+
expect(result).toEqual({
|
|
100
|
+
path: "https://sandbox.zenodo.org/records/12345/files/datapackage.json",
|
|
101
|
+
datasetUrl: "https://sandbox.zenodo.org/uploads/12345",
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
it("uploads resource files to deposition", async () => {
|
|
105
|
+
fetchMock.mockResolvedValueOnce({
|
|
106
|
+
ok: true,
|
|
107
|
+
json: () => Promise.resolve({
|
|
108
|
+
id: 12345,
|
|
109
|
+
links: {
|
|
110
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
111
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
112
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
113
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
114
|
+
},
|
|
115
|
+
metadata: {
|
|
116
|
+
title: "Test Package",
|
|
117
|
+
description: "A test package",
|
|
118
|
+
upload_type: "dataset",
|
|
119
|
+
creators: [],
|
|
120
|
+
},
|
|
121
|
+
state: "unsubmitted",
|
|
122
|
+
submitted: false,
|
|
123
|
+
files: [],
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
fetchMock.mockResolvedValueOnce({
|
|
127
|
+
ok: true,
|
|
128
|
+
json: () => Promise.resolve({
|
|
129
|
+
id: "file-1",
|
|
130
|
+
filename: "data.csv",
|
|
131
|
+
filesize: 100,
|
|
132
|
+
}),
|
|
133
|
+
});
|
|
134
|
+
fetchMock.mockResolvedValueOnce({
|
|
135
|
+
ok: true,
|
|
136
|
+
json: () => Promise.resolve({
|
|
137
|
+
id: "file-2",
|
|
138
|
+
filename: "datapackage.json",
|
|
139
|
+
filesize: 500,
|
|
140
|
+
}),
|
|
141
|
+
});
|
|
142
|
+
await savePackageToZenodo(mockPackage, mockOptions);
|
|
143
|
+
const fileUploadCall = fetchMock.mock.calls[1];
|
|
144
|
+
expect(fileUploadCall).toBeDefined();
|
|
145
|
+
if (!fileUploadCall)
|
|
146
|
+
return;
|
|
147
|
+
expect(fileUploadCall[0]).toContain("https://sandbox.zenodo.org/api/deposit/depositions/12345/files");
|
|
148
|
+
expect(fileUploadCall[0]).toContain("access_token=test-api-key");
|
|
149
|
+
expect(fileUploadCall[1]).toMatchObject({
|
|
150
|
+
method: "POST",
|
|
151
|
+
});
|
|
152
|
+
const formData = fileUploadCall[1].body;
|
|
153
|
+
expect(formData).toBeInstanceOf(FormData);
|
|
154
|
+
});
|
|
155
|
+
it("uploads datapackage.json metadata file", async () => {
|
|
156
|
+
fetchMock.mockResolvedValueOnce({
|
|
157
|
+
ok: true,
|
|
158
|
+
json: () => Promise.resolve({
|
|
159
|
+
id: 12345,
|
|
160
|
+
links: {
|
|
161
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
162
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
163
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
164
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
165
|
+
},
|
|
166
|
+
metadata: {
|
|
167
|
+
title: "Test Package",
|
|
168
|
+
description: "A test package",
|
|
169
|
+
upload_type: "dataset",
|
|
170
|
+
creators: [],
|
|
171
|
+
},
|
|
172
|
+
state: "unsubmitted",
|
|
173
|
+
submitted: false,
|
|
174
|
+
files: [],
|
|
175
|
+
}),
|
|
176
|
+
});
|
|
177
|
+
fetchMock.mockResolvedValueOnce({
|
|
178
|
+
ok: true,
|
|
179
|
+
json: () => Promise.resolve({
|
|
180
|
+
id: "file-1",
|
|
181
|
+
filename: "data.csv",
|
|
182
|
+
filesize: 100,
|
|
183
|
+
}),
|
|
184
|
+
});
|
|
185
|
+
fetchMock.mockResolvedValueOnce({
|
|
186
|
+
ok: true,
|
|
187
|
+
json: () => Promise.resolve({
|
|
188
|
+
id: "file-2",
|
|
189
|
+
filename: "datapackage.json",
|
|
190
|
+
filesize: 500,
|
|
191
|
+
}),
|
|
192
|
+
});
|
|
193
|
+
await savePackageToZenodo(mockPackage, mockOptions);
|
|
194
|
+
const datapackageUploadCall = fetchMock.mock.calls[2];
|
|
195
|
+
expect(datapackageUploadCall).toBeDefined();
|
|
196
|
+
if (!datapackageUploadCall)
|
|
197
|
+
return;
|
|
198
|
+
expect(datapackageUploadCall[0]).toContain("https://sandbox.zenodo.org/api/deposit/depositions/12345/files");
|
|
199
|
+
const formData = datapackageUploadCall[1].body;
|
|
200
|
+
expect(formData).toBeInstanceOf(FormData);
|
|
201
|
+
const fileBlob = formData.get("file");
|
|
202
|
+
expect(fileBlob).toBeInstanceOf(Blob);
|
|
203
|
+
});
|
|
204
|
+
it("uses production API when sandbox is false", async () => {
|
|
205
|
+
fetchMock.mockResolvedValueOnce({
|
|
206
|
+
ok: true,
|
|
207
|
+
json: () => Promise.resolve({
|
|
208
|
+
id: 12345,
|
|
209
|
+
links: {
|
|
210
|
+
self: "https://zenodo.org/api/deposit/depositions/12345",
|
|
211
|
+
html: "https://zenodo.org/deposit/12345",
|
|
212
|
+
files: "https://zenodo.org/api/deposit/depositions/12345/files",
|
|
213
|
+
bucket: "https://zenodo.org/api/files/bucket-id",
|
|
214
|
+
},
|
|
215
|
+
metadata: {
|
|
216
|
+
title: "Test Package",
|
|
217
|
+
description: "A test package",
|
|
218
|
+
upload_type: "dataset",
|
|
219
|
+
creators: [],
|
|
220
|
+
},
|
|
221
|
+
state: "unsubmitted",
|
|
222
|
+
submitted: false,
|
|
223
|
+
files: [],
|
|
224
|
+
}),
|
|
225
|
+
});
|
|
226
|
+
fetchMock.mockResolvedValue({
|
|
227
|
+
ok: true,
|
|
228
|
+
json: () => Promise.resolve({
|
|
229
|
+
id: "file-1",
|
|
230
|
+
filename: "data.csv",
|
|
231
|
+
}),
|
|
232
|
+
});
|
|
233
|
+
await savePackageToZenodo(mockPackage, {
|
|
234
|
+
apiKey: "test-api-key",
|
|
235
|
+
sandbox: false,
|
|
236
|
+
});
|
|
237
|
+
const depositionCreateCall = fetchMock.mock.calls[0];
|
|
238
|
+
expect(depositionCreateCall).toBeDefined();
|
|
239
|
+
if (!depositionCreateCall)
|
|
240
|
+
return;
|
|
241
|
+
expect(depositionCreateCall[0]).toContain("https://zenodo.org/api");
|
|
242
|
+
expect(depositionCreateCall[0]).not.toContain("sandbox");
|
|
243
|
+
});
|
|
244
|
+
it("passes API key as access_token query parameter", async () => {
|
|
245
|
+
fetchMock.mockResolvedValue({
|
|
246
|
+
ok: true,
|
|
247
|
+
json: () => Promise.resolve({
|
|
248
|
+
id: 12345,
|
|
249
|
+
links: {
|
|
250
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
251
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
252
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
253
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
254
|
+
},
|
|
255
|
+
metadata: {
|
|
256
|
+
title: "Test Package",
|
|
257
|
+
description: "A test package",
|
|
258
|
+
upload_type: "dataset",
|
|
259
|
+
creators: [],
|
|
260
|
+
},
|
|
261
|
+
state: "unsubmitted",
|
|
262
|
+
submitted: false,
|
|
263
|
+
files: [],
|
|
264
|
+
}),
|
|
265
|
+
});
|
|
266
|
+
await savePackageToZenodo(mockPackage, {
|
|
267
|
+
apiKey: "custom-api-key",
|
|
268
|
+
sandbox: true,
|
|
269
|
+
});
|
|
270
|
+
const depositionCreateCall = fetchMock.mock.calls[0];
|
|
271
|
+
expect(depositionCreateCall).toBeDefined();
|
|
272
|
+
if (!depositionCreateCall)
|
|
273
|
+
return;
|
|
274
|
+
expect(depositionCreateCall[0]).toContain("access_token=custom-api-key");
|
|
275
|
+
});
|
|
276
|
+
it("handles API errors from deposition creation", async () => {
|
|
277
|
+
fetchMock.mockResolvedValueOnce({
|
|
278
|
+
ok: false,
|
|
279
|
+
status: 400,
|
|
280
|
+
statusText: "Bad Request",
|
|
281
|
+
text: () => Promise.resolve("Invalid deposition data"),
|
|
282
|
+
});
|
|
283
|
+
await expect(savePackageToZenodo(mockPackage, mockOptions)).rejects.toThrow("Zenodo API error: 400 Bad Request");
|
|
284
|
+
});
|
|
285
|
+
it("handles API errors from file upload", async () => {
|
|
286
|
+
fetchMock.mockResolvedValueOnce({
|
|
287
|
+
ok: true,
|
|
288
|
+
json: () => Promise.resolve({
|
|
289
|
+
id: 12345,
|
|
290
|
+
links: {
|
|
291
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
292
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
293
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
294
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
295
|
+
},
|
|
296
|
+
metadata: {
|
|
297
|
+
title: "Test Package",
|
|
298
|
+
description: "A test package",
|
|
299
|
+
upload_type: "dataset",
|
|
300
|
+
creators: [],
|
|
301
|
+
},
|
|
302
|
+
state: "unsubmitted",
|
|
303
|
+
submitted: false,
|
|
304
|
+
files: [],
|
|
305
|
+
}),
|
|
306
|
+
});
|
|
307
|
+
fetchMock.mockResolvedValueOnce({
|
|
308
|
+
ok: false,
|
|
309
|
+
status: 500,
|
|
310
|
+
statusText: "Internal Server Error",
|
|
311
|
+
text: () => Promise.resolve("Failed to upload file"),
|
|
312
|
+
});
|
|
313
|
+
await expect(savePackageToZenodo(mockPackage, mockOptions)).rejects.toThrow("Zenodo API error: 500 Internal Server Error");
|
|
314
|
+
});
|
|
315
|
+
it("handles packages with multiple resources", async () => {
|
|
316
|
+
const multiResourcePackage = {
|
|
317
|
+
...mockPackage,
|
|
318
|
+
resources: [
|
|
319
|
+
{
|
|
320
|
+
name: "resource-1",
|
|
321
|
+
path: getFixturePath("data.csv"),
|
|
322
|
+
format: "csv",
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
name: "resource-2",
|
|
326
|
+
path: getFixturePath("data.csv"),
|
|
327
|
+
format: "json",
|
|
328
|
+
},
|
|
329
|
+
],
|
|
330
|
+
};
|
|
331
|
+
fetchMock.mockResolvedValue({
|
|
332
|
+
ok: true,
|
|
333
|
+
json: () => Promise.resolve({
|
|
334
|
+
id: 12345,
|
|
335
|
+
links: {
|
|
336
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
337
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
338
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
339
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
340
|
+
},
|
|
341
|
+
metadata: {
|
|
342
|
+
title: "Test Package",
|
|
343
|
+
description: "A test package",
|
|
344
|
+
upload_type: "dataset",
|
|
345
|
+
creators: [],
|
|
346
|
+
},
|
|
347
|
+
state: "unsubmitted",
|
|
348
|
+
submitted: false,
|
|
349
|
+
files: [],
|
|
350
|
+
}),
|
|
351
|
+
});
|
|
352
|
+
await savePackageToZenodo(multiResourcePackage, mockOptions);
|
|
353
|
+
expect(fetchMock).toHaveBeenCalledTimes(4);
|
|
354
|
+
const secondFileUploadCall = fetchMock.mock.calls[2];
|
|
355
|
+
expect(secondFileUploadCall).toBeDefined();
|
|
356
|
+
if (!secondFileUploadCall)
|
|
357
|
+
return;
|
|
358
|
+
expect(secondFileUploadCall[0]).toContain("/files");
|
|
359
|
+
});
|
|
360
|
+
it("handles packages with no resources", async () => {
|
|
361
|
+
const emptyPackage = {
|
|
362
|
+
...mockPackage,
|
|
363
|
+
resources: [],
|
|
364
|
+
};
|
|
365
|
+
fetchMock.mockResolvedValueOnce({
|
|
366
|
+
ok: true,
|
|
367
|
+
json: () => Promise.resolve({
|
|
368
|
+
id: 12345,
|
|
369
|
+
links: {
|
|
370
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
371
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
372
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
373
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
374
|
+
},
|
|
375
|
+
metadata: {
|
|
376
|
+
title: "Test Package",
|
|
377
|
+
description: "A test package",
|
|
378
|
+
upload_type: "dataset",
|
|
379
|
+
creators: [],
|
|
380
|
+
},
|
|
381
|
+
state: "unsubmitted",
|
|
382
|
+
submitted: false,
|
|
383
|
+
files: [],
|
|
384
|
+
}),
|
|
385
|
+
});
|
|
386
|
+
fetchMock.mockResolvedValueOnce({
|
|
387
|
+
ok: true,
|
|
388
|
+
json: () => Promise.resolve({
|
|
389
|
+
id: "file-1",
|
|
390
|
+
filename: "datapackage.json",
|
|
391
|
+
filesize: 500,
|
|
392
|
+
}),
|
|
393
|
+
});
|
|
394
|
+
const result = await savePackageToZenodo(emptyPackage, mockOptions);
|
|
395
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
396
|
+
expect(result.datasetUrl).toEqual("https://sandbox.zenodo.org/uploads/12345");
|
|
397
|
+
});
|
|
398
|
+
it("skips resources without path", async () => {
|
|
399
|
+
const packageWithoutPath = {
|
|
400
|
+
...mockPackage,
|
|
401
|
+
resources: [
|
|
402
|
+
{
|
|
403
|
+
name: "resource-without-path",
|
|
404
|
+
format: "csv",
|
|
405
|
+
},
|
|
406
|
+
],
|
|
407
|
+
};
|
|
408
|
+
fetchMock.mockResolvedValueOnce({
|
|
409
|
+
ok: true,
|
|
410
|
+
json: () => Promise.resolve({
|
|
411
|
+
id: 12345,
|
|
412
|
+
links: {
|
|
413
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
414
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
415
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
416
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
417
|
+
},
|
|
418
|
+
metadata: {
|
|
419
|
+
title: "Test Package",
|
|
420
|
+
description: "A test package",
|
|
421
|
+
upload_type: "dataset",
|
|
422
|
+
creators: [],
|
|
423
|
+
},
|
|
424
|
+
state: "unsubmitted",
|
|
425
|
+
submitted: false,
|
|
426
|
+
files: [],
|
|
427
|
+
}),
|
|
428
|
+
});
|
|
429
|
+
fetchMock.mockResolvedValueOnce({
|
|
430
|
+
ok: true,
|
|
431
|
+
json: () => Promise.resolve({
|
|
432
|
+
id: "file-1",
|
|
433
|
+
filename: "datapackage.json",
|
|
434
|
+
filesize: 500,
|
|
435
|
+
}),
|
|
436
|
+
});
|
|
437
|
+
await savePackageToZenodo(packageWithoutPath, mockOptions);
|
|
438
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
439
|
+
});
|
|
440
|
+
it("includes contributors with author role as creators in metadata", async () => {
|
|
441
|
+
const packageWithContributors = {
|
|
442
|
+
...mockPackage,
|
|
443
|
+
contributors: [
|
|
444
|
+
{
|
|
445
|
+
title: "Alice Smith",
|
|
446
|
+
role: "author",
|
|
447
|
+
path: "University of Example",
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
title: "Bob Jones",
|
|
451
|
+
role: "author",
|
|
452
|
+
path: "Institute of Testing",
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
title: "Charlie Brown",
|
|
456
|
+
role: "contributor",
|
|
457
|
+
},
|
|
458
|
+
],
|
|
459
|
+
};
|
|
460
|
+
fetchMock.mockResolvedValueOnce({
|
|
461
|
+
ok: true,
|
|
462
|
+
json: () => Promise.resolve({
|
|
463
|
+
id: 12345,
|
|
464
|
+
links: {
|
|
465
|
+
self: "https://sandbox.zenodo.org/api/deposit/depositions/12345",
|
|
466
|
+
html: "https://sandbox.zenodo.org/deposit/12345",
|
|
467
|
+
files: "https://sandbox.zenodo.org/api/deposit/depositions/12345/files",
|
|
468
|
+
bucket: "https://sandbox.zenodo.org/api/files/bucket-id",
|
|
469
|
+
},
|
|
470
|
+
metadata: {
|
|
471
|
+
title: "Test Package",
|
|
472
|
+
description: "A test package",
|
|
473
|
+
upload_type: "dataset",
|
|
474
|
+
creators: [
|
|
475
|
+
{
|
|
476
|
+
name: "Alice Smith",
|
|
477
|
+
affiliation: "University of Example",
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
name: "Bob Jones",
|
|
481
|
+
affiliation: "Institute of Testing",
|
|
482
|
+
},
|
|
483
|
+
],
|
|
484
|
+
},
|
|
485
|
+
state: "unsubmitted",
|
|
486
|
+
submitted: false,
|
|
487
|
+
files: [],
|
|
488
|
+
}),
|
|
489
|
+
});
|
|
490
|
+
fetchMock.mockResolvedValueOnce({
|
|
491
|
+
ok: true,
|
|
492
|
+
json: () => Promise.resolve({
|
|
493
|
+
id: "file-1",
|
|
494
|
+
filename: "data.csv",
|
|
495
|
+
filesize: 100,
|
|
496
|
+
}),
|
|
497
|
+
});
|
|
498
|
+
fetchMock.mockResolvedValueOnce({
|
|
499
|
+
ok: true,
|
|
500
|
+
json: () => Promise.resolve({
|
|
501
|
+
id: "file-2",
|
|
502
|
+
filename: "datapackage.json",
|
|
503
|
+
filesize: 500,
|
|
504
|
+
}),
|
|
505
|
+
});
|
|
506
|
+
await savePackageToZenodo(packageWithContributors, mockOptions);
|
|
507
|
+
const depositionCreateCall = fetchMock.mock.calls[0];
|
|
508
|
+
expect(depositionCreateCall).toBeDefined();
|
|
509
|
+
if (!depositionCreateCall)
|
|
510
|
+
return;
|
|
511
|
+
const depositionPayload = JSON.parse(depositionCreateCall[1].body);
|
|
512
|
+
expect(depositionPayload.metadata.creators).toEqual([
|
|
513
|
+
{
|
|
514
|
+
name: "Alice Smith",
|
|
515
|
+
affiliation: "University of Example",
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
name: "Bob Jones",
|
|
519
|
+
affiliation: "Institute of Testing",
|
|
520
|
+
},
|
|
521
|
+
]);
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F2ZS5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGx1Z2lucy96ZW5vZG8vcGFja2FnZS9zYXZlLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUVwQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDeEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRS9DLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxHQUFHLEVBQUU7SUFDbkMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUN0QyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLGFBQWEsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUVwRSxNQUFNLFdBQVcsR0FBWTtRQUMzQixJQUFJLEVBQUUsY0FBYztRQUNwQixLQUFLLEVBQUUsY0FBYztRQUNyQixXQUFXLEVBQUUsZ0JBQWdCO1FBQzdCLE9BQU8sRUFBRSxPQUFPO1FBQ2hCLFNBQVMsRUFBRTtZQUNUO2dCQUNFLElBQUksRUFBRSxlQUFlO2dCQUNyQixJQUFJLEVBQUUsY0FBYyxDQUFDLFVBQVUsQ0FBQztnQkFDaEMsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsS0FBSyxFQUFFLEdBQUc7YUFDWDtTQUNGO0tBQ0YsQ0FBQTtJQUVELE1BQU0sV0FBVyxHQUFHO1FBQ2xCLE1BQU0sRUFBRSxjQUFjO1FBQ3RCLE9BQU8sRUFBRSxJQUFJO0tBQ2QsQ0FBQTtJQUVELE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUE7SUFDdEMsSUFB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QUFpQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDbEQ7Z0JBQ0UsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLFdBQVcsRUFBRSx1QkFBdUI7YUFDckM7WUFDRDtnQkFDRSxJQUFJLEVBQUUsV0FBVztnQkFDakIsV0FBVyxFQUFFLHNCQUFzQjthQUNwQztTQUNGLENBQUMsQ0FBQTtJQUNKLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWxhdGl2ZSB9IGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHR5cGUgeyBQYWNrYWdlIH0gZnJvbSBcIkBmcmljdGlvbmxlc3MtdHMvbWV0YWRhdGFcIlxuaW1wb3J0IHsgbG9hZFBhY2thZ2VEZXNjcmlwdG9yIH0gZnJvbSBcIkBmcmljdGlvbmxlc3MtdHMvbWV0YWRhdGFcIlxuaW1wb3J0IHsgYWZ0ZXJFYWNoLCBiZWZvcmVFYWNoLCBkZXNjcmliZSwgZXhwZWN0LCBpdCwgdmkgfSBmcm9tIFwidml0ZXN0XCJcbmltcG9ydCB7IHNhdmVQYWNrYWdlVG9aZW5vZG8gfSBmcm9tIFwiLi9zYXZlLnRzXCJcblxuZGVzY3JpYmUoXCJzYXZlUGFja2FnZVRvWmVub2RvXCIsICgpID0+IHtcbiAgY29uc3QgZ2V0Rml4dHVyZVBhdGggPSAobmFtZTogc3RyaW5nKSA9PlxuICAgIHJlbGF0aXZlKHByb2Nlc3MuY3dkKCksIGAke2ltcG9ydC5tZXRhLmRpcm5hbWV9L2ZpeHR1cmVzLyR7bmFtZX1gKVxuXG4gIGNvbnN0IG1vY2tQYWNrYWdlOiBQYWNrYWdlID0ge1xuICAgIG5hbWU6IFwidGVzdC1wYWNrYWdlXCIsXG4gICAgdGl0bGU6IFwiVGVzdCBQYWNrYWdlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQSB0ZXN0IHBhY2thZ2VcIixcbiAgICB2ZXJzaW9uOiBcIjEuMC4wXCIsXG4gICAgcmVzb3VyY2VzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1yZXNvdXJjZVwiLFxuICAgICAgICBwYXRoOiBnZXRGaXh0dXJlUGF0aChcImRhdGEuY3N2XCIpLFxuICAgICAgICBmb3JtYXQ6IFwiY3N2XCIsXG4gICAgICAgIGJ5dGVzOiAxMDAsXG4gICAgICB9LFxuICAgIF0sXG4gIH1cblxuICBjb25zdCBtb2NrT3B0aW9ucyA9IHtcbiAgICBhcGlLZXk6IFwidGVzdC1hcGkta2V5XCIsXG4gICAgc2FuZGJveDogdHJ1ZSxcbiAgfVxuXG4gIGNvbnN0IG9yaWdpbmFsRmV0Y2ggPSBnbG9iYWxUaGlzLmZldGNoXG4gIGxldCBmZXRjaE1vY2s6IFJldHVyblR5cGU8dHlwZW9mIHZpLmZuPlxuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGZldGNoTW9jayA9IHZpLmZuKClcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgZ2xvYmFsVGhpcy5mZXRjaCA9IGZldGNoTW9ja1xuICB9KVxuXG4gIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgZ2xvYmFsVGhpcy5mZXRjaCA9IG9yaWdpbmFsRmV0Y2hcbiAgICB2aS5yZXNldEFsbE1vY2tzKClcbiAgfSlcblxuICBpdC5za2lwKFwic2hvdWxkIHNhdmUgYSBwYWNrYWdlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBkYXRhUGFja2FnZSA9IGF3YWl0IGxvYWRQYWNrYWdlRGVzY3JpcHRvcihcbiAgICAgIFwiY29yZS9wYWNrYWdlL2ZpeHR1cmVzL3BhY2thZ2UuanNvblwiLFxuICAgIClcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNhdmVQYWNrYWdlVG9aZW5vZG8oZGF0YVBhY2thZ2UsIHtcbiAgICAgIGFwaUtleTogXCI8a2V5PlwiLFxuICAgICAgc2FuZGJveDogdHJ1ZSxcbiAgICB9KVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZURlZmluZWQoKVxuICB9KVxuXG4gIGl0KFwiY3JlYXRlcyBhIGRlcG9zaXRpb24gaW4gWmVub2RvIHdpdGggY29ycmVjdCBBUEkgY2FsbHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiAxMjM0NSxcbiAgICAgICAgICBsaW5rczoge1xuICAgICAgICAgICAgc2VsZjogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NVwiLFxuICAgICAgICAgICAgaHRtbDogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9kZXBvc2l0LzEyMzQ1XCIsXG4gICAgICAgICAgICBmaWxlczpcbiAgICAgICAgICAgICAgXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NS9maWxlc1wiLFxuICAgICAgICAgICAgYnVja2V0OiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9maWxlcy9idWNrZXQtaWRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICB0aXRsZTogXCJUZXN0IFBhY2thZ2VcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkEgdGVzdCBwYWNrYWdlXCIsXG4gICAgICAgICAgICB1cGxvYWRfdHlwZTogXCJkYXRhc2V0XCIsXG4gICAgICAgICAgICBjcmVhdG9yczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZTogXCJ1bnN1Ym1pdHRlZFwiLFxuICAgICAgICAgIHN1Ym1pdHRlZDogZmFsc2UsXG4gICAgICAgICAgZmlsZXM6IFtdLFxuICAgICAgICB9KSxcbiAgICB9KVxuXG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIGpzb246ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgaWQ6IFwiZmlsZS0xXCIsXG4gICAgICAgICAgZmlsZW5hbWU6IFwiZGF0YS5jc3ZcIixcbiAgICAgICAgICBmaWxlc2l6ZTogMTAwLFxuICAgICAgICB9KSxcbiAgICB9KVxuXG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIGpzb246ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgaWQ6IFwiZmlsZS0yXCIsXG4gICAgICAgICAgZmlsZW5hbWU6IFwiZGF0YXBhY2thZ2UuanNvblwiLFxuICAgICAgICAgIGZpbGVzaXplOiA1MDAsXG4gICAgICAgIH0pLFxuICAgIH0pXG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzYXZlUGFja2FnZVRvWmVub2RvKG1vY2tQYWNrYWdlLCBtb2NrT3B0aW9ucylcblxuICAgIGV4cGVjdChmZXRjaE1vY2spLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygzKVxuXG4gICAgY29uc3QgZGVwb3NpdGlvbkNyZWF0ZUNhbGwgPSBmZXRjaE1vY2subW9jay5jYWxsc1swXVxuICAgIGV4cGVjdChkZXBvc2l0aW9uQ3JlYXRlQ2FsbCkudG9CZURlZmluZWQoKVxuICAgIGlmICghZGVwb3NpdGlvbkNyZWF0ZUNhbGwpIHJldHVyblxuXG4gICAgZXhwZWN0KGRlcG9zaXRpb25DcmVhdGVDYWxsWzBdKS50b0NvbnRhaW4oXG4gICAgICBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9kZXBvc2l0L2RlcG9zaXRpb25zXCIsXG4gICAgKVxuICAgIGV4cGVjdChkZXBvc2l0aW9uQ3JlYXRlQ2FsbFswXSkudG9Db250YWluKFwiYWNjZXNzX3Rva2VuPXRlc3QtYXBpLWtleVwiKVxuICAgIGV4cGVjdChkZXBvc2l0aW9uQ3JlYXRlQ2FsbFsxXSkudG9NYXRjaE9iamVjdCh7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIGNvbnN0IGRlcG9zaXRpb25QYXlsb2FkID0gSlNPTi5wYXJzZShkZXBvc2l0aW9uQ3JlYXRlQ2FsbFsxXS5ib2R5KVxuICAgIGV4cGVjdChkZXBvc2l0aW9uUGF5bG9hZC5tZXRhZGF0YS50aXRsZSkudG9FcXVhbChcIlRlc3QgUGFja2FnZVwiKVxuICAgIGV4cGVjdChkZXBvc2l0aW9uUGF5bG9hZC5tZXRhZGF0YS5kZXNjcmlwdGlvbikudG9FcXVhbChcIkEgdGVzdCBwYWNrYWdlXCIpXG5cbiAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKHtcbiAgICAgIHBhdGg6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvcmVjb3Jkcy8xMjM0NS9maWxlcy9kYXRhcGFja2FnZS5qc29uXCIsXG4gICAgICBkYXRhc2V0VXJsOiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL3VwbG9hZHMvMTIzNDVcIixcbiAgICB9KVxuICB9KVxuXG4gIGl0KFwidXBsb2FkcyByZXNvdXJjZSBmaWxlcyB0byBkZXBvc2l0aW9uXCIsIGFzeW5jICgpID0+IHtcbiAgICBmZXRjaE1vY2subW9ja1Jlc29sdmVkVmFsdWVPbmNlKHtcbiAgICAgIG9rOiB0cnVlLFxuICAgICAganNvbjogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBpZDogMTIzNDUsXG4gICAgICAgICAgbGlua3M6IHtcbiAgICAgICAgICAgIHNlbGY6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDVcIixcbiAgICAgICAgICAgIGh0bWw6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvZGVwb3NpdC8xMjM0NVwiLFxuICAgICAgICAgICAgZmlsZXM6XG4gICAgICAgICAgICAgIFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDUvZmlsZXNcIixcbiAgICAgICAgICAgIGJ1Y2tldDogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZmlsZXMvYnVja2V0LWlkXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgdGl0bGU6IFwiVGVzdCBQYWNrYWdlXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJBIHRlc3QgcGFja2FnZVwiLFxuICAgICAgICAgICAgdXBsb2FkX3R5cGU6IFwiZGF0YXNldFwiLFxuICAgICAgICAgICAgY3JlYXRvcnM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGU6IFwidW5zdWJtaXR0ZWRcIixcbiAgICAgICAgICBzdWJtaXR0ZWQ6IGZhbHNlLFxuICAgICAgICAgIGZpbGVzOiBbXSxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiBcImZpbGUtMVwiLFxuICAgICAgICAgIGZpbGVuYW1lOiBcImRhdGEuY3N2XCIsXG4gICAgICAgICAgZmlsZXNpemU6IDEwMCxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiBcImZpbGUtMlwiLFxuICAgICAgICAgIGZpbGVuYW1lOiBcImRhdGFwYWNrYWdlLmpzb25cIixcbiAgICAgICAgICBmaWxlc2l6ZTogNTAwLFxuICAgICAgICB9KSxcbiAgICB9KVxuXG4gICAgYXdhaXQgc2F2ZVBhY2thZ2VUb1plbm9kbyhtb2NrUGFja2FnZSwgbW9ja09wdGlvbnMpXG5cbiAgICBjb25zdCBmaWxlVXBsb2FkQ2FsbCA9IGZldGNoTW9jay5tb2NrLmNhbGxzWzFdXG4gICAgZXhwZWN0KGZpbGVVcGxvYWRDYWxsKS50b0JlRGVmaW5lZCgpXG4gICAgaWYgKCFmaWxlVXBsb2FkQ2FsbCkgcmV0dXJuXG5cbiAgICBleHBlY3QoZmlsZVVwbG9hZENhbGxbMF0pLnRvQ29udGFpbihcbiAgICAgIFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDUvZmlsZXNcIixcbiAgICApXG4gICAgZXhwZWN0KGZpbGVVcGxvYWRDYWxsWzBdKS50b0NvbnRhaW4oXCJhY2Nlc3NfdG9rZW49dGVzdC1hcGkta2V5XCIpXG4gICAgZXhwZWN0KGZpbGVVcGxvYWRDYWxsWzFdKS50b01hdGNoT2JqZWN0KHtcbiAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgfSlcblxuICAgIGNvbnN0IGZvcm1EYXRhID0gZmlsZVVwbG9hZENhbGxbMV0uYm9keVxuICAgIGV4cGVjdChmb3JtRGF0YSkudG9CZUluc3RhbmNlT2YoRm9ybURhdGEpXG4gIH0pXG5cbiAgaXQoXCJ1cGxvYWRzIGRhdGFwYWNrYWdlLmpzb24gbWV0YWRhdGEgZmlsZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIGpzb246ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgaWQ6IDEyMzQ1LFxuICAgICAgICAgIGxpbmtzOiB7XG4gICAgICAgICAgICBzZWxmOiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9kZXBvc2l0L2RlcG9zaXRpb25zLzEyMzQ1XCIsXG4gICAgICAgICAgICBodG1sOiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2RlcG9zaXQvMTIzNDVcIixcbiAgICAgICAgICAgIGZpbGVzOlxuICAgICAgICAgICAgICBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9kZXBvc2l0L2RlcG9zaXRpb25zLzEyMzQ1L2ZpbGVzXCIsXG4gICAgICAgICAgICBidWNrZXQ6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2ZpbGVzL2J1Y2tldC1pZFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHRpdGxlOiBcIlRlc3QgUGFja2FnZVwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQSB0ZXN0IHBhY2thZ2VcIixcbiAgICAgICAgICAgIHVwbG9hZF90eXBlOiBcImRhdGFzZXRcIixcbiAgICAgICAgICAgIGNyZWF0b3JzOiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXRlOiBcInVuc3VibWl0dGVkXCIsXG4gICAgICAgICAgc3VibWl0dGVkOiBmYWxzZSxcbiAgICAgICAgICBmaWxlczogW10sXG4gICAgICAgIH0pLFxuICAgIH0pXG5cbiAgICBmZXRjaE1vY2subW9ja1Jlc29sdmVkVmFsdWVPbmNlKHtcbiAgICAgIG9rOiB0cnVlLFxuICAgICAganNvbjogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBpZDogXCJmaWxlLTFcIixcbiAgICAgICAgICBmaWxlbmFtZTogXCJkYXRhLmNzdlwiLFxuICAgICAgICAgIGZpbGVzaXplOiAxMDAsXG4gICAgICAgIH0pLFxuICAgIH0pXG5cbiAgICBmZXRjaE1vY2subW9ja1Jlc29sdmVkVmFsdWVPbmNlKHtcbiAgICAgIG9rOiB0cnVlLFxuICAgICAganNvbjogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBpZDogXCJmaWxlLTJcIixcbiAgICAgICAgICBmaWxlbmFtZTogXCJkYXRhcGFja2FnZS5qc29uXCIsXG4gICAgICAgICAgZmlsZXNpemU6IDUwMCxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGF3YWl0IHNhdmVQYWNrYWdlVG9aZW5vZG8obW9ja1BhY2thZ2UsIG1vY2tPcHRpb25zKVxuXG4gICAgY29uc3QgZGF0YXBhY2thZ2VVcGxvYWRDYWxsID0gZmV0Y2hNb2NrLm1vY2suY2FsbHNbMl1cbiAgICBleHBlY3QoZGF0YXBhY2thZ2VVcGxvYWRDYWxsKS50b0JlRGVmaW5lZCgpXG4gICAgaWYgKCFkYXRhcGFja2FnZVVwbG9hZENhbGwpIHJldHVyblxuXG4gICAgZXhwZWN0KGRhdGFwYWNrYWdlVXBsb2FkQ2FsbFswXSkudG9Db250YWluKFxuICAgICAgXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NS9maWxlc1wiLFxuICAgIClcblxuICAgIGNvbnN0IGZvcm1EYXRhID0gZGF0YXBhY2thZ2VVcGxvYWRDYWxsWzFdLmJvZHlcbiAgICBleHBlY3QoZm9ybURhdGEpLnRvQmVJbnN0YW5jZU9mKEZvcm1EYXRhKVxuXG4gICAgY29uc3QgZmlsZUJsb2IgPSBmb3JtRGF0YS5nZXQoXCJmaWxlXCIpXG4gICAgZXhwZWN0KGZpbGVCbG9iKS50b0JlSW5zdGFuY2VPZihCbG9iKVxuICB9KVxuXG4gIGl0KFwidXNlcyBwcm9kdWN0aW9uIEFQSSB3aGVuIHNhbmRib3ggaXMgZmFsc2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiAxMjM0NSxcbiAgICAgICAgICBsaW5rczoge1xuICAgICAgICAgICAgc2VsZjogXCJodHRwczovL3plbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDVcIixcbiAgICAgICAgICAgIGh0bWw6IFwiaHR0cHM6Ly96ZW5vZG8ub3JnL2RlcG9zaXQvMTIzNDVcIixcbiAgICAgICAgICAgIGZpbGVzOiBcImh0dHBzOi8vemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NS9maWxlc1wiLFxuICAgICAgICAgICAgYnVja2V0OiBcImh0dHBzOi8vemVub2RvLm9yZy9hcGkvZmlsZXMvYnVja2V0LWlkXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgdGl0bGU6IFwiVGVzdCBQYWNrYWdlXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJBIHRlc3QgcGFja2FnZVwiLFxuICAgICAgICAgICAgdXBsb2FkX3R5cGU6IFwiZGF0YXNldFwiLFxuICAgICAgICAgICAgY3JlYXRvcnM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGU6IFwidW5zdWJtaXR0ZWRcIixcbiAgICAgICAgICBzdWJtaXR0ZWQ6IGZhbHNlLFxuICAgICAgICAgIGZpbGVzOiBbXSxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZSh7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIGpzb246ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgaWQ6IFwiZmlsZS0xXCIsXG4gICAgICAgICAgZmlsZW5hbWU6IFwiZGF0YS5jc3ZcIixcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGF3YWl0IHNhdmVQYWNrYWdlVG9aZW5vZG8obW9ja1BhY2thZ2UsIHtcbiAgICAgIGFwaUtleTogXCJ0ZXN0LWFwaS1rZXlcIixcbiAgICAgIHNhbmRib3g6IGZhbHNlLFxuICAgIH0pXG5cbiAgICBjb25zdCBkZXBvc2l0aW9uQ3JlYXRlQ2FsbCA9IGZldGNoTW9jay5tb2NrLmNhbGxzWzBdXG4gICAgZXhwZWN0KGRlcG9zaXRpb25DcmVhdGVDYWxsKS50b0JlRGVmaW5lZCgpXG4gICAgaWYgKCFkZXBvc2l0aW9uQ3JlYXRlQ2FsbCkgcmV0dXJuXG5cbiAgICBleHBlY3QoZGVwb3NpdGlvbkNyZWF0ZUNhbGxbMF0pLnRvQ29udGFpbihcImh0dHBzOi8vemVub2RvLm9yZy9hcGlcIilcbiAgICBleHBlY3QoZGVwb3NpdGlvbkNyZWF0ZUNhbGxbMF0pLm5vdC50b0NvbnRhaW4oXCJzYW5kYm94XCIpXG4gIH0pXG5cbiAgaXQoXCJwYXNzZXMgQVBJIGtleSBhcyBhY2Nlc3NfdG9rZW4gcXVlcnkgcGFyYW1ldGVyXCIsIGFzeW5jICgpID0+IHtcbiAgICBmZXRjaE1vY2subW9ja1Jlc29sdmVkVmFsdWUoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiAxMjM0NSxcbiAgICAgICAgICBsaW5rczoge1xuICAgICAgICAgICAgc2VsZjogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NVwiLFxuICAgICAgICAgICAgaHRtbDogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9kZXBvc2l0LzEyMzQ1XCIsXG4gICAgICAgICAgICBmaWxlczpcbiAgICAgICAgICAgICAgXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NS9maWxlc1wiLFxuICAgICAgICAgICAgYnVja2V0OiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9maWxlcy9idWNrZXQtaWRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICB0aXRsZTogXCJUZXN0IFBhY2thZ2VcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkEgdGVzdCBwYWNrYWdlXCIsXG4gICAgICAgICAgICB1cGxvYWRfdHlwZTogXCJkYXRhc2V0XCIsXG4gICAgICAgICAgICBjcmVhdG9yczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZTogXCJ1bnN1Ym1pdHRlZFwiLFxuICAgICAgICAgIHN1Ym1pdHRlZDogZmFsc2UsXG4gICAgICAgICAgZmlsZXM6IFtdLFxuICAgICAgICB9KSxcbiAgICB9KVxuXG4gICAgYXdhaXQgc2F2ZVBhY2thZ2VUb1plbm9kbyhtb2NrUGFja2FnZSwge1xuICAgICAgYXBpS2V5OiBcImN1c3RvbS1hcGkta2V5XCIsXG4gICAgICBzYW5kYm94OiB0cnVlLFxuICAgIH0pXG5cbiAgICBjb25zdCBkZXBvc2l0aW9uQ3JlYXRlQ2FsbCA9IGZldGNoTW9jay5tb2NrLmNhbGxzWzBdXG4gICAgZXhwZWN0KGRlcG9zaXRpb25DcmVhdGVDYWxsKS50b0JlRGVmaW5lZCgpXG4gICAgaWYgKCFkZXBvc2l0aW9uQ3JlYXRlQ2FsbCkgcmV0dXJuXG5cbiAgICBleHBlY3QoZGVwb3NpdGlvbkNyZWF0ZUNhbGxbMF0pLnRvQ29udGFpbihcImFjY2Vzc190b2tlbj1jdXN0b20tYXBpLWtleVwiKVxuICB9KVxuXG4gIGl0KFwiaGFuZGxlcyBBUEkgZXJyb3JzIGZyb20gZGVwb3NpdGlvbiBjcmVhdGlvblwiLCBhc3luYyAoKSA9PiB7XG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICBvazogZmFsc2UsXG4gICAgICBzdGF0dXM6IDQwMCxcbiAgICAgIHN0YXR1c1RleHQ6IFwiQmFkIFJlcXVlc3RcIixcbiAgICAgIHRleHQ6ICgpID0+IFByb21pc2UucmVzb2x2ZShcIkludmFsaWQgZGVwb3NpdGlvbiBkYXRhXCIpLFxuICAgIH0pXG5cbiAgICBhd2FpdCBleHBlY3Qoc2F2ZVBhY2thZ2VUb1plbm9kbyhtb2NrUGFja2FnZSwgbW9ja09wdGlvbnMpKS5yZWplY3RzLnRvVGhyb3coXG4gICAgICBcIlplbm9kbyBBUEkgZXJyb3I6IDQwMCBCYWQgUmVxdWVzdFwiLFxuICAgIClcbiAgfSlcblxuICBpdChcImhhbmRsZXMgQVBJIGVycm9ycyBmcm9tIGZpbGUgdXBsb2FkXCIsIGFzeW5jICgpID0+IHtcbiAgICBmZXRjaE1vY2subW9ja1Jlc29sdmVkVmFsdWVPbmNlKHtcbiAgICAgIG9rOiB0cnVlLFxuICAgICAganNvbjogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBpZDogMTIzNDUsXG4gICAgICAgICAgbGlua3M6IHtcbiAgICAgICAgICAgIHNlbGY6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDVcIixcbiAgICAgICAgICAgIGh0bWw6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvZGVwb3NpdC8xMjM0NVwiLFxuICAgICAgICAgICAgZmlsZXM6XG4gICAgICAgICAgICAgIFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDUvZmlsZXNcIixcbiAgICAgICAgICAgIGJ1Y2tldDogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZmlsZXMvYnVja2V0LWlkXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgdGl0bGU6IFwiVGVzdCBQYWNrYWdlXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJBIHRlc3QgcGFja2FnZVwiLFxuICAgICAgICAgICAgdXBsb2FkX3R5cGU6IFwiZGF0YXNldFwiLFxuICAgICAgICAgICAgY3JlYXRvcnM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGU6IFwidW5zdWJtaXR0ZWRcIixcbiAgICAgICAgICBzdWJtaXR0ZWQ6IGZhbHNlLFxuICAgICAgICAgIGZpbGVzOiBbXSxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IGZhbHNlLFxuICAgICAgc3RhdHVzOiA1MDAsXG4gICAgICBzdGF0dXNUZXh0OiBcIkludGVybmFsIFNlcnZlciBFcnJvclwiLFxuICAgICAgdGV4dDogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKFwiRmFpbGVkIHRvIHVwbG9hZCBmaWxlXCIpLFxuICAgIH0pXG5cbiAgICBhd2FpdCBleHBlY3Qoc2F2ZVBhY2thZ2VUb1plbm9kbyhtb2NrUGFja2FnZSwgbW9ja09wdGlvbnMpKS5yZWplY3RzLnRvVGhyb3coXG4gICAgICBcIlplbm9kbyBBUEkgZXJyb3I6IDUwMCBJbnRlcm5hbCBTZXJ2ZXIgRXJyb3JcIixcbiAgICApXG4gIH0pXG5cbiAgaXQoXCJoYW5kbGVzIHBhY2thZ2VzIHdpdGggbXVsdGlwbGUgcmVzb3VyY2VzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtdWx0aVJlc291cmNlUGFja2FnZTogUGFja2FnZSA9IHtcbiAgICAgIC4uLm1vY2tQYWNrYWdlLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInJlc291cmNlLTFcIixcbiAgICAgICAgICBwYXRoOiBnZXRGaXh0dXJlUGF0aChcImRhdGEuY3N2XCIpLFxuICAgICAgICAgIGZvcm1hdDogXCJjc3ZcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicmVzb3VyY2UtMlwiLFxuICAgICAgICAgIHBhdGg6IGdldEZpeHR1cmVQYXRoKFwiZGF0YS5jc3ZcIiksXG4gICAgICAgICAgZm9ybWF0OiBcImpzb25cIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlKHtcbiAgICAgIG9rOiB0cnVlLFxuICAgICAganNvbjogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBpZDogMTIzNDUsXG4gICAgICAgICAgbGlua3M6IHtcbiAgICAgICAgICAgIHNlbGY6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDVcIixcbiAgICAgICAgICAgIGh0bWw6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvZGVwb3NpdC8xMjM0NVwiLFxuICAgICAgICAgICAgZmlsZXM6XG4gICAgICAgICAgICAgIFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnMvMTIzNDUvZmlsZXNcIixcbiAgICAgICAgICAgIGJ1Y2tldDogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZmlsZXMvYnVja2V0LWlkXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgdGl0bGU6IFwiVGVzdCBQYWNrYWdlXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJBIHRlc3QgcGFja2FnZVwiLFxuICAgICAgICAgICAgdXBsb2FkX3R5cGU6IFwiZGF0YXNldFwiLFxuICAgICAgICAgICAgY3JlYXRvcnM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGU6IFwidW5zdWJtaXR0ZWRcIixcbiAgICAgICAgICBzdWJtaXR0ZWQ6IGZhbHNlLFxuICAgICAgICAgIGZpbGVzOiBbXSxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGF3YWl0IHNhdmVQYWNrYWdlVG9aZW5vZG8obXVsdGlSZXNvdXJjZVBhY2thZ2UsIG1vY2tPcHRpb25zKVxuXG4gICAgZXhwZWN0KGZldGNoTW9jaykudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDQpXG5cbiAgICBjb25zdCBzZWNvbmRGaWxlVXBsb2FkQ2FsbCA9IGZldGNoTW9jay5tb2NrLmNhbGxzWzJdXG4gICAgZXhwZWN0KHNlY29uZEZpbGVVcGxvYWRDYWxsKS50b0JlRGVmaW5lZCgpXG4gICAgaWYgKCFzZWNvbmRGaWxlVXBsb2FkQ2FsbCkgcmV0dXJuXG5cbiAgICBleHBlY3Qoc2Vjb25kRmlsZVVwbG9hZENhbGxbMF0pLnRvQ29udGFpbihcIi9maWxlc1wiKVxuICB9KVxuXG4gIGl0KFwiaGFuZGxlcyBwYWNrYWdlcyB3aXRoIG5vIHJlc291cmNlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW1wdHlQYWNrYWdlOiBQYWNrYWdlID0ge1xuICAgICAgLi4ubW9ja1BhY2thZ2UsXG4gICAgICByZXNvdXJjZXM6IFtdLFxuICAgIH1cblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiAxMjM0NSxcbiAgICAgICAgICBsaW5rczoge1xuICAgICAgICAgICAgc2VsZjogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NVwiLFxuICAgICAgICAgICAgaHRtbDogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9kZXBvc2l0LzEyMzQ1XCIsXG4gICAgICAgICAgICBmaWxlczpcbiAgICAgICAgICAgICAgXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NS9maWxlc1wiLFxuICAgICAgICAgICAgYnVja2V0OiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9maWxlcy9idWNrZXQtaWRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICB0aXRsZTogXCJUZXN0IFBhY2thZ2VcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkEgdGVzdCBwYWNrYWdlXCIsXG4gICAgICAgICAgICB1cGxvYWRfdHlwZTogXCJkYXRhc2V0XCIsXG4gICAgICAgICAgICBjcmVhdG9yczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZTogXCJ1bnN1Ym1pdHRlZFwiLFxuICAgICAgICAgIHN1Ym1pdHRlZDogZmFsc2UsXG4gICAgICAgICAgZmlsZXM6IFtdLFxuICAgICAgICB9KSxcbiAgICB9KVxuXG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIGpzb246ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgaWQ6IFwiZmlsZS0xXCIsXG4gICAgICAgICAgZmlsZW5hbWU6IFwiZGF0YXBhY2thZ2UuanNvblwiLFxuICAgICAgICAgIGZpbGVzaXplOiA1MDAsXG4gICAgICAgIH0pLFxuICAgIH0pXG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzYXZlUGFja2FnZVRvWmVub2RvKGVtcHR5UGFja2FnZSwgbW9ja09wdGlvbnMpXG5cbiAgICBleHBlY3QoZmV0Y2hNb2NrKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMilcbiAgICBleHBlY3QocmVzdWx0LmRhdGFzZXRVcmwpLnRvRXF1YWwoXG4gICAgICBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL3VwbG9hZHMvMTIzNDVcIixcbiAgICApXG4gIH0pXG5cbiAgaXQoXCJza2lwcyByZXNvdXJjZXMgd2l0aG91dCBwYXRoXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwYWNrYWdlV2l0aG91dFBhdGg6IFBhY2thZ2UgPSB7XG4gICAgICAuLi5tb2NrUGFja2FnZSxcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJyZXNvdXJjZS13aXRob3V0LXBhdGhcIixcbiAgICAgICAgICBmb3JtYXQ6IFwiY3N2XCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH1cblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiAxMjM0NSxcbiAgICAgICAgICBsaW5rczoge1xuICAgICAgICAgICAgc2VsZjogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NVwiLFxuICAgICAgICAgICAgaHRtbDogXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9kZXBvc2l0LzEyMzQ1XCIsXG4gICAgICAgICAgICBmaWxlczpcbiAgICAgICAgICAgICAgXCJodHRwczovL3NhbmRib3guemVub2RvLm9yZy9hcGkvZGVwb3NpdC9kZXBvc2l0aW9ucy8xMjM0NS9maWxlc1wiLFxuICAgICAgICAgICAgYnVja2V0OiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9maWxlcy9idWNrZXQtaWRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICB0aXRsZTogXCJUZXN0IFBhY2thZ2VcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkEgdGVzdCBwYWNrYWdlXCIsXG4gICAgICAgICAgICB1cGxvYWRfdHlwZTogXCJkYXRhc2V0XCIsXG4gICAgICAgICAgICBjcmVhdG9yczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0ZTogXCJ1bnN1Ym1pdHRlZFwiLFxuICAgICAgICAgIHN1Ym1pdHRlZDogZmFsc2UsXG4gICAgICAgICAgZmlsZXM6IFtdLFxuICAgICAgICB9KSxcbiAgICB9KVxuXG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIGpzb246ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgaWQ6IFwiZmlsZS0xXCIsXG4gICAgICAgICAgZmlsZW5hbWU6IFwiZGF0YXBhY2thZ2UuanNvblwiLFxuICAgICAgICAgIGZpbGVzaXplOiA1MDAsXG4gICAgICAgIH0pLFxuICAgIH0pXG5cbiAgICBhd2FpdCBzYXZlUGFja2FnZVRvWmVub2RvKHBhY2thZ2VXaXRob3V0UGF0aCwgbW9ja09wdGlvbnMpXG5cbiAgICBleHBlY3QoZmV0Y2hNb2NrKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMilcbiAgfSlcblxuICBpdChcImluY2x1ZGVzIGNvbnRyaWJ1dG9ycyB3aXRoIGF1dGhvciByb2xlIGFzIGNyZWF0b3JzIGluIG1ldGFkYXRhXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwYWNrYWdlV2l0aENvbnRyaWJ1dG9yczogUGFja2FnZSA9IHtcbiAgICAgIC4uLm1vY2tQYWNrYWdlLFxuICAgICAgY29udHJpYnV0b3JzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogXCJBbGljZSBTbWl0aFwiLFxuICAgICAgICAgIHJvbGU6IFwiYXV0aG9yXCIsXG4gICAgICAgICAgcGF0aDogXCJVbml2ZXJzaXR5IG9mIEV4YW1wbGVcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHRpdGxlOiBcIkJvYiBKb25lc1wiLFxuICAgICAgICAgIHJvbGU6IFwiYXV0aG9yXCIsXG4gICAgICAgICAgcGF0aDogXCJJbnN0aXR1dGUgb2YgVGVzdGluZ1wiLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGl0bGU6IFwiQ2hhcmxpZSBCcm93blwiLFxuICAgICAgICAgIHJvbGU6IFwiY29udHJpYnV0b3JcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgZmV0Y2hNb2NrLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIGpzb246ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgaWQ6IDEyMzQ1LFxuICAgICAgICAgIGxpbmtzOiB7XG4gICAgICAgICAgICBzZWxmOiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9kZXBvc2l0L2RlcG9zaXRpb25zLzEyMzQ1XCIsXG4gICAgICAgICAgICBodG1sOiBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2RlcG9zaXQvMTIzNDVcIixcbiAgICAgICAgICAgIGZpbGVzOlxuICAgICAgICAgICAgICBcImh0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL2FwaS9kZXBvc2l0L2RlcG9zaXRpb25zLzEyMzQ1L2ZpbGVzXCIsXG4gICAgICAgICAgICBidWNrZXQ6IFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2ZpbGVzL2J1Y2tldC1pZFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHRpdGxlOiBcIlRlc3QgUGFja2FnZVwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQSB0ZXN0IHBhY2thZ2VcIixcbiAgICAgICAgICAgIHVwbG9hZF90eXBlOiBcImRhdGFzZXRcIixcbiAgICAgICAgICAgIGNyZWF0b3JzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIkFsaWNlIFNtaXRoXCIsXG4gICAgICAgICAgICAgICAgYWZmaWxpYXRpb246IFwiVW5pdmVyc2l0eSBvZiBFeGFtcGxlXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIkJvYiBKb25lc1wiLFxuICAgICAgICAgICAgICAgIGFmZmlsaWF0aW9uOiBcIkluc3RpdHV0ZSBvZiBUZXN0aW5nXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGU6IFwidW5zdWJtaXR0ZWRcIixcbiAgICAgICAgICBzdWJtaXR0ZWQ6IGZhbHNlLFxuICAgICAgICAgIGZpbGVzOiBbXSxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiBcImZpbGUtMVwiLFxuICAgICAgICAgIGZpbGVuYW1lOiBcImRhdGEuY3N2XCIsXG4gICAgICAgICAgZmlsZXNpemU6IDEwMCxcbiAgICAgICAgfSksXG4gICAgfSlcblxuICAgIGZldGNoTW9jay5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgb2s6IHRydWUsXG4gICAgICBqc29uOiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGlkOiBcImZpbGUtMlwiLFxuICAgICAgICAgIGZpbGVuYW1lOiBcImRhdGFwYWNrYWdlLmpzb25cIixcbiAgICAgICAgICBmaWxlc2l6ZTogNTAwLFxuICAgICAgICB9KSxcbiAgICB9KVxuXG4gICAgYXdhaXQgc2F2ZVBhY2thZ2VUb1plbm9kbyhwYWNrYWdlV2l0aENvbnRyaWJ1dG9ycywgbW9ja09wdGlvbnMpXG5cbiAgICBjb25zdCBkZXBvc2l0aW9uQ3JlYXRlQ2FsbCA9IGZldGNoTW9jay5tb2NrLmNhbGxzWzBdXG4gICAgZXhwZWN0KGRlcG9zaXRpb25DcmVhdGVDYWxsKS50b0JlRGVmaW5lZCgpXG4gICAgaWYgKCFkZXBvc2l0aW9uQ3JlYXRlQ2FsbCkgcmV0dXJuXG5cbiAgICBjb25zdCBkZXBvc2l0aW9uUGF5bG9hZCA9IEpTT04ucGFyc2UoZGVwb3NpdGlvbkNyZWF0ZUNhbGxbMV0uYm9keSlcbiAgICBleHBlY3QoZGVwb3NpdGlvblBheWxvYWQubWV0YWRhdGEuY3JlYXRvcnMpLnRvRXF1YWwoW1xuICAgICAge1xuICAgICAgICBuYW1lOiBcIkFsaWNlIFNtaXRoXCIsXG4gICAgICAgIGFmZmlsaWF0aW9uOiBcIlVuaXZlcnNpdHkgb2YgRXhhbXBsZVwiLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogXCJCb2IgSm9uZXNcIixcbiAgICAgICAgYWZmaWxpYXRpb246IFwiSW5zdGl0dXRlIG9mIFRlc3RpbmdcIixcbiAgICAgIH0sXG4gICAgXSlcbiAgfSlcbn0pXG4iXX0=
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DatasetPlugin } from "../../plugin.ts";
|
|
2
|
+
export declare class ZenodoPlugin implements DatasetPlugin {
|
|
3
|
+
loadPackage(source: string): Promise<{
|
|
4
|
+
[x: `${string}:${string}`]: any;
|
|
5
|
+
$schema?: string;
|
|
6
|
+
resources: import("@frictionless-ts/metadata").Resource[];
|
|
7
|
+
name?: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
homepage?: string;
|
|
11
|
+
version?: string;
|
|
12
|
+
licenses?: import("@frictionless-ts/metadata").License[];
|
|
13
|
+
contributors?: import("@frictionless-ts/metadata").Contributor[];
|
|
14
|
+
sources?: import("@frictionless-ts/metadata").Source[];
|
|
15
|
+
keywords?: string[];
|
|
16
|
+
created?: string;
|
|
17
|
+
image?: string;
|
|
18
|
+
} | undefined>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isRemotePath } from "@frictionless-ts/metadata";
|
|
2
|
+
import { loadPackageFromZenodo } from "./package/load.js";
|
|
3
|
+
export class ZenodoPlugin {
|
|
4
|
+
async loadPackage(source) {
|
|
5
|
+
const isZenodo = getIsZenodo(source);
|
|
6
|
+
if (!isZenodo)
|
|
7
|
+
return undefined;
|
|
8
|
+
const dataPackage = await loadPackageFromZenodo(source);
|
|
9
|
+
return dataPackage;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function getIsZenodo(path) {
|
|
13
|
+
const isRemote = isRemotePath(path);
|
|
14
|
+
if (!isRemote)
|
|
15
|
+
return false;
|
|
16
|
+
return new URL(path).hostname.endsWith("zenodo.org");
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcGx1Z2lucy96ZW5vZG8vcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUV4RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUV6RCxNQUFNLE9BQU8sWUFBWTtJQUN2QixLQUFLLENBQUMsV0FBVyxDQUFDLE1BQWM7UUFDOUIsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3BDLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTyxTQUFTLENBQUE7UUFFL0IsTUFBTSxXQUFXLEdBQUcsTUFBTSxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUN2RCxPQUFPLFdBQVcsQ0FBQTtJQUNwQixDQUFDO0NBQ0Y7QUFFRCxTQUFTLFdBQVcsQ0FBQyxJQUFZO0lBQy9CLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNuQyxJQUFJLENBQUMsUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFBO0lBRTNCLE9BQU8sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUN0RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNSZW1vdGVQYXRoIH0gZnJvbSBcIkBmcmljdGlvbmxlc3MtdHMvbWV0YWRhdGFcIlxuaW1wb3J0IHR5cGUgeyBEYXRhc2V0UGx1Z2luIH0gZnJvbSBcIi4uLy4uL3BsdWdpbi50c1wiXG5pbXBvcnQgeyBsb2FkUGFja2FnZUZyb21aZW5vZG8gfSBmcm9tIFwiLi9wYWNrYWdlL2xvYWQudHNcIlxuXG5leHBvcnQgY2xhc3MgWmVub2RvUGx1Z2luIGltcGxlbWVudHMgRGF0YXNldFBsdWdpbiB7XG4gIGFzeW5jIGxvYWRQYWNrYWdlKHNvdXJjZTogc3RyaW5nKSB7XG4gICAgY29uc3QgaXNaZW5vZG8gPSBnZXRJc1plbm9kbyhzb3VyY2UpXG4gICAgaWYgKCFpc1plbm9kbykgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgY29uc3QgZGF0YVBhY2thZ2UgPSBhd2FpdCBsb2FkUGFja2FnZUZyb21aZW5vZG8oc291cmNlKVxuICAgIHJldHVybiBkYXRhUGFja2FnZVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldElzWmVub2RvKHBhdGg6IHN0cmluZykge1xuICBjb25zdCBpc1JlbW90ZSA9IGlzUmVtb3RlUGF0aChwYXRoKVxuICBpZiAoIWlzUmVtb3RlKSByZXR1cm4gZmFsc2VcblxuICByZXR1cm4gbmV3IFVSTChwYXRoKS5ob3N0bmFtZS5lbmRzV2l0aChcInplbm9kby5vcmdcIilcbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|