UNPKG

@squarecloud/api

Version:
1 lines 62.3 kB
{"version":3,"sources":["../../src/modules/index.ts","../../src/modules/applications.ts","../../src/structures/application/base.ts","../../src/lib/routes.ts","../../src/services/cache/base.ts","../../src/services/cache/application.ts","../../src/structures/application/application.ts","../../src/structures/backup.ts","../../src/structures/collection.ts","../../src/structures/deploy.ts","../../src/structures/error.ts","../../src/structures/status.ts","../../src/structures/user.ts","../../src/assertions/common.ts","../../src/assertions/literal.ts","../../src/modules/backups.ts","../../src/modules/deploys.ts","../../src/modules/files.ts","../../src/modules/network.ts","../../src/modules/user.ts"],"sourcesContent":["export * from \"./applications\";\nexport * from \"./backups\";\nexport * from \"./deploys\";\nexport * from \"./files\";\nexport * from \"./network\";\nexport * from \"./user\";\n","import type { RESTPostAPIApplicationUploadResult } from \"@squarecloud/api-types/v2\";\nimport { readFile } from \"fs/promises\";\n\nimport { assertPathLike, assertString } from \"@/assertions/literal\";\nimport { Routes } from \"@/lib/routes\";\nimport {\n\tApplication,\n\ttype BaseApplication,\n\ttype Collection,\n\tSimpleApplicationStatus,\n\tSquareCloudAPIError,\n\tUser,\n} from \"@/structures\";\nimport type { SquareCloudAPI } from \"..\";\n\nexport class ApplicationsModule {\n\tconstructor(public readonly client: SquareCloudAPI) {}\n\n\t/**\n\t * If the ID is provided, it will return an application that you can manage or get information\n\t * If the ID is not provided, it will return a collection of applications\n\t *\n\t * @param applicationId - The application ID, you must own the application\n\t */\n\tasync get(): Promise<Collection<string, BaseApplication>>;\n\tasync get(applicationId: string): Promise<BaseApplication>;\n\tasync get(\n\t\tapplicationId?: string,\n\t): Promise<BaseApplication | Collection<string, BaseApplication>> {\n\t\tconst { response } = await this.client.api.request(Routes.user());\n\t\tconst user = new User(this.client, response);\n\n\t\tthis.client.emit(\"userUpdate\", this.client.cache.user, user);\n\t\tthis.client.cache.set(\"user\", user);\n\n\t\tif (applicationId) {\n\t\t\tassertString(applicationId, \"APP_ID\");\n\t\t\tconst application = user.applications.get(applicationId);\n\n\t\t\tif (!application) {\n\t\t\t\tthrow new SquareCloudAPIError(\"APP_NOT_FOUND\");\n\t\t\t}\n\n\t\t\treturn application;\n\t\t}\n\n\t\treturn user.applications;\n\t}\n\n\t/**\n\t * Uploads an application\n\t *\n\t * @param file - The zip file path or Buffer\n\t *\n\t * @returns The uploaded application data\n\t */\n\tasync create(\n\t\tfile: string | Buffer,\n\t): Promise<RESTPostAPIApplicationUploadResult> {\n\t\tassertPathLike(file, \"UPLOAD_FILE\");\n\n\t\tif (typeof file === \"string\") {\n\t\t\tfile = await readFile(file);\n\t\t}\n\n\t\tconst formData = new FormData();\n\t\tconst blob = new Blob([file]);\n\t\tformData.append(\"file\", blob, \"app.zip\");\n\n\t\tconst data = await this.client.api.request(Routes.apps.upload(), {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: formData,\n\t\t});\n\n\t\treturn data.response;\n\t}\n\n\t/**\n\t * Gets the summary status for all your applications\n\t */\n\tasync statusAll(): Promise<SimpleApplicationStatus[]> {\n\t\tconst data = await this.client.api.request(Routes.apps.statusAll());\n\n\t\treturn data.response.map(\n\t\t\t(status) => new SimpleApplicationStatus(this.client, status),\n\t\t);\n\t}\n\n\t/**\n\t * Returns an application that you can manage or get information\n\t *\n\t * @param applicationId - The application ID, you must own the application\n\t */\n\tasync fetch(applicationId: string): Promise<Application> {\n\t\tconst { response } = await this.client.api.request(\n\t\t\tRoutes.apps.info(applicationId),\n\t\t);\n\n\t\treturn new Application(this.client, response);\n\t}\n}\n\nexport * from \"../services/cache/application\";\nexport * from \"./backups\";\nexport * from \"./deploys\";\nexport * from \"./files\";\nexport * from \"./network\";\n","import type {\n\tAPIUserApplication,\n\tApplicationLanguage,\n} from \"@squarecloud/api-types/v2\";\nimport { readFile } from \"fs/promises\";\n\nimport { assertPathLike, assertString } from \"@/assertions/literal\";\nimport type { SquareCloudAPI } from \"@/index\";\nimport { Routes } from \"@/lib/routes\";\nimport { BackupsModule, DeploysModule, FilesModule } from \"@/modules\";\nimport { ApplicationCacheService } from \"@/services\";\nimport { ApplicationStatus } from \"@/structures\";\nimport type { Application } from \"./application\";\n\n/**\n * Represents the base application from the user endpoint\n */\nexport class BaseApplication {\n\t/** The application ID */\n\tpublic readonly id: string;\n\t/** The application display name */\n\tpublic name: string;\n\t/** The application description */\n\tpublic description?: string;\n\t/** The url to manage the application via web */\n\tpublic url: string;\n\t/** The application total ram */\n\tpublic ram: number;\n\t/** The application current cluster */\n\tpublic cluster: string;\n\t/**\n\t * The application programming language\n\t *\n\t * - `javascript`\n\t * - `typescript`\n\t * - `python`\n\t * - `java`\n\t * - `elixir`\n\t * - `rust`\n\t * - `go`\n\t * - `php`\n\t * - `dotnet`\n\t * - `static`\n\t */\n\tpublic language: ApplicationLanguage;\n\n\t/** Cache service for this application */\n\tpublic readonly cache = new ApplicationCacheService();\n\t/** Files module for this application */\n\tpublic readonly files = new FilesModule(this);\n\t/** Backup module for this application */\n\tpublic readonly backups = new BackupsModule(this);\n\t/** Deploys module for this application */\n\tpublic readonly deploys = new DeploysModule(this);\n\n\t/**\n\t * Represents the base application from the user endpoint\n\t *\n\t * @constructor\n\t * @param client - The client for this application\n\t * @param data - The data from this application\n\t */\n\tconstructor(\n\t\tpublic readonly client: SquareCloudAPI,\n\t\tdata: APIUserApplication,\n\t) {\n\t\tconst { id, name, desc, ram, lang, cluster } = data;\n\n\t\tthis.id = id;\n\t\tthis.name = name;\n\t\tthis.description = desc;\n\t\tthis.ram = ram;\n\t\tthis.language = lang;\n\t\tthis.cluster = cluster;\n\t\tthis.url = `https://squarecloud.app/dashboard/app/${id}`;\n\t}\n\n\t/** @deprecated Use `Application#backups` instead */\n\tget backup() {\n\t\tconsole.warn(\n\t\t\t\"[SquareCloudAPI] The 'backup' property is deprecated and will be removed in the the next major version. Use Application#backups instead.\",\n\t\t);\n\t\treturn this.backups;\n\t}\n\n\t/**\n\t * Fetches this application for full information\n\t */\n\tasync fetch(): Promise<Application> {\n\t\treturn this.client.applications.fetch(this.id);\n\t}\n\n\t/**\n\t * Gets the application current status information\n\t */\n\tasync getStatus(): Promise<ApplicationStatus> {\n\t\tconst data = await this.client.api.request(Routes.apps.status(this.id));\n\t\tconst status = new ApplicationStatus(this.client, data.response, this.id);\n\n\t\tthis.client.emit(\"statusUpdate\", this, this.cache.status, status);\n\t\tthis.cache.set(\"status\", status);\n\n\t\treturn status;\n\t}\n\n\t/**\n\t * Gets the application current logs\n\t */\n\tasync getLogs(): Promise<string> {\n\t\tconst data = await this.client.api.request(Routes.apps.logs(this.id));\n\t\tconst { logs } = data.response;\n\n\t\tthis.client.emit(\"logsUpdate\", this, this.cache.logs, logs);\n\t\tthis.cache.set(\"logs\", logs);\n\n\t\treturn logs;\n\t}\n\n\t/**\n\t * Starts up the application\n\t * @returns `boolean` for success or fail\n\t */\n\tasync start(): Promise<boolean> {\n\t\tconst data = await this.client.api.request(Routes.apps.start(this.id), {\n\t\t\tmethod: \"POST\",\n\t\t});\n\n\t\treturn data?.status === \"success\";\n\t}\n\n\t/**\n\t * Stops the application\n\t * @returns `boolean` for success or fail\n\t */\n\tasync stop(): Promise<boolean> {\n\t\tconst data = await this.client.api.request(Routes.apps.stop(this.id), {\n\t\t\tmethod: \"POST\",\n\t\t});\n\n\t\treturn data?.status === \"success\";\n\t}\n\n\t/**\n\t * Restarts the application\n\t * @returns `boolean` for success or fail\n\t */\n\tasync restart(): Promise<boolean> {\n\t\tconst data = await this.client.api.request(Routes.apps.restart(this.id), {\n\t\t\tmethod: \"POST\",\n\t\t});\n\n\t\treturn data?.status === \"success\";\n\t}\n\n\t/**\n\t * Deletes your whole application\n\t * - This action is irreversible.\n\t *\n\t * @returns `boolean` for success or fail\n\t */\n\tasync delete(): Promise<boolean> {\n\t\tconst data = await this.client.api.request(Routes.apps.delete(this.id), {\n\t\t\tmethod: \"DELETE\",\n\t\t});\n\n\t\treturn data?.status === \"success\";\n\t}\n\n\t/**\n\t * Commit files to your application folder\n\t *\n\t * - This action is irreversible.\n\t *\n\t * - Tip: use this to get an absolute path.\n\t * ```ts\n\t * require('path').join(__dirname, 'fileName')\n\t * ```\n\t * - Tip 2: use a zip file to commit more than one archive\n\t *\n\t * @param file - Buffer or absolute path to the file\n\t * @param fileName - The file name (e.g.: \"index.js\")\n\t * @param restart - Whether the application should be restarted after the commit\n\t * @returns `true` for success or `false` for fail\n\t */\n\tasync commit(file: string | Buffer, fileName?: string): Promise<boolean> {\n\t\tassertPathLike(file, \"COMMIT_FILE\");\n\n\t\tif (fileName) {\n\t\t\tassertString(fileName, \"FILE_NAME\");\n\t\t}\n\n\t\tif (typeof file === \"string\") {\n\t\t\tfile = await readFile(file);\n\t\t}\n\n\t\tconst formData = new FormData();\n\t\tconst blob = new Blob([file]);\n\t\tformData.append(\"file\", blob, fileName || \"commit.zip\");\n\n\t\tconst data = await this.client.api.request(Routes.apps.commit(this.id), {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: formData,\n\t\t});\n\n\t\treturn data?.status === \"success\";\n\t}\n}\n","import type { APIEndpoint } from \"@/types\";\n\nexport type Route<T extends APIEndpoint> = string & { __route: T };\nexport const Route = <T extends APIEndpoint>(route: string) =>\n\troute as Route<T>;\n\ninterface IRoutes {\n\t[k: string]: ((...args: string[]) => Route<APIEndpoint>) | IRoutes;\n}\n\nexport const Routes = {\n\tuser: () => {\n\t\treturn Route<\"user\">(\"users/me\");\n\t},\n\tservice: {\n\t\tstatus: () => {\n\t\t\treturn Route<\"service/status\">(\"service/status\");\n\t\t},\n\t},\n\tapps: {\n\t\tupload: () => {\n\t\t\treturn Route<\"apps/upload\">(\"apps\");\n\t\t},\n\t\tstatusAll: () => {\n\t\t\treturn Route<\"apps/status-all\">(\"apps/status\");\n\t\t},\n\t\tinfo: (appId: string) => {\n\t\t\treturn Route<\"apps/info\">(`apps/${appId}`);\n\t\t},\n\t\tstatus: (appId: string) => {\n\t\t\treturn Route<\"apps/status\">(`apps/${appId}/status`);\n\t\t},\n\t\tlogs: (appId: string) => {\n\t\t\treturn Route<\"apps/logs\">(`apps/${appId}/logs`);\n\t\t},\n\t\tdelete: (appId: string) => {\n\t\t\treturn Route<\"apps/delete\">(`apps/${appId}`);\n\t\t},\n\t\tcommit: (appId: string) => {\n\t\t\treturn Route<\"apps/commit\">(`apps/${appId}/commit`);\n\t\t},\n\t\tsnapshots: (appId: string) => {\n\t\t\treturn Route<\"apps/snapshots\">(`apps/${appId}/snapshots`);\n\t\t},\n\t\tgenerateSnapshot: (appId: string) => {\n\t\t\treturn Route<\"apps/generate-snapshot\">(`apps/${appId}/snapshots`);\n\t\t},\n\t\tstart: (appId: string) => {\n\t\t\treturn Route<\"apps/start\">(`apps/${appId}/start`);\n\t\t},\n\t\trestart: (appId: string) => {\n\t\t\treturn Route<\"apps/restart\">(`apps/${appId}/restart`);\n\t\t},\n\t\tstop: (appId: string) => {\n\t\t\treturn Route<\"apps/stop\">(`apps/${appId}/stop`);\n\t\t},\n\t\tfiles: {\n\t\t\tread: (appId: string) => {\n\t\t\t\treturn Route<\"apps/files/read\">(`apps/${appId}/files/content`);\n\t\t\t},\n\t\t\tlist: (appId: string) => {\n\t\t\t\treturn Route<\"apps/files/list\">(`apps/${appId}/files`);\n\t\t\t},\n\t\t\tupsert: (appId: string) => {\n\t\t\t\treturn Route<\"apps/files/upsert\">(`apps/${appId}/files`);\n\t\t\t},\n\t\t\tmove: (appId: string) => {\n\t\t\t\treturn Route<\"apps/files/move\">(`apps/${appId}/files`);\n\t\t\t},\n\t\t\tdelete: (appId: string) => {\n\t\t\t\treturn Route<\"apps/files/delete\">(`apps/${appId}/files`);\n\t\t\t},\n\t\t},\n\t\tdeployments: {\n\t\t\tlist: (appId: string) => {\n\t\t\t\treturn Route<\"apps/deployments/list\">(`apps/${appId}/deployments`);\n\t\t\t},\n\t\t\tcurrent: (appId: string) => {\n\t\t\t\treturn Route<\"apps/deployments/current\">(\n\t\t\t\t\t`apps/${appId}/deployments/current`,\n\t\t\t\t);\n\t\t\t},\n\t\t\twebhook: (appId: string) => {\n\t\t\t\treturn Route<\"apps/deployments/webhook\">(\n\t\t\t\t\t`apps/${appId}/deploy/webhook`,\n\t\t\t\t);\n\t\t\t},\n\t\t},\n\t\tnetwork: {\n\t\t\tdns: (appId: string) => {\n\t\t\t\treturn Route<\"apps/network/dns\">(`apps/${appId}/network/dns`);\n\t\t\t},\n\t\t\tcustom: (appId: string) => {\n\t\t\t\treturn Route<\"apps/network/custom\">(`apps/${appId}/network/custom`);\n\t\t\t},\n\t\t\tanalytics: (appId: string) => {\n\t\t\t\treturn Route<\"apps/network/analytics\">(\n\t\t\t\t\t`apps/${appId}/network/analytics`,\n\t\t\t\t);\n\t\t\t},\n\t\t},\n\t},\n} satisfies IRoutes;\n","export abstract class BaseCacheService<\n\tStruct extends object,\n\tKeys extends keyof Struct = keyof Struct,\n> {\n\tprotected cache: Struct;\n\n\tset<T extends Keys>(key: T, value: Struct[T]) {\n\t\tReflect.set(this.cache, key, value);\n\t}\n\n\tget<T extends Keys>(key: T): Struct[T] {\n\t\treturn this.cache[key];\n\t}\n\n\tremove<T extends Keys>(key: T) {\n\t\tReflect.set(this.cache, key, undefined);\n\t}\n}\n","import type { ApplicationStatus } from \"@/structures\";\nimport type { Backup } from \"@/structures/backup\";\nimport { BaseCacheService } from \"./base\";\n\nexport interface ApplicationCache {\n\treadonly status?: ApplicationStatus;\n\treadonly backups?: Backup[];\n\treadonly logs?: string;\n}\n\nexport class ApplicationCacheService extends BaseCacheService<ApplicationCache> {\n\tprotected cache: ApplicationCache = {\n\t\tstatus: undefined,\n\t\tbackups: undefined,\n\t\tlogs: undefined,\n\t};\n\n\tget status() {\n\t\treturn this.cache.status;\n\t}\n\n\tget backups() {\n\t\treturn this.cache.backups;\n\t}\n\n\tget logs() {\n\t\treturn this.cache.logs;\n\t}\n}\n","import type { APIApplication } from \"@squarecloud/api-types/v2\";\n\nimport type { SquareCloudAPI } from \"@/index\";\nimport { BaseApplication } from \"./base\";\nimport type { WebsiteApplication } from \"./website\";\n\n/**\n * Represents a Square Cloud application\n */\nexport class Application extends BaseApplication {\n\t/**\n\t * Represents a Square Cloud application\n\t *\n\t * @constructor\n\t * @param client - The client for this application\n\t * @param data - The data from this application\n\t */\n\tconstructor(\n\t\tpublic readonly client: SquareCloudAPI,\n\t\tdata: APIApplication,\n\t) {\n\t\tsuper(client, { ...data, lang: data.language });\n\t}\n\n\tisWebsite(): this is WebsiteApplication {\n\t\tconst domain = Reflect.get(this, \"domain\");\n\t\treturn Boolean(domain);\n\t}\n}\n","import type { APIApplicationBackup } from \"@squarecloud/api-types/v2\";\n\nimport type { BaseApplication } from \"./application/base\";\n\n/**\n * Represents an application backup (snapshot)\n */\nexport class Backup {\n\t/** Size of the backup in bytes. */\n\tpublic size: number;\n\n\t/** Date of the last modification of the backup. */\n\tpublic modifiedAt: Date;\n\n\t/** Date of the last modification of the backup in millisseconds. */\n\tpublic modifiedTimestamp: number;\n\n\t/** AWS access key for the backup. */\n\tpublic readonly key: string;\n\n\t/** The URL for downloading this backup */\n\tpublic readonly url: string;\n\n\t/**\n\t * Represents an application backup (snapshot)\n\t *\n\t * @constructor\n\t * @param application - The application from which you fetched the backups\n\t * @param data - The data from this backup\n\t */\n\tconstructor(\n\t\tpublic readonly application: BaseApplication,\n\t\tdata: APIApplicationBackup,\n\t) {\n\t\tconst { name, size, modified, key } = data;\n\t\tconst { userId } = application.client.api;\n\n\t\tthis.size = size;\n\t\tthis.modifiedAt = new Date(modified);\n\t\tthis.modifiedTimestamp = this.modifiedAt.getTime();\n\t\tthis.key = key;\n\t\tthis.url = `https://snapshots.squarecloud.app/applications/${userId}/${name}.zip?${key}`;\n\t}\n\n\t/**\n\t * Downloads this backup\n\t * @returns The downloaded backup bufer\n\t */\n\tasync download(): Promise<Buffer> {\n\t\tconst res = await fetch(this.url)\n\t\t\t.then((res) => res.arrayBuffer())\n\t\t\t.catch(() => undefined);\n\n\t\tif (!res) {\n\t\t\tthrow new Error(\"BACKUP_DOWNLOAD_FAILED\");\n\t\t}\n\n\t\treturn Buffer.from(res);\n\t}\n}\n","/**\n * @internal\n */\nexport interface CollectionConstructor {\n\tnew (): Collection<unknown, unknown>;\n\tnew <K, V>(entries?: readonly (readonly [K, V])[] | null): Collection<K, V>;\n\tnew <K, V>(iterable: Iterable<readonly [K, V]>): Collection<K, V>;\n\treadonly prototype: Collection<unknown, unknown>;\n\treadonly [Symbol.species]: CollectionConstructor;\n}\n\n/**\n * Separate interface for the constructor so that emitted js does not have a constructor that overwrites itself\n *\n * @internal\n */\nexport interface Collection<K, V> extends Map<K, V> {\n\tconstructor: CollectionConstructor;\n}\n\n/**\n * A Map with additional utility methods. This is used throughout \\@squarecloud/api rather than Arrays for anything that has\n * an ID, for significantly improved performance and ease-of-use.\n *\n * @typeParam K - The key type this collection holds\n * @typeParam V - The value type this collection holds\n */\n// biome-ignore lint/suspicious/noUnsafeDeclarationMerging: Needed to merge the constructor and the instance methods\nexport class Collection<K, V> extends Map<K, V> {\n\t/**\n\t * Obtains the first value(s) in this collection.\n\t *\n\t * @param amount - Amount of values to obtain from the beginning\n\t * @returns A single value if no amount is provided or an array of values, starting from the end if amount is negative\n\t */\n\tpublic first(): V | undefined;\n\tpublic first(amount: number): V[];\n\tpublic first(amount?: number): V | V[] | undefined {\n\t\tif (typeof amount === \"undefined\") {\n\t\t\treturn this.values().next().value;\n\t\t}\n\n\t\tif (amount < 0) {\n\t\t\treturn this.last(amount * -1);\n\t\t}\n\n\t\tamount = Math.min(this.size, amount);\n\t\treturn Array.from({ length: amount }, (): V => this.values().next().value);\n\t}\n\n\t/**\n\t * Obtains the last value(s) in this collection.\n\t *\n\t * @param amount - Amount of values to obtain from the end\n\t * @returns A single value if no amount is provided or an array of values, starting from the start if\n\t * amount is negative\n\t */\n\tpublic last(): V | undefined;\n\tpublic last(amount: number): V[];\n\tpublic last(amount?: number): V | V[] | undefined {\n\t\tconst arr = [...this.values()];\n\t\tif (typeof amount === \"undefined\") return arr[arr.length - 1];\n\t\tif (amount < 0) return this.first(amount * -1);\n\t\tif (!amount) return [];\n\t\treturn arr.slice(-amount);\n\t}\n\n\t/**\n\t * Identical to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse Array.reverse()}\n\t * but returns a Collection instead of an Array.\n\t */\n\tpublic reverse() {\n\t\tconst entries = [...this.entries()].reverse();\n\t\tthis.clear();\n\n\t\tfor (const [key, value] of entries) {\n\t\t\tthis.set(key, value);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Searches for a single item where the given function returns a truthy value. This behaves like\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find Array.find()}.\n\t *\n\t * @param fn - The function to test with (should return boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.find(user => user.username === 'Bob');\n\t * ```\n\t */\n\tpublic find<V2 extends V>(\n\t\tfn: (value: V, key: K, collection: this) => value is V2,\n\t): V2 | undefined;\n\n\tpublic find(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t): V | undefined;\n\n\tpublic find<This, V2 extends V>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => value is V2,\n\t\tthisArg: This,\n\t): V2 | undefined;\n\n\tpublic find<This>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: This,\n\t): V | undefined;\n\n\tpublic find(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): V | undefined {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tfor (const [key, val] of this) {\n\t\t\tif (fn(val, key, this)) return val;\n\t\t}\n\t}\n\n\t/**\n\t * Identical to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter Array.filter()},\n\t * but returns a Collection instead of an Array.\n\t *\n\t * @param fn - The function to test with (should return boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.filter(user => user.username === 'Bob');\n\t * ```\n\t */\n\tpublic filter<K2 extends K>(\n\t\tfn: (value: V, key: K, collection: this) => key is K2,\n\t): Collection<K2, V>;\n\n\tpublic filter<V2 extends V>(\n\t\tfn: (value: V, key: K, collection: this) => value is V2,\n\t): Collection<K, V2>;\n\n\tpublic filter(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t): Collection<K, V>;\n\n\tpublic filter<This, K2 extends K>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => key is K2,\n\t\tthisArg: This,\n\t): Collection<K2, V>;\n\n\tpublic filter<This, V2 extends V>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => value is V2,\n\t\tthisArg: This,\n\t): Collection<K, V2>;\n\n\tpublic filter<This>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: This,\n\t): Collection<K, V>;\n\n\tpublic filter(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): Collection<K, V> {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tconst results = new this.constructor[Symbol.species]<K, V>();\n\t\tfor (const [key, val] of this) {\n\t\t\tif (fn(val, key, this)) results.set(key, val);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\t/**\n\t * Maps each item to another value into an array. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map Array.map()}.\n\t *\n\t * @param fn - Function that produces an element of the new array, taking three arguments\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.map(user => user.name);\n\t * ```\n\t */\n\tpublic map<T>(fn: (value: V, key: K, collection: this) => T): T[];\n\tpublic map<This, T>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => T,\n\t\tthisArg: This,\n\t): T[];\n\n\tpublic map<T>(\n\t\tfn: (value: V, key: K, collection: this) => T,\n\t\tthisArg?: unknown,\n\t): T[] {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\treturn Array.from({ length: this.size }, (): T => {\n\t\t\tconst [key, value] = this.entries().next().value;\n\t\t\treturn fn(value, key, this);\n\t\t});\n\t}\n\n\t/**\n\t * Checks if there exists an item that passes a test. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some Array.some()}.\n\t *\n\t * @param fn - Function used to test (should return a boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.some(user => user.discriminator === '0000');\n\t * ```\n\t */\n\tpublic some(fn: (value: V, key: K, collection: this) => unknown): boolean;\n\tpublic some<T>(\n\t\tfn: (this: T, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: T,\n\t): boolean;\n\n\tpublic some(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): boolean {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tfor (const [key, val] of this) {\n\t\t\tif (fn(val, key, this)) return true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks if all items passes a test. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every Array.every()}.\n\t *\n\t * @param fn - Function used to test (should return a boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.every(user => !user.bot);\n\t * ```\n\t */\n\tpublic every<K2 extends K>(\n\t\tfn: (value: V, key: K, collection: this) => key is K2,\n\t): this is Collection<K2, V>;\n\n\tpublic every<V2 extends V>(\n\t\tfn: (value: V, key: K, collection: this) => value is V2,\n\t): this is Collection<K, V2>;\n\n\tpublic every(fn: (value: V, key: K, collection: this) => unknown): boolean;\n\tpublic every<This, K2 extends K>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => key is K2,\n\t\tthisArg: This,\n\t): this is Collection<K2, V>;\n\n\tpublic every<This, V2 extends V>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => value is V2,\n\t\tthisArg: This,\n\t): this is Collection<K, V2>;\n\n\tpublic every<This>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: This,\n\t): boolean;\n\n\tpublic every(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): boolean {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tfor (const [key, val] of this) {\n\t\t\tif (!fn(val, key, this)) return false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Applies a function to produce a single value. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce Array.reduce()}.\n\t *\n\t * @param fn - Function used to reduce, taking four arguments; `accumulator`, `currentValue`, `currentKey`,\n\t * and `collection`\n\t * @param initialValue - Starting value for the accumulator\n\t * @example\n\t * ```ts\n\t * collection.reduce((acc, guild) => acc + guild.memberCount, 0);\n\t * ```\n\t */\n\tpublic reduce<T>(\n\t\tfn: (accumulator: T, value: V, key: K, collection: this) => T,\n\t\tinitialValue?: T,\n\t): T {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\t\tlet accumulator!: T;\n\n\t\tif (typeof initialValue !== \"undefined\") {\n\t\t\taccumulator = initialValue;\n\t\t\tfor (const [key, val] of this) {\n\t\t\t\taccumulator = fn(accumulator, val, key, this);\n\t\t\t}\n\t\t\treturn accumulator;\n\t\t}\n\n\t\tlet first = true;\n\t\tfor (const [key, val] of this) {\n\t\t\tif (first) {\n\t\t\t\taccumulator = val as unknown as T;\n\t\t\t\tfirst = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\taccumulator = fn(accumulator, val, key, this);\n\t\t}\n\n\t\tif (first) {\n\t\t\tthrow new TypeError(\"Reduce of empty collection with no initial value\");\n\t\t}\n\n\t\treturn accumulator;\n\t}\n\n\t/**\n\t * Identical to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach Map.forEach()},\n\t * but returns the collection instead of undefined.\n\t *\n\t * @param fn - Function to execute for each element\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection\n\t * .each(user => console.log(user.username))\n\t * .filter(user => user.bot)\n\t * .each(user => console.log(user.username));\n\t * ```\n\t */\n\tpublic each(fn: (value: V, key: K, collection: this) => void): this;\n\tpublic each<T>(\n\t\tfn: (this: T, value: V, key: K, collection: this) => void,\n\t\tthisArg: T,\n\t): this;\n\n\tpublic each(\n\t\tfn: (value: V, key: K, collection: this) => void,\n\t\tthisArg?: unknown,\n\t): this {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tthis.forEach(fn as (value: V, key: K, map: Map<K, V>) => void, thisArg);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates an identical shallow copy of this collection.\n\t *\n\t * @example\n\t * ```ts\n\t * const newColl = someColl.clone();\n\t * ```\n\t */\n\tpublic clone(): Collection<K, V> {\n\t\treturn new this.constructor[Symbol.species](this);\n\t}\n\n\tpublic toJSON() {\n\t\treturn [...this.values()];\n\t}\n}\n","import type { APIDeployment, DeploymentState } from \"@squarecloud/api-types/v2\";\n\nimport type { BaseApplication } from \"./application/base\";\n\n/**\n * Represents an application deployment\n */\nexport class Deployment {\n\t/** The ID of the deploy. */\n\tpublic readonly id: `git-${string}`;\n\n\t/** The current state of the deploy. */\n\tpublic state: DeploymentState;\n\n\t/** The date the deploy was created. */\n\tpublic createdAt: Date;\n\n\t/** The date the deploy was created in millisseconds. */\n\tpublic createdTimestamp: number;\n\n\t/**\n\t * Represents an application deployment\n\t *\n\t * @constructor\n\t * @param application - The application from which you fetched the deployment\n\t * @param data - The data from this deployment\n\t */\n\tconstructor(\n\t\tpublic readonly application: BaseApplication,\n\t\tdata: APIDeployment,\n\t) {\n\t\tconst { id, state, date } = data;\n\n\t\tthis.id = id;\n\t\tthis.state = state;\n\t\tthis.createdAt = new Date(date);\n\t\tthis.createdTimestamp = this.createdAt.getTime();\n\t}\n}\n","export class SquareCloudAPIError extends TypeError {\n\tconstructor(\n\t\tcode: string,\n\t\tmessage?: string,\n\t\toptions?: { stack?: string; cause?: unknown },\n\t) {\n\t\tsuper(code);\n\n\t\tthis.name = \"SquareCloudAPIError\";\n\n\t\tthis.message =\n\t\t\t(code\n\t\t\t\t?.replaceAll(\"_\", \" \")\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/(^|\\s)\\S/g, (L) => L.toUpperCase()) || \"UNKNOWN_CODE\") +\n\t\t\t(message ? `: ${message}` : \"\");\n\n\t\tif (options?.stack) {\n\t\t\tthis.stack = options.stack;\n\t\t}\n\n\t\tif (options?.cause) {\n\t\t\tthis.cause = options.cause;\n\t\t}\n\t}\n}\n","import type {\n\tAPIApplicationStatus,\n\tAPIApplicationStatusAll,\n\tApplicationStatus as ApplicationStatusType,\n} from \"@squarecloud/api-types/v2\";\n\nimport { Routes } from \"@/lib/routes\";\nimport type { ApplicationStatusUsage } from \"@/types/application\";\nimport type { SquareCloudAPI } from \"..\";\n\n/**\n * Represents an application status fetched from status all endpoint\n */\nexport class SimpleApplicationStatus<R extends boolean = boolean> {\n\t/** The application's ID this status came from */\n\tpublic readonly applicationId: string;\n\t/** Usage statuses for this application */\n\tpublic usage: R extends true\n\t\t? Pick<ApplicationStatusUsage, \"cpu\" | \"ram\">\n\t\t: undefined;\n\t/** Whether the application is running or not */\n\tpublic running: R;\n\n\t/**\n\t * Represents an application status fetched from status all endpoint\n\t *\n\t * @constructor\n\t * @param client - The client for this status\n\t * @param data - The data from this status\n\t */\n\tconstructor(\n\t\tpublic readonly client: SquareCloudAPI,\n\t\tdata: APIApplicationStatusAll,\n\t) {\n\t\tconst { id, running } = data;\n\n\t\tthis.applicationId = id;\n\t\tthis.running = running as R;\n\n\t\tif (running) {\n\t\t\tconst { cpu, ram } = data;\n\n\t\t\tthis.usage = { cpu, ram } as R extends true\n\t\t\t\t? Pick<ApplicationStatusUsage, \"cpu\" | \"ram\">\n\t\t\t\t: undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Fetches the full application status\n\t */\n\tasync fetch() {\n\t\tconst data = await this.client.api.request(\n\t\t\tRoutes.apps.status(this.applicationId),\n\t\t);\n\n\t\treturn new ApplicationStatus(\n\t\t\tthis.client,\n\t\t\tdata.response,\n\t\t\tthis.applicationId,\n\t\t);\n\t}\n}\n\n/**\n * Represents an application status\n */\nexport class ApplicationStatus {\n\t/** The application's ID this status came from */\n\tpublic readonly applicationId: string;\n\t/** Usage statuses for this application */\n\tpublic usage: ApplicationStatusUsage;\n\t/** Whether the application is running or not */\n\tpublic running: boolean;\n\t/**\n\t * The status of the application\n\t *\n\t * - 'exited' (stopped)\n\t * - 'created' (being created)\n\t * - 'running'\n\t * - 'starting'\n\t * - 'restarting'\n\t * - 'deleting'\n\t */\n\tpublic status: ApplicationStatusType;\n\t/** For how long the app is running in millisseconds */\n\tpublic uptimeTimestamp?: number;\n\t/** For how long the app is running */\n\tpublic uptime?: Date;\n\n\t/**\n\t * Represents an application status\n\t *\n\t * @constructor\n\t * @param client - The client for this status\n\t * @param data - The data from this status\n\t * @param applicationId - The application ID this status came from\n\t */\n\tconstructor(\n\t\tpublic readonly client: SquareCloudAPI,\n\t\tdata: APIApplicationStatus,\n\t\tapplicationId: string,\n\t) {\n\t\tconst { cpu, ram, network, storage, running, status, uptime } = data;\n\n\t\tthis.applicationId = applicationId;\n\t\tthis.usage = { cpu, ram, network, storage };\n\t\tthis.running = running;\n\t\tthis.status = status;\n\t\tthis.uptime = uptime ? new Date(uptime) : undefined;\n\t\tthis.uptimeTimestamp = uptime ?? undefined;\n\t}\n}\n","import type { APIUserInfo } from \"@squarecloud/api-types/v2\";\n\nimport type { UserPlan } from \"@/types/user\";\nimport type { SquareCloudAPI } from \"..\";\nimport { BaseApplication } from \"./application/base\";\nimport { Collection } from \"./collection\";\n\n/**\n * Represents a Square Cloud user\n */\nexport class User {\n\t/** The user's id */\n\tpublic readonly id: string;\n\t/** The user's display name */\n\tpublic name: string;\n\t/** The user's current plan */\n\tpublic plan: UserPlan;\n\t/** The user's registered email */\n\tpublic email: string;\n\t/** The user's registered applications Collection */\n\tpublic applications: Collection<string, BaseApplication>;\n\n\t/**\n\t * Represents a Square Cloud user\n\t *\n\t * @constructor\n\t * @param client - The client for this user\n\t * @param data - The data from this user\n\t */\n\tconstructor(client: SquareCloudAPI, data: APIUserInfo) {\n\t\tconst { user, applications } = data;\n\t\tconst { id, name, plan, email } = user;\n\t\tconst { duration } = plan;\n\n\t\tthis.id = id;\n\t\tthis.name = name;\n\t\tthis.email = email;\n\t\tthis.plan = {\n\t\t\t...plan,\n\t\t\texpiresInTimestamp: duration ?? undefined,\n\t\t\texpiresIn: duration ? new Date(duration) : undefined,\n\t\t};\n\t\tthis.applications = new Collection(\n\t\t\tapplications.map((app) => [app.id, new BaseApplication(client, app)]),\n\t\t);\n\t}\n}\n","import { SquareCloudAPIError } from \"../structures\";\n\nexport interface AssertionProps {\n\tvalidate: (value: unknown) => boolean;\n\texpect: string;\n\tvalue: unknown;\n\tname?: string;\n}\n\nexport function assert({ validate, value, expect, name }: AssertionProps) {\n\tif (!validate(value)) {\n\t\tconst code = name ? `INVALID_${name}` : \"VALIDATION_ERROR\";\n\t\tconst message = `Expected ${expect}, got ${typeof value}`;\n\n\t\tthrow new SquareCloudAPIError(code, message);\n\t}\n}\n\nexport function makeAssertion(\n\texpect: string,\n\tvalidate: (value: unknown) => boolean,\n) {\n\treturn (value: unknown, name?: string) => {\n\t\tassert({ validate, value, expect, name });\n\t};\n}\n","import { makeAssertion } from \"./common\";\n\nexport const assertString = makeAssertion(\n\t\"string\",\n\t(value) => typeof value === \"string\",\n);\n\nexport const assertBoolean = makeAssertion(\n\t\"boolean\",\n\t(value) => typeof value === \"boolean\",\n);\n\nexport const assertPathLike = makeAssertion(\n\t\"string or Buffer\",\n\t(value) => typeof value === \"string\" || value instanceof Buffer,\n);\n","import type { RESTPostAPIApplicationBackupResult } from \"@squarecloud/api-types/v2\";\n\nimport { Routes } from \"@/lib/routes\";\nimport { type BaseApplication, SquareCloudAPIError } from \"@/structures\";\nimport { Backup } from \"@/structures/backup\";\n\nexport class BackupsModule {\n\tconstructor(public readonly application: BaseApplication) {}\n\n\t/**\n\t * Gets the list of generated backups (snapshots) for this application\n\t */\n\tasync list(): Promise<Backup[]> {\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.snapshots(this.application.id),\n\t\t);\n\n\t\tconst backups = data.response.map(\n\t\t\t(backup) => new Backup(this.application, backup),\n\t\t);\n\n\t\tthis.application.client.emit(\n\t\t\t\"backupsUpdate\",\n\t\t\tthis.application,\n\t\t\tthis.application.cache.backups,\n\t\t\tbackups,\n\t\t);\n\t\tthis.application.cache.set(\"backups\", backups);\n\n\t\treturn backups;\n\t}\n\n\t/**\n\t * Generates a new backup\n\t * @returns The generated backup URL and key\n\t */\n\tasync create(): Promise<RESTPostAPIApplicationBackupResult> {\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.generateSnapshot(this.application.id),\n\t\t\t{ method: \"POST\" },\n\t\t);\n\n\t\treturn data.response;\n\t}\n\n\t/**\n\t * Generates a new backup and downloads it\n\t * @returns The downloaded backup bufer\n\t */\n\tasync download(): Promise<Buffer> {\n\t\tconst backup = await this.create();\n\n\t\tconst res = await fetch(backup.url)\n\t\t\t.then((res) => res.arrayBuffer())\n\t\t\t.catch(() => undefined);\n\n\t\tif (!res) {\n\t\t\tthrow new SquareCloudAPIError(\"BACKUP_DOWNLOAD_FAILED\");\n\t\t}\n\n\t\treturn Buffer.from(res);\n\t}\n}\n","import { assertString } from \"@/assertions/literal\";\nimport { Routes } from \"@/lib/routes\";\nimport type { BaseApplication } from \"@/structures\";\nimport { Deployment } from \"@/structures/deploy\";\n\nexport class DeploysModule {\n\tconstructor(public readonly application: BaseApplication) {}\n\n\t/**\n\t * Integrates Square Cloud with GitHub webhooks\n\t *\n\t * @param accessToken - The access token for your GitHub repository. You can find this in your [GitHub Tokens Classic](https://github.com/settings/tokens/new)\n\t */\n\tasync integrateGithubWebhook(accessToken: string) {\n\t\tassertString(accessToken);\n\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.deployments.webhook(this.application.id),\n\t\t\t{ method: \"POST\", body: { access_token: accessToken } },\n\t\t);\n\n\t\treturn data.response.webhook;\n\t}\n\n\t/**\n\t * Gets the last 10 deployments of an application from the last 24 hours\n\t */\n\tasync list() {\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.deployments.list(this.application.id),\n\t\t);\n\n\t\treturn data.response.map(\n\t\t\t(deployment) => new Deployment(this.application, deployment),\n\t\t);\n\t}\n\n\t/**\n\t * Gets the current webhook URL\n\t */\n\tasync webhookURL() {\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.deployments.current(this.application.id),\n\t\t);\n\n\t\treturn data.response.webhook;\n\t}\n}\n","import { join } from \"path\";\nimport { readFile } from \"fs/promises\";\n\nimport { assertPathLike, assertString } from \"@/assertions/literal\";\nimport { Routes } from \"@/lib/routes\";\nimport type { BaseApplication } from \"@/structures\";\n\nexport class FilesModule {\n\tconstructor(public readonly application: BaseApplication) {}\n\n\t/**\n\t * Lists the files inside a directory\n\t *\n\t * @param path - The absolute directory path\n\t */\n\tasync list(path = \"/\") {\n\t\tassertString(path, \"LIST_FILES_PATH\");\n\n\t\tconst { response } = await this.application.client.api.request(\n\t\t\tRoutes.apps.files.list(this.application.id),\n\t\t\t{ query: { path } },\n\t\t);\n\n\t\treturn response;\n\t}\n\n\t/**\n\t * Reads the specified file content\n\t *\n\t * @param path - The absolute file path\n\t */\n\tasync read(path: string) {\n\t\tassertString(path, \"READ_FILE_PATH\");\n\n\t\tconst { response } = await this.application.client.api.request(\n\t\t\tRoutes.apps.files.read(this.application.id),\n\t\t\t{ query: { path } },\n\t\t);\n\n\t\tif (!response) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn Buffer.from(response.data);\n\t}\n\n\t/**\n\t * Creates a new file\n\t *\n\t * @param file - The file content\n\t * @param fileName - The file name with extension\n\t * @param path - The absolute file path\n\t */\n\tasync create(file: string | Buffer, fileName: string, path = \"/\") {\n\t\tassertPathLike(file, \"CREATE_FILE\");\n\t\tassertString(fileName, \"CREATE_FILE_NAME\");\n\t\tassertString(path, \"CREATE_FILE_PATH\");\n\n\t\tif (typeof file === \"string\") {\n\t\t\tfile = await readFile(file);\n\t\t}\n\t\tpath = join(path, fileName).replaceAll(\"\\\\\", \"/\");\n\n\t\tconst { status } = await this.application.client.api.request(\n\t\t\tRoutes.apps.files.upsert(this.application.id),\n\t\t\t{\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\tbody: { content: file.toString(\"utf8\"), path },\n\t\t\t},\n\t\t);\n\n\t\treturn status === \"success\";\n\t}\n\n\t/**\n\t * Edits an existing file (same as create)\n\t *\n\t * @param file - The file content\n\t * @param path - The absolute file path\n\t */\n\tasync edit(file: string | Buffer, path = \"/\") {\n\t\tassertPathLike(file, \"EDIT_FILE\");\n\t\tassertString(path, \"EDIT_FILE_PATH\");\n\n\t\treturn this.create(file, \"\", path);\n\t}\n\n\t/**\n\t * Moves or renames a file\n\t *\n\t * @param path - The current absolute file path\n\t * @param newPath - The new absolute file path\n\t */\n\tasync move(path: string, newPath: string) {\n\t\tassertString(path, \"MOVE_FILE_PATH\");\n\t\tassertString(newPath, \"MOVE_FILE_NEW_PATH\");\n\n\t\tconst { status } = await this.application.client.api.request(\n\t\t\tRoutes.apps.files.move(this.application.id),\n\t\t\t{ method: \"PATCH\", body: { path, to: newPath } },\n\t\t);\n\n\t\treturn status === \"success\";\n\t}\n\n\t/**\n\t * Deletes the specified file or directory\n\t *\n\t * @param path - The absolute file or directory path\n\t */\n\tasync delete(path: string) {\n\t\tassertString(path, \"DELETE_FILE_PATH\");\n\n\t\tconst { status } = await this.application.client.api.request(\n\t\t\tRoutes.apps.files.delete(this.application.id),\n\t\t\t{ method: \"DELETE\", body: { path } },\n\t\t);\n\n\t\treturn status === \"success\";\n\t}\n}\n","import { assertString } from \"@/assertions/literal\";\nimport { Routes } from \"@/lib/routes\";\nimport type { WebsiteApplication } from \"@/structures\";\n\nexport class NetworkModule {\n\tconstructor(public readonly application: WebsiteApplication) {}\n\n\t/**\n\t * Integrates your website with a custom domain\n\t * - Requires [Senior plan](https://squarecloud.app/plans) or higher\n\t *\n\t * @param custom - The custom domain you want to use (e.g. yoursite.com)\n\t */\n\tasync setCustomDomain(custom: string) {\n\t\tassertString(custom, \"CUSTOM_DOMAIN\");\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.network.custom(this.application.id),\n\t\t\t{ method: \"POST\", body: { custom } },\n\t\t);\n\n\t\treturn data.status === \"success\";\n\t}\n\n\t/**\n\t * Gets analytics for a custom domain\n\t * - Requires [Senior plan](https://squarecloud.app/plans) or higher\n\t * - Requires the application to have an integrated custom domain\n\t */\n\tasync analytics() {\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.network.analytics(this.application.id),\n\t\t);\n\n\t\treturn data?.response;\n\t}\n\n\t/**\n\t * Get the DNS records for your custom domain.\n\t */\n\tasync dns() {\n\t\tconst data = await this.application.client.api.request(\n\t\t\tRoutes.apps.network.dns(this.application.id),\n\t\t);\n\n\t\treturn data?.response;\n\t}\n}\n","import { Routes } from \"@/lib/routes\";\nimport { User } from \"@/structures\";\nimport type { SquareCloudAPI } from \"..\";\n\nexport class UserModule {\n\tconstructor(public readonly client: SquareCloudAPI) {}\n\n\t/**\n\t * Gets the authenticated user information\n\t */\n\tasync get(): Promise<User> {\n\t\tconst { response } = await this.client.api.request(Routes.user());\n\t\tconst user = new User(this.client, response);\n\n\t\tthis.client.emit(\"userUpdate\", this.client.cache.user, user);\n\t\tthis.client.cache.set(\"user\", user);\n\n\t\treturn user;\n\t}\n}\n"],"mappings":"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