diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..da95507 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,37 @@ +name: Test, build, deploy + +on: + push: + branches: + - main # Set a branch to deploy + pull_request: + +jobs: + deploy: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.x + + - uses: szenius/set-timezone@v1.0 + with: + timezoneLinux: "Europe/Prague" + + - name: Build sources + run: make + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.ref == 'refs/heads/main' }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./dist \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ad539a0 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +.PHONY: all + +all: test build + +test: + deno test --allow-read utils/test.js + +build: + deno run --allow-read --allow-write utils/build.js + +format: + deno fmt + +fmt: format \ No newline at end of file diff --git a/data/clients/bluesky/index.yaml b/data/clients/bluesky/index.yaml index b48a9e9..f67b0d5 100644 --- a/data/clients/bluesky/index.yaml +++ b/data/clients/bluesky/index.yaml @@ -1 +1,3 @@ -name: Bluesky \ No newline at end of file +name: Bluesky +links: + web: https://blueskyweb.xyz/ \ No newline at end of file diff --git a/data/federations/bluesky-sandbox/index.yaml b/data/federations/bluesky-sandbox/index.yaml new file mode 100644 index 0000000..c3dd1bc --- /dev/null +++ b/data/federations/bluesky-sandbox/index.yaml @@ -0,0 +1 @@ +name: Bluesky Sandbox \ No newline at end of file diff --git a/data/federations/bluesky/index.yaml b/data/federations/bluesky/index.yaml new file mode 100644 index 0000000..b48a9e9 --- /dev/null +++ b/data/federations/bluesky/index.yaml @@ -0,0 +1 @@ +name: Bluesky \ No newline at end of file diff --git a/dist/index.json b/dist/index.json new file mode 100644 index 0000000..bbe3e39 --- /dev/null +++ b/dist/index.json @@ -0,0 +1,31 @@ +{ + "data": { + "bots": [], + "bridges": [], + "clients": [ + { + "id": "klearsky", + "name": "Klearsky" + }, + { + "id": "bluesky", + "name": "Bluesky", + "links": { + "web": "https://blueskyweb.xyz/" + } + } + ], + "federations": [ + { + "id": "bluesky-sandbox", + "name": "Bluesky Sandbox" + }, + { + "id": "bluesky", + "name": "Bluesky" + } + ], + "plc-directories": [] + }, + "time": "2023-06-28T06:08:14.709Z" +} \ No newline at end of file diff --git a/schema/client.yaml b/schema/client.yaml new file mode 100644 index 0000000..a34dc81 --- /dev/null +++ b/schema/client.yaml @@ -0,0 +1,10 @@ +type: object +additionalProperties: false +properties: + id: + type: string + pattern: '^[a-z0-9-]+$' + name: + type: string + links: + type: object diff --git a/utils/build.js b/utils/build.js new file mode 100644 index 0000000..05e5b76 --- /dev/null +++ b/utils/build.js @@ -0,0 +1,6 @@ +import { Engine } from "./engine.js"; + +const engine = new Engine(); +await engine.load(); + +await engine.build(); diff --git a/utils/engine.js b/utils/engine.js new file mode 100644 index 0000000..b093e29 --- /dev/null +++ b/utils/engine.js @@ -0,0 +1,60 @@ +import { parse } from "https://deno.land/std@0.192.0/yaml/mod.ts"; +import { join } from "https://deno.land/std@0.192.0/path/mod.ts"; +import { ensureDir } from "https://deno.land/std@0.192.0/fs/ensure_dir.ts"; + +const DATA_PATH = "./data"; +const SCHEMA_PATH = "./schema"; +const SCHEMA_MAP = { + clients: "client", +}; + +async function loadYAML(fn) { + return parse(await Deno.readTextFile(fn)); +} +async function saveJSON(fn, data) { + return Deno.writeTextFile(fn, JSON.stringify(data, null, 2)); +} + +export class Engine { + constructor() { + this.data = {}; + this.schemasData = {}; + this.schemaMap = SCHEMA_MAP; + } + + async load() { + for await (const cat of Deno.readDir(DATA_PATH)) { + this.data[cat.name] = []; + for await (const pkg of Deno.readDir(join(DATA_PATH, cat.name))) { + const base = await loadYAML( + join(DATA_PATH, cat.name, pkg.name, "index.yaml"), + ); + this.data[cat.name].push(Object.assign({ id: pkg.name }, base)); + } + } + console.log("Engine loaded"); + } + + async build(path = "./dist") { + await ensureDir(path); + + // write index + const fn = join(path, "index.json"); + await saveJSON(fn, { + data: this.data, + time: new Date(), + }); + console.log(`Build done: ${fn}`); + } + + async schemas() { + if (Object.keys(this.schemasData).length === 0) { + for await (const sf of Deno.readDir(SCHEMA_PATH)) { + const name = sf.name.match(/^(\w+)\./)[1]; + const schema = await loadYAML(join(SCHEMA_PATH, sf.name)); + this.schemasData[name] = schema; + } + } + return this.schemasData; + } +} diff --git a/utils/test.js b/utils/test.js new file mode 100644 index 0000000..2b152d6 --- /dev/null +++ b/utils/test.js @@ -0,0 +1,24 @@ +import Ajv from "npm:ajv@8.8.2"; +import addFormats from "npm:ajv-formats@2.1.1"; +import { Engine } from "./engine.js"; + +const ajv = new Ajv({ strict: false }); +addFormats(ajv); + +const engine = new Engine(); +await engine.load(); + +const schemas = await engine.schemas(); + +for (const col of Object.keys(engine.schemaMap)) { + const schemaName = engine.schemaMap[col]; + for (const item of engine.data[col]) { + const validator = ajv.compile(schemas[schemaName]); + + Deno.test(`${schemaName} (schema): ${item.id}`, () => { + if (!validator(item)) { + throw validator.errors; + } + }); + } +}