UNPKG

@aurios/jason

Version:

A simple, lightweight, and embeddable JSON document database built on Bun.

88 lines (83 loc) 3 kB
import { FileSystem } from "@effect/platform"; import { NodeContext } from "@effect/platform-node"; import { Effect, Schema } from "effect"; import { Json } from "./json.js"; import { isStandardSchema } from "../utils.js"; import type { AnySchema } from "./config.js"; import { ValidationError } from "../core/errors.js"; export class JsonFile extends Effect.Service<JsonFile>()("JsonFile", { dependencies: [Json.Default, NodeContext.layer], effect: Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; const json = yield* Json; return { /** * Reads, parses and decode a JSON file, returning * the typed object */ readJsonFile: (path: string, schema: AnySchema) => fs.readFileString(path).pipe( Effect.flatMap(json.parse), Effect.flatMap((parsedJson) => { if (isStandardSchema(schema)) { return Effect.tryPromise({ try: () => Promise.resolve(schema["~standard"].validate(parsedJson)), catch: (e) => new ValidationError({ message: `Validation failed: ${e}`, issues: [] }) }).pipe( Effect.flatMap((result) => { if (result.issues) { return Effect.fail( new ValidationError({ message: "Validation failed", issues: result.issues as any }) ); } return Effect.succeed(result.value); }) ); } return Schema.decode(schema as Schema.Schema<any, any>)(parsedJson); }) ), /** * Encode and serialize an object to a JSON string * writes it in a file. */ writeJsonFile: (path: string, schema: AnySchema, data: any) => { const validate = isStandardSchema(schema) ? Effect.tryPromise({ try: () => Promise.resolve(schema["~standard"].validate(data)), catch: (e) => new ValidationError({ message: `Validation failed: ${e}`, issues: [] }) }).pipe( Effect.flatMap((result) => { if (result.issues) { return Effect.fail( new ValidationError({ message: "Validation failed", issues: result.issues as any }) ); } return Effect.succeed(result.value); }) ) : Schema.encode(schema as Schema.Schema<any, any>)(data); return validate.pipe( Effect.flatMap(json.stringify), Effect.flatMap((content) => fs.writeFileString(path, content)), Effect.asVoid ); } }; }) }) {}