UNPKG

polen

Version:

A framework for delightful GraphQL developer portals

141 lines 4.86 kB
// @ts-nocheck /* * Examples * * polen open --introspect https://api.graphql-hive.com/graphql * polen open --introspect https://api.github.com/graphql --introspection-headers '{"Authorization": "Bearer $GITHUB_TOKEN"}' * polen open --sdl https://docs.github.com/public/fpt/schema.docs.graphql */ import { Api } from '#api/index'; import { Vite } from '#dep/vite/index'; import { Grafaid } from '#lib/grafaid/index'; import { GraphqlSchemaLoader } from '#lib/graphql-schema-loader/index'; import { Command } from '@molt/command'; import { Err, Fs, Json, Path, Rec } from '@wollybeard/kit'; import { homedir } from 'node:os'; import { z } from 'zod'; const args = Command.create() .parameter(`--introspection-headers --inh`, z .string() .optional() .describe(`Include headers in the introspection query request sent when using --introspection-url. Format is JSON Object.`)) .parametersExclusive(`source`, ($) => $.parameter(`--introspect --in -i`, { schema: z .string() .url() .describe(`Get the schema by sending a GraphQL introspection query to this URL.`), }) .parameter(`--sdl -s`, { schema: z .string() .describe(`Get the schema from a GraphQL Schema Definition Language file. Can be a path to a local file or an HTTP URL to a remote one.`), }) .parameter(`--name -n`, { schema: z .enum([`github`, `hive`]) .describe(`Pick from a well known public API. Polen already knows how to fetch the schema for these APIs.`), })) .parameter(`--cache`, z .boolean() .default(true) .describe(`Enable or disable caching. By default this command caches fetched schemas for re-use.`)) .settings({ parameters: { environment: { $default: { // todo prfix seting doesn't seem to work with Molt! prefix: `POLEN_CREATE_`, enabled: false, }, }, }, }) .parse(); // cache const cacheDir = Path.join(homedir(), `.polen`, `cache`, `cli`, `open`); const bsae64Codec = { encode: (str) => Buffer.from(str).toString(`base64`), decode: (str) => Buffer.from(str, `base64`).toString(`utf-8`), }; const cacheWrite = async (source, schema) => { if (!args.cache) return; await Err.tryCatchIgnore(async () => { const fileName = bsae64Codec.encode(source); const filePath = Path.join(cacheDir, fileName); const sdl = Grafaid.Schema.print(schema); await Fs.write({ path: filePath, content: sdl }); }); }; const cacheRead = async (source) => { if (!args.cache) return null; return Err.tryCatchIgnore(async () => { const fileName = bsae64Codec.encode(source); const filePath = Path.join(cacheDir, fileName); const sdl = await Fs.read(filePath); if (!sdl) return null; return Grafaid.Schema.fromAST(Grafaid.Schema.AST.parse(sdl)); }); }; const cache = { read: cacheRead, write: cacheWrite, }; const wrapCache = (fn) => { const wrapped = async (...args) => { const cacheKey = JSON.stringify(args); const cachedSchema = await cache.read(cacheKey); if (cachedSchema) { return cachedSchema; } const value = await fn(...args); await cache.write(cacheKey, value); return value; }; return wrapped; }; // cache end // todo: use a proper validation, e.g. zod, better yet: allow to specify the validation in molt itself const parseHeaders = (headersJsonEncoded) => { const headersJson = Json.codec.deserialize(headersJsonEncoded); if (!Rec.is(headersJson)) { console.log(`--introspection-headers must be a JSON object.`); process.exit(1); } return headersJson; }; const load = wrapCache(GraphqlSchemaLoader.load); const schema = await load(args.source._tag === `name` ? { type: `name`, name: args.source.value } : args.source._tag === `sdl` ? { type: `sdl`, pathOrUrl: args.source.value } : { type: `introspect`, url: args.source.value, headers: args.introspectionHeaders ? parseHeaders(args.introspectionHeaders) : undefined, }); const config = await Api.ConfigResolver.fromMemory({ root: await Fs.makeTemporaryDirectory(), schema: { dataSources: { data: { versions: [ { before: Grafaid.Schema.empty, after: schema, changes: [], date: new Date(), }, ], }, }, }, }); const viteDevServer = await Vite.createServer(config); await viteDevServer.listen(); viteDevServer.printUrls(); //# sourceMappingURL=open.js.map