diff --git a/apps/example/package.json b/apps/example/package.json index feab65b..43368a4 100644 --- a/apps/example/package.json +++ b/apps/example/package.json @@ -4,8 +4,8 @@ "private": true, "main": "index.js", "scripts": { - "s3": "vite-node ./src/s3-adapter.ts", - "fs": "vite-node ./src/fs-adapter.ts" + "s3": "vite-node ./src/s3-provider.ts", + "fs": "vite-node ./src/fs-provider.ts" }, "keywords": [], "author": "", diff --git a/apps/example/src/fs-adapter.ts b/apps/example/src/fs-provider.ts similarity index 66% rename from apps/example/src/fs-adapter.ts rename to apps/example/src/fs-provider.ts index 7f0fef5..008db93 100644 --- a/apps/example/src/fs-adapter.ts +++ b/apps/example/src/fs-provider.ts @@ -1,5 +1,5 @@ import { createClient } from "clyve"; -import { FileSystemAdapter } from "clyve/adapters"; +import { FileSystemProvider } from "clyve/providers"; import "dotenv/config"; type MySchema = { @@ -14,8 +14,8 @@ type MySchema = { }; }; -const adapter = new FileSystemAdapter("./data"); -const db = createClient(adapter); +const provider = new FileSystemProvider("./data"); +const db = createClient(provider); await db.users.upsert({ id: "1", diff --git a/apps/example/src/s3-adapter.ts b/apps/example/src/s3-providers.ts similarity index 79% rename from apps/example/src/s3-adapter.ts rename to apps/example/src/s3-providers.ts index 08fb6e1..20a74bb 100644 --- a/apps/example/src/s3-adapter.ts +++ b/apps/example/src/s3-providers.ts @@ -1,6 +1,6 @@ import { S3Client } from "@aws-sdk/client-s3"; import { createClient } from "clyve"; -import { S3Adapter } from "clyve/adapters"; +import { S3Provider } from "clyve/providers"; import "dotenv/config"; type MySchema = { @@ -24,8 +24,8 @@ export const s3Client = new S3Client({ }, }); -const adapter = new S3Adapter(s3Client, "scoreboard-app"); -const db = createClient(adapter); +const provider = new S3Provider(s3Client, "scoreboard-app"); +const db = createClient(provider); await db.users.upsert({ id: "1", diff --git a/packages/clyve/README.md b/packages/clyve/README.md index 0bef7e1..bb88273 100644 --- a/packages/clyve/README.md +++ b/packages/clyve/README.md @@ -1,5 +1,5 @@ # Clyve -A lightweight client for using either AWS S3 or the filesystem as a database via adapters. Perfect for quick MVPs or prototypes, it lets you store, retrieve, and manage JSON objects without a full database setup. While not suited for production, it takes advantage of S3’s scalability or the simplicity of the filesystem, enabling easy CRUD operations on structured data. +A lightweight client for using either AWS S3 or the filesystem as a database via providers. Perfect for quick MVPs or prototypes, it lets you store, retrieve, and manage JSON objects without a full database setup. While not suited for production, it takes advantage of S3’s scalability or the simplicity of the filesystem, enabling easy CRUD operations on structured data. ## Key Features - 🕒 Quick to prototype and iterate with. @@ -19,16 +19,16 @@ Install required packages npm install clyve ``` -Install the S3 client if you want to use the S3 adapter +Install the S3 client if you want to use the S3 provider ```bash npm install @aws-sdk/client-s3 ``` -## Usage with S3 Adapter +## Usage with S3 provider ```typescript import { S3Client } from "@aws-sdk/client-s3"; import { createClient } from "clyve"; -import { S3Adapter } from "clyve/adapters"; +import { S3Provider } from "clyve/providers"; // Create an S3 client. export const s3Client = new S3Client({ @@ -55,14 +55,14 @@ type MySchema = { // Create Clyve client. const bucketName = "my-bucket"; -const adapter = new S3Adapter(s3Client, bucketName); -const db = createClient(adapter); +const provider = new S3Provider(s3Client, bucketName); +const db = createClient(provider); ``` -## Usage with file system adapter +## Usage with file system provider ```typescript import { createClient } from "clyve"; -import { FileSystemAdapter } from "clyve/adapters"; +import { FileSystemProvider } from "clyve/providers"; // Create your schema type, id is required in every model. type MySchema = { @@ -78,8 +78,8 @@ type MySchema = { }; // Create Clyve client. -const adapter = new FileSystemAdapter("./data"); -const db = createClient(adapter); +const provider = new FileSystemProvider("./data"); +const db = createClient(provider); ``` ## Operations diff --git a/packages/clyve/package.json b/packages/clyve/package.json index 46ad90e..2cc5056 100644 --- a/packages/clyve/package.json +++ b/packages/clyve/package.json @@ -1,7 +1,7 @@ { "name": "clyve", "type": "module", - "version": "1.1.1", + "version": "1.1.3", "description": "A lightweight TypeScript client that uses AWS S3 or the file system as a schema-driven, JSON-based database.", "homepage": "https://github.com/feelixe/clyve", "repository": { @@ -19,9 +19,9 @@ "import": "./dist/errors.js", "types": "./dist/errors.d.ts" }, - "./adapters": { - "import": "./dist/adapters/index.js", - "types": "./dist/adapters/index.d.ts" + "./providers": { + "import": "./dist/providers/index.js", + "types": "./dist/providers/index.d.ts" } }, "files": [ @@ -31,7 +31,7 @@ "package.json" ], "scripts": { - "build": "tsc", + "build": "rimraf dist && tsc", "dev": "tsc --watch --incremental --preserveWatchOutput" }, "keywords": [], @@ -40,6 +40,7 @@ "devDependencies": { "@aws-sdk/client-s3": "^3.352.0", "@types/node": "^22.10.2", + "rimraf": "^6.0.1", "typescript": "^5.7.2", "vite-node": "^2.1.8" }, diff --git a/packages/clyve/src/index.ts b/packages/clyve/src/index.ts index e2340cc..d5cd9b4 100644 --- a/packages/clyve/src/index.ts +++ b/packages/clyve/src/index.ts @@ -1,5 +1,5 @@ import { CollectionObjectReadOnlyError } from "./errors.js"; -import { Adapter } from "./adapters/types.js"; +import { Provider } from "./providers/types.js"; import { Model } from "./model.js"; import { Operations } from "./operations.js"; @@ -25,8 +25,8 @@ export type ClyveClient = { }; }; -export function createClient(adapter: Adapter) { - const operations = new Operations(adapter); +export function createClient(provider: Provider) { + const operations = new Operations(provider); return new Proxy( {}, diff --git a/packages/clyve/src/operations.ts b/packages/clyve/src/operations.ts index ee5c44b..1559ad8 100644 --- a/packages/clyve/src/operations.ts +++ b/packages/clyve/src/operations.ts @@ -1,16 +1,16 @@ -import { Adapter } from "./adapters/types.js"; +import { Provider } from "./providers/types.js"; import { DuplicateKeyError, KeyDoesNotExistError } from "./errors.js"; import { Model } from "./model.js"; export class Operations { - private adapter: Adapter; + private provider: Provider; - constructor(adapter: Adapter) { - this.adapter = adapter; + constructor(provider: Provider) { + this.provider = provider; } async getById(collection: string, id: string) { - return await this.adapter.getByKey(`${collection}/${id}.json`); + return await this.provider.getByKey(`${collection}/${id}.json`); } async get(collection: string, id: string) { @@ -18,24 +18,24 @@ export class Operations { } async all(collection: string) { - const keys = await this.adapter.keys(collection); - return await Promise.all(keys.map((key) => this.adapter.getByKey(key))); + const keys = await this.provider.keys(collection); + return await Promise.all(keys.map((key) => this.provider.getByKey(key))); } async create(collection: string, data: Model) { - const doesKeyAlreadyExist = await this.adapter.exists(collection, data.id); + const doesKeyAlreadyExist = await this.provider.exists(collection, data.id); if (doesKeyAlreadyExist) { throw new DuplicateKeyError( `Key ${collection}/${data.id}.json already exists` ); } - return await this.adapter.upsert(collection, data); + return await this.provider.upsert(collection, data); } async createMany(collection: string, data: Array) { const entriesExist = await Promise.all( - data.map((data) => this.adapter.exists(collection, data.id)) + data.map((data) => this.provider.exists(collection, data.id)) ); const someExist = entriesExist.some((exists) => exists); if (someExist) { @@ -45,17 +45,17 @@ export class Operations { } return await Promise.all( - data.map((data) => this.adapter.upsert(collection, data)) + data.map((data) => this.provider.upsert(collection, data)) ); } async deleteObject(collection: string, id: string) { - await this.adapter.deleteObject(collection, id); + await this.provider.deleteObject(collection, id); } async deleteMany(collection: string, ids: Array) { const entriesExist = await Promise.all( - ids.map((id) => this.adapter.exists(collection, id)) + ids.map((id) => this.provider.exists(collection, id)) ); const allExist = entriesExist.every((exists) => exists); @@ -67,12 +67,12 @@ export class Operations { } await Promise.all( - ids.map((id) => this.adapter.deleteObject(collection, id)) + ids.map((id) => this.provider.deleteObject(collection, id)) ); } async allIds(collection: string) { - const keys = await this.adapter.keys(collection); + const keys = await this.provider.keys(collection); const fileNames = keys.map((key) => key.split("/")[1]); const ids = fileNames.map((fileName) => fileName.split(".")[0]); return ids; @@ -81,17 +81,17 @@ export class Operations { async deleteAll(collection: string) { const ids = await this.allIds(collection); await Promise.all( - ids.map((id) => this.adapter.deleteObject(collection, id)) + ids.map((id) => this.provider.deleteObject(collection, id)) ); } async count(collection: string) { - const keys = await this.adapter.keys(collection); + const keys = await this.provider.keys(collection); return keys.length; } async exists(collection: string, id: string) { - return await this.adapter.exists(collection, id); + return await this.provider.exists(collection, id); } async update(collection: string, data: Model) { @@ -106,7 +106,7 @@ export class Operations { } async upsert(collection: string, data: Model) { - return await this.adapter.upsert(collection, data); + return await this.provider.upsert(collection, data); } async edit( diff --git a/packages/clyve/src/adapters/file-system.ts b/packages/clyve/src/providers/file-system.ts similarity index 95% rename from packages/clyve/src/adapters/file-system.ts rename to packages/clyve/src/providers/file-system.ts index d0e8030..2c8d341 100644 --- a/packages/clyve/src/adapters/file-system.ts +++ b/packages/clyve/src/providers/file-system.ts @@ -1,10 +1,10 @@ import { Model } from "../model.js"; import { KeyDoesNotExistError } from "../errors.js"; -import { Adapter } from "./types.js"; +import { Provider } from "./types.js"; import { promises as fs } from "node:fs"; import path from "node:path"; -export class FileSystemAdapter implements Adapter { +export class FileSystemProvider implements Provider { private basePath: string; constructor(basePath: string) { diff --git a/packages/clyve/src/adapters/index.ts b/packages/clyve/src/providers/index.ts similarity index 100% rename from packages/clyve/src/adapters/index.ts rename to packages/clyve/src/providers/index.ts diff --git a/packages/clyve/src/adapters/s3.ts b/packages/clyve/src/providers/s3.ts similarity index 91% rename from packages/clyve/src/adapters/s3.ts rename to packages/clyve/src/providers/s3.ts index 23eec63..fe99012 100644 --- a/packages/clyve/src/adapters/s3.ts +++ b/packages/clyve/src/providers/s3.ts @@ -8,17 +8,17 @@ import { PutObjectCommand, S3Client, } from "@aws-sdk/client-s3"; -import { Adapter } from "./types.js"; +import { Provider } from "./types.js"; import { KeyDoesNotExistError, NoBodyError } from "../errors.js"; import { Model } from "../model.js"; -export type S3AdapterConstructorParams = [s3Client: S3Client, bucket: string]; +export type S3ProviderConstructorParams = [s3Client: S3Client, bucket: string]; -export class S3Adapter implements Adapter { +export class S3Provider implements Provider { private client: S3Client; private bucket: string; - constructor(...args: S3AdapterConstructorParams) { + constructor(...args: S3ProviderConstructorParams) { const [s3Client, bucket] = args; this.client = s3Client; this.bucket = bucket; diff --git a/packages/clyve/src/adapters/types.ts b/packages/clyve/src/providers/types.ts similarity index 92% rename from packages/clyve/src/adapters/types.ts rename to packages/clyve/src/providers/types.ts index 8698937..e027f0e 100644 --- a/packages/clyve/src/adapters/types.ts +++ b/packages/clyve/src/providers/types.ts @@ -1,6 +1,6 @@ import { Model } from "model.js"; -export interface Adapter { +export interface Provider { getByKey: (key: string) => Promise; exists: (collection: string, id: string) => Promise; keys: (collection: string) => Promise; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eafa0b4..442866b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,9 @@ importers: '@types/node': specifier: ^22.10.2 version: 22.10.2 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 typescript: specifier: ^5.7.2 version: 5.7.2 @@ -954,6 +957,18 @@ packages: engines: {node: '>=18.18'} dev: true + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1708,6 +1723,16 @@ packages: uri-js: 4.4.1 dev: true + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + dev: true + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -1715,6 +1740,11 @@ packages: color-convert: 2.0.1 dev: true + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true @@ -1809,6 +1839,18 @@ packages: engines: {node: '>=12'} dev: false + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + /es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} dev: true @@ -2017,6 +2059,14 @@ packages: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} dev: true + /foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + dev: true + /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2039,6 +2089,19 @@ packages: is-glob: 4.0.3 dev: true + /glob@11.0.0: + resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} + engines: {node: 20 || >=22} + hasBin: true + dependencies: + foreground-child: 3.3.0 + jackspeak: 4.0.2 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + dev: true + /globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -2081,6 +2144,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2097,6 +2165,13 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true + /jackspeak@4.0.2: + resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} + engines: {node: 20 || >=22} + dependencies: + '@isaacs/cliui': 8.0.2 + dev: true + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -2141,6 +2216,11 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lru-cache@11.0.2: + resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} + engines: {node: 20 || >=22} + dev: true + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2154,6 +2234,13 @@ packages: picomatch: 2.3.1 dev: true + /minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -2167,6 +2254,11 @@ packages: brace-expansion: 2.0.1 dev: true + /minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true @@ -2207,6 +2299,10 @@ packages: p-limit: 3.1.0 dev: true + /package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + dev: true + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2224,6 +2320,14 @@ packages: engines: {node: '>=8'} dev: true + /path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + dependencies: + lru-cache: 11.0.2 + minipass: 7.1.2 + dev: true + /pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} dev: true @@ -2270,6 +2374,15 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true + /rimraf@6.0.1: + resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} + engines: {node: 20 || >=22} + hasBin: true + dependencies: + glob: 11.0.0 + package-json-from-dist: 1.0.1 + dev: true + /rollup@4.28.1: resolution: {integrity: sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2323,11 +2436,48 @@ packages: engines: {node: '>=8'} dev: true + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + /source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} dev: true + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.1.0 + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2479,6 +2629,24 @@ packages: engines: {node: '>=0.10.0'} dev: true + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'}