@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.
Files changed (242) hide show
  1. package/README.md +3 -0
  2. package/build/file/copy.d.ts +4 -0
  3. package/build/file/copy.js +7 -0
  4. package/build/file/copy.spec.d.ts +1 -0
  5. package/build/file/copy.spec.js +104 -0
  6. package/build/file/describe.d.ts +7 -0
  7. package/build/file/describe.js +9 -0
  8. package/build/file/fetch.d.ts +2 -0
  9. package/build/file/fetch.js +21 -0
  10. package/build/file/index.d.ts +9 -0
  11. package/build/file/index.js +10 -0
  12. package/build/file/infer.d.ts +10 -0
  13. package/build/file/infer.js +48 -0
  14. package/build/file/infer.spec.d.ts +1 -0
  15. package/build/file/infer.spec.js +141 -0
  16. package/build/file/load.d.ts +3 -0
  17. package/build/file/load.js +7 -0
  18. package/build/file/path.d.ts +2 -0
  19. package/build/file/path.js +17 -0
  20. package/build/file/save.d.ts +3 -0
  21. package/build/file/save.js +7 -0
  22. package/build/file/temp.d.ts +11 -0
  23. package/build/file/temp.js +23 -0
  24. package/build/file/validate.d.ts +6 -0
  25. package/build/file/validate.js +47 -0
  26. package/build/file/validate.spec.d.ts +1 -0
  27. package/build/file/validate.spec.js +180 -0
  28. package/build/folder/create.d.ts +1 -0
  29. package/build/folder/create.js +5 -0
  30. package/build/folder/index.d.ts +2 -0
  31. package/build/folder/index.js +3 -0
  32. package/build/folder/temp.d.ts +3 -0
  33. package/build/folder/temp.js +16 -0
  34. package/build/index.d.ts +36 -0
  35. package/build/index.js +35 -0
  36. package/build/package/index.d.ts +2 -0
  37. package/build/package/index.js +3 -0
  38. package/build/package/merge.d.ts +23 -0
  39. package/build/package/merge.js +12 -0
  40. package/build/package/path.d.ts +3 -0
  41. package/build/package/path.js +43 -0
  42. package/build/package/path.spec.d.ts +1 -0
  43. package/build/package/path.spec.js +56 -0
  44. package/build/plugin.d.ts +11 -0
  45. package/build/plugin.js +2 -0
  46. package/build/plugins/ckan/ckan/index.d.ts +1 -0
  47. package/build/plugins/ckan/ckan/index.js +2 -0
  48. package/build/plugins/ckan/ckan/request.d.ts +11 -0
  49. package/build/plugins/ckan/ckan/request.js +35 -0
  50. package/build/plugins/ckan/index.d.ts +4 -0
  51. package/build/plugins/ckan/index.js +5 -0
  52. package/build/plugins/ckan/package/Organization.d.ts +21 -0
  53. package/build/plugins/ckan/package/Organization.js +2 -0
  54. package/build/plugins/ckan/package/Package.d.ts +76 -0
  55. package/build/plugins/ckan/package/Package.js +2 -0
  56. package/build/plugins/ckan/package/Tag.d.ts +17 -0
  57. package/build/plugins/ckan/package/Tag.js +2 -0
  58. package/build/plugins/ckan/package/convert/fromCkan.d.ts +3 -0
  59. package/build/plugins/ckan/package/convert/fromCkan.js +63 -0
  60. package/build/plugins/ckan/package/convert/fromCkan.spec.d.ts +1 -0
  61. package/build/plugins/ckan/package/convert/fromCkan.spec.js +80 -0
  62. package/build/plugins/ckan/package/convert/toCkan.d.ts +22 -0
  63. package/build/plugins/ckan/package/convert/toCkan.js +51 -0
  64. package/build/plugins/ckan/package/convert/toCkan.spec.d.ts +1 -0
  65. package/build/plugins/ckan/package/convert/toCkan.spec.js +153 -0
  66. package/build/plugins/ckan/package/fixtures/ckan-package.json +308 -0
  67. package/build/plugins/ckan/package/index.d.ts +7 -0
  68. package/build/plugins/ckan/package/index.js +5 -0
  69. package/build/plugins/ckan/package/load.d.ts +21 -0
  70. package/build/plugins/ckan/package/load.js +74 -0
  71. package/build/plugins/ckan/package/load.spec.d.ts +1 -0
  72. package/build/plugins/ckan/package/load.spec.js +11 -0
  73. package/build/plugins/ckan/package/save.d.ts +10 -0
  74. package/build/plugins/ckan/package/save.js +83 -0
  75. package/build/plugins/ckan/package/save.spec.d.ts +1 -0
  76. package/build/plugins/ckan/package/save.spec.js +319 -0
  77. package/build/plugins/ckan/plugin.d.ts +19 -0
  78. package/build/plugins/ckan/plugin.js +18 -0
  79. package/build/plugins/ckan/plugin.spec.d.ts +1 -0
  80. package/build/plugins/ckan/plugin.spec.js +83 -0
  81. package/build/plugins/ckan/resource/Resource.d.ts +56 -0
  82. package/build/plugins/ckan/resource/Resource.js +2 -0
  83. package/build/plugins/ckan/resource/convert/fromCkan.d.ts +3 -0
  84. package/build/plugins/ckan/resource/convert/fromCkan.js +39 -0
  85. package/build/plugins/ckan/resource/convert/toCkan.d.ts +3 -0
  86. package/build/plugins/ckan/resource/convert/toCkan.js +20 -0
  87. package/build/plugins/ckan/resource/index.d.ts +3 -0
  88. package/build/plugins/ckan/resource/index.js +3 -0
  89. package/build/plugins/ckan/schema/Field.d.ts +34 -0
  90. package/build/plugins/ckan/schema/Field.js +2 -0
  91. package/build/plugins/ckan/schema/Schema.d.ts +10 -0
  92. package/build/plugins/ckan/schema/Schema.js +2 -0
  93. package/build/plugins/ckan/schema/convert/fixtures/ckan-schema.json +115 -0
  94. package/build/plugins/ckan/schema/convert/fromCkan.d.ts +3 -0
  95. package/build/plugins/ckan/schema/convert/fromCkan.js +47 -0
  96. package/build/plugins/ckan/schema/convert/fromCkan.spec.d.ts +1 -0
  97. package/build/plugins/ckan/schema/convert/fromCkan.spec.js +157 -0
  98. package/build/plugins/ckan/schema/convert/toCkan.d.ts +3 -0
  99. package/build/plugins/ckan/schema/convert/toCkan.js +50 -0
  100. package/build/plugins/ckan/schema/convert/toCkan.spec.d.ts +1 -0
  101. package/build/plugins/ckan/schema/convert/toCkan.spec.js +278 -0
  102. package/build/plugins/ckan/schema/index.d.ts +4 -0
  103. package/build/plugins/ckan/schema/index.js +3 -0
  104. package/build/plugins/datahub/index.d.ts +2 -0
  105. package/build/plugins/datahub/index.js +3 -0
  106. package/build/plugins/datahub/package/index.d.ts +1 -0
  107. package/build/plugins/datahub/package/index.js +2 -0
  108. package/build/plugins/datahub/package/load.d.ts +1 -0
  109. package/build/plugins/datahub/package/load.js +9 -0
  110. package/build/plugins/datahub/package/load.spec.d.ts +1 -0
  111. package/build/plugins/datahub/package/load.spec.js +11 -0
  112. package/build/plugins/datahub/plugin.d.ts +4 -0
  113. package/build/plugins/datahub/plugin.js +18 -0
  114. package/build/plugins/datahub/plugin.spec.d.ts +1 -0
  115. package/build/plugins/datahub/plugin.spec.js +78 -0
  116. package/build/plugins/descriptor/index.d.ts +1 -0
  117. package/build/plugins/descriptor/index.js +2 -0
  118. package/build/plugins/descriptor/plugin.d.ts +11 -0
  119. package/build/plugins/descriptor/plugin.js +29 -0
  120. package/build/plugins/descriptor/plugin.spec.d.ts +1 -0
  121. package/build/plugins/descriptor/plugin.spec.js +169 -0
  122. package/build/plugins/folder/index.d.ts +2 -0
  123. package/build/plugins/folder/index.js +3 -0
  124. package/build/plugins/folder/package/index.d.ts +2 -0
  125. package/build/plugins/folder/package/index.js +3 -0
  126. package/build/plugins/folder/package/load.d.ts +1 -0
  127. package/build/plugins/folder/package/load.js +6 -0
  128. package/build/plugins/folder/package/load.spec.d.ts +1 -0
  129. package/build/plugins/folder/package/load.spec.js +175 -0
  130. package/build/plugins/folder/package/save.d.ts +7 -0
  131. package/build/plugins/folder/package/save.js +35 -0
  132. package/build/plugins/folder/package/save.spec.d.ts +1 -0
  133. package/build/plugins/folder/package/save.spec.js +328 -0
  134. package/build/plugins/folder/plugin.d.ts +4 -0
  135. package/build/plugins/folder/plugin.js +19 -0
  136. package/build/plugins/folder/plugin.spec.d.ts +1 -0
  137. package/build/plugins/folder/plugin.spec.js +53 -0
  138. package/build/plugins/github/github/index.d.ts +1 -0
  139. package/build/plugins/github/github/index.js +2 -0
  140. package/build/plugins/github/github/path.d.ts +1 -0
  141. package/build/plugins/github/github/path.js +4 -0
  142. package/build/plugins/github/github/request.d.ts +15 -0
  143. package/build/plugins/github/github/request.js +43 -0
  144. package/build/plugins/github/index.d.ts +3 -0
  145. package/build/plugins/github/index.js +4 -0
  146. package/build/plugins/github/package/License.d.ts +21 -0
  147. package/build/plugins/github/package/License.js +2 -0
  148. package/build/plugins/github/package/Owner.d.ts +25 -0
  149. package/build/plugins/github/package/Owner.js +2 -0
  150. package/build/plugins/github/package/Package.d.ts +87 -0
  151. package/build/plugins/github/package/Package.js +2 -0
  152. package/build/plugins/github/package/convert/fromGithub.d.ts +3 -0
  153. package/build/plugins/github/package/convert/fromGithub.js +50 -0
  154. package/build/plugins/github/package/index.d.ts +6 -0
  155. package/build/plugins/github/package/index.js +4 -0
  156. package/build/plugins/github/package/load.d.ts +23 -0
  157. package/build/plugins/github/package/load.js +48 -0
  158. package/build/plugins/github/package/load.spec.d.ts +1 -0
  159. package/build/plugins/github/package/load.spec.js +15 -0
  160. package/build/plugins/github/package/save.d.ts +14 -0
  161. package/build/plugins/github/package/save.js +69 -0
  162. package/build/plugins/github/package/save.spec.d.ts +1 -0
  163. package/build/plugins/github/package/save.spec.js +566 -0
  164. package/build/plugins/github/plugin.d.ts +19 -0
  165. package/build/plugins/github/plugin.js +18 -0
  166. package/build/plugins/github/plugin.spec.d.ts +1 -0
  167. package/build/plugins/github/plugin.spec.js +73 -0
  168. package/build/plugins/github/resource/Resource.d.ts +29 -0
  169. package/build/plugins/github/resource/Resource.js +2 -0
  170. package/build/plugins/github/resource/convert/fromGithub.d.ts +5 -0
  171. package/build/plugins/github/resource/convert/fromGithub.js +24 -0
  172. package/build/plugins/github/resource/convert/toGithub.d.ts +3 -0
  173. package/build/plugins/github/resource/convert/toGithub.js +10 -0
  174. package/build/plugins/github/resource/index.d.ts +3 -0
  175. package/build/plugins/github/resource/index.js +3 -0
  176. package/build/plugins/zenodo/index.d.ts +3 -0
  177. package/build/plugins/zenodo/index.js +4 -0
  178. package/build/plugins/zenodo/package/Creator.d.ts +20 -0
  179. package/build/plugins/zenodo/package/Creator.js +2 -0
  180. package/build/plugins/zenodo/package/Package.d.ts +94 -0
  181. package/build/plugins/zenodo/package/Package.js +2 -0
  182. package/build/plugins/zenodo/package/convert/fromZenodo.d.ts +3 -0
  183. package/build/plugins/zenodo/package/convert/fromZenodo.js +43 -0
  184. package/build/plugins/zenodo/package/convert/toZenodo.d.ts +3 -0
  185. package/build/plugins/zenodo/package/convert/toZenodo.js +79 -0
  186. package/build/plugins/zenodo/package/index.d.ts +6 -0
  187. package/build/plugins/zenodo/package/index.js +5 -0
  188. package/build/plugins/zenodo/package/load.d.ts +23 -0
  189. package/build/plugins/zenodo/package/load.js +45 -0
  190. package/build/plugins/zenodo/package/load.spec.d.ts +1 -0
  191. package/build/plugins/zenodo/package/load.spec.js +15 -0
  192. package/build/plugins/zenodo/package/save.d.ts +13 -0
  193. package/build/plugins/zenodo/package/save.js +74 -0
  194. package/build/plugins/zenodo/package/save.spec.d.ts +1 -0
  195. package/build/plugins/zenodo/package/save.spec.js +524 -0
  196. package/build/plugins/zenodo/plugin.d.ts +19 -0
  197. package/build/plugins/zenodo/plugin.js +18 -0
  198. package/build/plugins/zenodo/plugin.spec.d.ts +1 -0
  199. package/build/plugins/zenodo/plugin.spec.js +78 -0
  200. package/build/plugins/zenodo/resource/Resource.d.ts +27 -0
  201. package/build/plugins/zenodo/resource/Resource.js +2 -0
  202. package/build/plugins/zenodo/resource/convert/fromZenodo.d.ts +10 -0
  203. package/build/plugins/zenodo/resource/convert/fromZenodo.js +18 -0
  204. package/build/plugins/zenodo/resource/convert/toZenodo.d.ts +3 -0
  205. package/build/plugins/zenodo/resource/convert/toZenodo.js +13 -0
  206. package/build/plugins/zenodo/resource/index.d.ts +3 -0
  207. package/build/plugins/zenodo/resource/index.js +3 -0
  208. package/build/plugins/zenodo/zenodo/index.d.ts +1 -0
  209. package/build/plugins/zenodo/zenodo/index.js +2 -0
  210. package/build/plugins/zenodo/zenodo/request.d.ts +12 -0
  211. package/build/plugins/zenodo/zenodo/request.js +36 -0
  212. package/build/plugins/zip/index.d.ts +2 -0
  213. package/build/plugins/zip/index.js +3 -0
  214. package/build/plugins/zip/package/index.d.ts +2 -0
  215. package/build/plugins/zip/package/index.js +3 -0
  216. package/build/plugins/zip/package/load.d.ts +1 -0
  217. package/build/plugins/zip/package/load.js +30 -0
  218. package/build/plugins/zip/package/load.spec.d.ts +1 -0
  219. package/build/plugins/zip/package/load.spec.js +173 -0
  220. package/build/plugins/zip/package/save.d.ts +5 -0
  221. package/build/plugins/zip/package/save.js +50 -0
  222. package/build/plugins/zip/package/save.spec.d.ts +1 -0
  223. package/build/plugins/zip/package/save.spec.js +287 -0
  224. package/build/plugins/zip/plugin.d.ts +11 -0
  225. package/build/plugins/zip/plugin.js +24 -0
  226. package/build/plugins/zip/plugin.spec.d.ts +1 -0
  227. package/build/plugins/zip/plugin.spec.js +158 -0
  228. package/build/resource/index.d.ts +1 -0
  229. package/build/resource/index.js +2 -0
  230. package/build/resource/save.d.ts +13 -0
  231. package/build/resource/save.js +53 -0
  232. package/build/resource/save.spec.d.ts +1 -0
  233. package/build/resource/save.spec.js +107 -0
  234. package/build/stream/concat.d.ts +3 -0
  235. package/build/stream/concat.js +5 -0
  236. package/build/stream/index.d.ts +3 -0
  237. package/build/stream/index.js +4 -0
  238. package/build/stream/load.d.ts +5 -0
  239. package/build/stream/load.js +46 -0
  240. package/build/stream/save.d.ts +5 -0
  241. package/build/stream/save.js +13 -0
  242. 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 {};