utxo-prague/utils/engine.js

266 řádky
7.6 KiB
JavaScript
Surový Normální zobrazení Historie

2022-01-14 17:56:42 +01:00
import { emptyDir, exists } from "https://deno.land/std@0.119.0/fs/mod.ts";
import { copy } from "https://deno.land/std@0.119.0/fs/copy.ts";
import { load } from "https://deno.land/x/js_yaml_port@3.14.0/js-yaml.js";
2022-01-03 08:48:00 +01:00
2022-01-14 17:56:42 +01:00
const baseUrl = "https://spec.utxo.cz";
2022-01-03 08:54:10 +01:00
2022-01-03 08:48:00 +01:00
const banner = `
2022-01-14 17:56:42 +01:00
`;
2022-01-03 08:48:00 +01:00
2022-01-03 13:57:03 +01:00
export class UTXOEngine {
2022-01-14 17:56:42 +01:00
constructor(options = {}) {
this.options = options;
2022-01-28 17:07:43 +01:00
this.defaultSchemaVersion = "1";
2022-01-14 17:56:42 +01:00
this.srcDir = this.options.srcDir || "./spec";
2022-01-03 08:48:00 +01:00
if (!this.options.silent) {
2022-01-14 17:56:42 +01:00
console.log(banner);
2022-01-03 08:48:00 +01:00
}
2022-01-06 06:49:50 +01:00
this.imageTypes = [
2022-01-19 01:47:55 +01:00
["web", "svg"],
2022-01-14 17:56:42 +01:00
["web", "png"],
["web", "webp"],
["web", "jpg"],
["sm", "png"],
["sm", "webp"],
["twitter", "jpg"],
];
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
async init() {
this.entries = {};
2022-01-03 08:48:00 +01:00
for await (const f of Deno.readDir(this.srcDir)) {
if (!f.name.match(/^\d+$/)) {
2022-01-14 17:56:42 +01:00
continue;
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
const specDir = [this.srcDir, f.name].join("/");
2022-01-03 08:48:00 +01:00
2022-01-14 17:56:42 +01:00
const entry = this.entries[f.name] = {};
2022-01-03 08:48:00 +01:00
// load index
2022-01-14 17:56:42 +01:00
entry.index = await this._yamlLoad([specDir, "index.yaml"].join("/"));
2022-01-03 08:48:00 +01:00
// load sub-specs
2022-01-14 17:56:42 +01:00
entry.specs = {};
2022-01-03 08:48:00 +01:00
for (const sp of entry.index.specDef) {
2022-01-14 17:56:42 +01:00
entry.specs[sp.type] = await this._yamlLoad(
[specDir, `${sp.type}.yaml`].join("/"),
);
2022-01-06 06:49:50 +01:00
// post processing of sub-specs
2022-01-06 07:35:45 +01:00
switch (sp.type) {
2022-01-14 17:56:42 +01:00
case "speakers":
2022-01-19 01:15:57 +01:00
case "projects":
2022-01-14 17:56:42 +01:00
case "partners":
2022-01-06 06:49:50 +01:00
for (const s of entry.specs[sp.type]) {
if (!s.photos) {
2022-01-14 17:56:42 +01:00
s.photos = [];
2022-01-06 06:49:50 +01:00
}
2022-01-06 07:35:45 +01:00
for (const [it, format] of this.imageTypes) {
2022-01-14 17:56:42 +01:00
if (
await exists(
[
this.srcDir,
f.name,
"photos",
sp.type,
`${s.id}-${it}.${format}`,
].join("/"),
)
) {
s.photos.push(`${it}:${format}`);
2022-01-06 06:49:50 +01:00
}
}
}
2022-01-14 17:56:42 +01:00
if (sp.type === "speakers") {
entry.specs[sp.type] = entry.specs[sp.type].sort((x, y) =>
x.name.localeCompare(y.name)
);
2022-01-10 15:12:28 +01:00
}
2022-01-14 17:56:42 +01:00
break;
2022-01-06 06:49:50 +01:00
}
2022-01-03 08:48:00 +01:00
}
}
if (!this.options.silent) {
2022-01-14 17:56:42 +01:00
console.log(
`UTXO entries: [ ${Object.keys(this.entries).join(", ")} ]\n`,
);
2022-01-03 08:48:00 +01:00
}
}
2022-01-14 17:56:42 +01:00
entriesList() {
return Object.keys(this.entries);
2022-01-03 13:44:08 +01:00
}
2022-01-03 08:48:00 +01:00
2022-01-28 17:07:43 +01:00
async build(outputDir = "./dist") {
2022-01-14 17:56:42 +01:00
await emptyDir(outputDir);
const entriesIndex = [];
2022-01-03 08:48:00 +01:00
for (const entryId of Object.keys(this.entries)) {
if (!this.options.silent) {
2022-01-14 17:56:42 +01:00
console.log(`UTXO.${entryId}: building specs ..`);
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
const entry = this.entries[entryId];
const entryDir = [outputDir, entryId].join("/");
await emptyDir(entryDir);
2022-01-03 08:48:00 +01:00
// write sub-specs
2022-01-14 17:56:42 +01:00
const specEndpoints = {};
2022-01-03 08:48:00 +01:00
for (const specName of Object.keys(entry.specs)) {
2022-01-14 17:56:42 +01:00
await this._jsonWrite(
[entryDir, `${specName}.json`],
entry.specs[specName],
);
specEndpoints[specName] = `${baseUrl}/${entryId}/${specName}.json`;
2022-01-03 08:48:00 +01:00
}
// write index
2022-01-14 17:56:42 +01:00
const index = JSON.parse(JSON.stringify(entry.index));
delete index.specDef;
index.spec = specEndpoints;
index.stats = { counts: {} };
2022-01-12 21:03:33 +01:00
for (const sc of Object.keys(entry.specs)) {
2022-01-14 17:56:42 +01:00
index.stats.counts[sc] = entry.specs[sc].length;
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
index.time = new Date();
2022-01-03 08:48:00 +01:00
2022-01-14 17:56:42 +01:00
await this._jsonWrite([entryDir, "index.json"], index);
2022-01-03 08:48:00 +01:00
// write bundle
2022-01-14 17:56:42 +01:00
const bundle = JSON.parse(JSON.stringify(index));
bundle.spec = entry.specs;
await this._jsonWrite([entryDir, "bundle.json"], bundle);
2022-01-03 08:48:00 +01:00
// copy photos
2022-01-14 17:56:42 +01:00
const outputPhotosDir = [entryDir, "photos"].join("/");
2022-01-03 08:48:00 +01:00
if (!this.options.silent) {
2022-01-14 17:56:42 +01:00
console.log(`UTXO.${entryId}: copying photos ..`);
console.log(`copying photos to ${outputPhotosDir}`);
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
await copy([this.srcDir, entryId, "photos"].join("/"), outputPhotosDir, {
overwrite: true,
});
2022-01-03 08:54:10 +01:00
2022-04-28 04:20:27 +02:00
// copy media-kit
const outputMediaDir = [entryDir, "media-kit"].join("/");
if (!this.options.silent) {
console.log(`UTXO.${entryId}: copying media-kit ..`);
console.log(`copying media-kit to ${outputMediaDir}`);
}
await copy(
[this.srcDir, entryId, "media-kit"].join("/"),
outputMediaDir,
{
overwrite: true,
},
);
2022-06-02 23:45:11 +02:00
// write QA output of events (schedules)
const qa = this.qaSummary(entryId);
await this._jsonWrite([entryDir, "qa-summary.json"], qa);
2022-04-28 04:20:27 +02:00
// done
2022-01-03 08:54:10 +01:00
entriesIndex.push({
id: `utxo${entryId}`,
entryId,
2022-01-28 17:07:43 +01:00
url: `${baseUrl}/${entryId}/`,
schema: `${baseUrl}/schema/${entry.schemaVersion || "1"}/`,
2022-01-14 17:56:42 +01:00
});
2022-01-03 08:48:00 +01:00
}
2022-01-28 17:07:43 +01:00
// write schemas
const schemaVersion = this.defaultSchemaVersion;
const schemas = await this.schemas(schemaVersion);
const outputSchemaDir = [outputDir, "schema", schemaVersion].join("/");
await emptyDir(outputSchemaDir);
console.log(`UTXO: writing schema (v${schemaVersion}) ..`);
2022-04-12 13:34:18 +02:00
const schemaBundle = {};
2022-01-28 17:07:43 +01:00
for (const schema of schemas) {
await this._jsonWrite(
[outputSchemaDir, schema.name + ".json"],
schema.schema,
);
2022-04-12 13:34:18 +02:00
schemaBundle[schema.name] = schema.schema;
2022-01-28 17:07:43 +01:00
}
2022-04-12 13:37:40 +02:00
await this._jsonWrite([outputSchemaDir, "bundle.json"], {
definitions: schemaBundle,
});
2022-01-28 17:07:43 +01:00
2022-01-03 08:54:10 +01:00
// write global index
2022-01-14 17:56:42 +01:00
await this._jsonWrite([outputDir, "index.json"], entriesIndex);
2022-01-03 08:54:10 +01:00
2022-01-03 08:48:00 +01:00
if (!this.options.silent) {
2022-01-14 17:56:42 +01:00
console.log("\nBuild done");
2022-01-03 08:48:00 +01:00
}
}
2022-06-02 23:45:11 +02:00
qaSummary(entry) {
const arr = [];
for (
const ev of this.entries[entry].specs.events.filter((ev) =>
ev.type !== "lightning"
)
) {
const s = this.entries[entry].specs.schedule.find((s) =>
s.event === ev.id
);
if (!s) {
throw new Error(`Schedule not found (?): ${ev.id}`);
}
arr.push({
id: s.id,
eventId: ev.id,
name: ev.name,
period: s.period,
});
}
return arr;
}
2022-01-28 17:23:49 +01:00
schemaUrl(version = "1", type = "index") {
return `${baseUrl}/schema/${version}/${type}.json`;
}
2022-01-28 17:07:43 +01:00
async schemas(version = "1") {
const schemaDir = `./utils/schema/${version}`;
2022-01-14 17:56:42 +01:00
const arr = [];
2022-01-03 13:44:08 +01:00
for await (const f of Deno.readDir(schemaDir)) {
2022-01-14 17:56:42 +01:00
const m = f.name.match(/^(.+)\.yaml$/);
2022-01-03 13:44:08 +01:00
if (!m) {
2022-01-14 17:56:42 +01:00
continue;
2022-01-03 13:44:08 +01:00
}
2022-01-14 17:56:42 +01:00
arr.push({
name: m[1],
2022-01-28 17:23:49 +01:00
schema: Object.assign(
{ $id: this.schemaUrl(version, m[1]) },
await this._yamlLoad([schemaDir, f.name].join("/")),
),
2022-01-14 17:56:42 +01:00
});
2022-01-03 13:44:08 +01:00
}
2022-04-12 13:08:19 +02:00
return arr.sort((x, y) => x.name > y.name ? 1 : -1);
2022-01-03 13:44:08 +01:00
}
2022-01-14 17:56:42 +01:00
async _yamlLoad(fn) {
return load(await Deno.readTextFile(fn));
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
async _jsonWrite(fn, data) {
2022-01-03 08:48:00 +01:00
if (Array.isArray(fn)) {
2022-01-14 17:56:42 +01:00
fn = fn.join("/");
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
await Deno.writeTextFile(fn, JSON.stringify(data, null, 2));
2022-01-03 08:48:00 +01:00
if (!this.options.silent) {
2022-01-14 17:56:42 +01:00
console.log(`${fn} writed`);
2022-01-03 08:48:00 +01:00
}
2022-01-14 17:56:42 +01:00
return true;
2022-01-03 08:48:00 +01:00
}
}