diff --git a/README.md b/README.md index 8b725ad..4f93be6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,13 @@ _SUBJUGATE YOUR SCHEMAS_ ## Info -> To get started, run `deno run -A jsr:@hotsocket/lexiconqueror` +### Get Started + +- Run `deno run -A jsr:@hotsocket/lexiconqueror setup` in your project root +- Configure imports under `"@/"` to point to your `outputDir` +- Add `jsr:@hotsocket/dhmo` and `jsr:@hotsocket/atproto-common` to your project +- Run `deno run -A jsr:@hotsocket/lexiconqueror download` to retrieve lexicons +- Run `deno run -A jsr:@hotsocket/lexiconqueror convert` to convert your downloaded lexicons to TypeScript files ### Links diff --git a/deno.json b/deno.json index 991713f..3cb366f 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@hotsocket/lexiconqueror", - "version": "0.1.0", + "version": "0.1.1", "license": "GPL-3.0-or-later", "tasks": { "npm": "deno run -A npm.ts", diff --git a/info/jsdoc.md b/info/jsdoc.md new file mode 100644 index 0000000..00d1fda --- /dev/null +++ b/info/jsdoc.md @@ -0,0 +1,7 @@ +# Additional JSDoc Tags + +This document outlines extra tags used in generated doc comments. + +| Tag | Associated Types | Description | +| ----------------- | ---------------- | ------------------------------------------- | +| `@lextype ` | (all) | The original type specified in the lexicon. | diff --git a/npm.ts b/npm.ts index 04fea85..88c867f 100644 --- a/npm.ts +++ b/npm.ts @@ -6,12 +6,11 @@ import { build, emptyDir } from "@deno/dnt"; import { default as denoJson } from "./deno.json" with { type: "json" }; -import { PackageMappedSpecifier, SpecifierMappings } from "@deno/dnt/transform"; const OUT_DIR = "./npm"; await emptyDir(OUT_DIR); -const imports = denoJson.imports as Record; +// const imports = denoJson.imports as Record; await build({ filterDiagnostic(diag) { @@ -46,10 +45,7 @@ await build({ }, } as PackageJson, compilerOptions: { - lib: [ - "DOM", - "ESNext", - ], + lib: ["DOM", "ESNext"], }, // don't do commonjs, kids! scriptModule: false, @@ -128,5 +124,6 @@ interface PackageJson { /** * rest of the fields */ + //deno-lint-ignore no-explicit-any [propertyName: string]: any; } diff --git a/src/config.ts b/src/config.ts index 875cc11..c5dec26 100644 --- a/src/config.ts +++ b/src/config.ts @@ -36,8 +36,14 @@ export const atInput = z.union([ z.templateLiteral(["at://", did_z]), z.templateLiteral(["at://", z.hostname()]), ]); -/** zod union of git and at:// input formats */ -export const anyInput = z.union([atInput, gitInput]); + +/** file: input format */ +export const fileInput = z.union([ + z.string().regex(/^file:.*/), +]); + +/** zod union of all input formats */ +export const anyInput = z.union([atInput, gitInput, fileInput]); /** lxq.json format */ export const config_z = z.object({ diff --git a/src/config_public.ts b/src/config_public.ts index abde863..7ab7e47 100644 --- a/src/config_public.ts +++ b/src/config_public.ts @@ -1,3 +1,9 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + import z from "@zod/zod"; import { config_z } from "./config.ts"; diff --git a/src/generator/shared.ts b/src/generator/shared.ts index 14a2331..5d41c4c 100644 --- a/src/generator/shared.ts +++ b/src/generator/shared.ts @@ -85,9 +85,10 @@ export function addComments( ) { const commentParts: string[] = []; if (def.description) commentParts.push(def.description); - if ( - def.type == "query" || def.type == "procedure" || def.type == "subscription" - ) commentParts.push("@" + def.type); + // if ( + // def.type == "query" || def.type == "procedure" || def.type == "subscription" + // ) commentParts.push("@" + def.type); + commentParts.push(`@lextype ${def.type}`); if (def.type === "string" && "format" in def && (def as lex.String).format) { commentParts.push("@format " + (def as lex.String).format); } diff --git a/src/internaltypes.ts b/src/internaltypes.ts index 816b765..7ef44ac 100644 --- a/src/internaltypes.ts +++ b/src/internaltypes.ts @@ -36,16 +36,22 @@ export const resolvedAtInput = anyResolvedInput.safeExtend({ did: z.string(), }); +export const resolvedFileInput = anyResolvedInput.safeExtend({ + kind: z.literal("file"), + path: z.string(), +}); + export const resolvedGitInput = anyResolvedInput.safeExtend({ kind: z.literal("git"), url: z.url(), dir: z.string(), // rev: z.optional(z.string()), - ref: z.optional(z.string()), + ref: z.string(), }); export const resolvedInput_z = z.discriminatedUnion("kind", [ resolvedAtInput, resolvedGitInput, + resolvedFileInput, ]); export type ResolvedInput = z.infer; diff --git a/src/run.ts b/src/run.ts index 63f3187..d933029 100644 --- a/src/run.ts +++ b/src/run.ts @@ -46,11 +46,12 @@ export async function download(configPath: string = "./lxq.json") { const config = await configHelper(configPath); const dataDir = config.dataDir; console.log("⏳\tResolving inputs..."); - const resolvedInputs: types.ResolvedInput[] = []; - await Promise.all( - Object.keys(config.inputs).map(async (name) => { + const resolvedInputs: types.ResolvedInput[] = await Promise.all( + Object.keys(config.inputs).map(async (name): Promise => { const input = cfg.anyInput.parse(config.inputs[name]); let info = ""; + const raw = { name: name, input: input }; + let rv: types.ResolvedInput; if (input.startsWith("at://")) { // pulls straight from published in repo const inner = cfg.atInput.parse(input).substring(5); let did: types.DID; @@ -69,27 +70,37 @@ export async function download(configPath: string = "./lxq.json") { let pds = svc.serviceEndpoint; if (pds.endsWith("/")) pds = pds.substring(0, pds.length - 1); info = `DID: '${did}', PDS: '${svc.serviceEndpoint}'`; - resolvedInputs.push(types.resolvedAtInput.parse({ + rv = { raw: { name: name, input: input }, kind: "at", pds: pds, did: did, - })); + }; } else if (input.startsWith("git+")) { const inner = new URL(cfg.gitInput.parse(input).substring(4)); const repo = inner.origin + inner.pathname; - resolvedInputs.push(types.resolvedGitInput.parse({ + rv = { + raw: raw, kind: "git", - raw: { - name: name, - input: input, - }, - dir: inner.searchParams.get("dir"), - ref: inner.searchParams.get("ref") ?? undefined, + dir: inner.searchParams.get("dir")!, + ref: inner.searchParams.get("ref") ?? "main", url: repo, - } as z.infer)); + }; + } else if (input.startsWith("file:")) { + const dir = cfg.fileInput.parse(input).substring(5); + if (!fss.existsSync(dir)) throw new Error(`Directory '${dir}' (input '${name}') does not exist`); + const stat = await fs.stat(dir); + if (!stat.isDirectory()) throw new Error(`'${dir}' (input '${name}') is not a directory`); + rv = { + raw: raw, + kind: "file", + path: path.resolve(dir), + }; + } else { + throw new Error(`Input '${name}' is not valid?!`); } console.log(`✅\tResolved '${name}' (\`${input}\`)` + (info ? `to [${info}]` : "")); + return rv; }), ); @@ -117,7 +128,7 @@ export async function download(configPath: string = "./lxq.json") { // 91270de847fb763b1cb34ac8733c8bbc3991f820\trefs/heads/main => refs/heads/main const refs = proc.output[1]!.split("\n").map((line) => line.split("\t")[1]); // refs/heads/main => main - const heads = refs.map((ref) => ref.substring(ref.lastIndexOf("/") + 1)); + const heads = refs.map((ref) => ref!.substring(ref!.lastIndexOf("/") + 1)); if (!heads.includes(input.ref)) { throw new Error(`Could not find ref '${input.ref}' in git input '${input.raw.name}'`); } @@ -178,7 +189,7 @@ export async function download(configPath: string = "./lxq.json") { if (proc.status != 0) { throw new Error(`Error pulling git input '${input.raw.name}': ${proc.output[2]?.split("\n")[0]}`); } - if (proc.stdout.split("\n")[0].startsWith("Already up to date.")) { + if (proc.stdout.split("\n")[0]!.startsWith("Already up to date.")) { console.log(`ℹ️\tGit input '${input.raw.name}' already up to date`); } else { shouldCopy = true; @@ -200,6 +211,9 @@ export async function download(configPath: string = "./lxq.json") { await fs.cp(src, myPath, { recursive: true }); console.log(`✅\tCopied Git input '${input.raw.name}' to '${myPath}'`); } + } else if (input.kind == "file") { + await fs.cp(input.path, myPath, { recursive: true, force: true }); + console.log(`✅\tCopied file input '${input.raw.name}' to '${myPath}'`); } }), );