@frictionless-ts/metadata 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/assets/dialect-1.0.json +58 -0
- package/build/assets/dialect-2.0.json +98 -0
- package/build/assets/package-1.0.json +1517 -0
- package/build/assets/package-2.0.json +2168 -0
- package/build/assets/resource-1.0.json +1353 -0
- package/build/assets/resource-2.0.json +1987 -0
- package/build/assets/schema-1.0.json +1126 -0
- package/build/assets/schema-2.0.json +1715 -0
- package/build/descriptor/Descriptor.d.ts +2 -0
- package/build/descriptor/Descriptor.js +4 -0
- package/build/descriptor/index.d.ts +6 -0
- package/build/descriptor/index.js +6 -0
- package/build/descriptor/load.d.ts +8 -0
- package/build/descriptor/load.js +36 -0
- package/build/descriptor/load.spec.d.ts +1 -0
- package/build/descriptor/load.spec.js +44 -0
- package/build/descriptor/process/parse.d.ts +2 -0
- package/build/descriptor/process/parse.js +8 -0
- package/build/descriptor/process/stringify.d.ts +2 -0
- package/build/descriptor/process/stringify.js +4 -0
- package/build/descriptor/save.d.ts +9 -0
- package/build/descriptor/save.js +19 -0
- package/build/descriptor/save.spec.d.ts +1 -0
- package/build/descriptor/save.spec.js +99 -0
- package/build/dialect/Dialect.d.ts +89 -0
- package/build/dialect/Dialect.js +2 -0
- package/build/dialect/assert.d.ts +6 -0
- package/build/dialect/assert.js +12 -0
- package/build/dialect/assert.spec.d.ts +1 -0
- package/build/dialect/assert.spec.js +22 -0
- package/build/dialect/convert/fromDescriptor.d.ts +2 -0
- package/build/dialect/convert/fromDescriptor.js +20 -0
- package/build/dialect/convert/toDescriptor.d.ts +3 -0
- package/build/dialect/convert/toDescriptor.js +5 -0
- package/build/dialect/index.d.ts +8 -0
- package/build/dialect/index.js +8 -0
- package/build/dialect/load.d.ts +5 -0
- package/build/dialect/load.js +12 -0
- package/build/dialect/load.spec.d.ts +1 -0
- package/build/dialect/load.spec.js +18 -0
- package/build/dialect/resolve.d.ts +2 -0
- package/build/dialect/resolve.js +11 -0
- package/build/dialect/save.d.ts +9 -0
- package/build/dialect/save.js +16 -0
- package/build/dialect/save.spec.d.ts +1 -0
- package/build/dialect/save.spec.js +52 -0
- package/build/dialect/validate.d.ts +10 -0
- package/build/dialect/validate.js +25 -0
- package/build/dialect/validate.spec.d.ts +1 -0
- package/build/dialect/validate.spec.js +28 -0
- package/build/error/Bound.d.ts +4 -0
- package/build/error/Bound.js +2 -0
- package/build/error/Error.d.ts +3 -0
- package/build/error/Error.js +2 -0
- package/build/error/Unbound.d.ts +6 -0
- package/build/error/Unbound.js +2 -0
- package/build/error/index.d.ts +16 -0
- package/build/error/index.js +2 -0
- package/build/error/types/Base.d.ts +3 -0
- package/build/error/types/Base.js +2 -0
- package/build/error/types/Bytes.d.ts +6 -0
- package/build/error/types/Bytes.js +2 -0
- package/build/error/types/Cell.d.ts +56 -0
- package/build/error/types/Cell.js +2 -0
- package/build/error/types/Data.d.ts +5 -0
- package/build/error/types/Data.js +2 -0
- package/build/error/types/Document.d.ts +7 -0
- package/build/error/types/Document.js +2 -0
- package/build/error/types/Encoding.d.ts +6 -0
- package/build/error/types/Encoding.js +2 -0
- package/build/error/types/Field.d.ts +15 -0
- package/build/error/types/Field.js +2 -0
- package/build/error/types/Fields.d.ts +11 -0
- package/build/error/types/Fields.js +2 -0
- package/build/error/types/File.d.ts +4 -0
- package/build/error/types/File.js +2 -0
- package/build/error/types/ForeignKey.d.ts +7 -0
- package/build/error/types/ForeignKey.js +2 -0
- package/build/error/types/Hash.d.ts +6 -0
- package/build/error/types/Hash.js +2 -0
- package/build/error/types/Metadata.d.ts +9 -0
- package/build/error/types/Metadata.js +2 -0
- package/build/error/types/Row.d.ts +9 -0
- package/build/error/types/Row.js +2 -0
- package/build/error/types/Table.d.ts +6 -0
- package/build/error/types/Table.js +2 -0
- package/build/field/Field.d.ts +5 -0
- package/build/field/Field.js +2 -0
- package/build/field/Type.d.ts +2 -0
- package/build/field/Type.js +2 -0
- package/build/field/convert/fromDescriptor.d.ts +2 -0
- package/build/field/convert/fromDescriptor.js +61 -0
- package/build/field/convert/fromDescriptor.spec.d.ts +1 -0
- package/build/field/convert/fromDescriptor.spec.js +241 -0
- package/build/field/convert/toDescriptor.d.ts +3 -0
- package/build/field/convert/toDescriptor.js +5 -0
- package/build/field/convert/toDescriptor.spec.d.ts +1 -0
- package/build/field/convert/toDescriptor.spec.js +291 -0
- package/build/field/index.d.ts +5 -0
- package/build/field/index.js +3 -0
- package/build/field/types/Any.d.ts +20 -0
- package/build/field/types/Any.js +2 -0
- package/build/field/types/Array.d.ts +32 -0
- package/build/field/types/Array.js +2 -0
- package/build/field/types/Base.d.ts +60 -0
- package/build/field/types/Base.js +2 -0
- package/build/field/types/Boolean.d.ts +28 -0
- package/build/field/types/Boolean.js +2 -0
- package/build/field/types/Date.d.ts +43 -0
- package/build/field/types/Date.js +2 -0
- package/build/field/types/Datetime.d.ts +43 -0
- package/build/field/types/Datetime.js +2 -0
- package/build/field/types/Duration.d.ts +28 -0
- package/build/field/types/Duration.js +2 -0
- package/build/field/types/Geojson.d.ts +30 -0
- package/build/field/types/Geojson.js +2 -0
- package/build/field/types/Geopoint.d.ts +27 -0
- package/build/field/types/Geopoint.js +2 -0
- package/build/field/types/Integer.d.ts +57 -0
- package/build/field/types/Integer.js +2 -0
- package/build/field/types/List.d.ts +36 -0
- package/build/field/types/List.js +2 -0
- package/build/field/types/Number.d.ts +48 -0
- package/build/field/types/Number.js +2 -0
- package/build/field/types/Object.d.ts +32 -0
- package/build/field/types/Object.js +2 -0
- package/build/field/types/String.d.ts +51 -0
- package/build/field/types/String.js +2 -0
- package/build/field/types/Time.d.ts +43 -0
- package/build/field/types/Time.js +2 -0
- package/build/field/types/Year.d.ts +36 -0
- package/build/field/types/Year.js +2 -0
- package/build/field/types/Yearmonth.d.ts +36 -0
- package/build/field/types/Yearmonth.js +2 -0
- package/build/field/types/index.d.ts +16 -0
- package/build/field/types/index.js +17 -0
- package/build/index.d.ts +112 -0
- package/build/index.js +32 -0
- package/build/json/Schema.d.ts +2 -0
- package/build/json/Schema.js +2 -0
- package/build/json/Value.d.ts +1 -0
- package/build/json/Value.js +2 -0
- package/build/json/ajv.d.ts +2 -0
- package/build/json/ajv.js +10 -0
- package/build/json/assert.d.ts +2 -0
- package/build/json/assert.js +10 -0
- package/build/json/cache.d.ts +2 -0
- package/build/json/cache.js +5 -0
- package/build/json/index.d.ts +5 -0
- package/build/json/index.js +4 -0
- package/build/json/inspect/schema.d.ts +4 -0
- package/build/json/inspect/schema.js +10 -0
- package/build/json/inspect/schema.spec.d.ts +1 -0
- package/build/json/inspect/schema.spec.js +132 -0
- package/build/json/inspect/value.d.ts +11 -0
- package/build/json/inspect/value.js +21 -0
- package/build/json/inspect/value.spec.d.ts +1 -0
- package/build/json/inspect/value.spec.js +121 -0
- package/build/json/load.d.ts +3 -0
- package/build/json/load.js +13 -0
- package/build/json/resolve.d.ts +2 -0
- package/build/json/resolve.js +11 -0
- package/build/metadata/Metadata.d.ts +3 -0
- package/build/metadata/Metadata.js +2 -0
- package/build/metadata/index.d.ts +1 -0
- package/build/metadata/index.js +2 -0
- package/build/package/Contributor.d.ts +21 -0
- package/build/package/Contributor.js +2 -0
- package/build/package/Package.d.ts +64 -0
- package/build/package/Package.js +2 -0
- package/build/package/assert.d.ts +8 -0
- package/build/package/assert.js +12 -0
- package/build/package/assert.spec.d.ts +1 -0
- package/build/package/assert.spec.js +26 -0
- package/build/package/convert/fromDescriptor.d.ts +4 -0
- package/build/package/convert/fromDescriptor.js +36 -0
- package/build/package/convert/toDescriptor.d.ts +5 -0
- package/build/package/convert/toDescriptor.js +7 -0
- package/build/package/index.d.ts +8 -0
- package/build/package/index.js +7 -0
- package/build/package/load.d.ts +5 -0
- package/build/package/load.js +14 -0
- package/build/package/load.spec.d.ts +1 -0
- package/build/package/load.spec.js +28 -0
- package/build/package/save.d.ts +9 -0
- package/build/package/save.js +18 -0
- package/build/package/save.spec.d.ts +1 -0
- package/build/package/save.spec.js +311 -0
- package/build/package/validate.d.ts +12 -0
- package/build/package/validate.js +27 -0
- package/build/package/validate.spec.d.ts +1 -0
- package/build/package/validate.spec.js +41 -0
- package/build/path/basepath.d.ts +2 -0
- package/build/path/basepath.js +25 -0
- package/build/path/basepath.spec.d.ts +1 -0
- package/build/path/basepath.spec.js +55 -0
- package/build/path/denormalize.d.ts +3 -0
- package/build/path/denormalize.js +29 -0
- package/build/path/denormalize.spec.d.ts +1 -0
- package/build/path/denormalize.spec.js +45 -0
- package/build/path/index.d.ts +5 -0
- package/build/path/index.js +6 -0
- package/build/path/normalize.d.ts +6 -0
- package/build/path/normalize.js +54 -0
- package/build/path/normalize.spec.d.ts +1 -0
- package/build/path/normalize.spec.js +71 -0
- package/build/path/path.d.ts +5 -0
- package/build/path/path.js +48 -0
- package/build/path/path.spec.d.ts +1 -0
- package/build/path/path.spec.js +111 -0
- package/build/platform/index.d.ts +1 -0
- package/build/platform/index.js +2 -0
- package/build/platform/node.d.ts +130 -0
- package/build/platform/node.js +10 -0
- package/build/platform/node.spec.d.ts +1 -0
- package/build/platform/node.spec.js +16 -0
- package/build/profile/@minify.d.ts +1 -0
- package/build/profile/@minify.js +58 -0
- package/build/profile/Profile.d.ts +9 -0
- package/build/profile/Profile.js +2 -0
- package/build/profile/assert.d.ts +6 -0
- package/build/profile/assert.js +36 -0
- package/build/profile/assert.spec.d.ts +1 -0
- package/build/profile/assert.spec.js +115 -0
- package/build/profile/index.d.ts +2 -0
- package/build/profile/index.js +2 -0
- package/build/profile/load.d.ts +4 -0
- package/build/profile/load.js +12 -0
- package/build/profile/registry.d.ts +2 -0
- package/build/profile/registry.js +83 -0
- package/build/profile/resolve.d.ts +2 -0
- package/build/profile/resolve.js +8 -0
- package/build/profile/validate.d.ts +9 -0
- package/build/profile/validate.js +12 -0
- package/build/report/Report.d.ts +5 -0
- package/build/report/Report.js +2 -0
- package/build/report/create.d.ts +7 -0
- package/build/report/create.js +6 -0
- package/build/report/index.d.ts +2 -0
- package/build/report/index.js +2 -0
- package/build/resource/License.d.ts +18 -0
- package/build/resource/License.js +2 -0
- package/build/resource/Resource.d.ts +93 -0
- package/build/resource/Resource.js +2 -0
- package/build/resource/Source.d.ts +17 -0
- package/build/resource/Source.js +2 -0
- package/build/resource/assert.d.ts +8 -0
- package/build/resource/assert.js +12 -0
- package/build/resource/assert.spec.d.ts +1 -0
- package/build/resource/assert.spec.js +23 -0
- package/build/resource/convert/fromDescriptor.d.ts +4 -0
- package/build/resource/convert/fromDescriptor.js +69 -0
- package/build/resource/convert/toDescriptor.d.ts +5 -0
- package/build/resource/convert/toDescriptor.js +36 -0
- package/build/resource/helpers.d.ts +2 -0
- package/build/resource/helpers.js +6 -0
- package/build/resource/index.d.ts +11 -0
- package/build/resource/index.js +9 -0
- package/build/resource/infer.d.ts +3 -0
- package/build/resource/infer.js +35 -0
- package/build/resource/infer.spec.d.ts +1 -0
- package/build/resource/infer.spec.js +103 -0
- package/build/resource/load.d.ts +5 -0
- package/build/resource/load.js +14 -0
- package/build/resource/load.spec.d.ts +1 -0
- package/build/resource/load.spec.js +22 -0
- package/build/resource/save.d.ts +9 -0
- package/build/resource/save.js +18 -0
- package/build/resource/save.spec.d.ts +1 -0
- package/build/resource/save.spec.js +170 -0
- package/build/resource/validate.d.ts +13 -0
- package/build/resource/validate.js +57 -0
- package/build/resource/validate.spec.d.ts +1 -0
- package/build/resource/validate.spec.js +30 -0
- package/build/schema/ForeignKey.d.ts +23 -0
- package/build/schema/ForeignKey.js +2 -0
- package/build/schema/Schema.d.ts +56 -0
- package/build/schema/Schema.js +2 -0
- package/build/schema/assert.d.ts +6 -0
- package/build/schema/assert.js +12 -0
- package/build/schema/assert.spec.d.ts +1 -0
- package/build/schema/assert.spec.js +34 -0
- package/build/schema/convert/fromDescriptor.d.ts +2 -0
- package/build/schema/convert/fromDescriptor.js +70 -0
- package/build/schema/convert/fromJsonSchema.d.ts +3 -0
- package/build/schema/convert/fromJsonSchema.js +105 -0
- package/build/schema/convert/fromJsonSchema.spec.d.ts +1 -0
- package/build/schema/convert/fromJsonSchema.spec.js +156 -0
- package/build/schema/convert/toDescriptor.d.ts +3 -0
- package/build/schema/convert/toDescriptor.js +5 -0
- package/build/schema/convert/toJsonSchema.d.ts +3 -0
- package/build/schema/convert/toJsonSchema.js +173 -0
- package/build/schema/convert/toJsonSchema.spec.d.ts +1 -0
- package/build/schema/convert/toJsonSchema.spec.js +403 -0
- package/build/schema/index.d.ts +11 -0
- package/build/schema/index.js +10 -0
- package/build/schema/load.d.ts +5 -0
- package/build/schema/load.js +12 -0
- package/build/schema/load.spec.d.ts +1 -0
- package/build/schema/load.spec.js +55 -0
- package/build/schema/resolve.d.ts +2 -0
- package/build/schema/resolve.js +11 -0
- package/build/schema/save.d.ts +9 -0
- package/build/schema/save.js +16 -0
- package/build/schema/save.spec.d.ts +1 -0
- package/build/schema/save.spec.js +58 -0
- package/build/schema/validate.d.ts +10 -0
- package/build/schema/validate.js +25 -0
- package/build/schema/validate.spec.d.ts +1 -0
- package/build/schema/validate.spec.js +41 -0
- package/package.json +37 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { temporaryDirectory } from "tempy";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { saveResourceDescriptor } from "./save.js";
|
|
6
|
+
describe("saveResourceDescriptor", () => {
|
|
7
|
+
let testDir;
|
|
8
|
+
let testPath;
|
|
9
|
+
let testResource;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
testDir = temporaryDirectory();
|
|
12
|
+
testPath = path.join(testDir, "resource.json");
|
|
13
|
+
testResource = {
|
|
14
|
+
name: "test-resource",
|
|
15
|
+
path: path.join(testDir, "data.csv"),
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
try {
|
|
20
|
+
await fs.rm(testDir, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (error instanceof Error && !error.message.includes("ENOENT")) {
|
|
24
|
+
console.error(`Failed to clean up test directory: ${testDir}`, error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
it("should save a resource descriptor to a file and maintain its structure", async () => {
|
|
29
|
+
await saveResourceDescriptor(testResource, { path: testPath });
|
|
30
|
+
const fileExists = await fs
|
|
31
|
+
.stat(testPath)
|
|
32
|
+
.then(() => true)
|
|
33
|
+
.catch(() => false);
|
|
34
|
+
expect(fileExists).toBe(true);
|
|
35
|
+
const content = await fs.readFile(testPath, "utf-8");
|
|
36
|
+
const parsedContent = JSON.parse(content);
|
|
37
|
+
const { $schema, ...resourceWithoutSchema } = parsedContent;
|
|
38
|
+
expect(resourceWithoutSchema.name).toEqual(testResource.name);
|
|
39
|
+
expect(resourceWithoutSchema.path).toBe("data.csv");
|
|
40
|
+
expect($schema).toBe("https://datapackage.org/profiles/2.0/dataresource.json");
|
|
41
|
+
});
|
|
42
|
+
it("should add $schema property if not present", async () => {
|
|
43
|
+
await saveResourceDescriptor(testResource, { path: testPath });
|
|
44
|
+
const content = await fs.readFile(testPath, "utf-8");
|
|
45
|
+
const parsedContent = JSON.parse(content);
|
|
46
|
+
expect(parsedContent.$schema).toBe("https://datapackage.org/profiles/2.0/dataresource.json");
|
|
47
|
+
});
|
|
48
|
+
it("should preserve existing $schema property", async () => {
|
|
49
|
+
const resourceWithSchema = {
|
|
50
|
+
name: "test-resource",
|
|
51
|
+
path: path.join(testDir, "data.csv"),
|
|
52
|
+
$schema: "https://custom.schema.url",
|
|
53
|
+
};
|
|
54
|
+
await saveResourceDescriptor(resourceWithSchema, { path: testPath });
|
|
55
|
+
const content = await fs.readFile(testPath, "utf-8");
|
|
56
|
+
const parsedContent = JSON.parse(content);
|
|
57
|
+
expect(parsedContent.$schema).toBe("https://custom.schema.url");
|
|
58
|
+
});
|
|
59
|
+
it("should use pretty formatting with 2-space indentation", async () => {
|
|
60
|
+
await saveResourceDescriptor(testResource, { path: testPath });
|
|
61
|
+
const content = await fs.readFile(testPath, "utf-8");
|
|
62
|
+
const lines = content.split("\n");
|
|
63
|
+
expect(lines.length).toBeGreaterThan(1);
|
|
64
|
+
if (lines.length > 1 && lines[1]) {
|
|
65
|
+
expect(lines[1].startsWith(" ")).toBe(true);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
it("should save resource with schema", async () => {
|
|
69
|
+
const resourceWithSchema = {
|
|
70
|
+
name: "test-resource",
|
|
71
|
+
path: path.join(testDir, "data.csv"),
|
|
72
|
+
schema: {
|
|
73
|
+
fields: [
|
|
74
|
+
{ name: "id", type: "integer" },
|
|
75
|
+
{ name: "name", type: "string" },
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
await saveResourceDescriptor(resourceWithSchema, { path: testPath });
|
|
80
|
+
const content = await fs.readFile(testPath, "utf-8");
|
|
81
|
+
const parsedContent = JSON.parse(content);
|
|
82
|
+
expect(parsedContent.schema).toEqual(resourceWithSchema.schema);
|
|
83
|
+
});
|
|
84
|
+
it("should save resource with dialect", async () => {
|
|
85
|
+
const resourceWithDialect = {
|
|
86
|
+
name: "test-resource",
|
|
87
|
+
path: path.join(testDir, "data.csv"),
|
|
88
|
+
dialect: {
|
|
89
|
+
delimiter: ";",
|
|
90
|
+
lineTerminator: "\n",
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
await saveResourceDescriptor(resourceWithDialect, { path: testPath });
|
|
94
|
+
const content = await fs.readFile(testPath, "utf-8");
|
|
95
|
+
const parsedContent = JSON.parse(content);
|
|
96
|
+
expect(parsedContent.dialect).toEqual(resourceWithDialect.dialect);
|
|
97
|
+
});
|
|
98
|
+
it("should save resource to a nested directory path", async () => {
|
|
99
|
+
const nestedPath = path.join(testDir, "nested", "dir", "resource.json");
|
|
100
|
+
const nestedResource = {
|
|
101
|
+
name: "test-resource",
|
|
102
|
+
path: path.join(testDir, "nested", "dir", "data.csv"),
|
|
103
|
+
};
|
|
104
|
+
await saveResourceDescriptor(nestedResource, { path: nestedPath });
|
|
105
|
+
const fileExists = await fs
|
|
106
|
+
.stat(nestedPath)
|
|
107
|
+
.then(() => true)
|
|
108
|
+
.catch(() => false);
|
|
109
|
+
expect(fileExists).toBe(true);
|
|
110
|
+
const content = await fs.readFile(nestedPath, "utf-8");
|
|
111
|
+
const parsedContent = JSON.parse(content);
|
|
112
|
+
expect(parsedContent.name).toBe(nestedResource.name);
|
|
113
|
+
});
|
|
114
|
+
it("should throw an error when file exists and overwrite is false", async () => {
|
|
115
|
+
await saveResourceDescriptor(testResource, { path: testPath });
|
|
116
|
+
await expect(saveResourceDescriptor(testResource, {
|
|
117
|
+
path: testPath,
|
|
118
|
+
overwrite: false,
|
|
119
|
+
})).rejects.toThrow();
|
|
120
|
+
});
|
|
121
|
+
it("should throw an error when file exists and overwrite is not specified", async () => {
|
|
122
|
+
await saveResourceDescriptor(testResource, { path: testPath });
|
|
123
|
+
await expect(saveResourceDescriptor(testResource, { path: testPath })).rejects.toThrow();
|
|
124
|
+
});
|
|
125
|
+
it("should overwrite existing file when overwrite is true", async () => {
|
|
126
|
+
const initialResource = {
|
|
127
|
+
name: "initial",
|
|
128
|
+
path: path.join(testDir, "data1.csv"),
|
|
129
|
+
};
|
|
130
|
+
const updatedResource = {
|
|
131
|
+
name: "updated",
|
|
132
|
+
path: path.join(testDir, "data2.csv"),
|
|
133
|
+
description: "Updated resource",
|
|
134
|
+
};
|
|
135
|
+
await saveResourceDescriptor(initialResource, { path: testPath });
|
|
136
|
+
const initialContent = await fs.readFile(testPath, "utf-8");
|
|
137
|
+
const initialParsed = JSON.parse(initialContent);
|
|
138
|
+
expect(initialParsed.name).toBe("initial");
|
|
139
|
+
await saveResourceDescriptor(updatedResource, {
|
|
140
|
+
path: testPath,
|
|
141
|
+
overwrite: true,
|
|
142
|
+
});
|
|
143
|
+
const updatedContent = await fs.readFile(testPath, "utf-8");
|
|
144
|
+
const updatedParsed = JSON.parse(updatedContent);
|
|
145
|
+
expect(updatedParsed.name).toBe("updated");
|
|
146
|
+
expect(updatedParsed.description).toBe("Updated resource");
|
|
147
|
+
});
|
|
148
|
+
it("should save resource with all metadata fields", async () => {
|
|
149
|
+
const fullResource = {
|
|
150
|
+
name: "full-resource",
|
|
151
|
+
path: path.join(testDir, "data.csv"),
|
|
152
|
+
title: "Full Resource",
|
|
153
|
+
description: "A resource with all fields",
|
|
154
|
+
format: "csv",
|
|
155
|
+
mediatype: "text/csv",
|
|
156
|
+
encoding: "utf-8",
|
|
157
|
+
bytes: 1024,
|
|
158
|
+
hash: "abc123",
|
|
159
|
+
};
|
|
160
|
+
await saveResourceDescriptor(fullResource, { path: testPath });
|
|
161
|
+
const content = await fs.readFile(testPath, "utf-8");
|
|
162
|
+
const parsedContent = JSON.parse(content);
|
|
163
|
+
expect(parsedContent.name).toBe(fullResource.name);
|
|
164
|
+
expect(parsedContent.title).toBe(fullResource.title);
|
|
165
|
+
expect(parsedContent.description).toBe(fullResource.description);
|
|
166
|
+
expect(parsedContent.format).toBe(fullResource.format);
|
|
167
|
+
expect(parsedContent.bytes).toBe(fullResource.bytes);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F2ZS5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vcmVzb3VyY2Uvc2F2ZS5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDdEMsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUE7QUFDakMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sT0FBTyxDQUFBO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBRXBFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUVsRCxRQUFRLENBQUMsd0JBQXdCLEVBQUUsR0FBRyxFQUFFO0lBQ3RDLElBQUksT0FBZSxDQUFBO0lBQ25CLElBQUksUUFBZ0IsQ0FBQTtJQUNwQixJQUFJLFlBQXNCLENBQUE7SUFFMUIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLE9BQU8sR0FBRyxrQkFBa0IsRUFBRSxDQUFBO1FBQzlCLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxlQUFlLENBQUMsQ0FBQTtRQUM5QyxZQUFZLEdBQUc7WUFDYixJQUFJLEVBQUUsZUFBZTtZQUNyQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDO1NBQ3JDLENBQUE7SUFDSCxDQUFDLENBQUMsQ0FBQTtJQUVGLFNBQVMsQ0FBQyxLQUFLLElBQUksRUFBRTtRQUNuQixJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUN4RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLEtB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QUssQ0FBQyxDQUFBO0lBQ3RELENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgdGVtcG9yYXJ5RGlyZWN0b3J5IH0gZnJvbSBcInRlbXB5XCJcbmltcG9ydCB7IGFmdGVyRWFjaCwgYmVmb3JlRWFjaCwgZGVzY3JpYmUsIGV4cGVjdCwgaXQgfSBmcm9tIFwidml0ZXN0XCJcbmltcG9ydCB0eXBlIHsgUmVzb3VyY2UgfSBmcm9tIFwiLi9SZXNvdXJjZS50c1wiXG5pbXBvcnQgeyBzYXZlUmVzb3VyY2VEZXNjcmlwdG9yIH0gZnJvbSBcIi4vc2F2ZS50c1wiXG5cbmRlc2NyaWJlKFwic2F2ZVJlc291cmNlRGVzY3JpcHRvclwiLCAoKSA9PiB7XG4gIGxldCB0ZXN0RGlyOiBzdHJpbmdcbiAgbGV0IHRlc3RQYXRoOiBzdHJpbmdcbiAgbGV0IHRlc3RSZXNvdXJjZTogUmVzb3VyY2VcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICB0ZXN0RGlyID0gdGVtcG9yYXJ5RGlyZWN0b3J5KClcbiAgICB0ZXN0UGF0aCA9IHBhdGguam9pbih0ZXN0RGlyLCBcInJlc291cmNlLmpzb25cIilcbiAgICB0ZXN0UmVzb3VyY2UgPSB7XG4gICAgICBuYW1lOiBcInRlc3QtcmVzb3VyY2VcIixcbiAgICAgIHBhdGg6IHBhdGguam9pbih0ZXN0RGlyLCBcImRhdGEuY3N2XCIpLFxuICAgIH1cbiAgfSlcblxuICBhZnRlckVhY2goYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5ybSh0ZXN0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgIWVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoXCJFTk9FTlRcIikpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIGNsZWFuIHVwIHRlc3QgZGlyZWN0b3J5OiAke3Rlc3REaXJ9YCwgZXJyb3IpXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHNhdmUgYSByZXNvdXJjZSBkZXNjcmlwdG9yIHRvIGEgZmlsZSBhbmQgbWFpbnRhaW4gaXRzIHN0cnVjdHVyZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgc2F2ZVJlc291cmNlRGVzY3JpcHRvcih0ZXN0UmVzb3VyY2UsIHsgcGF0aDogdGVzdFBhdGggfSlcblxuICAgIGNvbnN0IGZpbGVFeGlzdHMgPSBhd2FpdCBmc1xuICAgICAgLnN0YXQodGVzdFBhdGgpXG4gICAgICAudGhlbigoKSA9PiB0cnVlKVxuICAgICAgLmNhdGNoKCgpID0+IGZhbHNlKVxuICAgIGV4cGVjdChmaWxlRXhpc3RzKS50b0JlKHRydWUpXG5cbiAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUodGVzdFBhdGgsIFwidXRmLThcIilcbiAgICBjb25zdCBwYXJzZWRDb250ZW50ID0gSlNPTi5wYXJzZShjb250ZW50KVxuXG4gICAgY29uc3QgeyAkc2NoZW1hLCAuLi5yZXNvdXJjZVdpdGhvdXRTY2hlbWEgfSA9IHBhcnNlZENvbnRlbnRcbiAgICBleHBlY3QocmVzb3VyY2VXaXRob3V0U2NoZW1hLm5hbWUpLnRvRXF1YWwodGVzdFJlc291cmNlLm5hbWUpXG4gICAgZXhwZWN0KHJlc291cmNlV2l0aG91dFNjaGVtYS5wYXRoKS50b0JlKFwiZGF0YS5jc3ZcIilcbiAgICBleHBlY3QoJHNjaGVtYSkudG9CZShcbiAgICAgIFwiaHR0cHM6Ly9kYXRhcGFja2FnZS5vcmcvcHJvZmlsZXMvMi4wL2RhdGFyZXNvdXJjZS5qc29uXCIsXG4gICAgKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGFkZCAkc2NoZW1hIHByb3BlcnR5IGlmIG5vdCBwcmVzZW50XCIsIGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBzYXZlUmVzb3VyY2VEZXNjcmlwdG9yKHRlc3RSZXNvdXJjZSwgeyBwYXRoOiB0ZXN0UGF0aCB9KVxuXG4gICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHRlc3RQYXRoLCBcInV0Zi04XCIpXG4gICAgY29uc3QgcGFyc2VkQ29udGVudCA9IEpTT04ucGFyc2UoY29udGVudClcbiAgICBleHBlY3QocGFyc2VkQ29udGVudC4kc2NoZW1hKS50b0JlKFxuICAgICAgXCJodHRwczovL2RhdGFwYWNrYWdlLm9yZy9wcm9maWxlcy8yLjAvZGF0YXJlc291cmNlLmpzb25cIixcbiAgICApXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgcHJlc2VydmUgZXhpc3RpbmcgJHNjaGVtYSBwcm9wZXJ0eVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2VXaXRoU2NoZW1hOiBSZXNvdXJjZSA9IHtcbiAgICAgIG5hbWU6IFwidGVzdC1yZXNvdXJjZVwiLFxuICAgICAgcGF0aDogcGF0aC5qb2luKHRlc3REaXIsIFwiZGF0YS5jc3ZcIiksXG4gICAgICAkc2NoZW1hOiBcImh0dHBzOi8vY3VzdG9tLnNjaGVtYS51cmxcIixcbiAgICB9XG5cbiAgICBhd2FpdCBzYXZlUmVzb3VyY2VEZXNjcmlwdG9yKHJlc291cmNlV2l0aFNjaGVtYSwgeyBwYXRoOiB0ZXN0UGF0aCB9KVxuXG4gICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHRlc3RQYXRoLCBcInV0Zi04XCIpXG4gICAgY29uc3QgcGFyc2VkQ29udGVudCA9IEpTT04ucGFyc2UoY29udGVudClcbiAgICBleHBlY3QocGFyc2VkQ29udGVudC4kc2NoZW1hKS50b0JlKFwiaHR0cHM6Ly9jdXN0b20uc2NoZW1hLnVybFwiKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHVzZSBwcmV0dHkgZm9ybWF0dGluZyB3aXRoIDItc3BhY2UgaW5kZW50YXRpb25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IHNhdmVSZXNvdXJjZURlc2NyaXB0b3IodGVzdFJlc291cmNlLCB7IHBhdGg6IHRlc3RQYXRoIH0pXG5cbiAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUodGVzdFBhdGgsIFwidXRmLThcIilcbiAgICBjb25zdCBsaW5lcyA9IGNvbnRlbnQuc3BsaXQoXCJcXG5cIilcbiAgICBleHBlY3QobGluZXMubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMSlcblxuICAgIGlmIChsaW5lcy5sZW5ndGggPiAxICYmIGxpbmVzWzFdKSB7XG4gICAgICBleHBlY3QobGluZXNbMV0uc3RhcnRzV2l0aChcIiAgXCIpKS50b0JlKHRydWUpXG4gICAgfVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHNhdmUgcmVzb3VyY2Ugd2l0aCBzY2hlbWFcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlV2l0aFNjaGVtYTogUmVzb3VyY2UgPSB7XG4gICAgICBuYW1lOiBcInRlc3QtcmVzb3VyY2VcIixcbiAgICAgIHBhdGg6IHBhdGguam9pbih0ZXN0RGlyLCBcImRhdGEuY3N2XCIpLFxuICAgICAgc2NoZW1hOiB7XG4gICAgICAgIGZpZWxkczogW1xuICAgICAgICAgIHsgbmFtZTogXCJpZFwiLCB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICAgIHsgbmFtZTogXCJuYW1lXCIsIHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgYXdhaXQgc2F2ZVJlc291cmNlRGVzY3JpcHRvcihyZXNvdXJjZVdpdGhTY2hlbWEsIHsgcGF0aDogdGVzdFBhdGggfSlcblxuICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZSh0ZXN0UGF0aCwgXCJ1dGYtOFwiKVxuICAgIGNvbnN0IHBhcnNlZENvbnRlbnQgPSBKU09OLnBhcnNlKGNvbnRlbnQpXG4gICAgZXhwZWN0KHBhcnNlZENvbnRlbnQuc2NoZW1hKS50b0VxdWFsKHJlc291cmNlV2l0aFNjaGVtYS5zY2hlbWEpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgc2F2ZSByZXNvdXJjZSB3aXRoIGRpYWxlY3RcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlV2l0aERpYWxlY3Q6IFJlc291cmNlID0ge1xuICAgICAgbmFtZTogXCJ0ZXN0LXJlc291cmNlXCIsXG4gICAgICBwYXRoOiBwYXRoLmpvaW4odGVzdERpciwgXCJkYXRhLmNzdlwiKSxcbiAgICAgIGRpYWxlY3Q6IHtcbiAgICAgICAgZGVsaW1pdGVyOiBcIjtcIixcbiAgICAgICAgbGluZVRlcm1pbmF0b3I6IFwiXFxuXCIsXG4gICAgICB9LFxuICAgIH1cblxuICAgIGF3YWl0IHNhdmVSZXNvdXJjZURlc2NyaXB0b3IocmVzb3VyY2VXaXRoRGlhbGVjdCwgeyBwYXRoOiB0ZXN0UGF0aCB9KVxuXG4gICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHRlc3RQYXRoLCBcInV0Zi04XCIpXG4gICAgY29uc3QgcGFyc2VkQ29udGVudCA9IEpTT04ucGFyc2UoY29udGVudClcbiAgICBleHBlY3QocGFyc2VkQ29udGVudC5kaWFsZWN0KS50b0VxdWFsKHJlc291cmNlV2l0aERpYWxlY3QuZGlhbGVjdClcbiAgfSlcblxuICBpdChcInNob3VsZCBzYXZlIHJlc291cmNlIHRvIGEgbmVzdGVkIGRpcmVjdG9yeSBwYXRoXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBuZXN0ZWRQYXRoID0gcGF0aC5qb2luKHRlc3REaXIsIFwibmVzdGVkXCIsIFwiZGlyXCIsIFwicmVzb3VyY2UuanNvblwiKVxuICAgIGNvbnN0IG5lc3RlZFJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIG5hbWU6IFwidGVzdC1yZXNvdXJjZVwiLFxuICAgICAgcGF0aDogcGF0aC5qb2luKHRlc3REaXIsIFwibmVzdGVkXCIsIFwiZGlyXCIsIFwiZGF0YS5jc3ZcIiksXG4gICAgfVxuXG4gICAgYXdhaXQgc2F2ZVJlc291cmNlRGVzY3JpcHRvcihuZXN0ZWRSZXNvdXJjZSwgeyBwYXRoOiBuZXN0ZWRQYXRoIH0pXG5cbiAgICBjb25zdCBmaWxlRXhpc3RzID0gYXdhaXQgZnNcbiAgICAgIC5zdGF0KG5lc3RlZFBhdGgpXG4gICAgICAudGhlbigoKSA9PiB0cnVlKVxuICAgICAgLmNhdGNoKCgpID0+IGZhbHNlKVxuICAgIGV4cGVjdChmaWxlRXhpc3RzKS50b0JlKHRydWUpXG5cbiAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUobmVzdGVkUGF0aCwgXCJ1dGYtOFwiKVxuICAgIGNvbnN0IHBhcnNlZENvbnRlbnQgPSBKU09OLnBhcnNlKGNvbnRlbnQpXG4gICAgZXhwZWN0KHBhcnNlZENvbnRlbnQubmFtZSkudG9CZShuZXN0ZWRSZXNvdXJjZS5uYW1lKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gZmlsZSBleGlzdHMgYW5kIG92ZXJ3cml0ZSBpcyBmYWxzZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgc2F2ZVJlc291cmNlRGVzY3JpcHRvcih0ZXN0UmVzb3VyY2UsIHsgcGF0aDogdGVzdFBhdGggfSlcblxuICAgIGF3YWl0IGV4cGVjdChcbiAgICAgIHNhdmVSZXNvdXJjZURlc2NyaXB0b3IodGVzdFJlc291cmNlLCB7XG4gICAgICAgIHBhdGg6IHRlc3RQYXRoLFxuICAgICAgICBvdmVyd3JpdGU6IGZhbHNlLFxuICAgICAgfSksXG4gICAgKS5yZWplY3RzLnRvVGhyb3coKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gZmlsZSBleGlzdHMgYW5kIG92ZXJ3cml0ZSBpcyBub3Qgc3BlY2lmaWVkXCIsIGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBzYXZlUmVzb3VyY2VEZXNjcmlwdG9yKHRlc3RSZXNvdXJjZSwgeyBwYXRoOiB0ZXN0UGF0aCB9KVxuXG4gICAgYXdhaXQgZXhwZWN0KFxuICAgICAgc2F2ZVJlc291cmNlRGVzY3JpcHRvcih0ZXN0UmVzb3VyY2UsIHsgcGF0aDogdGVzdFBhdGggfSksXG4gICAgKS5yZWplY3RzLnRvVGhyb3coKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIG92ZXJ3cml0ZSBleGlzdGluZyBmaWxlIHdoZW4gb3ZlcndyaXRlIGlzIHRydWVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGluaXRpYWxSZXNvdXJjZTogUmVzb3VyY2UgPSB7XG4gICAgICBuYW1lOiBcImluaXRpYWxcIixcbiAgICAgIHBhdGg6IHBhdGguam9pbih0ZXN0RGlyLCBcImRhdGExLmNzdlwiKSxcbiAgICB9XG5cbiAgICBjb25zdCB1cGRhdGVkUmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgbmFtZTogXCJ1cGRhdGVkXCIsXG4gICAgICBwYXRoOiBwYXRoLmpvaW4odGVzdERpciwgXCJkYXRhMi5jc3ZcIiksXG4gICAgICBkZXNjcmlwdGlvbjogXCJVcGRhdGVkIHJlc291cmNlXCIsXG4gICAgfVxuXG4gICAgYXdhaXQgc2F2ZVJlc291cmNlRGVzY3JpcHRvcihpbml0aWFsUmVzb3VyY2UsIHsgcGF0aDogdGVzdFBhdGggfSlcblxuICAgIGNvbnN0IGluaXRpYWxDb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUodGVzdFBhdGgsIFwidXRmLThcIilcbiAgICBjb25zdCBpbml0aWFsUGFyc2VkID0gSlNPTi5wYXJzZShpbml0aWFsQ29udGVudClcbiAgICBleHBlY3QoaW5pdGlhbFBhcnNlZC5uYW1lKS50b0JlKFwiaW5pdGlhbFwiKVxuXG4gICAgYXdhaXQgc2F2ZVJlc291cmNlRGVzY3JpcHRvcih1cGRhdGVkUmVzb3VyY2UsIHtcbiAgICAgIHBhdGg6IHRlc3RQYXRoLFxuICAgICAgb3ZlcndyaXRlOiB0cnVlLFxuICAgIH0pXG5cbiAgICBjb25zdCB1cGRhdGVkQ29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHRlc3RQYXRoLCBcInV0Zi04XCIpXG4gICAgY29uc3QgdXBkYXRlZFBhcnNlZCA9IEpTT04ucGFyc2UodXBkYXRlZENvbnRlbnQpXG4gICAgZXhwZWN0KHVwZGF0ZWRQYXJzZWQubmFtZSkudG9CZShcInVwZGF0ZWRcIilcbiAgICBleHBlY3QodXBkYXRlZFBhcnNlZC5kZXNjcmlwdGlvbikudG9CZShcIlVwZGF0ZWQgcmVzb3VyY2VcIilcbiAgfSlcblxuICBpdChcInNob3VsZCBzYXZlIHJlc291cmNlIHdpdGggYWxsIG1ldGFkYXRhIGZpZWxkc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZnVsbFJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIG5hbWU6IFwiZnVsbC1yZXNvdXJjZVwiLFxuICAgICAgcGF0aDogcGF0aC5qb2luKHRlc3REaXIsIFwiZGF0YS5jc3ZcIiksXG4gICAgICB0aXRsZTogXCJGdWxsIFJlc291cmNlXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJBIHJlc291cmNlIHdpdGggYWxsIGZpZWxkc1wiLFxuICAgICAgZm9ybWF0OiBcImNzdlwiLFxuICAgICAgbWVkaWF0eXBlOiBcInRleHQvY3N2XCIsXG4gICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgYnl0ZXM6IDEwMjQsXG4gICAgICBoYXNoOiBcImFiYzEyM1wiLFxuICAgIH1cblxuICAgIGF3YWl0IHNhdmVSZXNvdXJjZURlc2NyaXB0b3IoZnVsbFJlc291cmNlLCB7IHBhdGg6IHRlc3RQYXRoIH0pXG5cbiAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUodGVzdFBhdGgsIFwidXRmLThcIilcbiAgICBjb25zdCBwYXJzZWRDb250ZW50ID0gSlNPTi5wYXJzZShjb250ZW50KVxuICAgIGV4cGVjdChwYXJzZWRDb250ZW50Lm5hbWUpLnRvQmUoZnVsbFJlc291cmNlLm5hbWUpXG4gICAgZXhwZWN0KHBhcnNlZENvbnRlbnQudGl0bGUpLnRvQmUoZnVsbFJlc291cmNlLnRpdGxlKVxuICAgIGV4cGVjdChwYXJzZWRDb250ZW50LmRlc2NyaXB0aW9uKS50b0JlKGZ1bGxSZXNvdXJjZS5kZXNjcmlwdGlvbilcbiAgICBleHBlY3QocGFyc2VkQ29udGVudC5mb3JtYXQpLnRvQmUoZnVsbFJlc291cmNlLmZvcm1hdClcbiAgICBleHBlY3QocGFyc2VkQ29udGVudC5ieXRlcykudG9CZShmdWxsUmVzb3VyY2UuYnl0ZXMpXG4gIH0pXG59KVxuIl19
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Descriptor } from "../descriptor/index.ts";
|
|
2
|
+
import type { MetadataError } from "../error/index.ts";
|
|
3
|
+
import type { Resource } from "./Resource.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Validate a Resource descriptor (JSON Object) against its profile
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateResourceMetadata(source: Resource | Descriptor | string, options?: {
|
|
8
|
+
basepath?: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
resource: Resource | undefined;
|
|
11
|
+
errors: MetadataError[];
|
|
12
|
+
valid: boolean;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { loadDescriptor } from "../descriptor/index.js";
|
|
2
|
+
import { validateDialect } from "../dialect/index.js";
|
|
3
|
+
import { validateDescriptor } from "../profile/index.js";
|
|
4
|
+
import { validateSchema } from "../schema/index.js";
|
|
5
|
+
import { convertResourceFromDescriptor } from "./convert/fromDescriptor.js";
|
|
6
|
+
const DEFAULT_PROFILE = "https://datapackage.org/profiles/1.0/dataresource.json";
|
|
7
|
+
/**
|
|
8
|
+
* Validate a Resource descriptor (JSON Object) against its profile
|
|
9
|
+
*/
|
|
10
|
+
export async function validateResourceMetadata(source, options) {
|
|
11
|
+
const descriptor = typeof source === "string"
|
|
12
|
+
? await loadDescriptor(source)
|
|
13
|
+
: source;
|
|
14
|
+
const profile = typeof descriptor.$schema === "string"
|
|
15
|
+
? descriptor.$schema
|
|
16
|
+
: DEFAULT_PROFILE;
|
|
17
|
+
const report = await validateDescriptor(descriptor, {
|
|
18
|
+
profile,
|
|
19
|
+
});
|
|
20
|
+
let resource = undefined;
|
|
21
|
+
if (report.valid) {
|
|
22
|
+
// Validation + normalization = we can cast it
|
|
23
|
+
resource = convertResourceFromDescriptor(descriptor, {
|
|
24
|
+
basepath: options?.basepath,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (resource) {
|
|
28
|
+
const dialectErorrs = await inspectDialectIfExternal(resource);
|
|
29
|
+
report.errors.push(...dialectErorrs);
|
|
30
|
+
const schemaErorrs = await inspectSchemaIfExternal(resource);
|
|
31
|
+
report.errors.push(...schemaErorrs);
|
|
32
|
+
// TODO: Support external JSON Schema validation as well
|
|
33
|
+
// https://github.com/frictionlessdata/datapackage/issues/937
|
|
34
|
+
if (report.errors.length) {
|
|
35
|
+
resource = undefined;
|
|
36
|
+
report.valid = false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { ...report, resource };
|
|
40
|
+
}
|
|
41
|
+
async function inspectDialectIfExternal(resource) {
|
|
42
|
+
const errors = [];
|
|
43
|
+
if (typeof resource.dialect === "string") {
|
|
44
|
+
const report = await validateDialect(resource.dialect);
|
|
45
|
+
errors.push(...report.errors);
|
|
46
|
+
}
|
|
47
|
+
return errors;
|
|
48
|
+
}
|
|
49
|
+
async function inspectSchemaIfExternal(resource) {
|
|
50
|
+
const errors = [];
|
|
51
|
+
if (typeof resource.schema === "string") {
|
|
52
|
+
const report = await validateSchema(resource.schema);
|
|
53
|
+
errors.push(...report.errors);
|
|
54
|
+
}
|
|
55
|
+
return errors;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9yZXNvdXJjZS92YWxpZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBRXJELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3hELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUVuRCxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQUUzRSxNQUFNLGVBQWUsR0FBRyx3REFBd0QsQ0FBQTtBQUVoRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsd0JBQXdCLENBQzVDLE1BQXNDLEVBQ3RDLE9BRUM7SUFFRCxNQUFNLFVBQVUsR0FDZCxPQUFPLE1BQU0sS0FBSyxRQUFRO1FBQ3hCLENBQUMsQ0FBQyxNQUFNLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFDOUIsQ0FBQyxDQUFFLE1BQXFCLENBQUE7SUFFNUIsTUFBTSxPQUFPLEdBQ1gsT0FBTyxVQUFVLENBQUMsT0FBTyxLQUFLLFFBQVE7UUFDcEMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPO1FBQ3BCLENBQUMsQ0FBQyxlQUFlLENBQUE7SUFFckIsTUFBTSxNQUFNLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQyxVQUFVLEVBQUU7UUFDbEQsT0FBTztLQUNSLENBQUMsQ0FBQTtJQUVGLElBQUksUUFBUSxHQUF5QixTQUFTLENBQUE7SUFDOUMsSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDakIsOENBQThDO1FBQzlDLFFBQVEsR0FBRyw2QkFBNkIsQ0FBQyxVQUFVLEVBQUU7WUFDbkQsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRO1NBQzVCLENBQXdCLENBQUE7SUFDM0IsQ0FBQztJQUVELElBQUksUUFBUSxFQUFFLENBQUM7UUFDYixNQUFNLGFBQWEsR0FBRyxNQUFNLHdCQUF3QixDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQzlELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUE7UUFFcEMsTUFBTSxZQUFZLEdBQUcsTUFBTSx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUM1RCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFBO1FBRW5DLHdEQUF3RDtRQUN4RCw2REFBNkQ7UUFFN0QsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3pCLFFBQVEsR0FBRyxTQUFTLENBQUE7WUFDcEIsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUE7UUFDdEIsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsR0FBRyxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUE7QUFDaEMsQ0FBQztBQUVELEtBQUssVUFBVSx3QkFBd0IsQ0FBQyxRQUFrQjtJQUN4RCxNQUFNLE1BQU0sR0FBb0IsRUFBRSxDQUFBO0lBRWxDLElBQUksT0FBTyxRQUFRLENBQUMsT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sTUFBTSxHQUFHLE1BQU0sZUFBZSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN0RCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUM7QUFFRCxLQUFLLFVBQVUsdUJBQXVCLENBQUMsUUFBa0I7SUFDdkQsTUFBTSxNQUFNLEdBQW9CLEVBQUUsQ0FBQTtJQUVsQyxJQUFJLE9BQU8sUUFBUSxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN4QyxNQUFNLE1BQU0sR0FBRyxNQUFNLGNBQWMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDcEQsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMvQixDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUE7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBEZXNjcmlwdG9yIH0gZnJvbSBcIi4uL2Rlc2NyaXB0b3IvaW5kZXgudHNcIlxuaW1wb3J0IHsgbG9hZERlc2NyaXB0b3IgfSBmcm9tIFwiLi4vZGVzY3JpcHRvci9pbmRleC50c1wiXG5pbXBvcnQgeyB2YWxpZGF0ZURpYWxlY3QgfSBmcm9tIFwiLi4vZGlhbGVjdC9pbmRleC50c1wiXG5pbXBvcnQgdHlwZSB7IE1ldGFkYXRhRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3IvaW5kZXgudHNcIlxuaW1wb3J0IHsgdmFsaWRhdGVEZXNjcmlwdG9yIH0gZnJvbSBcIi4uL3Byb2ZpbGUvaW5kZXgudHNcIlxuaW1wb3J0IHsgdmFsaWRhdGVTY2hlbWEgfSBmcm9tIFwiLi4vc2NoZW1hL2luZGV4LnRzXCJcbmltcG9ydCB0eXBlIHsgUmVzb3VyY2UgfSBmcm9tIFwiLi9SZXNvdXJjZS50c1wiXG5pbXBvcnQgeyBjb252ZXJ0UmVzb3VyY2VGcm9tRGVzY3JpcHRvciB9IGZyb20gXCIuL2NvbnZlcnQvZnJvbURlc2NyaXB0b3IudHNcIlxuXG5jb25zdCBERUZBVUxUX1BST0ZJTEUgPSBcImh0dHBzOi8vZGF0YXBhY2thZ2Uub3JnL3Byb2ZpbGVzLzEuMC9kYXRhcmVzb3VyY2UuanNvblwiXG5cbi8qKlxuICogVmFsaWRhdGUgYSBSZXNvdXJjZSBkZXNjcmlwdG9yIChKU09OIE9iamVjdCkgYWdhaW5zdCBpdHMgcHJvZmlsZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVSZXNvdXJjZU1ldGFkYXRhKFxuICBzb3VyY2U6IFJlc291cmNlIHwgRGVzY3JpcHRvciB8IHN0cmluZyxcbiAgb3B0aW9ucz86IHtcbiAgICBiYXNlcGF0aD86IHN0cmluZ1xuICB9LFxuKSB7XG4gIGNvbnN0IGRlc2NyaXB0b3IgPVxuICAgIHR5cGVvZiBzb3VyY2UgPT09IFwic3RyaW5nXCJcbiAgICAgID8gYXdhaXQgbG9hZERlc2NyaXB0b3Ioc291cmNlKVxuICAgICAgOiAoc291cmNlIGFzIERlc2NyaXB0b3IpXG5cbiAgY29uc3QgcHJvZmlsZSA9XG4gICAgdHlwZW9mIGRlc2NyaXB0b3IuJHNjaGVtYSA9PT0gXCJzdHJpbmdcIlxuICAgICAgPyBkZXNjcmlwdG9yLiRzY2hlbWFcbiAgICAgIDogREVGQVVMVF9QUk9GSUxFXG5cbiAgY29uc3QgcmVwb3J0ID0gYXdhaXQgdmFsaWRhdGVEZXNjcmlwdG9yKGRlc2NyaXB0b3IsIHtcbiAgICBwcm9maWxlLFxuICB9KVxuXG4gIGxldCByZXNvdXJjZTogUmVzb3VyY2UgfCB1bmRlZmluZWQgPSB1bmRlZmluZWRcbiAgaWYgKHJlcG9ydC52YWxpZCkge1xuICAgIC8vIFZhbGlkYXRpb24gKyBub3JtYWxpemF0aW9uID0gd2UgY2FuIGNhc3QgaXRcbiAgICByZXNvdXJjZSA9IGNvbnZlcnRSZXNvdXJjZUZyb21EZXNjcmlwdG9yKGRlc2NyaXB0b3IsIHtcbiAgICAgIGJhc2VwYXRoOiBvcHRpb25zPy5iYXNlcGF0aCxcbiAgICB9KSBhcyB1bmtub3duIGFzIFJlc291cmNlXG4gIH1cblxuICBpZiAocmVzb3VyY2UpIHtcbiAgICBjb25zdCBkaWFsZWN0RXJvcnJzID0gYXdhaXQgaW5zcGVjdERpYWxlY3RJZkV4dGVybmFsKHJlc291cmNlKVxuICAgIHJlcG9ydC5lcnJvcnMucHVzaCguLi5kaWFsZWN0RXJvcnJzKVxuXG4gICAgY29uc3Qgc2NoZW1hRXJvcnJzID0gYXdhaXQgaW5zcGVjdFNjaGVtYUlmRXh0ZXJuYWwocmVzb3VyY2UpXG4gICAgcmVwb3J0LmVycm9ycy5wdXNoKC4uLnNjaGVtYUVyb3JycylcblxuICAgIC8vIFRPRE86IFN1cHBvcnQgZXh0ZXJuYWwgSlNPTiBTY2hlbWEgdmFsaWRhdGlvbiBhcyB3ZWxsXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZyaWN0aW9ubGVzc2RhdGEvZGF0YXBhY2thZ2UvaXNzdWVzLzkzN1xuXG4gICAgaWYgKHJlcG9ydC5lcnJvcnMubGVuZ3RoKSB7XG4gICAgICByZXNvdXJjZSA9IHVuZGVmaW5lZFxuICAgICAgcmVwb3J0LnZhbGlkID0gZmFsc2VcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyAuLi5yZXBvcnQsIHJlc291cmNlIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5zcGVjdERpYWxlY3RJZkV4dGVybmFsKHJlc291cmNlOiBSZXNvdXJjZSkge1xuICBjb25zdCBlcnJvcnM6IE1ldGFkYXRhRXJyb3JbXSA9IFtdXG5cbiAgaWYgKHR5cGVvZiByZXNvdXJjZS5kaWFsZWN0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgY29uc3QgcmVwb3J0ID0gYXdhaXQgdmFsaWRhdGVEaWFsZWN0KHJlc291cmNlLmRpYWxlY3QpXG4gICAgZXJyb3JzLnB1c2goLi4ucmVwb3J0LmVycm9ycylcbiAgfVxuXG4gIHJldHVybiBlcnJvcnNcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5zcGVjdFNjaGVtYUlmRXh0ZXJuYWwocmVzb3VyY2U6IFJlc291cmNlKSB7XG4gIGNvbnN0IGVycm9yczogTWV0YWRhdGFFcnJvcltdID0gW11cblxuICBpZiAodHlwZW9mIHJlc291cmNlLnNjaGVtYSA9PT0gXCJzdHJpbmdcIikge1xuICAgIGNvbnN0IHJlcG9ydCA9IGF3YWl0IHZhbGlkYXRlU2NoZW1hKHJlc291cmNlLnNjaGVtYSlcbiAgICBlcnJvcnMucHVzaCguLi5yZXBvcnQuZXJyb3JzKVxuICB9XG5cbiAgcmV0dXJuIGVycm9yc1xufVxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { validateResourceMetadata } from "./validate.js";
|
|
3
|
+
describe("validateResourceMetadata", () => {
|
|
4
|
+
it("returns valid report for valid resource", async () => {
|
|
5
|
+
const descriptor = {
|
|
6
|
+
name: "example-resource",
|
|
7
|
+
path: "data.csv",
|
|
8
|
+
format: "csv",
|
|
9
|
+
encoding: "utf-8",
|
|
10
|
+
};
|
|
11
|
+
const report = await validateResourceMetadata(descriptor);
|
|
12
|
+
expect(report.valid).toBe(true);
|
|
13
|
+
expect(report.errors).toEqual([]);
|
|
14
|
+
});
|
|
15
|
+
it("returns validation errors for invalid resource", async () => {
|
|
16
|
+
const invalidResource = {
|
|
17
|
+
name: 123, // Should be a string
|
|
18
|
+
path: true, // Should be a string or array of strings
|
|
19
|
+
};
|
|
20
|
+
const report = await validateResourceMetadata(invalidResource);
|
|
21
|
+
expect(report.valid).toBe(false);
|
|
22
|
+
expect(report.errors.length).toBeGreaterThan(0);
|
|
23
|
+
const error = report.errors[0];
|
|
24
|
+
expect(error).toBeDefined();
|
|
25
|
+
if (error) {
|
|
26
|
+
expect(error.pointer).toBe("/name");
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Jlc291cmNlL3ZhbGlkYXRlLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUV4RCxRQUFRLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxFQUFFO0lBQ3hDLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2RCxNQUFNLFVBQVUsR0FBRztZQUNqQixJQUFJLEVBQUUsa0JBQWtCO1lBQ3hCLElBQUksRUFBRSxVQUFVO1lBQ2hCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsUUFBUSxFQUFFLE9BQU87U0FDbEIsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sd0JBQXdCLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFekQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDL0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDbkMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsZ0RBQWdELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDOUQsTUFBTSxlQUFlLEdBQUc7WUFDdEIsSUFBSSxFQUFFLEdBQUcsRUFBRSxxQkFBcUI7WUFDaEMsSUFBSSxFQUFFLElBQUksRUFBRSx5Q0FBeUM7U0FDdEQsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sd0JBQXdCLENBQUMsZUFBZSxDQUFDLENBQUE7UUFFOUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDaEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRS9DLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBQzNCLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNyQyxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlc2NyaWJlLCBleHBlY3QsIGl0IH0gZnJvbSBcInZpdGVzdFwiXG5pbXBvcnQgeyB2YWxpZGF0ZVJlc291cmNlTWV0YWRhdGEgfSBmcm9tIFwiLi92YWxpZGF0ZS50c1wiXG5cbmRlc2NyaWJlKFwidmFsaWRhdGVSZXNvdXJjZU1ldGFkYXRhXCIsICgpID0+IHtcbiAgaXQoXCJyZXR1cm5zIHZhbGlkIHJlcG9ydCBmb3IgdmFsaWQgcmVzb3VyY2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7XG4gICAgICBuYW1lOiBcImV4YW1wbGUtcmVzb3VyY2VcIixcbiAgICAgIHBhdGg6IFwiZGF0YS5jc3ZcIixcbiAgICAgIGZvcm1hdDogXCJjc3ZcIixcbiAgICAgIGVuY29kaW5nOiBcInV0Zi04XCIsXG4gICAgfVxuXG4gICAgY29uc3QgcmVwb3J0ID0gYXdhaXQgdmFsaWRhdGVSZXNvdXJjZU1ldGFkYXRhKGRlc2NyaXB0b3IpXG5cbiAgICBleHBlY3QocmVwb3J0LnZhbGlkKS50b0JlKHRydWUpXG4gICAgZXhwZWN0KHJlcG9ydC5lcnJvcnMpLnRvRXF1YWwoW10pXG4gIH0pXG5cbiAgaXQoXCJyZXR1cm5zIHZhbGlkYXRpb24gZXJyb3JzIGZvciBpbnZhbGlkIHJlc291cmNlXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnZhbGlkUmVzb3VyY2UgPSB7XG4gICAgICBuYW1lOiAxMjMsIC8vIFNob3VsZCBiZSBhIHN0cmluZ1xuICAgICAgcGF0aDogdHJ1ZSwgLy8gU2hvdWxkIGJlIGEgc3RyaW5nIG9yIGFycmF5IG9mIHN0cmluZ3NcbiAgICB9XG5cbiAgICBjb25zdCByZXBvcnQgPSBhd2FpdCB2YWxpZGF0ZVJlc291cmNlTWV0YWRhdGEoaW52YWxpZFJlc291cmNlKVxuXG4gICAgZXhwZWN0KHJlcG9ydC52YWxpZCkudG9CZShmYWxzZSlcbiAgICBleHBlY3QocmVwb3J0LmVycm9ycy5sZW5ndGgpLnRvQmVHcmVhdGVyVGhhbigwKVxuXG4gICAgY29uc3QgZXJyb3IgPSByZXBvcnQuZXJyb3JzWzBdXG4gICAgZXhwZWN0KGVycm9yKS50b0JlRGVmaW5lZCgpXG4gICAgaWYgKGVycm9yKSB7XG4gICAgICBleHBlY3QoZXJyb3IucG9pbnRlcikudG9CZShcIi9uYW1lXCIpXG4gICAgfVxuICB9KVxufSlcbiJdfQ==
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foreign key definition for Table Schema
|
|
3
|
+
* Based on the specification at https://datapackage.org/standard/table-schema/#foreign-keys
|
|
4
|
+
*/
|
|
5
|
+
export interface ForeignKey {
|
|
6
|
+
/**
|
|
7
|
+
* Source field(s) in this schema
|
|
8
|
+
*/
|
|
9
|
+
fields: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Reference to fields in another resource
|
|
12
|
+
*/
|
|
13
|
+
reference: {
|
|
14
|
+
/**
|
|
15
|
+
* Target resource name (optional)
|
|
16
|
+
*/
|
|
17
|
+
resource?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Target field(s) in the referenced resource
|
|
20
|
+
*/
|
|
21
|
+
fields: string[];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRm9yZWlnbktleS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NjaGVtYS9Gb3JlaWduS2V5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZvcmVpZ24ga2V5IGRlZmluaXRpb24gZm9yIFRhYmxlIFNjaGVtYVxuICogQmFzZWQgb24gdGhlIHNwZWNpZmljYXRpb24gYXQgaHR0cHM6Ly9kYXRhcGFja2FnZS5vcmcvc3RhbmRhcmQvdGFibGUtc2NoZW1hLyNmb3JlaWduLWtleXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb3JlaWduS2V5IHtcbiAgLyoqXG4gICAqIFNvdXJjZSBmaWVsZChzKSBpbiB0aGlzIHNjaGVtYVxuICAgKi9cbiAgZmllbGRzOiBzdHJpbmdbXVxuXG4gIC8qKlxuICAgKiBSZWZlcmVuY2UgdG8gZmllbGRzIGluIGFub3RoZXIgcmVzb3VyY2VcbiAgICovXG4gIHJlZmVyZW5jZToge1xuICAgIC8qKlxuICAgICAqIFRhcmdldCByZXNvdXJjZSBuYW1lIChvcHRpb25hbClcbiAgICAgKi9cbiAgICByZXNvdXJjZT86IHN0cmluZ1xuXG4gICAgLyoqXG4gICAgICogVGFyZ2V0IGZpZWxkKHMpIGluIHRoZSByZWZlcmVuY2VkIHJlc291cmNlXG4gICAgICovXG4gICAgZmllbGRzOiBzdHJpbmdbXVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Field } from "../field/index.ts";
|
|
2
|
+
import type { Metadata } from "../metadata/index.ts";
|
|
3
|
+
import type { ForeignKey } from "./ForeignKey.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Table Schema definition
|
|
6
|
+
* Based on the specification at https://datapackage.org/standard/table-schema/
|
|
7
|
+
*/
|
|
8
|
+
export interface Schema extends Metadata {
|
|
9
|
+
/**
|
|
10
|
+
* URL of profile (optional)
|
|
11
|
+
*/
|
|
12
|
+
$schema?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Name of schema (optional)
|
|
15
|
+
*/
|
|
16
|
+
name?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Title of schema (optional)
|
|
19
|
+
*/
|
|
20
|
+
title?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Description of schema (optional)
|
|
23
|
+
*/
|
|
24
|
+
description?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Fields in this schema (required)
|
|
27
|
+
*/
|
|
28
|
+
fields: Field[];
|
|
29
|
+
/**
|
|
30
|
+
* Field matching rule (optional)
|
|
31
|
+
* Default: "exact"
|
|
32
|
+
*/
|
|
33
|
+
fieldsMatch?: "exact" | "equal" | "subset" | "superset" | "partial";
|
|
34
|
+
/**
|
|
35
|
+
* Values representing missing data (optional)
|
|
36
|
+
* Default: [""]
|
|
37
|
+
* Can be a simple array of strings or an array of {value, label} objects
|
|
38
|
+
* where label provides context for why the data is missing
|
|
39
|
+
*/
|
|
40
|
+
missingValues?: (string | {
|
|
41
|
+
value: string;
|
|
42
|
+
label: string;
|
|
43
|
+
})[];
|
|
44
|
+
/**
|
|
45
|
+
* Fields uniquely identifying each row (optional)
|
|
46
|
+
*/
|
|
47
|
+
primaryKey?: string[];
|
|
48
|
+
/**
|
|
49
|
+
* Field combinations that must be unique (optional)
|
|
50
|
+
*/
|
|
51
|
+
uniqueKeys?: string[][];
|
|
52
|
+
/**
|
|
53
|
+
* Foreign key relationships (optional)
|
|
54
|
+
*/
|
|
55
|
+
foreignKeys?: ForeignKey[];
|
|
56
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc2NoZW1hL1NjaGVtYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBGaWVsZCB9IGZyb20gXCIuLi9maWVsZC9pbmRleC50c1wiXG5pbXBvcnQgdHlwZSB7IE1ldGFkYXRhIH0gZnJvbSBcIi4uL21ldGFkYXRhL2luZGV4LnRzXCJcbmltcG9ydCB0eXBlIHsgRm9yZWlnbktleSB9IGZyb20gXCIuL0ZvcmVpZ25LZXkudHNcIlxuXG4vKipcbiAqIFRhYmxlIFNjaGVtYSBkZWZpbml0aW9uXG4gKiBCYXNlZCBvbiB0aGUgc3BlY2lmaWNhdGlvbiBhdCBodHRwczovL2RhdGFwYWNrYWdlLm9yZy9zdGFuZGFyZC90YWJsZS1zY2hlbWEvXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NoZW1hIGV4dGVuZHMgTWV0YWRhdGEge1xuICAvKipcbiAgICogVVJMIG9mIHByb2ZpbGUgKG9wdGlvbmFsKVxuICAgKi9cbiAgJHNjaGVtYT86IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHNjaGVtYSAob3B0aW9uYWwpXG4gICAqL1xuICBuYW1lPzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRpdGxlIG9mIHNjaGVtYSAob3B0aW9uYWwpXG4gICAqL1xuICB0aXRsZT86IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBEZXNjcmlwdGlvbiBvZiBzY2hlbWEgKG9wdGlvbmFsKVxuICAgKi9cbiAgZGVzY3JpcHRpb24/OiBzdHJpbmdcblxuICAvKipcbiAgICogRmllbGRzIGluIHRoaXMgc2NoZW1hIChyZXF1aXJlZClcbiAgICovXG4gIGZpZWxkczogRmllbGRbXVxuXG4gIC8qKlxuICAgKiBGaWVsZCBtYXRjaGluZyBydWxlIChvcHRpb25hbClcbiAgICogRGVmYXVsdDogXCJleGFjdFwiXG4gICAqL1xuICBmaWVsZHNNYXRjaD86IFwiZXhhY3RcIiB8IFwiZXF1YWxcIiB8IFwic3Vic2V0XCIgfCBcInN1cGVyc2V0XCIgfCBcInBhcnRpYWxcIlxuXG4gIC8qKlxuICAgKiBWYWx1ZXMgcmVwcmVzZW50aW5nIG1pc3NpbmcgZGF0YSAob3B0aW9uYWwpXG4gICAqIERlZmF1bHQ6IFtcIlwiXVxuICAgKiBDYW4gYmUgYSBzaW1wbGUgYXJyYXkgb2Ygc3RyaW5ncyBvciBhbiBhcnJheSBvZiB7dmFsdWUsIGxhYmVsfSBvYmplY3RzXG4gICAqIHdoZXJlIGxhYmVsIHByb3ZpZGVzIGNvbnRleHQgZm9yIHdoeSB0aGUgZGF0YSBpcyBtaXNzaW5nXG4gICAqL1xuICBtaXNzaW5nVmFsdWVzPzogKHN0cmluZyB8IHsgdmFsdWU6IHN0cmluZzsgbGFiZWw6IHN0cmluZyB9KVtdXG5cbiAgLyoqXG4gICAqIEZpZWxkcyB1bmlxdWVseSBpZGVudGlmeWluZyBlYWNoIHJvdyAob3B0aW9uYWwpXG4gICAqL1xuICBwcmltYXJ5S2V5Pzogc3RyaW5nW11cblxuICAvKipcbiAgICogRmllbGQgY29tYmluYXRpb25zIHRoYXQgbXVzdCBiZSB1bmlxdWUgKG9wdGlvbmFsKVxuICAgKi9cbiAgdW5pcXVlS2V5cz86IHN0cmluZ1tdW11cblxuICAvKipcbiAgICogRm9yZWlnbiBrZXkgcmVsYXRpb25zaGlwcyAob3B0aW9uYWwpXG4gICAqL1xuICBmb3JlaWduS2V5cz86IEZvcmVpZ25LZXlbXVxufVxuIl19
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { validateSchema } from "./validate.js";
|
|
2
|
+
/**
|
|
3
|
+
* Assert a Schema descriptor (JSON Object) against its profile
|
|
4
|
+
*/
|
|
5
|
+
export async function assertSchema(source) {
|
|
6
|
+
const report = await validateSchema(source);
|
|
7
|
+
if (!report.schema) {
|
|
8
|
+
throw new Error(`Schema "${JSON.stringify(source).slice(0, 100)}" is not valid`);
|
|
9
|
+
}
|
|
10
|
+
return report.schema;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXJ0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc2NoZW1hL2Fzc2VydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBRTlDOztHQUVHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxZQUFZLENBQUMsTUFBMkI7SUFDNUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUE7SUFFM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksS0FBSyxDQUNiLFdBQVcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FDaEUsQ0FBQTtJQUNILENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUE7QUFDdEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRGVzY3JpcHRvciB9IGZyb20gXCIuLi9kZXNjcmlwdG9yL2luZGV4LnRzXCJcbmltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSBcIi4vU2NoZW1hLnRzXCJcbmltcG9ydCB7IHZhbGlkYXRlU2NoZW1hIH0gZnJvbSBcIi4vdmFsaWRhdGUudHNcIlxuXG4vKipcbiAqIEFzc2VydCBhIFNjaGVtYSBkZXNjcmlwdG9yIChKU09OIE9iamVjdCkgYWdhaW5zdCBpdHMgcHJvZmlsZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXNzZXJ0U2NoZW1hKHNvdXJjZTogRGVzY3JpcHRvciB8IFNjaGVtYSkge1xuICBjb25zdCByZXBvcnQgPSBhd2FpdCB2YWxpZGF0ZVNjaGVtYShzb3VyY2UpXG5cbiAgaWYgKCFyZXBvcnQuc2NoZW1hKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFNjaGVtYSBcIiR7SlNPTi5zdHJpbmdpZnkoc291cmNlKS5zbGljZSgwLCAxMDApfVwiIGlzIG5vdCB2YWxpZGAsXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIHJlcG9ydC5zY2hlbWFcbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, expectTypeOf, it } from "vitest";
|
|
2
|
+
import { assertSchema } from "./assert.js";
|
|
3
|
+
describe("assertSchema", () => {
|
|
4
|
+
it("returns typed schema when valid", async () => {
|
|
5
|
+
const descriptor = {
|
|
6
|
+
fields: [
|
|
7
|
+
{
|
|
8
|
+
name: "id",
|
|
9
|
+
type: "integer",
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: "name",
|
|
13
|
+
type: "string",
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
primaryKey: ["id"],
|
|
17
|
+
};
|
|
18
|
+
const schema = await assertSchema(descriptor);
|
|
19
|
+
expectTypeOf(schema).toEqualTypeOf();
|
|
20
|
+
expect(schema).toEqual(descriptor);
|
|
21
|
+
});
|
|
22
|
+
it("throws Error when schema is invalid", async () => {
|
|
23
|
+
const descriptor = {
|
|
24
|
+
fields: [
|
|
25
|
+
{
|
|
26
|
+
name: "id",
|
|
27
|
+
type: 123,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
await expect(assertSchema(descriptor)).rejects.toThrow(Error);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXJ0LnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zY2hlbWEvYXNzZXJ0LnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUUzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRTFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO0lBQzVCLEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMvQyxNQUFNLFVBQVUsR0FBRztZQUNqQixNQUFNLEVBQUU7Z0JBQ047b0JBQ0UsSUFBSSxFQUFFLElBQUk7b0JBQ1YsSUFBSSxFQUFFLFNBQVM7aUJBQ2hCO2dCQUNEO29CQUNFLElBQUksRUFBRSxNQUFNO29CQUNaLElBQUksRUFBRSxRQUFRO2lCQUNmO2FBQ0Y7WUFDRCxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUM7U0FDbkIsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBRTdDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxhQUFhLEVBQVUsQ0FBQTtRQUM1QyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3BDLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ25ELE1BQU0sVUFBVSxHQUFHO1lBQ2pCLE1BQU0sRUFBRTtnQkFDTjtvQkFDRSxJQUFJLEVBQUUsSUFBSTtvQkFDVixJQUFJLEVBQUUsR0FBRztpQkFDVjthQUNGO1NBQ0YsQ0FBQTtRQUVELE1BQU0sTUFBTSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDL0QsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlc2NyaWJlLCBleHBlY3QsIGV4cGVjdFR5cGVPZiwgaXQgfSBmcm9tIFwidml0ZXN0XCJcbmltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSBcIi4vU2NoZW1hLnRzXCJcbmltcG9ydCB7IGFzc2VydFNjaGVtYSB9IGZyb20gXCIuL2Fzc2VydC50c1wiXG5cbmRlc2NyaWJlKFwiYXNzZXJ0U2NoZW1hXCIsICgpID0+IHtcbiAgaXQoXCJyZXR1cm5zIHR5cGVkIHNjaGVtYSB3aGVuIHZhbGlkXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBkZXNjcmlwdG9yID0ge1xuICAgICAgZmllbGRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImlkXCIsXG4gICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIm5hbWVcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIHByaW1hcnlLZXk6IFtcImlkXCJdLFxuICAgIH1cblxuICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGFzc2VydFNjaGVtYShkZXNjcmlwdG9yKVxuXG4gICAgZXhwZWN0VHlwZU9mKHNjaGVtYSkudG9FcXVhbFR5cGVPZjxTY2hlbWE+KClcbiAgICBleHBlY3Qoc2NoZW1hKS50b0VxdWFsKGRlc2NyaXB0b3IpXG4gIH0pXG5cbiAgaXQoXCJ0aHJvd3MgRXJyb3Igd2hlbiBzY2hlbWEgaXMgaW52YWxpZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IHtcbiAgICAgIGZpZWxkczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJpZFwiLFxuICAgICAgICAgIHR5cGU6IDEyMyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgYXdhaXQgZXhwZWN0KGFzc2VydFNjaGVtYShkZXNjcmlwdG9yKSkucmVqZWN0cy50b1Rocm93KEVycm9yKVxuICB9KVxufSlcbiJdfQ==
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import invariant from "tiny-invariant";
|
|
2
|
+
import { convertFieldFromDescriptor } from "../../field/index.js";
|
|
3
|
+
export function convertSchemaFromDescriptor(descriptor) {
|
|
4
|
+
descriptor = globalThis.structuredClone(descriptor);
|
|
5
|
+
convertProfile(descriptor);
|
|
6
|
+
convertFields(descriptor);
|
|
7
|
+
convertPrimaryKey(descriptor);
|
|
8
|
+
convertForeignKeys(descriptor);
|
|
9
|
+
convertUniqueKeys(descriptor);
|
|
10
|
+
return descriptor;
|
|
11
|
+
}
|
|
12
|
+
function convertProfile(descriptor) {
|
|
13
|
+
descriptor.$schema = descriptor.$schema ?? descriptor.profile;
|
|
14
|
+
}
|
|
15
|
+
function convertFields(descriptor) {
|
|
16
|
+
const fields = descriptor.fields;
|
|
17
|
+
if (!fields) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
invariant(Array.isArray(fields), "Fields being an array is guaranteed by the validation");
|
|
21
|
+
for (const field of fields) {
|
|
22
|
+
convertFieldFromDescriptor(field);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function convertPrimaryKey(descriptor) {
|
|
26
|
+
const primaryKey = descriptor.primaryKey;
|
|
27
|
+
if (!primaryKey) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (typeof primaryKey === "string") {
|
|
31
|
+
descriptor.primaryKey = [primaryKey];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function convertForeignKeys(descriptor) {
|
|
35
|
+
const foreignKeys = descriptor.foreignKeys;
|
|
36
|
+
if (!foreignKeys) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(foreignKeys)) {
|
|
40
|
+
for (const foreignKey of foreignKeys) {
|
|
41
|
+
const fields = foreignKey.fields;
|
|
42
|
+
if (typeof fields === "string") {
|
|
43
|
+
foreignKey.fields = [fields];
|
|
44
|
+
}
|
|
45
|
+
const referenceFields = foreignKey.reference?.fields;
|
|
46
|
+
if (typeof referenceFields === "string") {
|
|
47
|
+
foreignKey.reference.fields = [referenceFields];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function convertUniqueKeys(descriptor) {
|
|
53
|
+
const uniqueKeys = descriptor.uniqueKeys;
|
|
54
|
+
if (!uniqueKeys) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (!Array.isArray(uniqueKeys)) {
|
|
58
|
+
descriptor.uniqueKeys = undefined;
|
|
59
|
+
console.warn(`Ignoring v2.0 incompatible uniqueKeys: ${uniqueKeys}`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const uniqueKey of uniqueKeys) {
|
|
63
|
+
if (!Array.isArray(uniqueKey)) {
|
|
64
|
+
descriptor.uniqueKeys = undefined;
|
|
65
|
+
console.warn(`Ignoring v2.0 incompatible uniqueKey: ${uniqueKey}`);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbURlc2NyaXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zY2hlbWEvY29udmVydC9mcm9tRGVzY3JpcHRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFNBQVMsTUFBTSxnQkFBZ0IsQ0FBQTtBQUV0QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUVqRSxNQUFNLFVBQVUsMkJBQTJCLENBQUMsVUFBc0I7SUFDaEUsVUFBVSxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUE7SUFFbkQsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQzFCLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUN6QixpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUM3QixrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUM5QixpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUU3QixPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsVUFBc0I7SUFDNUMsVUFBVSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsT0FBTyxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUE7QUFDL0QsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLFVBQXNCO0lBQzNDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUE7SUFDaEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTTtJQUNSLENBQUM7SUFFRCxTQUFTLENBQ1AsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFDckIsdURBQXVELENBQ3hELENBQUE7SUFFRCxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzNCLDBCQUEwQixDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ25DLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxVQUFzQjtJQUMvQyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFBO0lBQ3hDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixPQUFNO0lBQ1IsQ0FBQztJQUVELElBQUksT0FBTyxVQUFVLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDbkMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3RDLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxVQUFzQjtJQUNoRCxNQUFNLFdBQVcsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFBO0lBQzFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQixPQUFNO0lBQ1IsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQy9CLEtBQUssTUFBTSxVQUFVLElBQUksV0FBVyxFQUFFLENBQUM7WUFDckMsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQTtZQUNoQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUMvQixVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDOUIsQ0FBQztZQUVELE1BQU0sZUFBZSxHQUFHLFVBQVUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFBO1lBQ3BELElBQUksT0FBTyxlQUFlLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3hDLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUE7WUFDakQsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsVUFBc0I7SUFDL0MsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQTtJQUN4QyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsT0FBTTtJQUNSLENBQUM7SUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQy9CLFVBQVUsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFBO1FBQ2pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsMENBQTBDLFVBQVUsRUFBRSxDQUFDLENBQUE7UUFDcEUsT0FBTTtJQUNSLENBQUM7SUFFRCxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDOUIsVUFBVSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUE7WUFDakMsT0FBTyxDQUFDLElBQUksQ0FBQyx5Q0FBeUMsU0FBUyxFQUFFLENBQUMsQ0FBQTtZQUNsRSxNQUFLO1FBQ1AsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGludmFyaWFudCBmcm9tIFwidGlueS1pbnZhcmlhbnRcIlxuaW1wb3J0IHR5cGUgeyBEZXNjcmlwdG9yIH0gZnJvbSBcIi4uLy4uL2Rlc2NyaXB0b3IvaW5kZXgudHNcIlxuaW1wb3J0IHsgY29udmVydEZpZWxkRnJvbURlc2NyaXB0b3IgfSBmcm9tIFwiLi4vLi4vZmllbGQvaW5kZXgudHNcIlxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFNjaGVtYUZyb21EZXNjcmlwdG9yKGRlc2NyaXB0b3I6IERlc2NyaXB0b3IpIHtcbiAgZGVzY3JpcHRvciA9IGdsb2JhbFRoaXMuc3RydWN0dXJlZENsb25lKGRlc2NyaXB0b3IpXG5cbiAgY29udmVydFByb2ZpbGUoZGVzY3JpcHRvcilcbiAgY29udmVydEZpZWxkcyhkZXNjcmlwdG9yKVxuICBjb252ZXJ0UHJpbWFyeUtleShkZXNjcmlwdG9yKVxuICBjb252ZXJ0Rm9yZWlnbktleXMoZGVzY3JpcHRvcilcbiAgY29udmVydFVuaXF1ZUtleXMoZGVzY3JpcHRvcilcblxuICByZXR1cm4gZGVzY3JpcHRvclxufVxuXG5mdW5jdGlvbiBjb252ZXJ0UHJvZmlsZShkZXNjcmlwdG9yOiBEZXNjcmlwdG9yKSB7XG4gIGRlc2NyaXB0b3IuJHNjaGVtYSA9IGRlc2NyaXB0b3IuJHNjaGVtYSA/PyBkZXNjcmlwdG9yLnByb2ZpbGVcbn1cblxuZnVuY3Rpb24gY29udmVydEZpZWxkcyhkZXNjcmlwdG9yOiBEZXNjcmlwdG9yKSB7XG4gIGNvbnN0IGZpZWxkcyA9IGRlc2NyaXB0b3IuZmllbGRzXG4gIGlmICghZmllbGRzKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBpbnZhcmlhbnQoXG4gICAgQXJyYXkuaXNBcnJheShmaWVsZHMpLFxuICAgIFwiRmllbGRzIGJlaW5nIGFuIGFycmF5IGlzIGd1YXJhbnRlZWQgYnkgdGhlIHZhbGlkYXRpb25cIixcbiAgKVxuXG4gIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB7XG4gICAgY29udmVydEZpZWxkRnJvbURlc2NyaXB0b3IoZmllbGQpXG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydFByaW1hcnlLZXkoZGVzY3JpcHRvcjogRGVzY3JpcHRvcikge1xuICBjb25zdCBwcmltYXJ5S2V5ID0gZGVzY3JpcHRvci5wcmltYXJ5S2V5XG4gIGlmICghcHJpbWFyeUtleSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKHR5cGVvZiBwcmltYXJ5S2V5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgZGVzY3JpcHRvci5wcmltYXJ5S2V5ID0gW3ByaW1hcnlLZXldXG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydEZvcmVpZ25LZXlzKGRlc2NyaXB0b3I6IERlc2NyaXB0b3IpIHtcbiAgY29uc3QgZm9yZWlnbktleXMgPSBkZXNjcmlwdG9yLmZvcmVpZ25LZXlzXG4gIGlmICghZm9yZWlnbktleXMpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KGZvcmVpZ25LZXlzKSkge1xuICAgIGZvciAoY29uc3QgZm9yZWlnbktleSBvZiBmb3JlaWduS2V5cykge1xuICAgICAgY29uc3QgZmllbGRzID0gZm9yZWlnbktleS5maWVsZHNcbiAgICAgIGlmICh0eXBlb2YgZmllbGRzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGZvcmVpZ25LZXkuZmllbGRzID0gW2ZpZWxkc11cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVmZXJlbmNlRmllbGRzID0gZm9yZWlnbktleS5yZWZlcmVuY2U/LmZpZWxkc1xuICAgICAgaWYgKHR5cGVvZiByZWZlcmVuY2VGaWVsZHMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgZm9yZWlnbktleS5yZWZlcmVuY2UuZmllbGRzID0gW3JlZmVyZW5jZUZpZWxkc11cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydFVuaXF1ZUtleXMoZGVzY3JpcHRvcjogRGVzY3JpcHRvcikge1xuICBjb25zdCB1bmlxdWVLZXlzID0gZGVzY3JpcHRvci51bmlxdWVLZXlzXG4gIGlmICghdW5pcXVlS2V5cykge1xuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KHVuaXF1ZUtleXMpKSB7XG4gICAgZGVzY3JpcHRvci51bmlxdWVLZXlzID0gdW5kZWZpbmVkXG4gICAgY29uc29sZS53YXJuKGBJZ25vcmluZyB2Mi4wIGluY29tcGF0aWJsZSB1bmlxdWVLZXlzOiAke3VuaXF1ZUtleXN9YClcbiAgICByZXR1cm5cbiAgfVxuXG4gIGZvciAoY29uc3QgdW5pcXVlS2V5IG9mIHVuaXF1ZUtleXMpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodW5pcXVlS2V5KSkge1xuICAgICAgZGVzY3JpcHRvci51bmlxdWVLZXlzID0gdW5kZWZpbmVkXG4gICAgICBjb25zb2xlLndhcm4oYElnbm9yaW5nIHYyLjAgaW5jb21wYXRpYmxlIHVuaXF1ZUtleTogJHt1bmlxdWVLZXl9YClcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG59XG4iXX0=
|