UNPKG

@reliverse/rse

Version:

@reliverse/rse is your all-in-one companion for bootstrapping and improving any kind of projects (especially web apps built with frameworks like Next.js) — whether you're kicking off something new or upgrading an existing app. It is also a little AI-power

119 lines (118 loc) 3.63 kB
import path from "@reliverse/pathkit"; import { ensuredir } from "@reliverse/relifso"; import fs from "@reliverse/relifso"; import { Type } from "@sinclair/typebox"; import { cliHomeRepos, cliVersion } from "../constants.js"; export const repoInfoSchema = Type.Object({ id: Type.String(), author: Type.String(), name: Type.String(), description: Type.String(), category: Type.String(), lastUpdated: Type.String(), // ISO date string localPath: Type.String(), // GitHub repository information from ungh github: Type.Object({ stars: Type.Number(), forks: Type.Number(), watchers: Type.Number(), createdAt: Type.String(), updatedAt: Type.String(), pushedAt: Type.String(), defaultBranch: Type.String() }) }); export const reposSchema = Type.Object( { $schema: Type.String(), version: Type.String(), // CLI version when repos.json was last updated repos: Type.Array(repoInfoSchema) }, { additionalProperties: false } ); export const DEFAULT_REPOS_CONFIG = { $schema: "./schema.json", version: cliVersion, repos: [] }; function convertTypeBoxToJsonSchema(schema) { if (!schema || typeof schema !== "object") return schema; if (schema.type === "string" && schema.enum) { return { type: "string", enum: schema.enum }; } if (schema.anyOf || schema.allOf || schema.oneOf) { const variants = schema.anyOf || schema.allOf || schema.oneOf; const allLiterals = variants.every((v) => v.const !== void 0); if (allLiterals) { return { type: "string", enum: variants.map((v) => v.const) }; } } if (schema.type === "object") { const result = { type: "object", properties: {} }; if (schema.required) { result.required = schema.required; } if (schema.properties) { for (const [key, value] of Object.entries(schema.properties)) { result.properties[key] = convertTypeBoxToJsonSchema(value); } } return result; } if (schema.type === "array") { return { type: "array", items: convertTypeBoxToJsonSchema(schema.items) }; } if (schema.type) { const result = { type: schema.type }; if (schema.minimum !== void 0) result.minimum = schema.minimum; if (schema.maximum !== void 0) result.maximum = schema.maximum; if (schema.minLength !== void 0) result.minLength = schema.minLength; if (schema.maxLength !== void 0) result.maxLength = schema.maxLength; if (schema.pattern !== void 0) result.pattern = schema.pattern; if (schema.format !== void 0) result.format = schema.format; if (schema.default !== void 0) result.default = schema.default; return result; } return schema; } export async function generateReposJsonSchema() { const converted = convertTypeBoxToJsonSchema(reposSchema); const schema = { $schema: "http://json-schema.org/draft-07/schema#", title: "rse Repos Schema", description: "Schema for repos.json configuration file", type: "object", properties: converted.properties, required: converted.required }; await ensuredir(cliHomeRepos); const schemaPath = path.join(cliHomeRepos, "schema.json"); await fs.writeFile(schemaPath, JSON.stringify(schema, null, 2)); } export async function shouldRegenerateSchema() { const configPath = path.join(cliHomeRepos, "repos.json"); if (!await fs.pathExists(configPath)) { return true; } try { const content = await fs.readFile(configPath, "utf-8"); const config = JSON.parse(content); return config.version !== cliVersion; } catch { return true; } }