├── .npmrc ├── test ├── fixtures │ ├── test-file.txt │ └── test-app.zip ├── user.test.js ├── snapshots.test.js ├── applications.test.js ├── files.test.js └── api.test.js ├── src ├── types │ ├── index.ts │ ├── user.ts │ ├── application.ts │ ├── client.ts │ └── api.ts ├── services │ ├── index.ts │ ├── cache │ │ ├── global.ts │ │ ├── base.ts │ │ └── application.ts │ └── api.ts ├── modules │ ├── index.ts │ ├── user.ts │ ├── network.ts │ ├── deploys.ts │ ├── snapshots.ts │ ├── applications.ts │ └── files.ts ├── structures │ ├── index.ts │ ├── error.ts │ ├── application │ │ ├── application.ts │ │ ├── website.ts │ │ └── base.ts │ ├── deploy.ts │ ├── user.ts │ ├── snapshot.ts │ ├── status.ts │ └── collection.ts ├── assertions │ ├── literal.ts │ └── common.ts ├── index.ts └── lib │ └── routes.ts ├── .gitattributes ├── pnpm-workspace.yaml ├── .gitignore ├── tsdown.config.ts ├── .changeset └── config.json ├── .github ├── dependabot.yml └── workflows │ └── release.yml ├── tsconfig.json ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── biome.json ├── package.json ├── CHANGELOG.md └── pnpm-lock.yaml /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true -------------------------------------------------------------------------------- /test/fixtures/test-file.txt: -------------------------------------------------------------------------------- 1 | Hello, World! -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api"; 2 | export * from "./client"; 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - '@biomejs/biome' 3 | - esbuild 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build 2 | /lib/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | yarn.lock 7 | 8 | # ds 9 | /.DS_Store -------------------------------------------------------------------------------- /test/fixtures/test-app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/squarecloudofc/sdk-api-js/HEAD/test/fixtures/test-app.zip -------------------------------------------------------------------------------- /src/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api"; 2 | export * from "./cache/application"; 3 | export * from "./cache/global"; 4 | -------------------------------------------------------------------------------- /src/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./applications"; 2 | export * from "./deploys"; 3 | export * from "./files"; 4 | export * from "./network"; 5 | export * from "./snapshots"; 6 | export * from "./user"; 7 | -------------------------------------------------------------------------------- /tsdown.config.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from "tsdown"; 2 | 3 | export default { 4 | target: "es2020", 5 | format: ["cjs", "esm"], 6 | outDir: "lib", 7 | dts: true, 8 | minify: false, 9 | clean: true, 10 | sourcemap: false, 11 | } satisfies UserConfig; 12 | -------------------------------------------------------------------------------- /src/types/user.ts: -------------------------------------------------------------------------------- 1 | import type { APIUserPlan } from "@squarecloud/api-types/v2"; 2 | 3 | export interface UserPlan extends Omit { 4 | /** In how many milliseconds the plan will expire */ 5 | expiresInTimestamp?: number; 6 | /** In how much time the plan will expire */ 7 | expiresIn?: Date; 8 | } 9 | -------------------------------------------------------------------------------- /src/structures/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./application/application"; 2 | export * from "./application/base"; 3 | export * from "./application/website"; 4 | export * from "./collection"; 5 | export * from "./deploy"; 6 | export * from "./error"; 7 | export * from "./snapshot"; 8 | export * from "./status"; 9 | export * from "./user"; 10 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | 8 | - package-ecosystem: "docker" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | 13 | - package-ecosystem: "github-actions" 14 | directory: "/" 15 | schedule: 16 | interval: "weekly" -------------------------------------------------------------------------------- /src/services/cache/global.ts: -------------------------------------------------------------------------------- 1 | import type { User } from "@/structures"; 2 | 3 | import { BaseCacheService } from "./base"; 4 | 5 | export interface GlobalCache { 6 | readonly user?: User; 7 | } 8 | 9 | export class GlobalCacheService extends BaseCacheService { 10 | protected cache: GlobalCache = { 11 | user: undefined, 12 | }; 13 | 14 | get user() { 15 | return this.cache.user; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/assertions/literal.ts: -------------------------------------------------------------------------------- 1 | import { makeAssertion } from "./common"; 2 | 3 | export const assertString = makeAssertion( 4 | "string", 5 | (value) => typeof value === "string", 6 | ); 7 | 8 | export const assertBoolean = makeAssertion( 9 | "boolean", 10 | (value) => typeof value === "boolean", 11 | ); 12 | 13 | export const assertPathLike = makeAssertion( 14 | "string or Buffer", 15 | (value) => typeof value === "string" || value instanceof Buffer, 16 | ); 17 | -------------------------------------------------------------------------------- /src/services/cache/base.ts: -------------------------------------------------------------------------------- 1 | export abstract class BaseCacheService< 2 | Struct extends object, 3 | Keys extends keyof Struct = keyof Struct, 4 | > { 5 | protected cache: Struct; 6 | 7 | set(key: T, value: Struct[T]) { 8 | Reflect.set(this.cache, key, value); 9 | } 10 | 11 | get(key: T): Struct[T] { 12 | return this.cache[key]; 13 | } 14 | 15 | remove(key: T) { 16 | Reflect.set(this.cache, key, undefined); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/types/application.ts: -------------------------------------------------------------------------------- 1 | import type { APIApplicationStatusNetwork } from "@squarecloud/api-types/v2"; 2 | 3 | export interface ApplicationStatusUsage { 4 | /** How much memory the application is currently using */ 5 | ram: string; 6 | /** How much cpu the application is currently using */ 7 | cpu: string; 8 | /** How much storage the application is currently using */ 9 | storage: string; 10 | /** The application's network status */ 11 | network: APIApplicationStatusNetwork; 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": ["DOM", "ESNext"], 5 | "module": "commonjs", 6 | "rootDir": "./src", 7 | "declaration": true, 8 | "sourceMap": true, 9 | "outDir": "./lib", 10 | "esModuleInterop": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noImplicitAny": true, 13 | "strictNullChecks": true, 14 | "strictFunctionTypes": true, 15 | "skipLibCheck": true, 16 | "paths": { 17 | "@/*": ["./src/*"] 18 | } 19 | }, 20 | "exclude": ["./test/", "./lib/", "tsdown.config.ts"] 21 | } 22 | -------------------------------------------------------------------------------- /src/modules/user.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from "@/lib/routes"; 2 | import { User } from "@/structures"; 3 | 4 | import type { SquareCloudAPI } from ".."; 5 | 6 | export class UserModule { 7 | constructor(public readonly client: SquareCloudAPI) {} 8 | 9 | /** 10 | * Gets the authenticated user information 11 | */ 12 | async get(): Promise { 13 | const { response } = await this.client.api.request(Routes.user()); 14 | const user = new User(this.client, response); 15 | 16 | this.client.emit("userUpdate", this.client.cache.user, user); 17 | this.client.cache.set("user", user); 18 | 19 | return user; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/structures/error.ts: -------------------------------------------------------------------------------- 1 | export class SquareCloudAPIError extends TypeError { 2 | constructor( 3 | code: string, 4 | message?: string, 5 | options?: { stack?: string; cause?: unknown }, 6 | ) { 7 | super(code); 8 | 9 | this.name = "SquareCloudAPIError"; 10 | 11 | this.message = 12 | (code 13 | ?.replaceAll("_", " ") 14 | .toLowerCase() 15 | .replace(/(^|\s)\S/g, (L) => L.toUpperCase()) || "UNKNOWN_CODE") + 16 | (message ? `: ${message}` : ""); 17 | 18 | if (options?.stack) { 19 | this.stack = options.stack; 20 | } 21 | 22 | if (options?.cause) { 23 | this.cause = options.cause; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/assertions/common.ts: -------------------------------------------------------------------------------- 1 | import { SquareCloudAPIError } from "../structures"; 2 | 3 | export interface AssertionProps { 4 | validate: (value: unknown) => boolean; 5 | expect: string; 6 | value: unknown; 7 | name?: string; 8 | } 9 | 10 | export function assert({ validate, value, expect, name }: AssertionProps) { 11 | if (!validate(value)) { 12 | const code = name ? `INVALID_${name}` : "VALIDATION_ERROR"; 13 | const message = `Expected ${expect}, got ${typeof value}`; 14 | 15 | throw new SquareCloudAPIError(code, message); 16 | } 17 | } 18 | 19 | export function makeAssertion( 20 | expect: string, 21 | validate: (value: unknown) => boolean, 22 | ) { 23 | return (value: unknown, name?: string) => { 24 | assert({ validate, value, expect, name }); 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/services/cache/application.ts: -------------------------------------------------------------------------------- 1 | import type { ApplicationStatus } from "@/structures"; 2 | import type { Snapshot } from "@/structures/snapshot"; 3 | 4 | import { BaseCacheService } from "./base"; 5 | 6 | export interface ApplicationCache { 7 | readonly status?: ApplicationStatus; 8 | readonly snapshots?: Snapshot[]; 9 | readonly logs?: string; 10 | } 11 | 12 | export class ApplicationCacheService extends BaseCacheService { 13 | protected cache: ApplicationCache = { 14 | status: undefined, 15 | snapshots: undefined, 16 | logs: undefined, 17 | }; 18 | 19 | get status() { 20 | return this.cache.status; 21 | } 22 | 23 | get snapshots() { 24 | return this.cache.snapshots; 25 | } 26 | 27 | get logs() { 28 | return this.cache.logs; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/structures/application/application.ts: -------------------------------------------------------------------------------- 1 | import type { APIApplication } from "@squarecloud/api-types/v2"; 2 | 3 | import type { SquareCloudAPI } from "@/index"; 4 | 5 | import type { WebsiteApplication } from "./website"; 6 | import { BaseApplication } from "./base"; 7 | 8 | /** 9 | * Represents a Square Cloud application 10 | */ 11 | export class Application extends BaseApplication { 12 | /** 13 | * Represents a Square Cloud application 14 | * 15 | * @constructor 16 | * @param client - The client for this application 17 | * @param data - The data from this application 18 | */ 19 | constructor( 20 | public readonly client: SquareCloudAPI, 21 | data: APIApplication, 22 | ) { 23 | super(client, { ...data, lang: data.language }); 24 | } 25 | 26 | isWebsite(): this is WebsiteApplication { 27 | const domain = Reflect.get(this, "domain"); 28 | return Boolean(domain); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "biomejs.biome", 3 | "editor.codeActionsOnSave": { 4 | "source.fixAll.biome": "explicit", 5 | "source.organizeImports.biome": "explicit", 6 | "source.organizeImports": "never" 7 | }, 8 | "editor.formatOnSave": true, 9 | 10 | "[css]": { 11 | "editor.defaultFormatter": "biomejs.biome" 12 | }, 13 | 14 | "[typescript]": { 15 | "editor.defaultFormatter": "biomejs.biome" 16 | }, 17 | 18 | "[typescriptreact]": { 19 | "editor.defaultFormatter": "biomejs.biome" 20 | }, 21 | 22 | "[json]": { 23 | "editor.defaultFormatter": "biomejs.biome" 24 | }, 25 | 26 | "[jsonc]": { 27 | "editor.defaultFormatter": "biomejs.biome" 28 | }, 29 | 30 | "json.schemas": [ 31 | { 32 | "fileMatch": ["biome.json"], 33 | "url": "./node_modules/@biomejs/biome/configuration_schema.json" 34 | }, 35 | { 36 | "fileMatch": ["package.json", "tsup.config.json"], 37 | "url": "https://cdn.jsdelivr.net/npm/tsup/schema.json" 38 | } 39 | ], 40 | 41 | "typescript.tsdk": "node_modules/typescript/lib" 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 João Gabriel Tonaco 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/structures/deploy.ts: -------------------------------------------------------------------------------- 1 | import type { APIDeployment, DeploymentState } from "@squarecloud/api-types/v2"; 2 | 3 | import type { BaseApplication } from "./application/base"; 4 | 5 | /** 6 | * Represents an application deployment 7 | */ 8 | export class Deployment { 9 | /** The ID of the deploy. */ 10 | public readonly id: `git-${string}`; 11 | 12 | /** The current state of the deploy. */ 13 | public state: DeploymentState; 14 | 15 | /** The date the deploy was created. */ 16 | public createdAt: Date; 17 | 18 | /** The date the deploy was created in millisseconds. */ 19 | public createdTimestamp: number; 20 | 21 | /** 22 | * Represents an application deployment 23 | * 24 | * @constructor 25 | * @param application - The application from which you fetched the deployment 26 | * @param data - The data from this deployment 27 | */ 28 | constructor( 29 | public readonly application: BaseApplication, 30 | data: APIDeployment, 31 | ) { 32 | const { id, state, date } = data; 33 | 34 | this.id = id; 35 | this.state = state; 36 | this.createdAt = new Date(date); 37 | this.createdTimestamp = this.createdAt.getTime(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/structures/application/website.ts: -------------------------------------------------------------------------------- 1 | import type { APIWebsiteApplication } from "@squarecloud/api-types/v2"; 2 | 3 | import type { SquareCloudAPI } from "@/index"; 4 | import { NetworkModule } from "@/modules"; 5 | 6 | import { Application } from "./application"; 7 | 8 | /** 9 | * Represents a Square Cloud application 10 | */ 11 | export class WebsiteApplication extends Application { 12 | /** The application default domain (e.g. example.squareweb.app) */ 13 | public domain: string; 14 | /** The custom configured domain (e.g. yoursite.com) */ 15 | public custom?: string; 16 | 17 | /** Network module for this application */ 18 | public readonly network = new NetworkModule(this); 19 | 20 | /** 21 | * Represents a Square Cloud application 22 | * 23 | * @constructor 24 | * @param client - The client for this application 25 | * @param data - The data from this application 26 | */ 27 | constructor( 28 | public readonly client: SquareCloudAPI, 29 | data: APIWebsiteApplication, 30 | ) { 31 | super(client, data); 32 | 33 | const { domain, custom } = data; 34 | 35 | this.domain = domain; 36 | this.custom = custom || undefined; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/user.test.js: -------------------------------------------------------------------------------- 1 | import assert from "node:assert/strict"; 2 | import { describe, it } from "node:test"; 3 | 4 | import { SquareCloudAPI } from "../lib/index.js"; 5 | 6 | describe("UserModule", async () => { 7 | const client = new SquareCloudAPI(process.env.SQUARE_API_KEY); 8 | 9 | await it("should get user information", async () => { 10 | const user = await client.user.get(); 11 | 12 | assert.ok(user); 13 | assert.ok(user.id); 14 | assert.ok(typeof user.email === "string"); 15 | assert.ok(typeof user.name === "string"); 16 | assert.ok(user.applications); 17 | assert.ok(user.applications.size >= 0); 18 | }); 19 | 20 | await it("should update cache on user fetch", async () => { 21 | const firstUser = await client.user.get(); 22 | const cachedUser = client.cache.get("user"); 23 | 24 | assert.strictEqual(cachedUser?.id, firstUser.id); 25 | assert.strictEqual(cachedUser?.email, firstUser.email); 26 | }); 27 | 28 | await it("should emit userUpdate event", async () => { 29 | let emitted = false; 30 | const oldUser = client.cache.get("user"); 31 | 32 | client.on("userUpdate", (oldUserEvent, newUserEvent) => { 33 | assert.strictEqual(oldUserEvent, oldUser); 34 | assert.ok(newUserEvent); 35 | emitted = true; 36 | }); 37 | 38 | await client.user.get(); 39 | assert.ok(emitted, "userUpdate event should have been emitted"); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | ci: 12 | name: CI 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v5 16 | - uses: pnpm/action-setup@v4 17 | with: 18 | run_install: false 19 | - uses: actions/setup-node@v5 20 | 21 | - name: Install dependencies 22 | run: pnpm install 23 | 24 | - name: Run lint 25 | run: pnpm lint 26 | 27 | - name: Build 28 | run: pnpm build 29 | 30 | - name: Run tests 31 | run: pnpm test 32 | env: 33 | SQUARE_API_KEY: ${{ secrets.SQUARE_API_KEY }} 34 | 35 | release: 36 | name: Release 37 | runs-on: ubuntu-latest 38 | needs: ci 39 | steps: 40 | - uses: actions/checkout@v5 41 | - uses: pnpm/action-setup@v4 42 | with: 43 | run_install: false 44 | - uses: actions/setup-node@v5 45 | 46 | - name: Install dependencies 47 | run: pnpm install 48 | 49 | - name: Create PR or publish to npm 50 | id: changesets 51 | uses: changesets/action@v1 52 | with: 53 | publish: pnpm run release 54 | env: 55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 56 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 57 | 58 | permissions: 59 | contents: write 60 | pull-requests: write -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { assertString } from "./assertions/literal"; 2 | import { ApplicationsModule, UserModule } from "./modules"; 3 | import { APIService, GlobalCacheService } from "./services"; 4 | import { type ClientEvents, TypedEventEmitter } from "./types"; 5 | 6 | export class SquareCloudAPI extends TypedEventEmitter { 7 | public static apiInfo = { 8 | baseUrl: "https://api.squarecloud.app", 9 | version: "v2", 10 | }; 11 | 12 | /** The API service */ 13 | public readonly api: APIService; 14 | 15 | /** The applications module */ 16 | public readonly applications = new ApplicationsModule(this); 17 | /** The user module */ 18 | public readonly user = new UserModule(this); 19 | /** The global cache service */ 20 | public readonly cache = new GlobalCacheService(); 21 | 22 | /** 23 | * Creates an API instance 24 | * 25 | * @param apiKey - Your API Token (request at [Square Cloud Dashboard](https://squarecloud.app/dashboard)) 26 | */ 27 | constructor(apiKey: string) { 28 | super(); 29 | 30 | assertString(apiKey, "API_KEY"); 31 | this.api = new APIService(apiKey); 32 | } 33 | 34 | /** @deprecated Use SquareCloudAPI#user instead. */ 35 | get users() { 36 | console.warn( 37 | "[SquareCloudAPI] The 'users' property is deprecated and will be removed in the next major version. Use SquareCloudAPI#user instead.", 38 | ); 39 | return this.user; 40 | } 41 | } 42 | 43 | export * from "./structures"; 44 | export * from "./types"; 45 | -------------------------------------------------------------------------------- /src/structures/user.ts: -------------------------------------------------------------------------------- 1 | import type { APIUserInfo } from "@squarecloud/api-types/v2"; 2 | 3 | import type { UserPlan } from "@/types/user"; 4 | 5 | import type { SquareCloudAPI } from ".."; 6 | import { BaseApplication } from "./application/base"; 7 | import { Collection } from "./collection"; 8 | 9 | /** 10 | * Represents a Square Cloud user 11 | */ 12 | export class User { 13 | /** The user's id */ 14 | public readonly id: string; 15 | /** The user's display name */ 16 | public name: string; 17 | /** The user's current plan */ 18 | public plan: UserPlan; 19 | /** The user's registered email */ 20 | public email: string; 21 | /** The user's registered applications Collection */ 22 | public applications: Collection; 23 | 24 | /** 25 | * Represents a Square Cloud user 26 | * 27 | * @constructor 28 | * @param client - The client for this user 29 | * @param data - The data from this user 30 | */ 31 | constructor(client: SquareCloudAPI, data: APIUserInfo) { 32 | const { user, applications } = data; 33 | const { id, name, plan, email } = user; 34 | const { duration } = plan; 35 | 36 | this.id = id; 37 | this.name = name; 38 | this.email = email; 39 | this.plan = { 40 | ...plan, 41 | expiresInTimestamp: duration ?? undefined, 42 | expiresIn: duration ? new Date(duration) : undefined, 43 | }; 44 | this.applications = new Collection( 45 | applications.map((app) => [app.id, new BaseApplication(client, app)]), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/modules/network.ts: -------------------------------------------------------------------------------- 1 | import type { WebsiteApplication } from "@/structures"; 2 | import { assertString } from "@/assertions/literal"; 3 | import { Routes } from "@/lib/routes"; 4 | 5 | export class NetworkModule { 6 | constructor(public readonly application: WebsiteApplication) {} 7 | 8 | /** 9 | * Integrates your website with a custom domain 10 | * - Requires [Senior plan](https://squarecloud.app/plans) or higher 11 | * 12 | * @param custom - The custom domain you want to use (e.g. yoursite.com) 13 | */ 14 | async setCustomDomain(custom: string) { 15 | assertString(custom, "CUSTOM_DOMAIN"); 16 | const data = await this.application.client.api.request( 17 | Routes.apps.network.custom(this.application.id), 18 | { method: "POST", body: { custom } }, 19 | ); 20 | 21 | return data.status === "success"; 22 | } 23 | 24 | /** 25 | * Gets analytics for a custom domain 26 | * - Requires [Senior plan](https://squarecloud.app/plans) or higher 27 | * - Requires the application to have an integrated custom domain 28 | */ 29 | async analytics() { 30 | const data = await this.application.client.api.request( 31 | Routes.apps.network.analytics(this.application.id), 32 | ); 33 | 34 | return data?.response; 35 | } 36 | 37 | /** 38 | * Get the DNS records for your custom domain. 39 | */ 40 | async dns() { 41 | const data = await this.application.client.api.request( 42 | Routes.apps.network.dns(this.application.id), 43 | ); 44 | 45 | return data?.response; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/modules/deploys.ts: -------------------------------------------------------------------------------- 1 | import type { BaseApplication } from "@/structures"; 2 | import { assertString } from "@/assertions/literal"; 3 | import { Routes } from "@/lib/routes"; 4 | import { Deployment } from "@/structures/deploy"; 5 | 6 | export class DeploysModule { 7 | constructor(public readonly application: BaseApplication) {} 8 | 9 | /** 10 | * Integrates Square Cloud with GitHub webhooks 11 | * 12 | * @param accessToken - The access token for your GitHub repository. You can find this in your [GitHub Tokens Classic](https://github.com/settings/tokens/new) 13 | */ 14 | async integrateGithubWebhook(accessToken: string) { 15 | assertString(accessToken); 16 | 17 | const data = await this.application.client.api.request( 18 | Routes.apps.deployments.webhook(this.application.id), 19 | { method: "POST", body: { access_token: accessToken } }, 20 | ); 21 | 22 | return data.response.webhook; 23 | } 24 | 25 | /** 26 | * Gets the last 10 deployments of an application from the last 24 hours 27 | */ 28 | async list() { 29 | const data = await this.application.client.api.request( 30 | Routes.apps.deployments.list(this.application.id), 31 | ); 32 | 33 | return data.response.map( 34 | (deployment) => new Deployment(this.application, deployment), 35 | ); 36 | } 37 | 38 | /** 39 | * Gets the current webhook URL 40 | */ 41 | async webhookURL() { 42 | const data = await this.application.client.api.request( 43 | Routes.apps.deployments.current(this.application.id), 44 | ); 45 | 46 | return data.response.webhook; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/types/client.ts: -------------------------------------------------------------------------------- 1 | import EventEmitter from "events"; 2 | 3 | import type { 4 | Application, 5 | ApplicationStatus, 6 | BaseApplication, 7 | User, 8 | WebsiteApplication, 9 | } from "@/structures"; 10 | import type { Snapshot } from "@/structures/snapshot"; 11 | 12 | export class TypedEventEmitter> { 13 | private emitter = new EventEmitter(); 14 | 15 | emit( 16 | eventName: TEventName, 17 | ...eventArg: TEvents[TEventName] 18 | ) { 19 | this.emitter.emit(eventName, ...(eventArg as [])); 20 | } 21 | 22 | on( 23 | eventName: TEventName, 24 | handler: (...eventArg: TEvents[TEventName]) => void, 25 | ) { 26 | this.emitter.on(eventName, handler as any); 27 | } 28 | 29 | off( 30 | eventName: TEventName, 31 | handler: (...eventArg: TEvents[TEventName]) => void, 32 | ) { 33 | this.emitter.off(eventName, handler as any); 34 | } 35 | } 36 | 37 | export interface ClientEvents { 38 | logsUpdate: [ 39 | application: BaseApplication | Application | WebsiteApplication, 40 | before: string | undefined, 41 | after: string, 42 | ]; 43 | snapshotsUpdate: [ 44 | application: BaseApplication | Application | WebsiteApplication, 45 | before: Snapshot[] | undefined, 46 | after: Snapshot[], 47 | ]; 48 | statusUpdate: [ 49 | application: BaseApplication | Application | WebsiteApplication, 50 | before: ApplicationStatus | undefined, 51 | after: ApplicationStatus, 52 | ]; 53 | userUpdate: [before: User | undefined, after: User]; 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | Square Cloud Banner 3 |
4 | 5 |

@squarecloud/api

6 | 7 |

A NodeJS SDK for consuming the Square Cloud API.

8 | 9 |
10 |
11 | NPM License 12 | NPM Downloads 13 | 14 | NPM Version 15 | 16 |
17 |
18 | 19 | ## Installation 20 | 21 | ```bash 22 | npm install @squarecloud/api 23 | // or 24 | yarn add @squarecloud/api 25 | // or 26 | pnpm add @squarecloud/api 27 | ``` 28 | 29 | ## Documentation 30 | 31 | Visit our [official documentation](https://docs.squarecloud.app/sdks/js/) for more information about how to use this library. 32 | 33 | ## Getting Started 34 | 35 | ```ts 36 | import { SquareCloudAPI } from "@squarecloud/api" 37 | // const { SquareCloudAPI } = require("@squarecloud/api"); 38 | 39 | const api = new SquareCloudAPI("Your API Key") 40 | const user = await api.users.get() 41 | const application = user.applications.get("Application ID") 42 | ``` 43 | 44 | ## Contributing 45 | 46 | Feel free to contribute with suggestions or bug reports at our [GitHub repository](https://github.com/squarecloudofc/sdk-api-js). 47 | 48 | ## Authors 49 | 50 | - [@joaotonaco](https://github.com/joaotonaco) 51 | - [@joaootavios](https://github.com/joaootavios) -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "vcs": { 3 | "enabled": true, 4 | "clientKind": "git", 5 | "useIgnoreFile": true, 6 | "defaultBranch": "main" 7 | }, 8 | 9 | "linter": { 10 | "enabled": true, 11 | "rules": { 12 | "recommended": true, 13 | "style": { 14 | "noParameterAssign": "off", 15 | "useNodejsImportProtocol": "off" 16 | }, 17 | "suspicious": { 18 | "noExplicitAny": "off" 19 | }, 20 | "correctness": { 21 | "noUnusedImports": { "level": "warn", "fix": "safe" }, 22 | "noUnusedVariables": { "level": "warn", "fix": "none" }, 23 | "noUnusedFunctionParameters": "warn" 24 | } 25 | } 26 | }, 27 | 28 | "formatter": { 29 | "enabled": true, 30 | "formatWithErrors": false, 31 | "indentStyle": "space", 32 | "indentWidth": 2, 33 | "lineEnding": "lf", 34 | "lineWidth": 80, 35 | "attributePosition": "auto" 36 | }, 37 | 38 | "assist": { 39 | "actions": { 40 | "source": { 41 | "organizeImports": { 42 | "level": "on", 43 | "options": { 44 | "groups": [ 45 | { 46 | "type": true, 47 | "source": [ 48 | ":NODE:", 49 | ":URL:", 50 | ":PACKAGE_WITH_PROTOCOL:", 51 | ":PACKAGE:" 52 | ] 53 | }, 54 | [":NODE:", ":URL:", ":PACKAGE_WITH_PROTOCOL:", ":PACKAGE:"], 55 | ":BLANK_LINE:", 56 | { "type": true, "source": "@/**" }, 57 | "@/**", 58 | ":BLANK_LINE:", 59 | { "type": true, "source": ":PATH:" }, 60 | ":PATH:" 61 | ] 62 | } 63 | } 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@squarecloud/api", 3 | "version": "3.8.0", 4 | "description": "A NodeJS wrapper for Square Cloud API", 5 | "type": "module", 6 | "main": "./lib/index.cjs", 7 | "module": "./lib/index.mjs", 8 | "types": "./lib/index.d.mts", 9 | "exports": { 10 | ".": { 11 | "import": { 12 | "types": "./lib/index.d.mts", 13 | "default": "./lib/index.mjs" 14 | }, 15 | "require": { 16 | "types": "./lib/index.d.cts", 17 | "default": "./lib/index.cjs" 18 | } 19 | } 20 | }, 21 | "files": [ 22 | "lib" 23 | ], 24 | "packageManager": "pnpm@10.25.0", 25 | "scripts": { 26 | "release": "pnpm build && changeset publish", 27 | "build": "tsdown ./src", 28 | "check-types": "tsc --noEmit", 29 | "lint": "biome check --write .", 30 | "lint:ci": "biome check .", 31 | "test": "node --test test/*.test.js" 32 | }, 33 | "engines": { 34 | "node": ">=18.0.0" 35 | }, 36 | "devDependencies": { 37 | "@biomejs/biome": "^2.3.8", 38 | "@changesets/cli": "^2.29.8", 39 | "@squarecloud/api-types": "^0.6.0", 40 | "@types/node": "^24.10.2", 41 | "ts-node": "^10.9.2", 42 | "ts-node-dev": "^2.0.0", 43 | "tsc-alias": "^1.8.16", 44 | "tsdown": "^0.17.2", 45 | "typescript": "^5.9.3" 46 | }, 47 | "keywords": [ 48 | "wrapper", 49 | "square", 50 | "squarecloud", 51 | "api", 52 | "typescript", 53 | "app", 54 | "bot", 55 | "website", 56 | "host" 57 | ], 58 | "author": { 59 | "name": "joaotonaco", 60 | "url": "https://github.com/joaotonaco" 61 | }, 62 | "repository": { 63 | "type": "git", 64 | "url": "git+https://github.com/squarecloudofc/sdk-api-js.git" 65 | }, 66 | "bugs": { 67 | "url": "https://github.com/squarecloudofc/sdk-api-js/issues" 68 | }, 69 | "homepage": "https://docs.squarecloud.app/sdks/js/client", 70 | "license": "MIT" 71 | } 72 | -------------------------------------------------------------------------------- /src/modules/snapshots.ts: -------------------------------------------------------------------------------- 1 | import type { RESTPostAPISnapshotResult } from "@squarecloud/api-types/v2"; 2 | 3 | import { Routes } from "@/lib/routes"; 4 | import { type BaseApplication, SquareCloudAPIError } from "@/structures"; 5 | import { Snapshot } from "@/structures/snapshot"; 6 | 7 | export class SnapshotsModule { 8 | constructor(public readonly application: BaseApplication) {} 9 | 10 | /** 11 | * Gets the list of generated snapshots for this application 12 | */ 13 | async list(): Promise { 14 | const data = await this.application.client.api.request( 15 | Routes.apps.snapshots(this.application.id), 16 | ); 17 | 18 | const snapshots = data.response.map( 19 | (snapshot) => new Snapshot(this.application, snapshot), 20 | ); 21 | 22 | this.application.client.emit( 23 | "snapshotsUpdate", 24 | this.application, 25 | this.application.cache.snapshots, 26 | snapshots, 27 | ); 28 | this.application.cache.set("snapshots", snapshots); 29 | 30 | return snapshots; 31 | } 32 | 33 | /** 34 | * Generates a new snapshot 35 | * @returns The generated snapshot URL and key 36 | */ 37 | async create(): Promise { 38 | const data = await this.application.client.api.request( 39 | Routes.apps.generateSnapshot(this.application.id), 40 | { method: "POST" }, 41 | ); 42 | 43 | return data.response; 44 | } 45 | 46 | /** 47 | * Generates a new snapshot and downloads it 48 | * @returns The downloaded snapshot buffer 49 | */ 50 | async download(): Promise { 51 | const snapshot = await this.create(); 52 | 53 | const res = await fetch(snapshot.url) 54 | .then((res) => res.arrayBuffer()) 55 | .catch(() => undefined); 56 | 57 | if (!res) { 58 | throw new SquareCloudAPIError("SNAPSHOT_DOWNLOAD_FAILED"); 59 | } 60 | 61 | return Buffer.from(res); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/structures/snapshot.ts: -------------------------------------------------------------------------------- 1 | import type { APISnapshot } from "@squarecloud/api-types/v2"; 2 | 3 | import type { BaseApplication } from "./application/base"; 4 | 5 | /** 6 | * Represents an application snapshot 7 | */ 8 | export class Snapshot { 9 | /** Size of the snapshot in bytes. */ 10 | public size: number; 11 | 12 | /** Date of the last modification of the snapshot. */ 13 | public modifiedAt: Date; 14 | 15 | /** Date of the last modification of the snapshot in millisseconds. */ 16 | public modifiedTimestamp: number; 17 | 18 | /** AWS access key for the snapshot. */ 19 | public readonly key: string; 20 | 21 | /** The URL for downloading this snapshot */ 22 | public readonly url: string; 23 | 24 | /** 25 | * Represents an application snapshot 26 | * 27 | * @constructor 28 | * @param application - The application from which you fetched the snapshots 29 | * @param data - The data from this snapshot 30 | */ 31 | constructor( 32 | public readonly application: BaseApplication, 33 | data: APISnapshot, 34 | ) { 35 | const { name, size, modified, key } = data; 36 | const { userId } = application.client.api; 37 | 38 | this.size = size; 39 | this.modifiedAt = new Date(modified); 40 | this.modifiedTimestamp = this.modifiedAt.getTime(); 41 | this.key = key; 42 | this.url = `https://snapshots.squarecloud.app/applications/${userId}/${name}.zip?${key}`; 43 | } 44 | 45 | /** 46 | * Downloads this snapshot 47 | * @returns The downloaded snapshot bufer 48 | */ 49 | async download(): Promise { 50 | const res = await fetch(this.url) 51 | .then((res) => res.arrayBuffer()) 52 | .catch(() => undefined); 53 | 54 | if (!res) { 55 | throw new Error("SNAPSHOT_DOWNLOAD_FAILED"); 56 | } 57 | 58 | return Buffer.from(res); 59 | } 60 | } 61 | 62 | /** 63 | * @deprecated Use Snapshot instead. 64 | */ 65 | export class Backup extends Snapshot {} 66 | -------------------------------------------------------------------------------- /test/snapshots.test.js: -------------------------------------------------------------------------------- 1 | import assert from "node:assert/strict"; 2 | import { before, describe, it } from "node:test"; 3 | 4 | import { SquareCloudAPI } from "../lib/index.js"; 5 | 6 | describe("SnapshotsModule", async () => { 7 | const client = new SquareCloudAPI(process.env.SQUARE_API_KEY); 8 | 9 | /** @type {import("../lib/index.js").Application} */ 10 | let testApp; 11 | 12 | before(async () => { 13 | const apps = await client.applications.get(); 14 | testApp = apps.first(); 15 | 16 | if (!testApp) { 17 | throw new Error("No test application found"); 18 | } 19 | }); 20 | 21 | await it("should create snapshot", async (t) => { 22 | try { 23 | const snapshot = await testApp.snapshots.create(); 24 | assert.ok(snapshot.url); 25 | assert.ok(snapshot.key); 26 | } catch (err) { 27 | if (err.message.includes("Rate Limit Exceeded")) { 28 | t.skip("Rate limit exceeded"); 29 | } 30 | } 31 | }); 32 | 33 | await it("should download snapshot", async () => { 34 | const snapshots = await testApp.snapshots.list(); 35 | const buffer = await snapshots[0].download(); 36 | assert.ok(Buffer.isBuffer(buffer)); 37 | assert.ok(buffer.length > 0); 38 | }); 39 | 40 | await it("should list snapshots", async () => { 41 | const snapshots = await testApp.snapshots.list(); 42 | 43 | assert.ok(Array.isArray(snapshots)); 44 | if (snapshots.length > 0) { 45 | assert.ok(snapshots[0].url); 46 | assert.ok(snapshots[0].size); 47 | assert.ok(snapshots[0].modifiedAt); 48 | } 49 | }); 50 | 51 | await it("should update cache on snapshots list", async () => { 52 | const snapshots = await testApp.snapshots.list(); 53 | const cachedSnapshots = testApp.cache.get("snapshots"); 54 | 55 | assert.deepStrictEqual(cachedSnapshots, snapshots); 56 | }); 57 | 58 | await it("should emit snapshotsUpdate event", async () => { 59 | let emitted = false; 60 | const oldSnapshots = testApp.cache.get("snapshots"); 61 | 62 | client.on( 63 | "snapshotsUpdate", 64 | (app, oldSnapshotsEvent, newSnapshotsEvent) => { 65 | assert.strictEqual(app, testApp); 66 | assert.deepStrictEqual(oldSnapshotsEvent, oldSnapshots); 67 | assert.ok(Array.isArray(newSnapshotsEvent)); 68 | emitted = true; 69 | }, 70 | ); 71 | 72 | await testApp.snapshots.list(); 73 | assert.ok(emitted, "snapshotsUpdate event should have been emitted"); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /test/applications.test.js: -------------------------------------------------------------------------------- 1 | import assert from "node:assert/strict"; 2 | import { describe, it } from "node:test"; 3 | import { readFile } from "fs/promises"; 4 | import path from "path"; 5 | import { fileURLToPath } from "url"; 6 | 7 | import { SquareCloudAPI } from "../lib/index.js"; 8 | 9 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 10 | 11 | describe("ApplicationsModule", async () => { 12 | const client = new SquareCloudAPI(process.env.SQUARE_API_KEY); 13 | 14 | await it("should list all applications", async () => { 15 | const applications = await client.applications.get(); 16 | assert.ok(applications); 17 | assert.ok(applications.size >= 0); 18 | }); 19 | 20 | await describe("Lifecycle", async () => { 21 | const testAppPath = path.join(__dirname, "fixtures/test-app.zip"); 22 | const fileContent = await readFile(testAppPath); 23 | 24 | const createdApp = await client.applications.create(fileContent); 25 | 26 | await it("should create application", async () => { 27 | assert.ok(createdApp); 28 | assert.ok(createdApp.id); 29 | }); 30 | 31 | const app = await client.applications.fetch(createdApp.id); 32 | 33 | await it("should fetch application", async () => { 34 | assert.strictEqual(app.id, createdApp.id); 35 | }); 36 | 37 | await it("should get status", async () => { 38 | const status = await app.getStatus(); 39 | assert.strictEqual(status.applicationId, createdApp.id); 40 | }); 41 | 42 | await it("should get application logs", async () => { 43 | const logs = await app.getLogs(); 44 | assert.ok(typeof logs === "string"); 45 | }); 46 | 47 | const testFilePath = path.join(__dirname, "fixtures/test-file.txt"); 48 | 49 | await it("should commit file to application", async () => { 50 | const pathResult = await app.commit(testFilePath, "test-file.txt"); 51 | assert.strictEqual(pathResult, true); 52 | }); 53 | 54 | await it("should stop application", async () => { 55 | const result = await app.stop(); 56 | assert.strictEqual(result, true); 57 | }); 58 | 59 | await it("should start application", async () => { 60 | const result = await app.start(); 61 | assert.strictEqual(result, true); 62 | }); 63 | 64 | await it("should restart application", async () => { 65 | const result = await app.restart(); 66 | assert.strictEqual(result, true); 67 | }); 68 | 69 | await it("should delete application", async () => { 70 | const deleteResult = await app.delete(); 71 | assert.strictEqual(deleteResult, true); 72 | }); 73 | }); 74 | 75 | await it("should get status for all applications", async () => { 76 | const statuses = await client.applications.statusAll(); 77 | assert.ok(Array.isArray(statuses)); 78 | }); 79 | }); 80 | -------------------------------------------------------------------------------- /src/services/api.ts: -------------------------------------------------------------------------------- 1 | import type { APIVersion } from "@squarecloud/api-types/v2"; 2 | 3 | import type { 4 | APIEndpoint, 5 | APIRequestArgs, 6 | APIRequestOptions, 7 | APIResponse, 8 | } from "@/types"; 9 | import { SquareCloudAPIError } from "@/structures"; 10 | 11 | export class APIService { 12 | public readonly baseUrl = "https://api.squarecloud.app"; 13 | public readonly version: APIVersion<1 | 2> = "v2"; 14 | public readonly sdkVersion: string = require("../../package.json").version; 15 | public readonly userId: string; 16 | 17 | constructor(protected readonly apiKey: string) { 18 | this.userId = apiKey.split("-")[0]; 19 | } 20 | 21 | async request( 22 | ...[path, options]: APIRequestArgs 23 | ): Promise> { 24 | const { url, init } = this.parseRequestOptions(path, options); 25 | 26 | const response = await fetch(url, init).catch((err) => { 27 | throw new SquareCloudAPIError(err.code, err.message); 28 | }); 29 | 30 | if (response.status === 413) { 31 | throw new SquareCloudAPIError("PAYLOAD_TOO_LARGE"); 32 | } 33 | 34 | if (response.status === 429) { 35 | throw new SquareCloudAPIError("RATE_LIMIT_EXCEEDED", "Try again later"); 36 | } 37 | 38 | if (response.status === 502 || response.status === 504) { 39 | throw new SquareCloudAPIError("SERVER_UNAVAILABLE", "Try again later"); 40 | } 41 | 42 | const data = await response.json().catch(() => { 43 | throw new SquareCloudAPIError( 44 | "CANNOT_PARSE_RESPONSE", 45 | `Failed with status ${response.status}`, 46 | ); 47 | }); 48 | 49 | if (!data || data.status === "error" || !response.ok) { 50 | throw new SquareCloudAPIError( 51 | data?.code || `UNKNOWN_ERROR_${response.status}`, 52 | ); 53 | } 54 | 55 | return data; 56 | } 57 | 58 | private parseRequestOptions( 59 | path: string, 60 | options?: APIRequestOptions, 61 | ) { 62 | const init: RequestInit = options || {}; 63 | 64 | init.method = init.method || "GET"; 65 | init.headers = { 66 | Accept: "application/json", 67 | ...(init.headers || {}), 68 | Authorization: this.apiKey, 69 | "User-Agent": `squarecloud-sdk-js/${this.sdkVersion}`, 70 | }; 71 | 72 | const url = new URL(path, `${this.baseUrl}/${this.version}/`); 73 | 74 | if ("query" in init && init.query) { 75 | const query = new URLSearchParams(init.query as Record); 76 | url.search = query.toString(); 77 | init.query = undefined; 78 | } 79 | 80 | if ("body" in init && init.body && !(init.body instanceof FormData)) { 81 | init.body = JSON.stringify(init.body); 82 | init.headers = { 83 | ...init.headers, 84 | "Content-Type": "application/json", 85 | }; 86 | } 87 | 88 | return { url, init }; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/lib/routes.ts: -------------------------------------------------------------------------------- 1 | import type { APIEndpoint } from "@/types"; 2 | 3 | export type Route = string & { __route: T }; 4 | export const Route = (route: string) => 5 | route as Route; 6 | 7 | interface IRoutes { 8 | [k: string]: ((...args: string[]) => Route) | IRoutes; 9 | } 10 | 11 | export const Routes = { 12 | user: () => { 13 | return Route<"user">("users/me"); 14 | }, 15 | service: { 16 | status: () => { 17 | return Route<"service/status">("service/status"); 18 | }, 19 | }, 20 | apps: { 21 | upload: () => { 22 | return Route<"apps/upload">("apps"); 23 | }, 24 | statusAll: () => { 25 | return Route<"apps/status-all">("apps/status"); 26 | }, 27 | info: (appId: string) => { 28 | return Route<"apps/info">(`apps/${appId}`); 29 | }, 30 | status: (appId: string) => { 31 | return Route<"apps/status">(`apps/${appId}/status`); 32 | }, 33 | logs: (appId: string) => { 34 | return Route<"apps/logs">(`apps/${appId}/logs`); 35 | }, 36 | delete: (appId: string) => { 37 | return Route<"apps/delete">(`apps/${appId}`); 38 | }, 39 | commit: (appId: string) => { 40 | return Route<"apps/commit">(`apps/${appId}/commit`); 41 | }, 42 | snapshots: (appId: string) => { 43 | return Route<"apps/snapshots">(`apps/${appId}/snapshots`); 44 | }, 45 | generateSnapshot: (appId: string) => { 46 | return Route<"apps/generate-snapshot">(`apps/${appId}/snapshots`); 47 | }, 48 | start: (appId: string) => { 49 | return Route<"apps/start">(`apps/${appId}/start`); 50 | }, 51 | restart: (appId: string) => { 52 | return Route<"apps/restart">(`apps/${appId}/restart`); 53 | }, 54 | stop: (appId: string) => { 55 | return Route<"apps/stop">(`apps/${appId}/stop`); 56 | }, 57 | files: { 58 | read: (appId: string) => { 59 | return Route<"apps/files/read">(`apps/${appId}/files/content`); 60 | }, 61 | list: (appId: string) => { 62 | return Route<"apps/files/list">(`apps/${appId}/files`); 63 | }, 64 | upsert: (appId: string) => { 65 | return Route<"apps/files/upsert">(`apps/${appId}/files`); 66 | }, 67 | move: (appId: string) => { 68 | return Route<"apps/files/move">(`apps/${appId}/files`); 69 | }, 70 | delete: (appId: string) => { 71 | return Route<"apps/files/delete">(`apps/${appId}/files`); 72 | }, 73 | }, 74 | deployments: { 75 | list: (appId: string) => { 76 | return Route<"apps/deployments/list">(`apps/${appId}/deployments`); 77 | }, 78 | current: (appId: string) => { 79 | return Route<"apps/deployments/current">( 80 | `apps/${appId}/deployments/current`, 81 | ); 82 | }, 83 | webhook: (appId: string) => { 84 | return Route<"apps/deployments/webhook">( 85 | `apps/${appId}/deploy/webhook`, 86 | ); 87 | }, 88 | }, 89 | network: { 90 | dns: (appId: string) => { 91 | return Route<"apps/network/dns">(`apps/${appId}/network/dns`); 92 | }, 93 | custom: (appId: string) => { 94 | return Route<"apps/network/custom">(`apps/${appId}/network/custom`); 95 | }, 96 | analytics: (appId: string) => { 97 | return Route<"apps/network/analytics">( 98 | `apps/${appId}/network/analytics`, 99 | ); 100 | }, 101 | }, 102 | }, 103 | } satisfies IRoutes; 104 | -------------------------------------------------------------------------------- /src/modules/applications.ts: -------------------------------------------------------------------------------- 1 | import type { RESTPostAPIApplicationUploadResult } from "@squarecloud/api-types/v2"; 2 | import { readFile } from "fs/promises"; 3 | 4 | import { assertPathLike, assertString } from "@/assertions/literal"; 5 | import { Routes } from "@/lib/routes"; 6 | import { 7 | Application, 8 | type BaseApplication, 9 | type Collection, 10 | SimpleApplicationStatus, 11 | SquareCloudAPIError, 12 | User, 13 | } from "@/structures"; 14 | 15 | import type { SquareCloudAPI } from ".."; 16 | 17 | export class ApplicationsModule { 18 | constructor(public readonly client: SquareCloudAPI) {} 19 | 20 | /** 21 | * If the ID is provided, it will return an application that you can manage or get information 22 | * If the ID is not provided, it will return a collection of applications 23 | * 24 | * @param applicationId - The application ID, you must own the application 25 | */ 26 | async get(): Promise>; 27 | async get(applicationId: string): Promise; 28 | async get( 29 | applicationId?: string, 30 | ): Promise> { 31 | const { response } = await this.client.api.request(Routes.user()); 32 | const user = new User(this.client, response); 33 | 34 | this.client.emit("userUpdate", this.client.cache.user, user); 35 | this.client.cache.set("user", user); 36 | 37 | if (applicationId) { 38 | assertString(applicationId, "APP_ID"); 39 | const application = user.applications.get(applicationId); 40 | 41 | if (!application) { 42 | throw new SquareCloudAPIError("APP_NOT_FOUND"); 43 | } 44 | 45 | return application; 46 | } 47 | 48 | return user.applications; 49 | } 50 | 51 | /** 52 | * Uploads an application 53 | * 54 | * @param file - The zip file path or Buffer 55 | * 56 | * @returns The uploaded application data 57 | */ 58 | async create( 59 | file: string | Buffer, 60 | ): Promise { 61 | assertPathLike(file, "UPLOAD_FILE"); 62 | 63 | if (typeof file === "string") { 64 | file = await readFile(file); 65 | } 66 | 67 | const formData = new FormData(); 68 | const blob = new Blob([new Uint8Array(file)]); 69 | formData.append("file", blob, "app.zip"); 70 | 71 | const data = await this.client.api.request(Routes.apps.upload(), { 72 | method: "POST", 73 | body: formData, 74 | }); 75 | 76 | return data.response; 77 | } 78 | 79 | /** 80 | * Gets the summary status for all your applications 81 | */ 82 | async statusAll(): Promise { 83 | const data = await this.client.api.request(Routes.apps.statusAll()); 84 | 85 | return data.response.map( 86 | (status) => new SimpleApplicationStatus(this.client, status), 87 | ); 88 | } 89 | 90 | /** 91 | * Returns an application that you can manage or get information 92 | * 93 | * @param applicationId - The application ID, you must own the application 94 | */ 95 | async fetch(applicationId: string): Promise { 96 | const { response } = await this.client.api.request( 97 | Routes.apps.info(applicationId), 98 | ); 99 | 100 | return new Application(this.client, response); 101 | } 102 | } 103 | 104 | export * from "../services/cache/application"; 105 | export * from "./deploys"; 106 | export * from "./files"; 107 | export * from "./network"; 108 | export * from "./snapshots"; 109 | -------------------------------------------------------------------------------- /src/structures/status.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | APIApplicationStatus, 3 | APIApplicationStatusAll, 4 | ApplicationStatus as ApplicationStatusType, 5 | } from "@squarecloud/api-types/v2"; 6 | 7 | import type { ApplicationStatusUsage } from "@/types/application"; 8 | import { Routes } from "@/lib/routes"; 9 | 10 | import type { SquareCloudAPI } from ".."; 11 | 12 | /** 13 | * Represents an application status fetched from status all endpoint 14 | */ 15 | export class SimpleApplicationStatus { 16 | /** The application's ID this status came from */ 17 | public readonly applicationId: string; 18 | /** Usage statuses for this application */ 19 | public usage: R extends true 20 | ? Pick 21 | : undefined; 22 | /** Whether the application is running or not */ 23 | public running: R; 24 | 25 | /** 26 | * Represents an application status fetched from status all endpoint 27 | * 28 | * @constructor 29 | * @param client - The client for this status 30 | * @param data - The data from this status 31 | */ 32 | constructor( 33 | public readonly client: SquareCloudAPI, 34 | data: APIApplicationStatusAll, 35 | ) { 36 | const { id, running } = data; 37 | 38 | this.applicationId = id; 39 | this.running = running as R; 40 | 41 | if (running) { 42 | const { cpu, ram } = data; 43 | 44 | this.usage = { cpu, ram } as R extends true 45 | ? Pick 46 | : undefined; 47 | } 48 | } 49 | 50 | /** 51 | * Fetches the full application status 52 | */ 53 | async fetch() { 54 | const data = await this.client.api.request( 55 | Routes.apps.status(this.applicationId), 56 | ); 57 | 58 | return new ApplicationStatus( 59 | this.client, 60 | data.response, 61 | this.applicationId, 62 | ); 63 | } 64 | } 65 | 66 | /** 67 | * Represents an application status 68 | */ 69 | export class ApplicationStatus { 70 | /** The application's ID this status came from */ 71 | public readonly applicationId: string; 72 | /** Usage statuses for this application */ 73 | public usage: ApplicationStatusUsage; 74 | /** Whether the application is running or not */ 75 | public running: boolean; 76 | /** 77 | * The status of the application 78 | * 79 | * - 'exited' (stopped) 80 | * - 'created' (being created) 81 | * - 'running' 82 | * - 'starting' 83 | * - 'restarting' 84 | * - 'deleting' 85 | */ 86 | public status: ApplicationStatusType; 87 | /** For how long the app is running in millisseconds */ 88 | public uptimeTimestamp?: number; 89 | /** For how long the app is running */ 90 | public uptime?: Date; 91 | 92 | /** 93 | * Represents an application status 94 | * 95 | * @constructor 96 | * @param client - The client for this status 97 | * @param data - The data from this status 98 | * @param applicationId - The application ID this status came from 99 | */ 100 | constructor( 101 | public readonly client: SquareCloudAPI, 102 | data: APIApplicationStatus, 103 | applicationId: string, 104 | ) { 105 | const { cpu, ram, network, storage, running, status, uptime } = data; 106 | 107 | this.applicationId = applicationId; 108 | this.usage = { cpu, ram, network, storage }; 109 | this.running = running; 110 | this.status = status; 111 | this.uptime = uptime ? new Date(uptime) : undefined; 112 | this.uptimeTimestamp = uptime ?? undefined; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/modules/files.ts: -------------------------------------------------------------------------------- 1 | import { readFile } from "fs/promises"; 2 | import { join } from "path"; 3 | 4 | import type { BaseApplication } from "@/structures"; 5 | import { assertPathLike, assertString } from "@/assertions/literal"; 6 | import { Routes } from "@/lib/routes"; 7 | 8 | export class FilesModule { 9 | constructor(public readonly application: BaseApplication) {} 10 | 11 | /** 12 | * Lists the files inside a directory 13 | * 14 | * @param path - The absolute directory path 15 | */ 16 | async list(path = "/") { 17 | assertString(path, "LIST_FILES_PATH"); 18 | 19 | const { response } = await this.application.client.api.request( 20 | Routes.apps.files.list(this.application.id), 21 | { query: { path } }, 22 | ); 23 | 24 | return response; 25 | } 26 | 27 | /** 28 | * Reads the specified file content 29 | * 30 | * @param path - The absolute file path 31 | */ 32 | async read(path: string) { 33 | assertString(path, "READ_FILE_PATH"); 34 | 35 | const { response } = await this.application.client.api.request( 36 | Routes.apps.files.read(this.application.id), 37 | { query: { path } }, 38 | ); 39 | 40 | if (!response) { 41 | return; 42 | } 43 | 44 | return Buffer.from(response.data); 45 | } 46 | 47 | /** 48 | * Creates a new file 49 | * 50 | * @param file - The file content 51 | * @param fileName - The file name with extension 52 | * @param path - The absolute file path 53 | */ 54 | async create(file: string | Buffer, fileName: string, path = "/") { 55 | assertPathLike(file, "CREATE_FILE"); 56 | assertString(fileName, "CREATE_FILE_NAME"); 57 | assertString(path, "CREATE_FILE_PATH"); 58 | 59 | if (typeof file === "string") { 60 | file = await readFile(file); 61 | } 62 | path = join(path, fileName).replaceAll("\\", "/"); 63 | 64 | const { status } = await this.application.client.api.request( 65 | Routes.apps.files.upsert(this.application.id), 66 | { 67 | method: "PUT", 68 | body: { content: file.toString("utf8"), path }, 69 | }, 70 | ); 71 | 72 | return status === "success"; 73 | } 74 | 75 | /** 76 | * Edits an existing file (same as create) 77 | * 78 | * @param file - The file content 79 | * @param path - The absolute file path 80 | */ 81 | async edit(file: string | Buffer, path = "/") { 82 | assertPathLike(file, "EDIT_FILE"); 83 | assertString(path, "EDIT_FILE_PATH"); 84 | 85 | return this.create(file, "", path); 86 | } 87 | 88 | /** 89 | * Moves or renames a file 90 | * 91 | * @param path - The current absolute file path 92 | * @param newPath - The new absolute file path 93 | */ 94 | async move(path: string, newPath: string) { 95 | assertString(path, "MOVE_FILE_PATH"); 96 | assertString(newPath, "MOVE_FILE_NEW_PATH"); 97 | 98 | const { status } = await this.application.client.api.request( 99 | Routes.apps.files.move(this.application.id), 100 | { method: "PATCH", body: { path, to: newPath } }, 101 | ); 102 | 103 | return status === "success"; 104 | } 105 | 106 | /** 107 | * Deletes the specified file or directory 108 | * 109 | * @param path - The absolute file or directory path 110 | */ 111 | async delete(path: string) { 112 | assertString(path, "DELETE_FILE_PATH"); 113 | 114 | const { status } = await this.application.client.api.request( 115 | Routes.apps.files.delete(this.application.id), 116 | { method: "DELETE", body: { path } }, 117 | ); 118 | 119 | return status === "success"; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /test/files.test.js: -------------------------------------------------------------------------------- 1 | import assert from "node:assert/strict"; 2 | import { before, describe, it } from "node:test"; 3 | 4 | import { SquareCloudAPI } from "../lib/index.js"; 5 | 6 | describe("FilesModule", async () => { 7 | const client = new SquareCloudAPI(process.env.SQUARE_API_KEY); 8 | 9 | /** @type {import("../lib").Application} */ 10 | let testApp; 11 | 12 | before(async () => { 13 | const apps = await client.applications.get(); 14 | testApp = apps.first(); 15 | 16 | if (!testApp) { 17 | throw new Error("No test application found"); 18 | } 19 | }); 20 | 21 | await it("should list files in root directory", async () => { 22 | const files = await testApp.files.list(); 23 | assert.ok(Array.isArray(files)); 24 | if (files.length > 0) { 25 | const file = files[0]; 26 | assert.ok(["file", "directory"].includes(file.type)); 27 | assert.ok(typeof file.name === "string"); 28 | if (file.type === "file") { 29 | assert.ok(typeof file.size === "number"); 30 | assert.ok(typeof file.lastModified === "number"); 31 | } 32 | } 33 | }); 34 | 35 | await it("should create and read file", async () => { 36 | const testContent = "test content"; 37 | const fileName = "test.txt"; 38 | 39 | const createResult = await testApp.files.create( 40 | Buffer.from(testContent), 41 | fileName, 42 | ); 43 | assert.strictEqual(createResult, true); 44 | 45 | const fileContent = await testApp.files.read(`/${fileName}`); 46 | assert.ok(Buffer.isBuffer(fileContent)); 47 | assert.strictEqual(fileContent?.toString(), testContent); 48 | }); 49 | 50 | await it("should edit existing file", async () => { 51 | const newContent = "updated content"; 52 | const fileName = "test.txt"; 53 | 54 | const editResult = await testApp.files.edit( 55 | Buffer.from(newContent), 56 | `/${fileName}`, 57 | ); 58 | assert.strictEqual(editResult, true); 59 | 60 | const fileContent = await testApp.files.read(`/${fileName}`); 61 | assert.strictEqual(fileContent?.toString(), newContent); 62 | }); 63 | 64 | await it("should move/rename file", async () => { 65 | const oldPath = "/test.txt"; 66 | const newPath = "/test2.txt"; 67 | 68 | const moveResult = await testApp.files.move(oldPath, newPath); 69 | assert.strictEqual(moveResult, true); 70 | 71 | const files = await testApp.files.list(); 72 | assert.ok(files.some((file) => file.name === "test2.txt")); 73 | }); 74 | 75 | await it("should handle non-existent file read", async () => { 76 | const content = await testApp.files.read("/non-existent.txt"); 77 | assert.ok(content.byteLength === 0); 78 | }); 79 | 80 | await it("should delete file", async () => { 81 | const deleteResult = await testApp.files.delete("/test2.txt"); 82 | assert.strictEqual(deleteResult, true); 83 | 84 | const files = await testApp.files.list(); 85 | assert.ok(!files.some((file) => file.name === "test2.txt")); 86 | }); 87 | 88 | await it("should handle directory operations", async () => { 89 | await testApp.files.create(Buffer.from("file1"), "file1.txt", "/testdir"); 90 | await testApp.files.create(Buffer.from("file2"), "file2.txt", "/testdir"); 91 | 92 | const dirContents = await testApp.files.list("/testdir"); 93 | assert.strictEqual(dirContents.length, 2); 94 | assert.ok(dirContents.some((file) => file.name === "file1.txt")); 95 | assert.ok(dirContents.some((file) => file.name === "file2.txt")); 96 | 97 | const deleteResult = await testApp.files.delete("/testdir"); 98 | assert.strictEqual(deleteResult, true); 99 | 100 | const rootContents = await testApp.files.list(); 101 | assert.ok(!rootContents.some((file) => file.name === "testdir")); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /src/types/api.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | APIApplication, 3 | APIApplicationLogs, 4 | APIApplicationStatus, 5 | APIApplicationStatusAll, 6 | APIDeployment, 7 | APIDeploymentCurrent, 8 | APIListedFile, 9 | APINetworkAnalytics, 10 | APINetworkDNS, 11 | APIPayload, 12 | APIReadFile, 13 | APIServiceStatus, 14 | APISnapshot, 15 | APIUserInfo, 16 | RESTDeleteAPIFileDeleteQuery, 17 | RESTGetAPIFileContentQuery, 18 | RESTGetAPIFilesListQuery, 19 | RESTPatchAPIFileMoveJSONBody, 20 | RESTPostAPIApplicationUploadResult, 21 | RESTPostAPIGithubWebhookJSONBody, 22 | RESTPostAPIGithubWebhookResult, 23 | RESTPostAPINetworkCustomDomainJSONBody, 24 | RESTPostAPISnapshotResult, 25 | RESTPutAPIFileUpsertJSONBody, 26 | } from "@squarecloud/api-types/v2"; 27 | 28 | import type { Route } from "@/lib/routes"; 29 | 30 | export interface APIEndpoints { 31 | user: { 32 | response: APIUserInfo; 33 | }; 34 | "service/status": { 35 | response: APIServiceStatus; 36 | }; 37 | "apps/upload": { 38 | method: "POST"; 39 | body: FormData; 40 | response: RESTPostAPIApplicationUploadResult; 41 | }; 42 | "apps/status-all": { 43 | response: APIApplicationStatusAll[]; 44 | }; 45 | "apps/info": { 46 | response: APIApplication; 47 | }; 48 | "apps/status": { 49 | response: APIApplicationStatus; 50 | }; 51 | "apps/logs": { 52 | response: APIApplicationLogs; 53 | }; 54 | "apps/snapshots": { 55 | response: APISnapshot[]; 56 | }; 57 | "apps/generate-snapshot": { 58 | method: "POST"; 59 | response: RESTPostAPISnapshotResult; 60 | }; 61 | "apps/start": { 62 | method: "POST"; 63 | response: undefined; 64 | }; 65 | "apps/restart": { 66 | method: "POST"; 67 | response: undefined; 68 | }; 69 | "apps/stop": { 70 | method: "POST"; 71 | response: undefined; 72 | }; 73 | "apps/delete": { 74 | method: "DELETE"; 75 | response: undefined; 76 | }; 77 | "apps/commit": { 78 | method: "POST"; 79 | body: FormData; 80 | response: undefined; 81 | }; 82 | "apps/files/read": { 83 | query: RESTGetAPIFileContentQuery; 84 | response: APIReadFile; 85 | }; 86 | "apps/files/list": { 87 | query: RESTGetAPIFilesListQuery; 88 | response: APIListedFile[]; 89 | }; 90 | "apps/files/upsert": { 91 | method: "PUT"; 92 | body: RESTPutAPIFileUpsertJSONBody; 93 | response: undefined; 94 | }; 95 | "apps/files/move": { 96 | method: "PATCH"; 97 | body: RESTPatchAPIFileMoveJSONBody; 98 | response: undefined; 99 | }; 100 | "apps/files/delete": { 101 | method: "DELETE"; 102 | body: RESTDeleteAPIFileDeleteQuery; 103 | response: undefined; 104 | }; 105 | "apps/deployments/list": { 106 | response: APIDeployment[]; 107 | }; 108 | "apps/deployments/current": { 109 | response: APIDeploymentCurrent; 110 | }; 111 | "apps/deployments/webhook": { 112 | method: "POST"; 113 | body: RESTPostAPIGithubWebhookJSONBody; 114 | response: RESTPostAPIGithubWebhookResult; 115 | }; 116 | "apps/network/dns": { 117 | response: APINetworkDNS[]; 118 | }; 119 | "apps/network/analytics": { 120 | response: APINetworkAnalytics; 121 | }; 122 | "apps/network/custom": { 123 | method: "POST"; 124 | body: RESTPostAPINetworkCustomDomainJSONBody; 125 | response: undefined; 126 | }; 127 | } 128 | 129 | export type APIEndpoint = keyof APIEndpoints; 130 | 131 | export type APIMethod = "GET" | "POST" | "PATCH" | "PUT" | "DELETE"; 132 | 133 | export type APIRequestOptions = { 134 | headers?: HeadersInit; 135 | } & Omit; 136 | 137 | export type APIResponse = APIPayload< 138 | APIEndpoints[T]["response"] 139 | >; 140 | 141 | export type QueryOrBody = 142 | | { query: any } 143 | | { body: any } 144 | | { method: APIMethod }; 145 | 146 | export type APIRequestArgs< 147 | T extends APIEndpoint, 148 | U extends APIRequestOptions = APIRequestOptions, 149 | > = U extends QueryOrBody 150 | ? [path: Route, options: U] 151 | : [path: Route, options?: U]; 152 | -------------------------------------------------------------------------------- /test/api.test.js: -------------------------------------------------------------------------------- 1 | import assert from "node:assert/strict"; 2 | import { describe, it } from "node:test"; 3 | 4 | import { APIService } from "../lib/services/api.js"; 5 | 6 | describe("APIService", async () => { 7 | const service = new APIService("123-test-key"); 8 | 9 | await it("should initialize with correct properties", () => { 10 | assert.strictEqual(service.baseUrl, "https://api.squarecloud.app"); 11 | assert.strictEqual(service.version, "v2"); 12 | assert.strictEqual(service.userId, "123"); 13 | }); 14 | 15 | await it("should parse request options correctly", async (t) => { 16 | const originalFetch = global.fetch; 17 | 18 | await it("should handle basic GET request", async () => { 19 | let requestUrl; 20 | let requestInit; 21 | 22 | global.fetch = async (url, init) => { 23 | requestUrl = url; 24 | requestInit = init; 25 | return new Response(JSON.stringify({ status: "success" })); 26 | }; 27 | 28 | await service.request("test"); 29 | 30 | assert.strictEqual( 31 | requestUrl.toString(), 32 | "https://api.squarecloud.app/v2/test", 33 | ); 34 | assert.strictEqual(requestInit.method, "GET"); 35 | assert.strictEqual(requestInit.headers.Authorization, "123-test-key"); 36 | assert.strictEqual(requestInit.headers.Accept, "application/json"); 37 | }); 38 | 39 | await it("should handle query parameters", async () => { 40 | let requestUrl; 41 | 42 | global.fetch = async (url) => { 43 | requestUrl = url; 44 | return new Response(JSON.stringify({ status: "success" })); 45 | }; 46 | 47 | await service.request("test", { 48 | query: { param1: "value1", param2: "value2" }, 49 | }); 50 | 51 | assert.ok(requestUrl.toString().includes("param1=value1")); 52 | assert.ok(requestUrl.toString().includes("param2=value2")); 53 | }); 54 | 55 | await it("should handle JSON body", async () => { 56 | let requestInit; 57 | 58 | global.fetch = async (_url, init) => { 59 | requestInit = init; 60 | return new Response(JSON.stringify({ status: "success" })); 61 | }; 62 | 63 | const body = { test: "data" }; 64 | await service.request("test", { 65 | method: "POST", 66 | body, 67 | }); 68 | 69 | assert.strictEqual( 70 | requestInit.headers["Content-Type"], 71 | "application/json", 72 | ); 73 | assert.strictEqual(requestInit.body, JSON.stringify(body)); 74 | }); 75 | 76 | await it("should handle FormData body", async () => { 77 | let requestInit; 78 | 79 | global.fetch = async (_url, init) => { 80 | requestInit = init; 81 | return new Response(JSON.stringify({ status: "success" })); 82 | }; 83 | 84 | const formData = new FormData(); 85 | await service.request("test", { 86 | method: "POST", 87 | body: formData, 88 | }); 89 | 90 | assert.strictEqual(requestInit.body, formData); 91 | assert.ok(!requestInit.headers["Content-Type"]); 92 | }); 93 | 94 | await it("should handle error responses", async () => { 95 | global.fetch = async () => { 96 | return new Response( 97 | JSON.stringify({ status: "error", code: "TEST_ERROR" }), 98 | ); 99 | }; 100 | 101 | await assert.rejects(() => service.request("test"), { 102 | name: "SquareCloudAPIError", 103 | message: "Test Error", 104 | }); 105 | }); 106 | 107 | await it("should handle network errors", async () => { 108 | global.fetch = async () => { 109 | throw new Error("Network error"); 110 | }; 111 | 112 | await assert.rejects(() => service.request("test"), { 113 | name: "SquareCloudAPIError", 114 | }); 115 | }); 116 | 117 | await it("should handle specific HTTP status codes", async () => { 118 | const statusTests = [ 119 | { status: 413, code: "Payload Too Large" }, 120 | { status: 429, code: "Rate Limit Exceeded" }, 121 | { status: 502, code: "Server Unavailable" }, 122 | { status: 504, code: "Server Unavailable" }, 123 | ]; 124 | 125 | for (const { status, code } of statusTests) { 126 | global.fetch = async () => new Response(null, { status }); 127 | 128 | await assert.rejects(() => service.request("test"), { 129 | name: "SquareCloudAPIError", 130 | message: new RegExp(code, "ig"), 131 | }); 132 | } 133 | }); 134 | 135 | t.after(() => { 136 | global.fetch = originalFetch; 137 | }); 138 | }); 139 | }); 140 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @squarecloud/api 2 | 3 | ## 3.8.0 4 | 5 | ### Minor Changes 6 | 7 | - dd583f8: Rename `backups` to `snapshots`. The old `backups` property will be removed in the next major release. 8 | 9 | ### Patch Changes 10 | 11 | - bd3ea4e: Show response status at unknown API errors 12 | 13 | ## 3.7.9 14 | 15 | ### Patch Changes 16 | 17 | - afa7761: Update backups routes to snapshots 18 | 19 | ## 3.7.8 20 | 21 | ### Patch Changes 22 | 23 | - 80ce036: Fix deleting application files. 24 | 25 | ## 3.7.7 26 | 27 | ### Patch Changes 28 | 29 | - 15d9dc5: Fix CommonJS require not working. 30 | 31 | ## 3.7.6 32 | 33 | ### Patch Changes 34 | 35 | - 92c7eb6: Remove `zod` dependency. 36 | - cfd06d4: Deprecate `SquareCloudAPI#users` in favor of `SquareCloudAPI#user`. Deprecated property will be removed in the the next major version. 37 | - 775886d: Update backups cache to use `Backup` class instead of API object. 38 | - 3855207: Remove `form-data` dependency. 39 | - 2803f49: Fix cache not being updated. 40 | 41 | ## 3.7.5 42 | 43 | ### Patch Changes 44 | 45 | - b791055: Remove `requests` prop from `ApplicationStatus` 46 | 47 | ## 3.7.4 48 | 49 | ### Patch Changes 50 | 51 | - 4df5b0a: Removed `student` and `enterprise-16` from plans. 52 | - 589db60: Removed all API request validations. 53 | - 4df5b0a: Added `advanced` and `enterprise-24` to plans. 54 | 55 | ## 3.7.0 56 | 57 | ### Minor Changes 58 | 59 | - cbe5512: Remove commit `restart` option. Instead call `application.restart()` manually. 60 | 61 | ## 3.6.6 62 | 63 | ### Patch Changes 64 | 65 | - fa15164: Improve API error handling to avoid HTML parse error. 66 | 67 | ## 3.6.5 68 | 69 | ### Patch Changes 70 | 71 | - b560485: Better request JSON parse error debugging. 72 | 73 | ## 3.6.4 74 | 75 | ### Patch Changes 76 | 77 | - 47ac220: Fix cache defaults not working. 78 | 79 | ## 3.6.3 80 | 81 | ### Patch Changes 82 | 83 | - 138d9d8: Rename `deploys#current()` to `deploys#webhookURL()`. 84 | - 7a806b0: New structure for backups with download method. It's used at `backups.list()` method. 85 | - 6f302d8: New structure for deployments. It's used at `deploys.list()` method. 86 | 87 | ## 3.6.2 88 | 89 | ### Patch Changes 90 | 91 | - d59f57f: Now `backups`, `deploys`, `files` and `cache` are available in the BaseApplication. 92 | 93 | ## 3.6.1 94 | 95 | ### Patch Changes 96 | 97 | - ed4a0b5: Fix CSharp detecting as invalid lang. 98 | 99 | ## 3.6.0 100 | 101 | ### Minor Changes 102 | 103 | - d7e9b0e: New `Application#deploys#current` method for getting the current deployment URL 104 | - 73c92c2: New `Application#files#edit` method for editing files 105 | - 010e8b9: New `Application#backups#list` method for listing snapshots 106 | - 18cf349: New `Application#network#dns` method for getting DNS records status 107 | - 2da679a: New `Application#files#move` for moving or renaming files 108 | - 4f68026: Implement new API routes convention 109 | 110 | ### Patch Changes 111 | 112 | - a138094: Rename `Application#deploys#getGithubWebhook` to `integrateGithubWebhook` 113 | 114 | ## 3.5.3 115 | 116 | ### Patch Changes 117 | 118 | - 613579f: Fix `Application#fetch` request loop 119 | 120 | ## 3.5.1 121 | 122 | ### Patch Changes 123 | 124 | - 6809d52: Fix circular dependency error 125 | - 4dee45a: Attempt to fix circular dependency error 126 | 127 | ## 3.5.1-next.0 128 | 129 | ### Patch Changes 130 | 131 | - Attempt to fix circular dependency error 132 | 133 | ## 3.5.0 134 | 135 | ### Minor Changes 136 | 137 | - 6e42e39: Rename all `tag` properties (user and application) to `name` as API deprecated them. 138 | - 6394ebd: Allow some app methods at BaseApplication 139 | 140 | ### Patch Changes 141 | 142 | - 9adbbfe: Rename `ApplicationManager#status` method to `statusAll` to match its API endpoint. 143 | 144 | ## 3.4.3 145 | 146 | ### Patch Changes 147 | 148 | - 3298bff: Fix `Application#deploys#setGithubWebhook` not returning the webhook URL 149 | - 3298bff: Rename `Application#deploys#setGithubWebhook` to `getGithubWebhook` 150 | 151 | ## 3.4.2 152 | 153 | ### Patch Changes 154 | 155 | - 066a0a3: update API types ([Check changes](https://github.com/squarecloudofc/api-types/releases/tag/v0.2.3)) 156 | - 825da92: improve new assertions debugging 157 | 158 | ## 3.4.1 159 | 160 | ### Patch Changes 161 | 162 | - b05f12b: Update API types 163 | 164 | ## 3.4.0 165 | 166 | ### Minor Changes 167 | 168 | - a8320be: Remove `Application#avatar` due to API changes 169 | - 5e84636: Remove `Application#gitIntegration` due to API changes 170 | 171 | ### Patch Changes 172 | 173 | - 08f91ee: Add assertions for `User` structure 174 | - db0ddb0: Add assertions for `Application` and `WebsiteApplication` 175 | - 86765eb: Refactor typing and add assertions for `SimpleApplicationStatus` and `ApplicationStatus` 176 | - 384a563: Using @biomejs/biome as linter instead of eslint 177 | - 7ac1d2e: Using tsup as builder instead of tsc 178 | 179 | ## 3.3.3 180 | 181 | ### Patch Changes 182 | 183 | - 298743f: Fix error interpretation exception 184 | 185 | ## 3.3.2 186 | 187 | ### Patch Changes 188 | 189 | - ef6ff49: Edit README to feature new official documentation 190 | - dbca1f8: Fix incorrect file path at `FilesManager#create` 191 | 192 | ## 3.3.1 193 | 194 | ### Patch Changes 195 | 196 | - a4e4c3f: fix Class extends value undefined 197 | -------------------------------------------------------------------------------- /src/structures/application/base.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | APIUserApplication, 3 | ApplicationLanguage, 4 | } from "@squarecloud/api-types/v2"; 5 | import { readFile } from "fs/promises"; 6 | 7 | import type { SquareCloudAPI } from "@/index"; 8 | import { assertPathLike, assertString } from "@/assertions/literal"; 9 | import { Routes } from "@/lib/routes"; 10 | import { DeploysModule, FilesModule, SnapshotsModule } from "@/modules"; 11 | import { ApplicationCacheService } from "@/services"; 12 | import { ApplicationStatus } from "@/structures"; 13 | 14 | import type { Application } from "./application"; 15 | 16 | /** 17 | * Represents the base application from the user endpoint 18 | */ 19 | export class BaseApplication { 20 | /** The application ID */ 21 | public readonly id: string; 22 | /** The application display name */ 23 | public name: string; 24 | /** The application description */ 25 | public description?: string; 26 | /** The url to manage the application via web */ 27 | public url: string; 28 | /** The application total ram */ 29 | public ram: number; 30 | /** The application current cluster */ 31 | public cluster: string; 32 | /** 33 | * The application programming language 34 | * 35 | * - `javascript` 36 | * - `typescript` 37 | * - `python` 38 | * - `java` 39 | * - `elixir` 40 | * - `rust` 41 | * - `go` 42 | * - `php` 43 | * - `dotnet` 44 | * - `static` 45 | */ 46 | public language: ApplicationLanguage; 47 | 48 | /** Cache service for this application */ 49 | public readonly cache = new ApplicationCacheService(); 50 | /** Files module for this application */ 51 | public readonly files = new FilesModule(this); 52 | /** Snapshots module for this application */ 53 | public readonly snapshots = new SnapshotsModule(this); 54 | /** Deploys module for this application */ 55 | public readonly deploys = new DeploysModule(this); 56 | 57 | /** 58 | * Represents the base application from the user endpoint 59 | * 60 | * @constructor 61 | * @param client - The client for this application 62 | * @param data - The data from this application 63 | */ 64 | constructor( 65 | public readonly client: SquareCloudAPI, 66 | data: APIUserApplication, 67 | ) { 68 | const { id, name, desc, ram, lang, cluster } = data; 69 | 70 | this.id = id; 71 | this.name = name; 72 | this.description = desc; 73 | this.ram = ram; 74 | this.language = lang; 75 | this.cluster = cluster; 76 | this.url = `https://squarecloud.app/dashboard/app/${id}`; 77 | } 78 | 79 | /** @deprecated Use `Application#snapshots` instead */ 80 | get backup() { 81 | console.warn( 82 | "[SquareCloudAPI] The 'backup' property is deprecated and will be removed in the next major version. Use Application#snapshots instead.", 83 | ); 84 | return this.snapshots; 85 | } 86 | 87 | /** @deprecated Use `Application#snapshots` instead */ 88 | get backups() { 89 | console.warn( 90 | "[SquareCloudAPI] The 'backups' property is deprecated and will be removed in the next major version. Use Application#snapshots instead.", 91 | ); 92 | return this.snapshots; 93 | } 94 | 95 | /** 96 | * Fetches this application for full information 97 | */ 98 | async fetch(): Promise { 99 | return this.client.applications.fetch(this.id); 100 | } 101 | 102 | /** 103 | * Gets the application current status information 104 | */ 105 | async getStatus(): Promise { 106 | const data = await this.client.api.request(Routes.apps.status(this.id)); 107 | const status = new ApplicationStatus(this.client, data.response, this.id); 108 | 109 | this.client.emit("statusUpdate", this, this.cache.status, status); 110 | this.cache.set("status", status); 111 | 112 | return status; 113 | } 114 | 115 | /** 116 | * Gets the application current logs 117 | */ 118 | async getLogs(): Promise { 119 | const data = await this.client.api.request(Routes.apps.logs(this.id)); 120 | const { logs } = data.response; 121 | 122 | this.client.emit("logsUpdate", this, this.cache.logs, logs); 123 | this.cache.set("logs", logs); 124 | 125 | return logs; 126 | } 127 | 128 | /** 129 | * Starts up the application 130 | * @returns `boolean` for success or fail 131 | */ 132 | async start(): Promise { 133 | const data = await this.client.api.request(Routes.apps.start(this.id), { 134 | method: "POST", 135 | }); 136 | 137 | return data?.status === "success"; 138 | } 139 | 140 | /** 141 | * Stops the application 142 | * @returns `boolean` for success or fail 143 | */ 144 | async stop(): Promise { 145 | const data = await this.client.api.request(Routes.apps.stop(this.id), { 146 | method: "POST", 147 | }); 148 | 149 | return data?.status === "success"; 150 | } 151 | 152 | /** 153 | * Restarts the application 154 | * @returns `boolean` for success or fail 155 | */ 156 | async restart(): Promise { 157 | const data = await this.client.api.request(Routes.apps.restart(this.id), { 158 | method: "POST", 159 | }); 160 | 161 | return data?.status === "success"; 162 | } 163 | 164 | /** 165 | * Deletes your whole application 166 | * - This action is irreversible. 167 | * 168 | * @returns `boolean` for success or fail 169 | */ 170 | async delete(): Promise { 171 | const data = await this.client.api.request(Routes.apps.delete(this.id), { 172 | method: "DELETE", 173 | }); 174 | 175 | return data?.status === "success"; 176 | } 177 | 178 | /** 179 | * Commit files to your application folder 180 | * 181 | * - This action is irreversible. 182 | * 183 | * - Tip: use this to get an absolute path. 184 | * ```ts 185 | * require('path').join(__dirname, 'fileName') 186 | * ``` 187 | * - Tip 2: use a zip file to commit more than one archive 188 | * 189 | * @param file - Buffer or absolute path to the file 190 | * @param fileName - The file name (e.g.: "index.js") 191 | * @param restart - Whether the application should be restarted after the commit 192 | * @returns `true` for success or `false` for fail 193 | */ 194 | async commit(file: string | Buffer, fileName?: string): Promise { 195 | assertPathLike(file, "COMMIT_FILE"); 196 | 197 | if (fileName) { 198 | assertString(fileName, "FILE_NAME"); 199 | } 200 | 201 | if (typeof file === "string") { 202 | file = await readFile(file); 203 | } 204 | 205 | const formData = new FormData(); 206 | const blob = new Blob([new Uint8Array(file)]); 207 | formData.append("file", blob, fileName || "commit.zip"); 208 | 209 | const data = await this.client.api.request(Routes.apps.commit(this.id), { 210 | method: "POST", 211 | body: formData, 212 | }); 213 | 214 | return data?.status === "success"; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/structures/collection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @internal 3 | */ 4 | export interface CollectionConstructor { 5 | new (): Collection; 6 | // biome-ignore lint/correctness/noUnusedVariables: They are being used 7 | new (entries?: readonly (readonly [K, V])[] | null): Collection; 8 | new (iterable: Iterable): Collection; 9 | readonly prototype: Collection; 10 | readonly [Symbol.species]: CollectionConstructor; 11 | } 12 | 13 | /** 14 | * Separate interface for the constructor so that emitted js does not have a constructor that overwrites itself 15 | * 16 | * @internal 17 | */ 18 | export interface Collection extends Map { 19 | constructor: CollectionConstructor; 20 | } 21 | 22 | /** 23 | * A Map with additional utility methods. This is used throughout \@squarecloud/api rather than Arrays for anything that has 24 | * an ID, for significantly improved performance and ease-of-use. 25 | * 26 | * @typeParam K - The key type this collection holds 27 | * @typeParam V - The value type this collection holds 28 | */ 29 | // biome-ignore lint/suspicious/noUnsafeDeclarationMerging: Needed to merge the constructor and the instance methods 30 | export class Collection extends Map { 31 | /** 32 | * Obtains the first value(s) in this collection. 33 | * 34 | * @param amount - Amount of values to obtain from the beginning 35 | * @returns A single value if no amount is provided or an array of values, starting from the end if amount is negative 36 | */ 37 | public first(): V | undefined; 38 | public first(amount: number): V[]; 39 | public first(amount?: number): V | V[] | undefined { 40 | if (typeof amount === "undefined") { 41 | return this.values().next().value; 42 | } 43 | 44 | if (amount < 0) { 45 | return this.last(amount * -1); 46 | } 47 | 48 | amount = Math.min(this.size, amount); 49 | return Array.from({ length: amount }, (): V => this.values().next().value); 50 | } 51 | 52 | /** 53 | * Obtains the last value(s) in this collection. 54 | * 55 | * @param amount - Amount of values to obtain from the end 56 | * @returns A single value if no amount is provided or an array of values, starting from the start if 57 | * amount is negative 58 | */ 59 | public last(): V | undefined; 60 | public last(amount: number): V[]; 61 | public last(amount?: number): V | V[] | undefined { 62 | const arr = [...this.values()]; 63 | if (typeof amount === "undefined") return arr[arr.length - 1]; 64 | if (amount < 0) return this.first(amount * -1); 65 | if (!amount) return []; 66 | return arr.slice(-amount); 67 | } 68 | 69 | /** 70 | * Identical to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse Array.reverse()} 71 | * but returns a Collection instead of an Array. 72 | */ 73 | public reverse() { 74 | const entries = [...this.entries()].reverse(); 75 | this.clear(); 76 | 77 | for (const [key, value] of entries) { 78 | this.set(key, value); 79 | } 80 | 81 | return this; 82 | } 83 | 84 | /** 85 | * Searches for a single item where the given function returns a truthy value. This behaves like 86 | * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find Array.find()}. 87 | * 88 | * @param fn - The function to test with (should return boolean) 89 | * @param thisArg - Value to use as `this` when executing function 90 | * @example 91 | * ```ts 92 | * collection.find(user => user.username === 'Bob'); 93 | * ``` 94 | */ 95 | public find( 96 | fn: (value: V, key: K, collection: this) => value is V2, 97 | ): V2 | undefined; 98 | 99 | public find( 100 | fn: (value: V, key: K, collection: this) => unknown, 101 | ): V | undefined; 102 | 103 | public find( 104 | fn: (this: This, value: V, key: K, collection: this) => value is V2, 105 | thisArg: This, 106 | ): V2 | undefined; 107 | 108 | public find( 109 | fn: (this: This, value: V, key: K, collection: this) => unknown, 110 | thisArg: This, 111 | ): V | undefined; 112 | 113 | public find( 114 | fn: (value: V, key: K, collection: this) => unknown, 115 | thisArg?: unknown, 116 | ): V | undefined { 117 | if (typeof fn !== "function") { 118 | throw new TypeError(`${fn} is not a function`); 119 | } 120 | 121 | if (typeof thisArg !== "undefined") { 122 | fn = fn.bind(thisArg); 123 | } 124 | 125 | for (const [key, val] of this) { 126 | if (fn(val, key, this)) return val; 127 | } 128 | } 129 | 130 | /** 131 | * Identical to 132 | * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter Array.filter()}, 133 | * but returns a Collection instead of an Array. 134 | * 135 | * @param fn - The function to test with (should return boolean) 136 | * @param thisArg - Value to use as `this` when executing function 137 | * @example 138 | * ```ts 139 | * collection.filter(user => user.username === 'Bob'); 140 | * ``` 141 | */ 142 | public filter( 143 | fn: (value: V, key: K, collection: this) => key is K2, 144 | ): Collection; 145 | 146 | public filter( 147 | fn: (value: V, key: K, collection: this) => value is V2, 148 | ): Collection; 149 | 150 | public filter( 151 | fn: (value: V, key: K, collection: this) => unknown, 152 | ): Collection; 153 | 154 | public filter( 155 | fn: (this: This, value: V, key: K, collection: this) => key is K2, 156 | thisArg: This, 157 | ): Collection; 158 | 159 | public filter( 160 | fn: (this: This, value: V, key: K, collection: this) => value is V2, 161 | thisArg: This, 162 | ): Collection; 163 | 164 | public filter( 165 | fn: (this: This, value: V, key: K, collection: this) => unknown, 166 | thisArg: This, 167 | ): Collection; 168 | 169 | public filter( 170 | fn: (value: V, key: K, collection: this) => unknown, 171 | thisArg?: unknown, 172 | ): Collection { 173 | if (typeof fn !== "function") { 174 | throw new TypeError(`${fn} is not a function`); 175 | } 176 | 177 | if (typeof thisArg !== "undefined") { 178 | fn = fn.bind(thisArg); 179 | } 180 | 181 | const results = new this.constructor[Symbol.species](); 182 | for (const [key, val] of this) { 183 | if (fn(val, key, this)) results.set(key, val); 184 | } 185 | 186 | return results; 187 | } 188 | 189 | /** 190 | * Maps each item to another value into an array. Identical in behavior to 191 | * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map Array.map()}. 192 | * 193 | * @param fn - Function that produces an element of the new array, taking three arguments 194 | * @param thisArg - Value to use as `this` when executing function 195 | * @example 196 | * ```ts 197 | * collection.map(user => user.name); 198 | * ``` 199 | */ 200 | public map(fn: (value: V, key: K, collection: this) => T): T[]; 201 | public map( 202 | fn: (this: This, value: V, key: K, collection: this) => T, 203 | thisArg: This, 204 | ): T[]; 205 | 206 | public map( 207 | fn: (value: V, key: K, collection: this) => T, 208 | thisArg?: unknown, 209 | ): T[] { 210 | if (typeof fn !== "function") { 211 | throw new TypeError(`${fn} is not a function`); 212 | } 213 | 214 | if (typeof thisArg !== "undefined") { 215 | fn = fn.bind(thisArg); 216 | } 217 | 218 | return Array.from({ length: this.size }, (): T => { 219 | const [key, value] = this.entries().next().value; 220 | return fn(value, key, this); 221 | }); 222 | } 223 | 224 | /** 225 | * Checks if there exists an item that passes a test. Identical in behavior to 226 | * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some Array.some()}. 227 | * 228 | * @param fn - Function used to test (should return a boolean) 229 | * @param thisArg - Value to use as `this` when executing function 230 | * @example 231 | * ```ts 232 | * collection.some(user => user.discriminator === '0000'); 233 | * ``` 234 | */ 235 | public some(fn: (value: V, key: K, collection: this) => unknown): boolean; 236 | public some( 237 | fn: (this: T, value: V, key: K, collection: this) => unknown, 238 | thisArg: T, 239 | ): boolean; 240 | 241 | public some( 242 | fn: (value: V, key: K, collection: this) => unknown, 243 | thisArg?: unknown, 244 | ): boolean { 245 | if (typeof fn !== "function") { 246 | throw new TypeError(`${fn} is not a function`); 247 | } 248 | 249 | if (typeof thisArg !== "undefined") { 250 | fn = fn.bind(thisArg); 251 | } 252 | 253 | for (const [key, val] of this) { 254 | if (fn(val, key, this)) return true; 255 | } 256 | 257 | return false; 258 | } 259 | 260 | /** 261 | * Checks if all items passes a test. Identical in behavior to 262 | * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every Array.every()}. 263 | * 264 | * @param fn - Function used to test (should return a boolean) 265 | * @param thisArg - Value to use as `this` when executing function 266 | * @example 267 | * ```ts 268 | * collection.every(user => !user.bot); 269 | * ``` 270 | */ 271 | public every( 272 | fn: (value: V, key: K, collection: this) => key is K2, 273 | ): this is Collection; 274 | 275 | public every( 276 | fn: (value: V, key: K, collection: this) => value is V2, 277 | ): this is Collection; 278 | 279 | public every(fn: (value: V, key: K, collection: this) => unknown): boolean; 280 | public every( 281 | fn: (this: This, value: V, key: K, collection: this) => key is K2, 282 | thisArg: This, 283 | ): this is Collection; 284 | 285 | public every( 286 | fn: (this: This, value: V, key: K, collection: this) => value is V2, 287 | thisArg: This, 288 | ): this is Collection; 289 | 290 | public every( 291 | fn: (this: This, value: V, key: K, collection: this) => unknown, 292 | thisArg: This, 293 | ): boolean; 294 | 295 | public every( 296 | fn: (value: V, key: K, collection: this) => unknown, 297 | thisArg?: unknown, 298 | ): boolean { 299 | if (typeof fn !== "function") { 300 | throw new TypeError(`${fn} is not a function`); 301 | } 302 | 303 | if (typeof thisArg !== "undefined") { 304 | fn = fn.bind(thisArg); 305 | } 306 | 307 | for (const [key, val] of this) { 308 | if (!fn(val, key, this)) return false; 309 | } 310 | 311 | return true; 312 | } 313 | 314 | /** 315 | * Applies a function to produce a single value. Identical in behavior to 316 | * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce Array.reduce()}. 317 | * 318 | * @param fn - Function used to reduce, taking four arguments; `accumulator`, `currentValue`, `currentKey`, 319 | * and `collection` 320 | * @param initialValue - Starting value for the accumulator 321 | * @example 322 | * ```ts 323 | * collection.reduce((acc, guild) => acc + guild.memberCount, 0); 324 | * ``` 325 | */ 326 | public reduce( 327 | fn: (accumulator: T, value: V, key: K, collection: this) => T, 328 | initialValue?: T, 329 | ): T { 330 | if (typeof fn !== "function") { 331 | throw new TypeError(`${fn} is not a function`); 332 | } 333 | let accumulator!: T; 334 | 335 | if (typeof initialValue !== "undefined") { 336 | accumulator = initialValue; 337 | for (const [key, val] of this) { 338 | accumulator = fn(accumulator, val, key, this); 339 | } 340 | return accumulator; 341 | } 342 | 343 | let first = true; 344 | for (const [key, val] of this) { 345 | if (first) { 346 | accumulator = val as unknown as T; 347 | first = false; 348 | continue; 349 | } 350 | 351 | accumulator = fn(accumulator, val, key, this); 352 | } 353 | 354 | if (first) { 355 | throw new TypeError("Reduce of empty collection with no initial value"); 356 | } 357 | 358 | return accumulator; 359 | } 360 | 361 | /** 362 | * Identical to 363 | * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach Map.forEach()}, 364 | * but returns the collection instead of undefined. 365 | * 366 | * @param fn - Function to execute for each element 367 | * @param thisArg - Value to use as `this` when executing function 368 | * @example 369 | * ```ts 370 | * collection 371 | * .each(user => console.log(user.username)) 372 | * .filter(user => user.bot) 373 | * .each(user => console.log(user.username)); 374 | * ``` 375 | */ 376 | public each(fn: (value: V, key: K, collection: this) => void): this; 377 | public each( 378 | fn: (this: T, value: V, key: K, collection: this) => void, 379 | thisArg: T, 380 | ): this; 381 | 382 | public each( 383 | fn: (value: V, key: K, collection: this) => void, 384 | thisArg?: unknown, 385 | ): this { 386 | if (typeof fn !== "function") { 387 | throw new TypeError(`${fn} is not a function`); 388 | } 389 | 390 | this.forEach(fn as (value: V, key: K, map: Map) => void, thisArg); 391 | return this; 392 | } 393 | 394 | /** 395 | * Creates an identical shallow copy of this collection. 396 | * 397 | * @example 398 | * ```ts 399 | * const newColl = someColl.clone(); 400 | * ``` 401 | */ 402 | public clone(): Collection { 403 | return new this.constructor[Symbol.species](this); 404 | } 405 | 406 | public toJSON() { 407 | return [...this.values()]; 408 | } 409 | } 410 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | devDependencies: 11 | '@biomejs/biome': 12 | specifier: ^2.3.8 13 | version: 2.3.8 14 | '@changesets/cli': 15 | specifier: ^2.29.8 16 | version: 2.29.8(@types/node@24.10.2) 17 | '@squarecloud/api-types': 18 | specifier: ^0.6.0 19 | version: 0.6.0 20 | '@types/node': 21 | specifier: ^24.10.2 22 | version: 24.10.2 23 | ts-node: 24 | specifier: ^10.9.2 25 | version: 10.9.2(@types/node@24.10.2)(typescript@5.9.3) 26 | ts-node-dev: 27 | specifier: ^2.0.0 28 | version: 2.0.0(@types/node@24.10.2)(typescript@5.9.3) 29 | tsc-alias: 30 | specifier: ^1.8.16 31 | version: 1.8.16 32 | tsdown: 33 | specifier: ^0.17.2 34 | version: 0.17.2(typescript@5.9.3) 35 | typescript: 36 | specifier: ^5.9.3 37 | version: 5.9.3 38 | 39 | packages: 40 | 41 | '@babel/generator@7.28.5': 42 | resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} 43 | engines: {node: '>=6.9.0'} 44 | 45 | '@babel/helper-string-parser@7.27.1': 46 | resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} 47 | engines: {node: '>=6.9.0'} 48 | 49 | '@babel/helper-validator-identifier@7.28.5': 50 | resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} 51 | engines: {node: '>=6.9.0'} 52 | 53 | '@babel/parser@7.28.5': 54 | resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} 55 | engines: {node: '>=6.0.0'} 56 | hasBin: true 57 | 58 | '@babel/runtime@7.28.4': 59 | resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} 60 | engines: {node: '>=6.9.0'} 61 | 62 | '@babel/types@7.28.5': 63 | resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} 64 | engines: {node: '>=6.9.0'} 65 | 66 | '@biomejs/biome@2.3.8': 67 | resolution: {integrity: sha512-Qjsgoe6FEBxWAUzwFGFrB+1+M8y/y5kwmg5CHac+GSVOdmOIqsAiXM5QMVGZJ1eCUCLlPZtq4aFAQ0eawEUuUA==} 68 | engines: {node: '>=14.21.3'} 69 | hasBin: true 70 | 71 | '@biomejs/cli-darwin-arm64@2.3.8': 72 | resolution: {integrity: sha512-HM4Zg9CGQ3txTPflxD19n8MFPrmUAjaC7PQdLkugeeC0cQ+PiVrd7i09gaBS/11QKsTDBJhVg85CEIK9f50Qww==} 73 | engines: {node: '>=14.21.3'} 74 | cpu: [arm64] 75 | os: [darwin] 76 | 77 | '@biomejs/cli-darwin-x64@2.3.8': 78 | resolution: {integrity: sha512-lUDQ03D7y/qEao7RgdjWVGCu+BLYadhKTm40HkpJIi6kn8LSv5PAwRlew/DmwP4YZ9ke9XXoTIQDO1vAnbRZlA==} 79 | engines: {node: '>=14.21.3'} 80 | cpu: [x64] 81 | os: [darwin] 82 | 83 | '@biomejs/cli-linux-arm64-musl@2.3.8': 84 | resolution: {integrity: sha512-PShR4mM0sjksUMyxbyPNMxoKFPVF48fU8Qe8Sfx6w6F42verbwRLbz+QiKNiDPRJwUoMG1nPM50OBL3aOnTevA==} 85 | engines: {node: '>=14.21.3'} 86 | cpu: [arm64] 87 | os: [linux] 88 | 89 | '@biomejs/cli-linux-arm64@2.3.8': 90 | resolution: {integrity: sha512-Uo1OJnIkJgSgF+USx970fsM/drtPcQ39I+JO+Fjsaa9ZdCN1oysQmy6oAGbyESlouz+rzEckLTF6DS7cWse95g==} 91 | engines: {node: '>=14.21.3'} 92 | cpu: [arm64] 93 | os: [linux] 94 | 95 | '@biomejs/cli-linux-x64-musl@2.3.8': 96 | resolution: {integrity: sha512-YGLkqU91r1276uwSjiUD/xaVikdxgV1QpsicT0bIA1TaieM6E5ibMZeSyjQ/izBn4tKQthUSsVZacmoJfa3pDA==} 97 | engines: {node: '>=14.21.3'} 98 | cpu: [x64] 99 | os: [linux] 100 | 101 | '@biomejs/cli-linux-x64@2.3.8': 102 | resolution: {integrity: sha512-QDPMD5bQz6qOVb3kiBui0zKZXASLo0NIQ9JVJio5RveBEFgDgsvJFUvZIbMbUZT3T00M/1wdzwWXk4GIh0KaAw==} 103 | engines: {node: '>=14.21.3'} 104 | cpu: [x64] 105 | os: [linux] 106 | 107 | '@biomejs/cli-win32-arm64@2.3.8': 108 | resolution: {integrity: sha512-H4IoCHvL1fXKDrTALeTKMiE7GGWFAraDwBYFquE/L/5r1927Te0mYIGseXi4F+lrrwhSWbSGt5qPFswNoBaCxg==} 109 | engines: {node: '>=14.21.3'} 110 | cpu: [arm64] 111 | os: [win32] 112 | 113 | '@biomejs/cli-win32-x64@2.3.8': 114 | resolution: {integrity: sha512-RguzimPoZWtBapfKhKjcWXBVI91tiSprqdBYu7tWhgN8pKRZhw24rFeNZTNf6UiBfjCYCi9eFQs/JzJZIhuK4w==} 115 | engines: {node: '>=14.21.3'} 116 | cpu: [x64] 117 | os: [win32] 118 | 119 | '@changesets/apply-release-plan@7.0.14': 120 | resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} 121 | 122 | '@changesets/assemble-release-plan@6.0.9': 123 | resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} 124 | 125 | '@changesets/changelog-git@0.2.1': 126 | resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} 127 | 128 | '@changesets/cli@2.29.8': 129 | resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==} 130 | hasBin: true 131 | 132 | '@changesets/config@3.1.2': 133 | resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==} 134 | 135 | '@changesets/errors@0.2.0': 136 | resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} 137 | 138 | '@changesets/get-dependents-graph@2.1.3': 139 | resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} 140 | 141 | '@changesets/get-release-plan@4.0.14': 142 | resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==} 143 | 144 | '@changesets/get-version-range-type@0.4.0': 145 | resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} 146 | 147 | '@changesets/git@3.0.4': 148 | resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} 149 | 150 | '@changesets/logger@0.1.1': 151 | resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} 152 | 153 | '@changesets/parse@0.4.2': 154 | resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==} 155 | 156 | '@changesets/pre@2.0.2': 157 | resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} 158 | 159 | '@changesets/read@0.6.6': 160 | resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==} 161 | 162 | '@changesets/should-skip-package@0.1.2': 163 | resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} 164 | 165 | '@changesets/types@4.1.0': 166 | resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} 167 | 168 | '@changesets/types@6.1.0': 169 | resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} 170 | 171 | '@changesets/write@0.4.0': 172 | resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} 173 | 174 | '@cspotcode/source-map-support@0.8.1': 175 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 176 | engines: {node: '>=12'} 177 | 178 | '@emnapi/core@1.7.1': 179 | resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} 180 | 181 | '@emnapi/runtime@1.7.1': 182 | resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} 183 | 184 | '@emnapi/wasi-threads@1.1.0': 185 | resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} 186 | 187 | '@inquirer/external-editor@1.0.3': 188 | resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} 189 | engines: {node: '>=18'} 190 | peerDependencies: 191 | '@types/node': '>=18' 192 | peerDependenciesMeta: 193 | '@types/node': 194 | optional: true 195 | 196 | '@jridgewell/gen-mapping@0.3.13': 197 | resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} 198 | 199 | '@jridgewell/resolve-uri@3.1.2': 200 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 201 | engines: {node: '>=6.0.0'} 202 | 203 | '@jridgewell/sourcemap-codec@1.5.0': 204 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 205 | 206 | '@jridgewell/sourcemap-codec@1.5.5': 207 | resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} 208 | 209 | '@jridgewell/trace-mapping@0.3.31': 210 | resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} 211 | 212 | '@jridgewell/trace-mapping@0.3.9': 213 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 214 | 215 | '@manypkg/find-root@1.1.0': 216 | resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} 217 | 218 | '@manypkg/get-packages@1.1.3': 219 | resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} 220 | 221 | '@napi-rs/wasm-runtime@1.1.0': 222 | resolution: {integrity: sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==} 223 | 224 | '@nodelib/fs.scandir@2.1.5': 225 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 226 | engines: {node: '>= 8'} 227 | 228 | '@nodelib/fs.stat@2.0.5': 229 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 230 | engines: {node: '>= 8'} 231 | 232 | '@nodelib/fs.walk@1.2.8': 233 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 234 | engines: {node: '>= 8'} 235 | 236 | '@oxc-project/types@0.101.0': 237 | resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==} 238 | 239 | '@quansync/fs@1.0.0': 240 | resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} 241 | 242 | '@rolldown/binding-android-arm64@1.0.0-beta.53': 243 | resolution: {integrity: sha512-Ok9V8o7o6YfSdTTYA/uHH30r3YtOxLD6G3wih/U9DO0ucBBFq8WPt/DslU53OgfteLRHITZny9N/qCUxMf9kjQ==} 244 | engines: {node: ^20.19.0 || >=22.12.0} 245 | cpu: [arm64] 246 | os: [android] 247 | 248 | '@rolldown/binding-darwin-arm64@1.0.0-beta.53': 249 | resolution: {integrity: sha512-yIsKqMz0CtRnVa6x3Pa+mzTihr4Ty+Z6HfPbZ7RVbk1Uxnco4+CUn7Qbm/5SBol1JD/7nvY8rphAgyAi7Lj6Vg==} 250 | engines: {node: ^20.19.0 || >=22.12.0} 251 | cpu: [arm64] 252 | os: [darwin] 253 | 254 | '@rolldown/binding-darwin-x64@1.0.0-beta.53': 255 | resolution: {integrity: sha512-GTXe+mxsCGUnJOFMhfGWmefP7Q9TpYUseHvhAhr21nCTgdS8jPsvirb0tJwM3lN0/u/cg7bpFNa16fQrjKrCjQ==} 256 | engines: {node: ^20.19.0 || >=22.12.0} 257 | cpu: [x64] 258 | os: [darwin] 259 | 260 | '@rolldown/binding-freebsd-x64@1.0.0-beta.53': 261 | resolution: {integrity: sha512-9Tmp7bBvKqyDkMcL4e089pH3RsjD3SUungjmqWtyhNOxoQMh0fSmINTyYV8KXtE+JkxYMPWvnEt+/mfpVCkk8w==} 262 | engines: {node: ^20.19.0 || >=22.12.0} 263 | cpu: [x64] 264 | os: [freebsd] 265 | 266 | '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': 267 | resolution: {integrity: sha512-a1y5fiB0iovuzdbjUxa7+Zcvgv+mTmlGGC4XydVIsyl48eoxgaYkA3l9079hyTyhECsPq+mbr0gVQsFU11OJAQ==} 268 | engines: {node: ^20.19.0 || >=22.12.0} 269 | cpu: [arm] 270 | os: [linux] 271 | 272 | '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': 273 | resolution: {integrity: sha512-bpIGX+ov9PhJYV+wHNXl9rzq4F0QvILiURn0y0oepbQx+7stmQsKA0DhPGwmhfvF856wq+gbM8L92SAa/CBcLg==} 274 | engines: {node: ^20.19.0 || >=22.12.0} 275 | cpu: [arm64] 276 | os: [linux] 277 | 278 | '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': 279 | resolution: {integrity: sha512-bGe5EBB8FVjHBR1mOLOPEFg1Lp3//7geqWkU5NIhxe+yH0W8FVrQ6WRYOap4SUTKdklD/dC4qPLREkMMQ855FA==} 280 | engines: {node: ^20.19.0 || >=22.12.0} 281 | cpu: [arm64] 282 | os: [linux] 283 | 284 | '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': 285 | resolution: {integrity: sha512-qL+63WKVQs1CMvFedlPt0U9PiEKJOAL/bsHMKUDS6Vp2Q+YAv/QLPu8rcvkfIMvQ0FPU2WL0aX4eWwF6e/GAnA==} 286 | engines: {node: ^20.19.0 || >=22.12.0} 287 | cpu: [x64] 288 | os: [linux] 289 | 290 | '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': 291 | resolution: {integrity: sha512-VGl9JIGjoJh3H8Mb+7xnVqODajBmrdOOb9lxWXdcmxyI+zjB2sux69br0hZJDTyLJfvBoYm439zPACYbCjGRmw==} 292 | engines: {node: ^20.19.0 || >=22.12.0} 293 | cpu: [x64] 294 | os: [linux] 295 | 296 | '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': 297 | resolution: {integrity: sha512-B4iIserJXuSnNzA5xBLFUIjTfhNy7d9sq4FUMQY3GhQWGVhS2RWWzzDnkSU6MUt7/aHUrep0CdQfXUJI9D3W7A==} 298 | engines: {node: ^20.19.0 || >=22.12.0} 299 | cpu: [arm64] 300 | os: [openharmony] 301 | 302 | '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': 303 | resolution: {integrity: sha512-BUjAEgpABEJXilGq/BPh7jeU3WAJ5o15c1ZEgHaDWSz3LB881LQZnbNJHmUiM4d1JQWMYYyR1Y490IBHi2FPJg==} 304 | engines: {node: '>=14.0.0'} 305 | cpu: [wasm32] 306 | 307 | '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': 308 | resolution: {integrity: sha512-s27uU7tpCWSjHBnxyVXHt3rMrQdJq5MHNv3BzsewCIroIw3DJFjMH1dzCPPMUFxnh1r52Nf9IJ/eWp6LDoyGcw==} 309 | engines: {node: ^20.19.0 || >=22.12.0} 310 | cpu: [arm64] 311 | os: [win32] 312 | 313 | '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': 314 | resolution: {integrity: sha512-cjWL/USPJ1g0en2htb4ssMjIycc36RvdQAx1WlXnS6DpULswiUTVXPDesTifSKYSyvx24E0YqQkEm0K/M2Z/AA==} 315 | engines: {node: ^20.19.0 || >=22.12.0} 316 | cpu: [x64] 317 | os: [win32] 318 | 319 | '@rolldown/pluginutils@1.0.0-beta.53': 320 | resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} 321 | 322 | '@squarecloud/api-types@0.6.0': 323 | resolution: {integrity: sha512-LTCi90LyLK1PPOpV1VQkPpFi/llpTZaRTWPvnlKbEeTX8mcX9O3t8jSHRYsePKRykvahdZIH+8P6kBqGSz8FEg==} 324 | 325 | '@tsconfig/node10@1.0.11': 326 | resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} 327 | 328 | '@tsconfig/node12@1.0.11': 329 | resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} 330 | 331 | '@tsconfig/node14@1.0.3': 332 | resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} 333 | 334 | '@tsconfig/node16@1.0.4': 335 | resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} 336 | 337 | '@tybys/wasm-util@0.10.1': 338 | resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} 339 | 340 | '@types/node@12.20.55': 341 | resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} 342 | 343 | '@types/node@24.10.2': 344 | resolution: {integrity: sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==} 345 | 346 | '@types/strip-bom@3.0.0': 347 | resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} 348 | 349 | '@types/strip-json-comments@0.0.30': 350 | resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} 351 | 352 | acorn-walk@8.3.4: 353 | resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} 354 | engines: {node: '>=0.4.0'} 355 | 356 | acorn@8.14.1: 357 | resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} 358 | engines: {node: '>=0.4.0'} 359 | hasBin: true 360 | 361 | ansi-colors@4.1.3: 362 | resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} 363 | engines: {node: '>=6'} 364 | 365 | ansi-regex@5.0.1: 366 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 367 | engines: {node: '>=8'} 368 | 369 | ansis@4.2.0: 370 | resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} 371 | engines: {node: '>=14'} 372 | 373 | anymatch@3.1.3: 374 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 375 | engines: {node: '>= 8'} 376 | 377 | arg@4.1.3: 378 | resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} 379 | 380 | argparse@1.0.10: 381 | resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} 382 | 383 | argparse@2.0.1: 384 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 385 | 386 | array-union@2.1.0: 387 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 388 | engines: {node: '>=8'} 389 | 390 | ast-kit@2.2.0: 391 | resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} 392 | engines: {node: '>=20.19.0'} 393 | 394 | balanced-match@1.0.2: 395 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 396 | 397 | better-path-resolve@1.0.0: 398 | resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} 399 | engines: {node: '>=4'} 400 | 401 | binary-extensions@2.3.0: 402 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} 403 | engines: {node: '>=8'} 404 | 405 | birpc@3.0.0: 406 | resolution: {integrity: sha512-by+04pHuxpCEQcucAXqzopqfhyI8TLK5Qg5MST0cB6MP+JhHna9ollrtK9moVh27aq6Q6MEJgebD0cVm//yBkg==} 407 | 408 | brace-expansion@1.1.11: 409 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 410 | 411 | braces@3.0.3: 412 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 413 | engines: {node: '>=8'} 414 | 415 | buffer-from@1.1.2: 416 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 417 | 418 | cac@6.7.14: 419 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 420 | engines: {node: '>=8'} 421 | 422 | chardet@2.1.1: 423 | resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} 424 | 425 | chokidar@3.6.0: 426 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 427 | engines: {node: '>= 8.10.0'} 428 | 429 | ci-info@3.9.0: 430 | resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} 431 | engines: {node: '>=8'} 432 | 433 | commander@9.5.0: 434 | resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} 435 | engines: {node: ^12.20.0 || >=14} 436 | 437 | concat-map@0.0.1: 438 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 439 | 440 | create-require@1.1.1: 441 | resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} 442 | 443 | cross-spawn@7.0.6: 444 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 445 | engines: {node: '>= 8'} 446 | 447 | detect-indent@6.1.0: 448 | resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} 449 | engines: {node: '>=8'} 450 | 451 | diff@4.0.2: 452 | resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} 453 | engines: {node: '>=0.3.1'} 454 | 455 | dir-glob@3.0.1: 456 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 457 | engines: {node: '>=8'} 458 | 459 | dts-resolver@2.1.3: 460 | resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} 461 | engines: {node: '>=20.19.0'} 462 | peerDependencies: 463 | oxc-resolver: '>=11.0.0' 464 | peerDependenciesMeta: 465 | oxc-resolver: 466 | optional: true 467 | 468 | dynamic-dedupe@0.3.0: 469 | resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} 470 | 471 | empathic@2.0.0: 472 | resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} 473 | engines: {node: '>=14'} 474 | 475 | enquirer@2.4.1: 476 | resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} 477 | engines: {node: '>=8.6'} 478 | 479 | esprima@4.0.1: 480 | resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} 481 | engines: {node: '>=4'} 482 | hasBin: true 483 | 484 | extendable-error@0.1.7: 485 | resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} 486 | 487 | fast-glob@3.3.3: 488 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 489 | engines: {node: '>=8.6.0'} 490 | 491 | fastq@1.19.1: 492 | resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} 493 | 494 | fdir@6.5.0: 495 | resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} 496 | engines: {node: '>=12.0.0'} 497 | peerDependencies: 498 | picomatch: ^3 || ^4 499 | peerDependenciesMeta: 500 | picomatch: 501 | optional: true 502 | 503 | fill-range@7.1.1: 504 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 505 | engines: {node: '>=8'} 506 | 507 | find-up@4.1.0: 508 | resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} 509 | engines: {node: '>=8'} 510 | 511 | fs-extra@7.0.1: 512 | resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} 513 | engines: {node: '>=6 <7 || >=8'} 514 | 515 | fs-extra@8.1.0: 516 | resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} 517 | engines: {node: '>=6 <7 || >=8'} 518 | 519 | fs.realpath@1.0.0: 520 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 521 | 522 | fsevents@2.3.3: 523 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 524 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 525 | os: [darwin] 526 | 527 | function-bind@1.1.2: 528 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 529 | 530 | get-tsconfig@4.10.0: 531 | resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} 532 | 533 | get-tsconfig@4.13.0: 534 | resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} 535 | 536 | glob-parent@5.1.2: 537 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 538 | engines: {node: '>= 6'} 539 | 540 | glob@7.2.3: 541 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 542 | deprecated: Glob versions prior to v9 are no longer supported 543 | 544 | globby@11.1.0: 545 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 546 | engines: {node: '>=10'} 547 | 548 | graceful-fs@4.2.11: 549 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 550 | 551 | hasown@2.0.2: 552 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 553 | engines: {node: '>= 0.4'} 554 | 555 | hookable@5.5.3: 556 | resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} 557 | 558 | human-id@4.1.3: 559 | resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} 560 | hasBin: true 561 | 562 | iconv-lite@0.7.0: 563 | resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} 564 | engines: {node: '>=0.10.0'} 565 | 566 | ignore@5.3.2: 567 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 568 | engines: {node: '>= 4'} 569 | 570 | import-without-cache@0.2.2: 571 | resolution: {integrity: sha512-4TTuRrZ0jBULXzac3EoX9ZviOs8Wn9iAbNhJEyLhTpAGF9eNmYSruaMMN/Tec/yqaO7H6yS2kALfQDJ5FxfatA==} 572 | engines: {node: '>=20.19.0'} 573 | 574 | inflight@1.0.6: 575 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 576 | deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. 577 | 578 | inherits@2.0.4: 579 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 580 | 581 | is-binary-path@2.1.0: 582 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 583 | engines: {node: '>=8'} 584 | 585 | is-core-module@2.16.1: 586 | resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} 587 | engines: {node: '>= 0.4'} 588 | 589 | is-extglob@2.1.1: 590 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 591 | engines: {node: '>=0.10.0'} 592 | 593 | is-glob@4.0.3: 594 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 595 | engines: {node: '>=0.10.0'} 596 | 597 | is-number@7.0.0: 598 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 599 | engines: {node: '>=0.12.0'} 600 | 601 | is-subdir@1.2.0: 602 | resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} 603 | engines: {node: '>=4'} 604 | 605 | is-windows@1.0.2: 606 | resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} 607 | engines: {node: '>=0.10.0'} 608 | 609 | isexe@2.0.0: 610 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 611 | 612 | js-yaml@3.14.2: 613 | resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} 614 | hasBin: true 615 | 616 | js-yaml@4.1.1: 617 | resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} 618 | hasBin: true 619 | 620 | jsesc@3.1.0: 621 | resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} 622 | engines: {node: '>=6'} 623 | hasBin: true 624 | 625 | jsonfile@4.0.0: 626 | resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 627 | 628 | locate-path@5.0.0: 629 | resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} 630 | engines: {node: '>=8'} 631 | 632 | lodash.startcase@4.4.0: 633 | resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} 634 | 635 | magic-string@0.30.21: 636 | resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} 637 | 638 | make-error@1.3.6: 639 | resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} 640 | 641 | merge2@1.4.1: 642 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 643 | engines: {node: '>= 8'} 644 | 645 | micromatch@4.0.8: 646 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 647 | engines: {node: '>=8.6'} 648 | 649 | minimatch@3.1.2: 650 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 651 | 652 | minimist@1.2.8: 653 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 654 | 655 | mkdirp@1.0.4: 656 | resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} 657 | engines: {node: '>=10'} 658 | hasBin: true 659 | 660 | mri@1.2.0: 661 | resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 662 | engines: {node: '>=4'} 663 | 664 | mylas@2.1.13: 665 | resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==} 666 | engines: {node: '>=12.0.0'} 667 | 668 | normalize-path@3.0.0: 669 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 670 | engines: {node: '>=0.10.0'} 671 | 672 | obug@2.1.1: 673 | resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} 674 | 675 | once@1.4.0: 676 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 677 | 678 | outdent@0.5.0: 679 | resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} 680 | 681 | p-filter@2.1.0: 682 | resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} 683 | engines: {node: '>=8'} 684 | 685 | p-limit@2.3.0: 686 | resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} 687 | engines: {node: '>=6'} 688 | 689 | p-locate@4.1.0: 690 | resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} 691 | engines: {node: '>=8'} 692 | 693 | p-map@2.1.0: 694 | resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} 695 | engines: {node: '>=6'} 696 | 697 | p-try@2.2.0: 698 | resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} 699 | engines: {node: '>=6'} 700 | 701 | package-manager-detector@0.2.11: 702 | resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} 703 | 704 | path-exists@4.0.0: 705 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 706 | engines: {node: '>=8'} 707 | 708 | path-is-absolute@1.0.1: 709 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 710 | engines: {node: '>=0.10.0'} 711 | 712 | path-key@3.1.1: 713 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 714 | engines: {node: '>=8'} 715 | 716 | path-parse@1.0.7: 717 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 718 | 719 | path-type@4.0.0: 720 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 721 | engines: {node: '>=8'} 722 | 723 | pathe@2.0.3: 724 | resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 725 | 726 | picocolors@1.1.1: 727 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 728 | 729 | picomatch@2.3.1: 730 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 731 | engines: {node: '>=8.6'} 732 | 733 | picomatch@4.0.3: 734 | resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} 735 | engines: {node: '>=12'} 736 | 737 | pify@4.0.1: 738 | resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} 739 | engines: {node: '>=6'} 740 | 741 | plimit-lit@1.6.1: 742 | resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} 743 | engines: {node: '>=12'} 744 | 745 | prettier@2.8.8: 746 | resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} 747 | engines: {node: '>=10.13.0'} 748 | hasBin: true 749 | 750 | quansync@0.2.11: 751 | resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} 752 | 753 | quansync@1.0.0: 754 | resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} 755 | 756 | queue-lit@1.5.2: 757 | resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==} 758 | engines: {node: '>=12'} 759 | 760 | queue-microtask@1.2.3: 761 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 762 | 763 | read-yaml-file@1.1.0: 764 | resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} 765 | engines: {node: '>=6'} 766 | 767 | readdirp@3.6.0: 768 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 769 | engines: {node: '>=8.10.0'} 770 | 771 | resolve-from@5.0.0: 772 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 773 | engines: {node: '>=8'} 774 | 775 | resolve-pkg-maps@1.0.0: 776 | resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 777 | 778 | resolve@1.22.10: 779 | resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} 780 | engines: {node: '>= 0.4'} 781 | hasBin: true 782 | 783 | reusify@1.1.0: 784 | resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} 785 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 786 | 787 | rimraf@2.7.1: 788 | resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} 789 | deprecated: Rimraf versions prior to v4 are no longer supported 790 | hasBin: true 791 | 792 | rolldown-plugin-dts@0.18.3: 793 | resolution: {integrity: sha512-rd1LZ0Awwfyn89UndUF/HoFF4oH9a5j+2ZeuKSJYM80vmeN/p0gslYMnHTQHBEXPhUlvAlqGA3tVgXB/1qFNDg==} 794 | engines: {node: '>=20.19.0'} 795 | peerDependencies: 796 | '@ts-macro/tsc': ^0.3.6 797 | '@typescript/native-preview': '>=7.0.0-dev.20250601.1' 798 | rolldown: ^1.0.0-beta.51 799 | typescript: ^5.0.0 800 | vue-tsc: ~3.1.0 801 | peerDependenciesMeta: 802 | '@ts-macro/tsc': 803 | optional: true 804 | '@typescript/native-preview': 805 | optional: true 806 | typescript: 807 | optional: true 808 | vue-tsc: 809 | optional: true 810 | 811 | rolldown@1.0.0-beta.53: 812 | resolution: {integrity: sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw==} 813 | engines: {node: ^20.19.0 || >=22.12.0} 814 | hasBin: true 815 | 816 | run-parallel@1.2.0: 817 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 818 | 819 | safer-buffer@2.1.2: 820 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 821 | 822 | semver@7.7.3: 823 | resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} 824 | engines: {node: '>=10'} 825 | hasBin: true 826 | 827 | shebang-command@2.0.0: 828 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 829 | engines: {node: '>=8'} 830 | 831 | shebang-regex@3.0.0: 832 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 833 | engines: {node: '>=8'} 834 | 835 | signal-exit@4.1.0: 836 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 837 | engines: {node: '>=14'} 838 | 839 | slash@3.0.0: 840 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 841 | engines: {node: '>=8'} 842 | 843 | source-map-support@0.5.21: 844 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 845 | 846 | source-map@0.6.1: 847 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 848 | engines: {node: '>=0.10.0'} 849 | 850 | spawndamnit@3.0.1: 851 | resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} 852 | 853 | sprintf-js@1.0.3: 854 | resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 855 | 856 | strip-ansi@6.0.1: 857 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 858 | engines: {node: '>=8'} 859 | 860 | strip-bom@3.0.0: 861 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 862 | engines: {node: '>=4'} 863 | 864 | strip-json-comments@2.0.1: 865 | resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} 866 | engines: {node: '>=0.10.0'} 867 | 868 | supports-preserve-symlinks-flag@1.0.0: 869 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 870 | engines: {node: '>= 0.4'} 871 | 872 | term-size@2.2.1: 873 | resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} 874 | engines: {node: '>=8'} 875 | 876 | tinyexec@1.0.2: 877 | resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} 878 | engines: {node: '>=18'} 879 | 880 | tinyglobby@0.2.15: 881 | resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 882 | engines: {node: '>=12.0.0'} 883 | 884 | to-regex-range@5.0.1: 885 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 886 | engines: {node: '>=8.0'} 887 | 888 | tree-kill@1.2.2: 889 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 890 | hasBin: true 891 | 892 | ts-node-dev@2.0.0: 893 | resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} 894 | engines: {node: '>=0.8.0'} 895 | hasBin: true 896 | peerDependencies: 897 | node-notifier: '*' 898 | typescript: '*' 899 | peerDependenciesMeta: 900 | node-notifier: 901 | optional: true 902 | 903 | ts-node@10.9.2: 904 | resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} 905 | hasBin: true 906 | peerDependencies: 907 | '@swc/core': '>=1.2.50' 908 | '@swc/wasm': '>=1.2.50' 909 | '@types/node': '*' 910 | typescript: '>=2.7' 911 | peerDependenciesMeta: 912 | '@swc/core': 913 | optional: true 914 | '@swc/wasm': 915 | optional: true 916 | 917 | tsc-alias@1.8.16: 918 | resolution: {integrity: sha512-QjCyu55NFyRSBAl6+MTFwplpFcnm2Pq01rR/uxfqJoLMm6X3O14KEGtaSDZpJYaE1bJBGDjD0eSuiIWPe2T58g==} 919 | engines: {node: '>=16.20.2'} 920 | hasBin: true 921 | 922 | tsconfig@7.0.0: 923 | resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} 924 | 925 | tsdown@0.17.2: 926 | resolution: {integrity: sha512-SuU+0CWm/95KfXqojHTVuwcouIsdn7HpYcwDyOdKktJi285NxKwysjFUaxYLxpCNqqPvcFvokXLO4dZThRwzkw==} 927 | engines: {node: '>=20.19.0'} 928 | hasBin: true 929 | peerDependencies: 930 | '@arethetypeswrong/core': ^0.18.1 931 | '@vitejs/devtools': ^0.0.0-alpha.19 932 | publint: ^0.3.0 933 | typescript: ^5.0.0 934 | unplugin-lightningcss: ^0.4.0 935 | unplugin-unused: ^0.5.0 936 | peerDependenciesMeta: 937 | '@arethetypeswrong/core': 938 | optional: true 939 | '@vitejs/devtools': 940 | optional: true 941 | publint: 942 | optional: true 943 | typescript: 944 | optional: true 945 | unplugin-lightningcss: 946 | optional: true 947 | unplugin-unused: 948 | optional: true 949 | 950 | tslib@2.8.1: 951 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 952 | 953 | typescript@5.9.3: 954 | resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} 955 | engines: {node: '>=14.17'} 956 | hasBin: true 957 | 958 | unconfig-core@7.4.2: 959 | resolution: {integrity: sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==} 960 | 961 | undici-types@7.16.0: 962 | resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} 963 | 964 | universalify@0.1.2: 965 | resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 966 | engines: {node: '>= 4.0.0'} 967 | 968 | unrun@0.2.19: 969 | resolution: {integrity: sha512-DbwbJ9BvPEb3BeZnIpP9S5tGLO/JIgPQ3JrpMRFIfZMZfMG19f26OlLbC2ml8RRdrI2ZA7z2t+at5tsIHbh6Qw==} 970 | engines: {node: '>=20.19.0'} 971 | hasBin: true 972 | peerDependencies: 973 | synckit: ^0.11.11 974 | peerDependenciesMeta: 975 | synckit: 976 | optional: true 977 | 978 | v8-compile-cache-lib@3.0.1: 979 | resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} 980 | 981 | which@2.0.2: 982 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 983 | engines: {node: '>= 8'} 984 | hasBin: true 985 | 986 | wrappy@1.0.2: 987 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 988 | 989 | xtend@4.0.2: 990 | resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 991 | engines: {node: '>=0.4'} 992 | 993 | yn@3.1.1: 994 | resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} 995 | engines: {node: '>=6'} 996 | 997 | snapshots: 998 | 999 | '@babel/generator@7.28.5': 1000 | dependencies: 1001 | '@babel/parser': 7.28.5 1002 | '@babel/types': 7.28.5 1003 | '@jridgewell/gen-mapping': 0.3.13 1004 | '@jridgewell/trace-mapping': 0.3.31 1005 | jsesc: 3.1.0 1006 | 1007 | '@babel/helper-string-parser@7.27.1': {} 1008 | 1009 | '@babel/helper-validator-identifier@7.28.5': {} 1010 | 1011 | '@babel/parser@7.28.5': 1012 | dependencies: 1013 | '@babel/types': 7.28.5 1014 | 1015 | '@babel/runtime@7.28.4': {} 1016 | 1017 | '@babel/types@7.28.5': 1018 | dependencies: 1019 | '@babel/helper-string-parser': 7.27.1 1020 | '@babel/helper-validator-identifier': 7.28.5 1021 | 1022 | '@biomejs/biome@2.3.8': 1023 | optionalDependencies: 1024 | '@biomejs/cli-darwin-arm64': 2.3.8 1025 | '@biomejs/cli-darwin-x64': 2.3.8 1026 | '@biomejs/cli-linux-arm64': 2.3.8 1027 | '@biomejs/cli-linux-arm64-musl': 2.3.8 1028 | '@biomejs/cli-linux-x64': 2.3.8 1029 | '@biomejs/cli-linux-x64-musl': 2.3.8 1030 | '@biomejs/cli-win32-arm64': 2.3.8 1031 | '@biomejs/cli-win32-x64': 2.3.8 1032 | 1033 | '@biomejs/cli-darwin-arm64@2.3.8': 1034 | optional: true 1035 | 1036 | '@biomejs/cli-darwin-x64@2.3.8': 1037 | optional: true 1038 | 1039 | '@biomejs/cli-linux-arm64-musl@2.3.8': 1040 | optional: true 1041 | 1042 | '@biomejs/cli-linux-arm64@2.3.8': 1043 | optional: true 1044 | 1045 | '@biomejs/cli-linux-x64-musl@2.3.8': 1046 | optional: true 1047 | 1048 | '@biomejs/cli-linux-x64@2.3.8': 1049 | optional: true 1050 | 1051 | '@biomejs/cli-win32-arm64@2.3.8': 1052 | optional: true 1053 | 1054 | '@biomejs/cli-win32-x64@2.3.8': 1055 | optional: true 1056 | 1057 | '@changesets/apply-release-plan@7.0.14': 1058 | dependencies: 1059 | '@changesets/config': 3.1.2 1060 | '@changesets/get-version-range-type': 0.4.0 1061 | '@changesets/git': 3.0.4 1062 | '@changesets/should-skip-package': 0.1.2 1063 | '@changesets/types': 6.1.0 1064 | '@manypkg/get-packages': 1.1.3 1065 | detect-indent: 6.1.0 1066 | fs-extra: 7.0.1 1067 | lodash.startcase: 4.4.0 1068 | outdent: 0.5.0 1069 | prettier: 2.8.8 1070 | resolve-from: 5.0.0 1071 | semver: 7.7.3 1072 | 1073 | '@changesets/assemble-release-plan@6.0.9': 1074 | dependencies: 1075 | '@changesets/errors': 0.2.0 1076 | '@changesets/get-dependents-graph': 2.1.3 1077 | '@changesets/should-skip-package': 0.1.2 1078 | '@changesets/types': 6.1.0 1079 | '@manypkg/get-packages': 1.1.3 1080 | semver: 7.7.3 1081 | 1082 | '@changesets/changelog-git@0.2.1': 1083 | dependencies: 1084 | '@changesets/types': 6.1.0 1085 | 1086 | '@changesets/cli@2.29.8(@types/node@24.10.2)': 1087 | dependencies: 1088 | '@changesets/apply-release-plan': 7.0.14 1089 | '@changesets/assemble-release-plan': 6.0.9 1090 | '@changesets/changelog-git': 0.2.1 1091 | '@changesets/config': 3.1.2 1092 | '@changesets/errors': 0.2.0 1093 | '@changesets/get-dependents-graph': 2.1.3 1094 | '@changesets/get-release-plan': 4.0.14 1095 | '@changesets/git': 3.0.4 1096 | '@changesets/logger': 0.1.1 1097 | '@changesets/pre': 2.0.2 1098 | '@changesets/read': 0.6.6 1099 | '@changesets/should-skip-package': 0.1.2 1100 | '@changesets/types': 6.1.0 1101 | '@changesets/write': 0.4.0 1102 | '@inquirer/external-editor': 1.0.3(@types/node@24.10.2) 1103 | '@manypkg/get-packages': 1.1.3 1104 | ansi-colors: 4.1.3 1105 | ci-info: 3.9.0 1106 | enquirer: 2.4.1 1107 | fs-extra: 7.0.1 1108 | mri: 1.2.0 1109 | p-limit: 2.3.0 1110 | package-manager-detector: 0.2.11 1111 | picocolors: 1.1.1 1112 | resolve-from: 5.0.0 1113 | semver: 7.7.3 1114 | spawndamnit: 3.0.1 1115 | term-size: 2.2.1 1116 | transitivePeerDependencies: 1117 | - '@types/node' 1118 | 1119 | '@changesets/config@3.1.2': 1120 | dependencies: 1121 | '@changesets/errors': 0.2.0 1122 | '@changesets/get-dependents-graph': 2.1.3 1123 | '@changesets/logger': 0.1.1 1124 | '@changesets/types': 6.1.0 1125 | '@manypkg/get-packages': 1.1.3 1126 | fs-extra: 7.0.1 1127 | micromatch: 4.0.8 1128 | 1129 | '@changesets/errors@0.2.0': 1130 | dependencies: 1131 | extendable-error: 0.1.7 1132 | 1133 | '@changesets/get-dependents-graph@2.1.3': 1134 | dependencies: 1135 | '@changesets/types': 6.1.0 1136 | '@manypkg/get-packages': 1.1.3 1137 | picocolors: 1.1.1 1138 | semver: 7.7.3 1139 | 1140 | '@changesets/get-release-plan@4.0.14': 1141 | dependencies: 1142 | '@changesets/assemble-release-plan': 6.0.9 1143 | '@changesets/config': 3.1.2 1144 | '@changesets/pre': 2.0.2 1145 | '@changesets/read': 0.6.6 1146 | '@changesets/types': 6.1.0 1147 | '@manypkg/get-packages': 1.1.3 1148 | 1149 | '@changesets/get-version-range-type@0.4.0': {} 1150 | 1151 | '@changesets/git@3.0.4': 1152 | dependencies: 1153 | '@changesets/errors': 0.2.0 1154 | '@manypkg/get-packages': 1.1.3 1155 | is-subdir: 1.2.0 1156 | micromatch: 4.0.8 1157 | spawndamnit: 3.0.1 1158 | 1159 | '@changesets/logger@0.1.1': 1160 | dependencies: 1161 | picocolors: 1.1.1 1162 | 1163 | '@changesets/parse@0.4.2': 1164 | dependencies: 1165 | '@changesets/types': 6.1.0 1166 | js-yaml: 4.1.1 1167 | 1168 | '@changesets/pre@2.0.2': 1169 | dependencies: 1170 | '@changesets/errors': 0.2.0 1171 | '@changesets/types': 6.1.0 1172 | '@manypkg/get-packages': 1.1.3 1173 | fs-extra: 7.0.1 1174 | 1175 | '@changesets/read@0.6.6': 1176 | dependencies: 1177 | '@changesets/git': 3.0.4 1178 | '@changesets/logger': 0.1.1 1179 | '@changesets/parse': 0.4.2 1180 | '@changesets/types': 6.1.0 1181 | fs-extra: 7.0.1 1182 | p-filter: 2.1.0 1183 | picocolors: 1.1.1 1184 | 1185 | '@changesets/should-skip-package@0.1.2': 1186 | dependencies: 1187 | '@changesets/types': 6.1.0 1188 | '@manypkg/get-packages': 1.1.3 1189 | 1190 | '@changesets/types@4.1.0': {} 1191 | 1192 | '@changesets/types@6.1.0': {} 1193 | 1194 | '@changesets/write@0.4.0': 1195 | dependencies: 1196 | '@changesets/types': 6.1.0 1197 | fs-extra: 7.0.1 1198 | human-id: 4.1.3 1199 | prettier: 2.8.8 1200 | 1201 | '@cspotcode/source-map-support@0.8.1': 1202 | dependencies: 1203 | '@jridgewell/trace-mapping': 0.3.9 1204 | 1205 | '@emnapi/core@1.7.1': 1206 | dependencies: 1207 | '@emnapi/wasi-threads': 1.1.0 1208 | tslib: 2.8.1 1209 | optional: true 1210 | 1211 | '@emnapi/runtime@1.7.1': 1212 | dependencies: 1213 | tslib: 2.8.1 1214 | optional: true 1215 | 1216 | '@emnapi/wasi-threads@1.1.0': 1217 | dependencies: 1218 | tslib: 2.8.1 1219 | optional: true 1220 | 1221 | '@inquirer/external-editor@1.0.3(@types/node@24.10.2)': 1222 | dependencies: 1223 | chardet: 2.1.1 1224 | iconv-lite: 0.7.0 1225 | optionalDependencies: 1226 | '@types/node': 24.10.2 1227 | 1228 | '@jridgewell/gen-mapping@0.3.13': 1229 | dependencies: 1230 | '@jridgewell/sourcemap-codec': 1.5.0 1231 | '@jridgewell/trace-mapping': 0.3.31 1232 | 1233 | '@jridgewell/resolve-uri@3.1.2': {} 1234 | 1235 | '@jridgewell/sourcemap-codec@1.5.0': {} 1236 | 1237 | '@jridgewell/sourcemap-codec@1.5.5': {} 1238 | 1239 | '@jridgewell/trace-mapping@0.3.31': 1240 | dependencies: 1241 | '@jridgewell/resolve-uri': 3.1.2 1242 | '@jridgewell/sourcemap-codec': 1.5.0 1243 | 1244 | '@jridgewell/trace-mapping@0.3.9': 1245 | dependencies: 1246 | '@jridgewell/resolve-uri': 3.1.2 1247 | '@jridgewell/sourcemap-codec': 1.5.0 1248 | 1249 | '@manypkg/find-root@1.1.0': 1250 | dependencies: 1251 | '@babel/runtime': 7.28.4 1252 | '@types/node': 12.20.55 1253 | find-up: 4.1.0 1254 | fs-extra: 8.1.0 1255 | 1256 | '@manypkg/get-packages@1.1.3': 1257 | dependencies: 1258 | '@babel/runtime': 7.28.4 1259 | '@changesets/types': 4.1.0 1260 | '@manypkg/find-root': 1.1.0 1261 | fs-extra: 8.1.0 1262 | globby: 11.1.0 1263 | read-yaml-file: 1.1.0 1264 | 1265 | '@napi-rs/wasm-runtime@1.1.0': 1266 | dependencies: 1267 | '@emnapi/core': 1.7.1 1268 | '@emnapi/runtime': 1.7.1 1269 | '@tybys/wasm-util': 0.10.1 1270 | optional: true 1271 | 1272 | '@nodelib/fs.scandir@2.1.5': 1273 | dependencies: 1274 | '@nodelib/fs.stat': 2.0.5 1275 | run-parallel: 1.2.0 1276 | 1277 | '@nodelib/fs.stat@2.0.5': {} 1278 | 1279 | '@nodelib/fs.walk@1.2.8': 1280 | dependencies: 1281 | '@nodelib/fs.scandir': 2.1.5 1282 | fastq: 1.19.1 1283 | 1284 | '@oxc-project/types@0.101.0': {} 1285 | 1286 | '@quansync/fs@1.0.0': 1287 | dependencies: 1288 | quansync: 1.0.0 1289 | 1290 | '@rolldown/binding-android-arm64@1.0.0-beta.53': 1291 | optional: true 1292 | 1293 | '@rolldown/binding-darwin-arm64@1.0.0-beta.53': 1294 | optional: true 1295 | 1296 | '@rolldown/binding-darwin-x64@1.0.0-beta.53': 1297 | optional: true 1298 | 1299 | '@rolldown/binding-freebsd-x64@1.0.0-beta.53': 1300 | optional: true 1301 | 1302 | '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': 1303 | optional: true 1304 | 1305 | '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': 1306 | optional: true 1307 | 1308 | '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': 1309 | optional: true 1310 | 1311 | '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': 1312 | optional: true 1313 | 1314 | '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': 1315 | optional: true 1316 | 1317 | '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': 1318 | optional: true 1319 | 1320 | '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': 1321 | dependencies: 1322 | '@napi-rs/wasm-runtime': 1.1.0 1323 | optional: true 1324 | 1325 | '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': 1326 | optional: true 1327 | 1328 | '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': 1329 | optional: true 1330 | 1331 | '@rolldown/pluginutils@1.0.0-beta.53': {} 1332 | 1333 | '@squarecloud/api-types@0.6.0': {} 1334 | 1335 | '@tsconfig/node10@1.0.11': {} 1336 | 1337 | '@tsconfig/node12@1.0.11': {} 1338 | 1339 | '@tsconfig/node14@1.0.3': {} 1340 | 1341 | '@tsconfig/node16@1.0.4': {} 1342 | 1343 | '@tybys/wasm-util@0.10.1': 1344 | dependencies: 1345 | tslib: 2.8.1 1346 | optional: true 1347 | 1348 | '@types/node@12.20.55': {} 1349 | 1350 | '@types/node@24.10.2': 1351 | dependencies: 1352 | undici-types: 7.16.0 1353 | 1354 | '@types/strip-bom@3.0.0': {} 1355 | 1356 | '@types/strip-json-comments@0.0.30': {} 1357 | 1358 | acorn-walk@8.3.4: 1359 | dependencies: 1360 | acorn: 8.14.1 1361 | 1362 | acorn@8.14.1: {} 1363 | 1364 | ansi-colors@4.1.3: {} 1365 | 1366 | ansi-regex@5.0.1: {} 1367 | 1368 | ansis@4.2.0: {} 1369 | 1370 | anymatch@3.1.3: 1371 | dependencies: 1372 | normalize-path: 3.0.0 1373 | picomatch: 2.3.1 1374 | 1375 | arg@4.1.3: {} 1376 | 1377 | argparse@1.0.10: 1378 | dependencies: 1379 | sprintf-js: 1.0.3 1380 | 1381 | argparse@2.0.1: {} 1382 | 1383 | array-union@2.1.0: {} 1384 | 1385 | ast-kit@2.2.0: 1386 | dependencies: 1387 | '@babel/parser': 7.28.5 1388 | pathe: 2.0.3 1389 | 1390 | balanced-match@1.0.2: {} 1391 | 1392 | better-path-resolve@1.0.0: 1393 | dependencies: 1394 | is-windows: 1.0.2 1395 | 1396 | binary-extensions@2.3.0: {} 1397 | 1398 | birpc@3.0.0: {} 1399 | 1400 | brace-expansion@1.1.11: 1401 | dependencies: 1402 | balanced-match: 1.0.2 1403 | concat-map: 0.0.1 1404 | 1405 | braces@3.0.3: 1406 | dependencies: 1407 | fill-range: 7.1.1 1408 | 1409 | buffer-from@1.1.2: {} 1410 | 1411 | cac@6.7.14: {} 1412 | 1413 | chardet@2.1.1: {} 1414 | 1415 | chokidar@3.6.0: 1416 | dependencies: 1417 | anymatch: 3.1.3 1418 | braces: 3.0.3 1419 | glob-parent: 5.1.2 1420 | is-binary-path: 2.1.0 1421 | is-glob: 4.0.3 1422 | normalize-path: 3.0.0 1423 | readdirp: 3.6.0 1424 | optionalDependencies: 1425 | fsevents: 2.3.3 1426 | 1427 | ci-info@3.9.0: {} 1428 | 1429 | commander@9.5.0: {} 1430 | 1431 | concat-map@0.0.1: {} 1432 | 1433 | create-require@1.1.1: {} 1434 | 1435 | cross-spawn@7.0.6: 1436 | dependencies: 1437 | path-key: 3.1.1 1438 | shebang-command: 2.0.0 1439 | which: 2.0.2 1440 | 1441 | detect-indent@6.1.0: {} 1442 | 1443 | diff@4.0.2: {} 1444 | 1445 | dir-glob@3.0.1: 1446 | dependencies: 1447 | path-type: 4.0.0 1448 | 1449 | dts-resolver@2.1.3: {} 1450 | 1451 | dynamic-dedupe@0.3.0: 1452 | dependencies: 1453 | xtend: 4.0.2 1454 | 1455 | empathic@2.0.0: {} 1456 | 1457 | enquirer@2.4.1: 1458 | dependencies: 1459 | ansi-colors: 4.1.3 1460 | strip-ansi: 6.0.1 1461 | 1462 | esprima@4.0.1: {} 1463 | 1464 | extendable-error@0.1.7: {} 1465 | 1466 | fast-glob@3.3.3: 1467 | dependencies: 1468 | '@nodelib/fs.stat': 2.0.5 1469 | '@nodelib/fs.walk': 1.2.8 1470 | glob-parent: 5.1.2 1471 | merge2: 1.4.1 1472 | micromatch: 4.0.8 1473 | 1474 | fastq@1.19.1: 1475 | dependencies: 1476 | reusify: 1.1.0 1477 | 1478 | fdir@6.5.0(picomatch@4.0.3): 1479 | optionalDependencies: 1480 | picomatch: 4.0.3 1481 | 1482 | fill-range@7.1.1: 1483 | dependencies: 1484 | to-regex-range: 5.0.1 1485 | 1486 | find-up@4.1.0: 1487 | dependencies: 1488 | locate-path: 5.0.0 1489 | path-exists: 4.0.0 1490 | 1491 | fs-extra@7.0.1: 1492 | dependencies: 1493 | graceful-fs: 4.2.11 1494 | jsonfile: 4.0.0 1495 | universalify: 0.1.2 1496 | 1497 | fs-extra@8.1.0: 1498 | dependencies: 1499 | graceful-fs: 4.2.11 1500 | jsonfile: 4.0.0 1501 | universalify: 0.1.2 1502 | 1503 | fs.realpath@1.0.0: {} 1504 | 1505 | fsevents@2.3.3: 1506 | optional: true 1507 | 1508 | function-bind@1.1.2: {} 1509 | 1510 | get-tsconfig@4.10.0: 1511 | dependencies: 1512 | resolve-pkg-maps: 1.0.0 1513 | 1514 | get-tsconfig@4.13.0: 1515 | dependencies: 1516 | resolve-pkg-maps: 1.0.0 1517 | 1518 | glob-parent@5.1.2: 1519 | dependencies: 1520 | is-glob: 4.0.3 1521 | 1522 | glob@7.2.3: 1523 | dependencies: 1524 | fs.realpath: 1.0.0 1525 | inflight: 1.0.6 1526 | inherits: 2.0.4 1527 | minimatch: 3.1.2 1528 | once: 1.4.0 1529 | path-is-absolute: 1.0.1 1530 | 1531 | globby@11.1.0: 1532 | dependencies: 1533 | array-union: 2.1.0 1534 | dir-glob: 3.0.1 1535 | fast-glob: 3.3.3 1536 | ignore: 5.3.2 1537 | merge2: 1.4.1 1538 | slash: 3.0.0 1539 | 1540 | graceful-fs@4.2.11: {} 1541 | 1542 | hasown@2.0.2: 1543 | dependencies: 1544 | function-bind: 1.1.2 1545 | 1546 | hookable@5.5.3: {} 1547 | 1548 | human-id@4.1.3: {} 1549 | 1550 | iconv-lite@0.7.0: 1551 | dependencies: 1552 | safer-buffer: 2.1.2 1553 | 1554 | ignore@5.3.2: {} 1555 | 1556 | import-without-cache@0.2.2: {} 1557 | 1558 | inflight@1.0.6: 1559 | dependencies: 1560 | once: 1.4.0 1561 | wrappy: 1.0.2 1562 | 1563 | inherits@2.0.4: {} 1564 | 1565 | is-binary-path@2.1.0: 1566 | dependencies: 1567 | binary-extensions: 2.3.0 1568 | 1569 | is-core-module@2.16.1: 1570 | dependencies: 1571 | hasown: 2.0.2 1572 | 1573 | is-extglob@2.1.1: {} 1574 | 1575 | is-glob@4.0.3: 1576 | dependencies: 1577 | is-extglob: 2.1.1 1578 | 1579 | is-number@7.0.0: {} 1580 | 1581 | is-subdir@1.2.0: 1582 | dependencies: 1583 | better-path-resolve: 1.0.0 1584 | 1585 | is-windows@1.0.2: {} 1586 | 1587 | isexe@2.0.0: {} 1588 | 1589 | js-yaml@3.14.2: 1590 | dependencies: 1591 | argparse: 1.0.10 1592 | esprima: 4.0.1 1593 | 1594 | js-yaml@4.1.1: 1595 | dependencies: 1596 | argparse: 2.0.1 1597 | 1598 | jsesc@3.1.0: {} 1599 | 1600 | jsonfile@4.0.0: 1601 | optionalDependencies: 1602 | graceful-fs: 4.2.11 1603 | 1604 | locate-path@5.0.0: 1605 | dependencies: 1606 | p-locate: 4.1.0 1607 | 1608 | lodash.startcase@4.4.0: {} 1609 | 1610 | magic-string@0.30.21: 1611 | dependencies: 1612 | '@jridgewell/sourcemap-codec': 1.5.5 1613 | 1614 | make-error@1.3.6: {} 1615 | 1616 | merge2@1.4.1: {} 1617 | 1618 | micromatch@4.0.8: 1619 | dependencies: 1620 | braces: 3.0.3 1621 | picomatch: 2.3.1 1622 | 1623 | minimatch@3.1.2: 1624 | dependencies: 1625 | brace-expansion: 1.1.11 1626 | 1627 | minimist@1.2.8: {} 1628 | 1629 | mkdirp@1.0.4: {} 1630 | 1631 | mri@1.2.0: {} 1632 | 1633 | mylas@2.1.13: {} 1634 | 1635 | normalize-path@3.0.0: {} 1636 | 1637 | obug@2.1.1: {} 1638 | 1639 | once@1.4.0: 1640 | dependencies: 1641 | wrappy: 1.0.2 1642 | 1643 | outdent@0.5.0: {} 1644 | 1645 | p-filter@2.1.0: 1646 | dependencies: 1647 | p-map: 2.1.0 1648 | 1649 | p-limit@2.3.0: 1650 | dependencies: 1651 | p-try: 2.2.0 1652 | 1653 | p-locate@4.1.0: 1654 | dependencies: 1655 | p-limit: 2.3.0 1656 | 1657 | p-map@2.1.0: {} 1658 | 1659 | p-try@2.2.0: {} 1660 | 1661 | package-manager-detector@0.2.11: 1662 | dependencies: 1663 | quansync: 0.2.11 1664 | 1665 | path-exists@4.0.0: {} 1666 | 1667 | path-is-absolute@1.0.1: {} 1668 | 1669 | path-key@3.1.1: {} 1670 | 1671 | path-parse@1.0.7: {} 1672 | 1673 | path-type@4.0.0: {} 1674 | 1675 | pathe@2.0.3: {} 1676 | 1677 | picocolors@1.1.1: {} 1678 | 1679 | picomatch@2.3.1: {} 1680 | 1681 | picomatch@4.0.3: {} 1682 | 1683 | pify@4.0.1: {} 1684 | 1685 | plimit-lit@1.6.1: 1686 | dependencies: 1687 | queue-lit: 1.5.2 1688 | 1689 | prettier@2.8.8: {} 1690 | 1691 | quansync@0.2.11: {} 1692 | 1693 | quansync@1.0.0: {} 1694 | 1695 | queue-lit@1.5.2: {} 1696 | 1697 | queue-microtask@1.2.3: {} 1698 | 1699 | read-yaml-file@1.1.0: 1700 | dependencies: 1701 | graceful-fs: 4.2.11 1702 | js-yaml: 3.14.2 1703 | pify: 4.0.1 1704 | strip-bom: 3.0.0 1705 | 1706 | readdirp@3.6.0: 1707 | dependencies: 1708 | picomatch: 2.3.1 1709 | 1710 | resolve-from@5.0.0: {} 1711 | 1712 | resolve-pkg-maps@1.0.0: {} 1713 | 1714 | resolve@1.22.10: 1715 | dependencies: 1716 | is-core-module: 2.16.1 1717 | path-parse: 1.0.7 1718 | supports-preserve-symlinks-flag: 1.0.0 1719 | 1720 | reusify@1.1.0: {} 1721 | 1722 | rimraf@2.7.1: 1723 | dependencies: 1724 | glob: 7.2.3 1725 | 1726 | rolldown-plugin-dts@0.18.3(rolldown@1.0.0-beta.53)(typescript@5.9.3): 1727 | dependencies: 1728 | '@babel/generator': 7.28.5 1729 | '@babel/parser': 7.28.5 1730 | '@babel/types': 7.28.5 1731 | ast-kit: 2.2.0 1732 | birpc: 3.0.0 1733 | dts-resolver: 2.1.3 1734 | get-tsconfig: 4.13.0 1735 | magic-string: 0.30.21 1736 | obug: 2.1.1 1737 | rolldown: 1.0.0-beta.53 1738 | optionalDependencies: 1739 | typescript: 5.9.3 1740 | transitivePeerDependencies: 1741 | - oxc-resolver 1742 | 1743 | rolldown@1.0.0-beta.53: 1744 | dependencies: 1745 | '@oxc-project/types': 0.101.0 1746 | '@rolldown/pluginutils': 1.0.0-beta.53 1747 | optionalDependencies: 1748 | '@rolldown/binding-android-arm64': 1.0.0-beta.53 1749 | '@rolldown/binding-darwin-arm64': 1.0.0-beta.53 1750 | '@rolldown/binding-darwin-x64': 1.0.0-beta.53 1751 | '@rolldown/binding-freebsd-x64': 1.0.0-beta.53 1752 | '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.53 1753 | '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.53 1754 | '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.53 1755 | '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.53 1756 | '@rolldown/binding-linux-x64-musl': 1.0.0-beta.53 1757 | '@rolldown/binding-openharmony-arm64': 1.0.0-beta.53 1758 | '@rolldown/binding-wasm32-wasi': 1.0.0-beta.53 1759 | '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.53 1760 | '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.53 1761 | 1762 | run-parallel@1.2.0: 1763 | dependencies: 1764 | queue-microtask: 1.2.3 1765 | 1766 | safer-buffer@2.1.2: {} 1767 | 1768 | semver@7.7.3: {} 1769 | 1770 | shebang-command@2.0.0: 1771 | dependencies: 1772 | shebang-regex: 3.0.0 1773 | 1774 | shebang-regex@3.0.0: {} 1775 | 1776 | signal-exit@4.1.0: {} 1777 | 1778 | slash@3.0.0: {} 1779 | 1780 | source-map-support@0.5.21: 1781 | dependencies: 1782 | buffer-from: 1.1.2 1783 | source-map: 0.6.1 1784 | 1785 | source-map@0.6.1: {} 1786 | 1787 | spawndamnit@3.0.1: 1788 | dependencies: 1789 | cross-spawn: 7.0.6 1790 | signal-exit: 4.1.0 1791 | 1792 | sprintf-js@1.0.3: {} 1793 | 1794 | strip-ansi@6.0.1: 1795 | dependencies: 1796 | ansi-regex: 5.0.1 1797 | 1798 | strip-bom@3.0.0: {} 1799 | 1800 | strip-json-comments@2.0.1: {} 1801 | 1802 | supports-preserve-symlinks-flag@1.0.0: {} 1803 | 1804 | term-size@2.2.1: {} 1805 | 1806 | tinyexec@1.0.2: {} 1807 | 1808 | tinyglobby@0.2.15: 1809 | dependencies: 1810 | fdir: 6.5.0(picomatch@4.0.3) 1811 | picomatch: 4.0.3 1812 | 1813 | to-regex-range@5.0.1: 1814 | dependencies: 1815 | is-number: 7.0.0 1816 | 1817 | tree-kill@1.2.2: {} 1818 | 1819 | ts-node-dev@2.0.0(@types/node@24.10.2)(typescript@5.9.3): 1820 | dependencies: 1821 | chokidar: 3.6.0 1822 | dynamic-dedupe: 0.3.0 1823 | minimist: 1.2.8 1824 | mkdirp: 1.0.4 1825 | resolve: 1.22.10 1826 | rimraf: 2.7.1 1827 | source-map-support: 0.5.21 1828 | tree-kill: 1.2.2 1829 | ts-node: 10.9.2(@types/node@24.10.2)(typescript@5.9.3) 1830 | tsconfig: 7.0.0 1831 | typescript: 5.9.3 1832 | transitivePeerDependencies: 1833 | - '@swc/core' 1834 | - '@swc/wasm' 1835 | - '@types/node' 1836 | 1837 | ts-node@10.9.2(@types/node@24.10.2)(typescript@5.9.3): 1838 | dependencies: 1839 | '@cspotcode/source-map-support': 0.8.1 1840 | '@tsconfig/node10': 1.0.11 1841 | '@tsconfig/node12': 1.0.11 1842 | '@tsconfig/node14': 1.0.3 1843 | '@tsconfig/node16': 1.0.4 1844 | '@types/node': 24.10.2 1845 | acorn: 8.14.1 1846 | acorn-walk: 8.3.4 1847 | arg: 4.1.3 1848 | create-require: 1.1.1 1849 | diff: 4.0.2 1850 | make-error: 1.3.6 1851 | typescript: 5.9.3 1852 | v8-compile-cache-lib: 3.0.1 1853 | yn: 3.1.1 1854 | 1855 | tsc-alias@1.8.16: 1856 | dependencies: 1857 | chokidar: 3.6.0 1858 | commander: 9.5.0 1859 | get-tsconfig: 4.10.0 1860 | globby: 11.1.0 1861 | mylas: 2.1.13 1862 | normalize-path: 3.0.0 1863 | plimit-lit: 1.6.1 1864 | 1865 | tsconfig@7.0.0: 1866 | dependencies: 1867 | '@types/strip-bom': 3.0.0 1868 | '@types/strip-json-comments': 0.0.30 1869 | strip-bom: 3.0.0 1870 | strip-json-comments: 2.0.1 1871 | 1872 | tsdown@0.17.2(typescript@5.9.3): 1873 | dependencies: 1874 | ansis: 4.2.0 1875 | cac: 6.7.14 1876 | empathic: 2.0.0 1877 | hookable: 5.5.3 1878 | import-without-cache: 0.2.2 1879 | obug: 2.1.1 1880 | rolldown: 1.0.0-beta.53 1881 | rolldown-plugin-dts: 0.18.3(rolldown@1.0.0-beta.53)(typescript@5.9.3) 1882 | semver: 7.7.3 1883 | tinyexec: 1.0.2 1884 | tinyglobby: 0.2.15 1885 | tree-kill: 1.2.2 1886 | unconfig-core: 7.4.2 1887 | unrun: 0.2.19 1888 | optionalDependencies: 1889 | typescript: 5.9.3 1890 | transitivePeerDependencies: 1891 | - '@ts-macro/tsc' 1892 | - '@typescript/native-preview' 1893 | - oxc-resolver 1894 | - synckit 1895 | - vue-tsc 1896 | 1897 | tslib@2.8.1: 1898 | optional: true 1899 | 1900 | typescript@5.9.3: {} 1901 | 1902 | unconfig-core@7.4.2: 1903 | dependencies: 1904 | '@quansync/fs': 1.0.0 1905 | quansync: 1.0.0 1906 | 1907 | undici-types@7.16.0: {} 1908 | 1909 | universalify@0.1.2: {} 1910 | 1911 | unrun@0.2.19: 1912 | dependencies: 1913 | rolldown: 1.0.0-beta.53 1914 | 1915 | v8-compile-cache-lib@3.0.1: {} 1916 | 1917 | which@2.0.2: 1918 | dependencies: 1919 | isexe: 2.0.0 1920 | 1921 | wrappy@1.0.2: {} 1922 | 1923 | xtend@4.0.2: {} 1924 | 1925 | yn@3.1.1: {} 1926 | --------------------------------------------------------------------------------