44 lines
1.9 KiB
JavaScript
44 lines
1.9 KiB
JavaScript
import { lstat, readFile, readdir } from "node:fs/promises";
|
|
import { basename, join, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import { normalizeDataProductDefinition } from "./data-product-policy.mjs";
|
|
import { persistDataProductDefinition } from "./data-product-delivery.mjs";
|
|
|
|
const bundledDefinitionsDir = fileURLToPath(new URL("../definitions/", import.meta.url));
|
|
|
|
export async function loadDataProductDefinitions(directory = bundledDefinitionsDir) {
|
|
const root = resolve(directory);
|
|
const entries = (await readdir(root, { withFileTypes: true }))
|
|
.filter((entry) => entry.name.endsWith(".json"))
|
|
.sort((left, right) => left.name.localeCompare(right.name));
|
|
const definitions = [];
|
|
for (const entry of entries) {
|
|
if (!entry.isFile() || entry.isSymbolicLink()) throw new Error("data_product_definition_file_invalid");
|
|
const path = join(root, entry.name);
|
|
const metadata = await lstat(path);
|
|
if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.size < 2 || metadata.size > 256 * 1024) {
|
|
throw new Error("data_product_definition_file_invalid");
|
|
}
|
|
let value;
|
|
try {
|
|
value = JSON.parse(await readFile(path, "utf8"));
|
|
} catch {
|
|
throw new Error("data_product_definition_json_invalid");
|
|
}
|
|
const definition = normalizeDataProductDefinition(value);
|
|
if (`${definition.id}.json` !== basename(path)) throw new Error("data_product_definition_filename_mismatch");
|
|
definitions.push(definition);
|
|
}
|
|
if (new Set(definitions.map((definition) => definition.id)).size !== definitions.length) {
|
|
throw new Error("data_product_definition_duplicate");
|
|
}
|
|
return Object.freeze(definitions);
|
|
}
|
|
|
|
export async function reconcileDataProductDefinitions(db, directory = bundledDefinitionsDir) {
|
|
const definitions = await loadDataProductDefinitions(directory);
|
|
for (const definition of definitions) await persistDataProductDefinition(db, definition);
|
|
return definitions;
|
|
}
|