2022-01-06 06:49:50 +01:00
|
|
|
import { emptyDir, exists } from 'https://deno.land/std@0.119.0/fs/mod.ts'
|
2022-01-03 13:44:08 +01:00
|
|
|
import { copy } from 'https://deno.land/std@0.119.0/fs/copy.ts'
|
2022-01-03 20:30:13 +01:00
|
|
|
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-03 08:54:10 +01:00
|
|
|
const baseUrl = 'https://spec.utxo.cz'
|
|
|
|
|
2022-01-03 08:48:00 +01:00
|
|
|
const banner = `
|
|
|
|
██╗░░░██╗████████╗██╗░░██╗░█████╗░
|
|
|
|
██║░░░██║╚══██╔══╝╚██╗██╔╝██╔══██╗
|
|
|
|
██║░░░██║░░░██║░░░░╚███╔╝░██║░░██║
|
|
|
|
██║░░░██║░░░██║░░░░██╔██╗░██║░░██║
|
|
|
|
╚██████╔╝░░░██║░░░██╔╝╚██╗╚█████╔╝
|
|
|
|
░╚═════╝░░░░╚═╝░░░╚═╝░░╚═╝░╚════╝░
|
|
|
|
`
|
|
|
|
|
2022-01-03 13:57:03 +01:00
|
|
|
export class UTXOEngine {
|
2022-01-03 08:48:00 +01:00
|
|
|
constructor (options = {}) {
|
|
|
|
this.options = options
|
|
|
|
this.srcDir = this.options.srcDir || './spec'
|
|
|
|
if (!this.options.silent) {
|
|
|
|
console.log(banner)
|
|
|
|
}
|
2022-01-06 06:49:50 +01:00
|
|
|
this.imageTypes = [
|
2022-01-06 07:59:40 +01:00
|
|
|
['web', 'png'],
|
|
|
|
['web', 'webp'],
|
|
|
|
['web', 'jpg'],
|
2022-01-06 07:35:45 +01:00
|
|
|
['sm', 'png'],
|
|
|
|
['sm', 'webp'],
|
|
|
|
['twitter', 'jpg']
|
2022-01-06 06:49:50 +01:00
|
|
|
]
|
2022-01-03 08:48:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async init () {
|
|
|
|
this.entries = {}
|
|
|
|
|
|
|
|
for await (const f of Deno.readDir(this.srcDir)) {
|
|
|
|
if (!f.name.match(/^\d+$/)) {
|
|
|
|
continue
|
|
|
|
}
|
2022-01-03 13:44:08 +01:00
|
|
|
const specDir = [this.srcDir, f.name].join('/')
|
2022-01-03 08:48:00 +01:00
|
|
|
|
|
|
|
const entry = this.entries[f.name] = {}
|
|
|
|
// load index
|
2022-01-03 13:44:08 +01:00
|
|
|
entry.index = await this._yamlLoad([specDir, 'index.yaml'].join('/'))
|
2022-01-03 08:48:00 +01:00
|
|
|
|
|
|
|
// load sub-specs
|
|
|
|
entry.specs = {}
|
|
|
|
for (const sp of entry.index.specDef) {
|
2022-01-03 13:44:08 +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-06 06:49:50 +01:00
|
|
|
case 'speakers':
|
2022-01-09 12:40:44 +01:00
|
|
|
case 'partners':
|
2022-01-06 06:49:50 +01:00
|
|
|
for (const s of entry.specs[sp.type]) {
|
|
|
|
if (!s.photos) {
|
|
|
|
s.photos = []
|
|
|
|
}
|
2022-01-06 07:35:45 +01:00
|
|
|
for (const [it, format] of this.imageTypes) {
|
2022-01-09 12:40:44 +01:00
|
|
|
if (await exists([this.srcDir, f.name, 'photos', sp.type, `${s.id}-${it}.${format}`].join('/'))) {
|
2022-01-06 06:49:50 +01:00
|
|
|
s.photos.push(`${it}:${format}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-10 15:12:28 +01:00
|
|
|
if (sp.type === 'speakers') {
|
|
|
|
entry.specs[sp.type] = entry.specs[sp.type].sort((x, y) => x.name.localeCompare(y.name))
|
|
|
|
}
|
2022-01-06 06:49:50 +01:00
|
|
|
break
|
|
|
|
}
|
2022-01-03 08:48:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!this.options.silent) {
|
|
|
|
console.log(`UTXO entries: [ ${Object.keys(this.entries).join(', ')} ]\n`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-03 13:44:08 +01:00
|
|
|
entriesList () {
|
|
|
|
return Object.keys(this.entries)
|
|
|
|
}
|
2022-01-03 08:48:00 +01:00
|
|
|
|
2022-01-03 13:44:08 +01:00
|
|
|
async build (outputDir) {
|
2022-01-03 08:48:00 +01:00
|
|
|
await emptyDir(outputDir)
|
2022-01-03 08:54:10 +01:00
|
|
|
const entriesIndex = []
|
2022-01-03 08:48:00 +01:00
|
|
|
|
|
|
|
for (const entryId of Object.keys(this.entries)) {
|
|
|
|
if (!this.options.silent) {
|
|
|
|
console.log(`UTXO.${entryId}: building specs ..`)
|
|
|
|
}
|
|
|
|
const entry = this.entries[entryId]
|
2022-01-03 13:44:08 +01:00
|
|
|
const entryDir = [outputDir, entryId].join('/')
|
2022-01-03 08:48:00 +01:00
|
|
|
await emptyDir(entryDir)
|
|
|
|
|
|
|
|
// write sub-specs
|
|
|
|
const specEndpoints = {}
|
|
|
|
for (const specName of Object.keys(entry.specs)) {
|
2022-01-03 13:44:08 +01:00
|
|
|
await this._jsonWrite([entryDir, `${specName}.json`], entry.specs[specName])
|
2022-01-03 08:54:10 +01:00
|
|
|
specEndpoints[specName] = `${baseUrl}/${entryId}/${specName}.json`
|
2022-01-03 08:48:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// write index
|
2022-01-03 13:44:08 +01:00
|
|
|
const index = JSON.parse(JSON.stringify(entry.index))
|
2022-01-03 08:48:00 +01:00
|
|
|
delete index.specDef
|
|
|
|
index.spec = specEndpoints
|
|
|
|
index.stats = {
|
|
|
|
tracks: entry.specs.tracks.length,
|
|
|
|
speakers: entry.specs.speakers.length,
|
2022-01-07 08:22:44 +01:00
|
|
|
events: entry.specs.events.length,
|
|
|
|
faqs: entry.specs.faqs.length
|
2022-01-03 08:48:00 +01:00
|
|
|
}
|
|
|
|
|
2022-01-03 13:44:08 +01:00
|
|
|
await this._jsonWrite([entryDir, 'index.json'], index)
|
2022-01-03 08:48:00 +01:00
|
|
|
|
|
|
|
// write bundle
|
2022-01-03 13:44:08 +01:00
|
|
|
const bundle = JSON.parse(JSON.stringify(index))
|
2022-01-03 08:48:00 +01:00
|
|
|
bundle.spec = entry.specs
|
2022-01-03 13:44:08 +01:00
|
|
|
await this._jsonWrite([entryDir, 'bundle.json'], bundle)
|
2022-01-03 08:48:00 +01:00
|
|
|
|
|
|
|
// copy photos
|
|
|
|
const outputPhotosDir = [entryDir, 'photos'].join('/')
|
|
|
|
if (!this.options.silent) {
|
|
|
|
console.log(`UTXO.${entryId}: copying photos ..`)
|
|
|
|
console.log(`copying photos to ${outputPhotosDir}`)
|
|
|
|
}
|
2022-01-03 13:44:08 +01:00
|
|
|
await copy([this.srcDir, entryId, 'photos'].join('/'), outputPhotosDir, { overwrite: true })
|
2022-01-03 08:54:10 +01:00
|
|
|
|
|
|
|
entriesIndex.push({
|
|
|
|
id: `utxo${entryId}`,
|
|
|
|
entryId,
|
|
|
|
url: `${baseUrl}/${entryId}`
|
|
|
|
})
|
2022-01-03 08:48:00 +01:00
|
|
|
}
|
|
|
|
|
2022-01-03 08:54:10 +01:00
|
|
|
// write global index
|
2022-01-03 13:44:08 +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) {
|
|
|
|
console.log('\nBuild done')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-03 13:44:08 +01:00
|
|
|
async schemas () {
|
|
|
|
const schemaDir = './utils/schema'
|
|
|
|
const arr = []
|
|
|
|
for await (const f of Deno.readDir(schemaDir)) {
|
|
|
|
const m = f.name.match(/^(.+)\.yaml$/)
|
|
|
|
if (!m) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
arr.push({ name: m[1], schema: await this._yamlLoad([schemaDir, f.name].join('/')) })
|
|
|
|
}
|
|
|
|
return arr
|
|
|
|
}
|
|
|
|
|
2022-01-03 08:48:00 +01:00
|
|
|
async _yamlLoad (fn) {
|
|
|
|
return load(await Deno.readTextFile(fn))
|
|
|
|
}
|
|
|
|
|
|
|
|
async _jsonWrite (fn, data) {
|
|
|
|
if (Array.isArray(fn)) {
|
|
|
|
fn = fn.join('/')
|
|
|
|
}
|
|
|
|
await Deno.writeTextFile(fn, JSON.stringify(data, null, 2))
|
|
|
|
if (!this.options.silent) {
|
|
|
|
console.log(`${fn} writed`)
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|