diff --git a/.changeset/silent-ducks-listen.md b/.changeset/silent-ducks-listen.md new file mode 100644 index 00000000..07f2c80a --- /dev/null +++ b/.changeset/silent-ducks-listen.md @@ -0,0 +1,5 @@ +--- +'pockethost': minor +--- + +Feature: cloud volume support for instances diff --git a/ecosystem.config.cjs b/ecosystem.config.cjs index 8f5bb68e..e0ed6725 100644 --- a/ecosystem.config.cjs +++ b/ecosystem.config.cjs @@ -12,7 +12,10 @@ module.exports = { { name: `edge-ftp`, script: 'pnpm prod:cli edge ftp serve', - cron_restart: '0 0 * * *', + { + name: `edge-volume`, + script: 'pnpm prod:cli edge volume mount', + // cron_restart: '0 0 * * *', }, { name: `mothership`, diff --git a/packages/pockethost/package.json b/packages/pockethost/package.json index e566f423..389b1774 100644 --- a/packages/pockethost/package.json +++ b/packages/pockethost/package.json @@ -40,6 +40,7 @@ "express": "^4.18.2", "express-async-errors": "^3.1.1", "express-sslify": "^1.2.0", + "fs-extra": "^11.2.0", "ftp-srv": "github:pockethost/ftp-srv#0fc708bae0d5d7a55ce948767f082d6fcfb2af59", "glob": "^11.0.0", "gobot": "1.0.0-alpha.41", @@ -68,6 +69,7 @@ "@types/eventsource": "^1.1.14", "@types/express": "^4.17.21", "@types/express-sslify": "^1.2.5", + "@types/fs-extra": "^11.0.4", "@types/http-proxy": "^1.17.13", "@types/js-cookie": "^3.0.5", "@types/json-stringify-safe": "^5.0.2", diff --git a/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/MigrateCommand.ts b/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/MigrateCommand.ts new file mode 100644 index 00000000..e6695c3c --- /dev/null +++ b/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/MigrateCommand.ts @@ -0,0 +1,90 @@ +import { Command } from 'commander' +import { existsSync } from 'fs' +import fse from 'fs-extra' +import { InstanceFields, PocketBase } from '../../../../common' +import { + mkInstanceDataPath, + MOTHERSHIP_ADMIN_PASSWORD, + MOTHERSHIP_ADMIN_USERNAME, + MOTHERSHIP_URL, +} from '../../../../core' + +const { moveSync } = fse + +export const MigrateCommand = () => { + return new Command(`migrate`) + .description(`Migrate instance(s)`) + .option(`-i, --instance `, `The instance to migrate`) + .option( + `-m, --mount-point `, + `The mount point`, + `cloud-storage`, + ) + .action(async (options) => { + console.log({ options }) + const { instance: instanceId, mountPoint } = options + + const pb = new PocketBase(MOTHERSHIP_URL()) + + await pb.admins.authWithPassword( + MOTHERSHIP_ADMIN_USERNAME(), + MOTHERSHIP_ADMIN_PASSWORD(), + ) + + const filter = [`status='idle'`, `volume=''`] + if (instanceId) { + filter.push(`id = '${instanceId}'`) + } + console.log(`Filter is`, filter.join(` && `)) + + do { + try { + await migrate(mountPoint, pb, filter.join(` && `)) + } catch (e) { + console.error(`No record found ${e}`) + } + } while (!instanceId) + }) +} + +async function migrate(mountPoint: string, pb: PocketBase, filter: string) { + const instance = await pb + .collection('instances') + .getFirstListItem(filter) + + const oldSuspension = instance.suspension + try { + console.log(`Suspending instance ${instance.id}`) + await pb.collection('instances').update(instance.id, { + suspension: 'migrating', + }) + + const instanceDataSrc = mkInstanceDataPath('', instance.id) + const instanceDataDst = mkInstanceDataPath(mountPoint, instance.id) + + if (existsSync(instanceDataSrc) && !existsSync(instanceDataDst)) { + console.log(`Moving ${instanceDataSrc} to ${instanceDataDst}`) + moveSync(instanceDataSrc, instanceDataDst) + } else { + console.warn( + `Skipping ${instanceDataSrc} to ${instanceDataDst} because source does not exist or destination already exists`, + ) + } + + console.log(`Updating instance ${instance.id} with volume ${mountPoint}`) + await pb.collection('instances').update(instance.id, { + volume: mountPoint, + }) + + console.log(`Migrated ${instanceDataSrc} to ${instanceDataDst}`) + } catch (e) { + console.error(`${e}`, JSON.stringify(e, null, 2)) + } finally { + console.log( + `Restoring previous suspension value of instance ${instance.id}`, + ) + await pb.collection('instances').update(instance.id, { + suspension: oldSuspension === 'migrating' ? '' : oldSuspension, + }) + } +} diff --git a/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/MountCommand.ts b/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/MountCommand.ts new file mode 100644 index 00000000..8580560a --- /dev/null +++ b/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/MountCommand.ts @@ -0,0 +1,157 @@ +import { exec, spawn } from 'child_process' +import { Command } from 'commander' +import { promisify } from 'util' +import { logger } from '../../../../common' +import { + DEBUG, + VOLUME_BUCKET_NAME, + VOLUME_CACHE_DIR, + VOLUME_DEBUG, + VOLUME_DIR_CACHE_TIME, + VOLUME_MOUNT_POINT, + VOLUME_REMOTE_NAME, + VOLUME_VFS_CACHE_MAX_AGE, + VOLUME_VFS_CACHE_MIN_FREE_SPACE, + VOLUME_VFS_READ_CHUNK_SIZE, + VOLUME_VFS_READ_CHUNK_STREAMS, + VOLUME_VFS_WRITE_BACK, +} from '../../../../core' +import { asyncExitHook, gracefulExit } from '../../../../core/exit' + +const execAsync = promisify(exec) + +export type MountOptions = { + mountPoint: string + cacheDir: string + vfsCacheMaxAge: string + vfsCacheMinFreeSpace: string + vfsReadChunkSize: string + vfsReadChunkStreams: string + vfsWriteBack: string + dirCacheTime: string +} + +// Add this helper function to check if path is mounted +const isMounted = async (path: string): Promise => { + try { + const { stdout } = await execAsync(`mount | grep "${path}"`) + return stdout.length > 0 + } catch { + return false + } +} + +// Add cleanup function +const cleanup = async (mountPoint: string) => { + try { + await execAsync(`fusermount -u "${mountPoint}"`) + console.log(`Cleanup successful: ${mountPoint}`) + } catch (err) { + console.error(`Cleanup failed: ${mountPoint}: ${err}`) + } +} + +const mount = async ( + remoteName: string, + bucketName: string, + optionsIn: Partial = {}, +) => { + const options: MountOptions = { + mountPoint: VOLUME_MOUNT_POINT(), + cacheDir: VOLUME_CACHE_DIR(), + vfsCacheMaxAge: VOLUME_VFS_CACHE_MAX_AGE(), + vfsCacheMinFreeSpace: VOLUME_VFS_CACHE_MIN_FREE_SPACE(), + vfsReadChunkSize: VOLUME_VFS_READ_CHUNK_SIZE(), + vfsReadChunkStreams: VOLUME_VFS_READ_CHUNK_STREAMS(), + vfsWriteBack: VOLUME_VFS_WRITE_BACK(), + dirCacheTime: VOLUME_DIR_CACHE_TIME(), + ...optionsIn, + } + + const { dbg, info, error } = logger().child(`MountCommand`) + await cleanup(options.mountPoint) + + const args = [ + 'mount', + `${remoteName}:${bucketName}`, + options.mountPoint, + '--vfs-cache-mode', + 'full', + '--cache-dir', + options.cacheDir, + '--vfs-cache-max-age', + options.vfsCacheMaxAge, + '--vfs-cache-min-free-space', + options.vfsCacheMinFreeSpace, + '--vfs-fast-fingerprint', + '--vfs-read-chunk-streams', + options.vfsReadChunkStreams, + '--vfs-read-chunk-size', + options.vfsReadChunkSize, + '--vfs-write-back', + options.vfsWriteBack, + '--dir-cache-time', + options.dirCacheTime, + '--allow-non-empty', + ] + + if (DEBUG() || VOLUME_DEBUG()) { + args.push('--verbose') + } + + dbg(`rclone ${args.join(' ')}`) + + const p = new Promise((resolve, reject) => { + const rclone = spawn('rclone', args) + + // Register cleanup on exit + asyncExitHook(async () => { + rclone.kill() + }) + + rclone.stdout.on('data', (data) => { + info(data.toString().trim()) + }) + + rclone.stderr.on('data', (data) => { + info(data.toString().trim()) + }) + + rclone.on('spawn', () => { + info('rclone process spawned') + }) + + rclone.on('error', async (err) => { + error('Failed to start rclone process:', err) + await gracefulExit(1) + reject(err) + }) + + rclone.on('close', async (code) => { + dbg(`rclone process exited with code ${code}`) + await cleanup(options.mountPoint) + resolve(code || 0) + }) + }) + + asyncExitHook(() => p) + + return p +} + +export const MountCommand = () => { + return new Command(`mount`) + .description(`Mount a volume`) + .option(`-r, --remote `, `The remote name`, VOLUME_REMOTE_NAME()) + .option(`-b, --bucket `, `The bucket name`, VOLUME_BUCKET_NAME()) + .action(async (options) => { + const { dbg, error } = logger().child(`MountCommand`) + const { remote, bucket } = options + try { + await mount(remote, bucket) + } catch (err) { + error(err) + await gracefulExit(1) + } + }) +} diff --git a/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/index.ts b/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/index.ts new file mode 100644 index 00000000..36a4adc8 --- /dev/null +++ b/packages/pockethost/src/cli/commands/EdgeCommand/VolumeCommand/index.ts @@ -0,0 +1,17 @@ +import { Command } from 'commander' +import fse from 'fs-extra' +import { MigrateCommand } from './MigrateCommand' +import { MountCommand } from './MountCommand' + +const { moveSync } = fse + +export const VolumeCommand = () => { + const cmd = new Command(`volume`) + .description(`Volume commands`) + .addCommand(MountCommand()) + .addCommand(MigrateCommand()) + .action(() => { + cmd.help() + }) + return cmd +} diff --git a/packages/pockethost/src/cli/commands/EdgeCommand/index.ts b/packages/pockethost/src/cli/commands/EdgeCommand/index.ts index a9fb0942..c5b6692a 100644 --- a/packages/pockethost/src/cli/commands/EdgeCommand/index.ts +++ b/packages/pockethost/src/cli/commands/EdgeCommand/index.ts @@ -1,6 +1,7 @@ import { Command } from 'commander' import { DaemonCommand } from './DaemonCommand' import { FtpCommand } from './FtpCommand' +import { VolumeCommand } from './VolumeCommand' type Options = { debug: boolean @@ -12,6 +13,7 @@ export const EdgeCommand = () => { cmd .addCommand(DaemonCommand()) .addCommand(FtpCommand()) + .addCommand(VolumeCommand()) .action(() => { cmd.help() }) diff --git a/packages/pockethost/src/constants.ts b/packages/pockethost/src/constants.ts index f9f5caa5..984b4e18 100644 --- a/packages/pockethost/src/constants.ts +++ b/packages/pockethost/src/constants.ts @@ -8,7 +8,6 @@ import { dirname, join } from 'path' import { fileURLToPath } from 'url' import { InstanceFields, - InstanceId, SettingsHandlerFactory, SettingsService, ioc, @@ -144,6 +143,22 @@ export const createSettings = () => ({ DOCKER_CONTAINER_HOST: mkString(`host.docker.internal`), PH_GOBOT_ROOT: mkPath(join(_PH_HOME, 'gobot'), { create: true }), + + VOLUME_MOUNT_POINT: mkPath(join(_DATA_ROOT, 'cloud-storage-mount'), { + create: true, + }), + VOLUME_CACHE_DIR: mkPath(join(_PH_HOME, 'rclone', 'cloud-storage-cache'), { + create: true, + }), + VOLUME_REMOTE_NAME: mkString(``, { required: true }), + VOLUME_BUCKET_NAME: mkString(``, { required: true }), + VOLUME_VFS_CACHE_MAX_AGE: mkString(`100w`), + VOLUME_VFS_CACHE_MIN_FREE_SPACE: mkString(`10G`), + VOLUME_VFS_READ_CHUNK_SIZE: mkString(`1m`), + VOLUME_VFS_READ_CHUNK_STREAMS: mkString(`64`), + VOLUME_VFS_WRITE_BACK: mkString(`1h`), + VOLUME_DIR_CACHE_TIME: mkString(`100d`), + VOLUME_DEBUG: mkBoolean(_DEBUG), }) export type Settings = ReturnType @@ -254,6 +269,22 @@ export const PH_MOTHERSHIP_MIRROR_PORT = () => export const PH_GOBOT_VERBOSITY = () => env.get(`PH_GOBOT_VERBOSITY`).default(1).asIntPositive() +export const VOLUME_MOUNT_POINT = () => settings().VOLUME_MOUNT_POINT +export const VOLUME_CACHE_DIR = () => settings().VOLUME_CACHE_DIR +export const VOLUME_REMOTE_NAME = () => settings().VOLUME_REMOTE_NAME +export const VOLUME_BUCKET_NAME = () => settings().VOLUME_BUCKET_NAME +export const VOLUME_VFS_CACHE_MAX_AGE = () => + settings().VOLUME_VFS_CACHE_MAX_AGE +export const VOLUME_VFS_CACHE_MIN_FREE_SPACE = () => + settings().VOLUME_VFS_CACHE_MIN_FREE_SPACE +export const VOLUME_VFS_READ_CHUNK_SIZE = () => + settings().VOLUME_VFS_READ_CHUNK_SIZE +export const VOLUME_VFS_READ_CHUNK_STREAMS = () => + settings().VOLUME_VFS_READ_CHUNK_STREAMS +export const VOLUME_VFS_WRITE_BACK = () => settings().VOLUME_VFS_WRITE_BACK +export const VOLUME_DIR_CACHE_TIME = () => settings().VOLUME_DIR_CACHE_TIME +export const VOLUME_DEBUG = () => settings().VOLUME_DEBUG + /** Helpers */ export const MOTHERSHIP_DATA_ROOT = (...paths: string[]) => @@ -324,6 +355,15 @@ export const logConstants = () => { MOTHERSHIP_DATA_DB, PH_EDGE_MIRROR_PORT: PH_MOTHERSHIP_MIRROR_PORT, PH_GOBOT_VERBOSITY, + VOLUME_MOUNT_POINT, + VOLUME_CACHE_DIR, + VOLUME_REMOTE_NAME, + VOLUME_BUCKET_NAME, + VOLUME_VFS_CACHE_MAX_AGE, + VOLUME_VFS_CACHE_MIN_FREE_SPACE, + VOLUME_VFS_READ_CHUNK_SIZE, + VOLUME_VFS_READ_CHUNK_STREAMS, + VOLUME_VFS_WRITE_BACK, } forEach(vars, (v, k) => { console.log(`${k}: ${v()}`) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d5d888bf..5ead6fa4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -205,6 +205,9 @@ importers: express-sslify: specifier: ^1.2.0 version: 1.2.0 + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 ftp-srv: specifier: github:pockethost/ftp-srv#0fc708bae0d5d7a55ce948767f082d6fcfb2af59 version: https://codeload.github.com/pockethost/ftp-srv/tar.gz/0fc708bae0d5d7a55ce948767f082d6fcfb2af59 @@ -229,6 +232,9 @@ importers: memorystream: specifier: ^0.3.1 version: 0.3.1 + minio: + specifier: ^8.0.2 + version: 8.0.2 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -284,6 +290,9 @@ importers: '@types/express-sslify': specifier: ^1.2.5 version: 1.2.5 + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 '@types/http-proxy': specifier: ^1.17.13 version: 1.17.15 @@ -1437,6 +1446,9 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/get-port@3.2.0': resolution: {integrity: sha512-TiNg8R1kjDde5Pub9F9vCwZA/BNW9HeXP5b9j7Qucqncy/McfPZ6xze/EyBdXS5FhMIGN6Fx3vg75l5KHy3V1Q==} @@ -1455,6 +1467,9 @@ packages: '@types/json-stringify-safe@5.0.3': resolution: {integrity: sha512-oNOjRxLfPeYbBSQ60maucaFNqbslVOPU4WWs5t/sHvAh6tyo/CThXSG+E24tEzkgh/fzvxyDrYdOJufgeNy1sQ==} + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/lodash@4.14.202': resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} @@ -1542,6 +1557,9 @@ packages: '@types/vhost@3.0.9': resolution: {integrity: sha512-1XtvjHU2Y/ULSFsh7GT3mfTQa7dh8vfN48quUlFJdbh4nSM5BgjK+extSErJvmOueWqtXA30ACDha7aApx7Pvw==} + '@zxing/text-encoding@0.9.0': + resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==} + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -1640,6 +1658,10 @@ packages: peerDependencies: postcss: ^8.1.0 + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -1683,6 +1705,9 @@ packages: blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + block-stream2@2.1.0: + resolution: {integrity: sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==} + bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -1703,6 +1728,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browser-or-node@2.1.1: + resolution: {integrity: sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==} + browserslist@4.24.0: resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -1717,6 +1745,10 @@ packages: buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + buffer-fill@1.0.0: resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} @@ -1881,10 +1913,6 @@ packages: cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - cross-spawn@7.0.5: resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} engines: {node: '>= 8'} @@ -1983,6 +2011,10 @@ packages: decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + decompress-bzip2@4.0.0: resolution: {integrity: sha512-RwEcbZWaM7F5EiYfsAXUmZ/KLEVAPjYXfGbb5bztXZQ3d5PMpXYxa/1j04QL/gjotRdmzpHh++/cxz+rNZ4AZg==} engines: {node: '>=4'} @@ -2195,6 +2227,9 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventsource@2.0.2: resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} engines: {node: '>=12.0.0'} @@ -2243,6 +2278,10 @@ packages: fast-uri@3.0.2: resolution: {integrity: sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==} + fast-xml-parser@4.5.0: + resolution: {integrity: sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==} + hasBin: true + fastparse@1.1.2: resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==} @@ -2302,6 +2341,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + finalhandler@1.3.1: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} @@ -2326,6 +2369,9 @@ packages: debug: optional: true + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + foreground-child@3.1.1: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} @@ -2352,6 +2398,10 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -2538,6 +2588,14 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + ipaddr.js@2.2.0: + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + engines: {node: '>= 10'} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -2545,6 +2603,10 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + is-core-module@2.15.1: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} @@ -2560,6 +2622,10 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2601,6 +2667,10 @@ packages: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + is-valid-domain@0.1.6: resolution: {integrity: sha512-ZKtq737eFkZr71At8NxOFcP9O1K89gW3DkdrGMpp1upr/ueWjj+Weh4l9AI4rN0Gt8W2M1w7jrG2b/Yv83Ljpg==} @@ -2659,6 +2729,9 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jstransformer@1.0.0: resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} @@ -2898,6 +2971,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minio@8.0.2: + resolution: {integrity: sha512-7ipWbtgzzboctf+McK+2cXwCrNOhuboTA/O1g9iWa0gH8R4GkeyFWwk12aVDEHdzjPiG8wxnjwfHS7pgraKuHw==} + engines: {node: ^16 || ^18 || >=20} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} @@ -3160,6 +3237,10 @@ packages: pocketbase@0.21.5: resolution: {integrity: sha512-bnI/uinnQps+ElSlzxkc4yvwuSFfKcoszDtXH/4QT2FhGq2mJVUvDlxn+rjRXVntUjPfmMG5LEPZ1eGqV6ssog==} + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} @@ -3330,6 +3411,10 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3464,6 +3549,9 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + seek-bzip@1.0.6: resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} hasBin: true @@ -3572,6 +3660,10 @@ packages: split-ca@1.0.1: resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -3596,6 +3688,16 @@ packages: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -3629,6 +3731,9 @@ packages: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} + strnum@1.0.5: + resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + strtok3@7.0.0: resolution: {integrity: sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==} engines: {node: '>=14.16'} @@ -3759,6 +3864,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -3911,6 +4019,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -3924,6 +4036,9 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + utility-types@3.10.0: resolution: {integrity: sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==} engines: {node: '>= 4'} @@ -3994,6 +4109,9 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + web-encoding@1.1.5: + resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==} + web-streams-polyfill@3.2.1: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} @@ -4007,6 +4125,10 @@ packages: which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true @@ -4070,10 +4192,18 @@ packages: utf-8-validate: optional: true + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + xmlbuilder2@3.1.1: resolution: {integrity: sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw==} engines: {node: '>=12.0'} + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -5003,6 +5133,11 @@ snapshots: '@types/qs': 6.9.11 '@types/serve-static': 1.15.5 + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 20.16.11 + '@types/get-port@3.2.0': {} '@types/glob@5.0.38': @@ -5020,6 +5155,10 @@ snapshots: '@types/json-stringify-safe@5.0.3': {} + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 20.16.11 + '@types/lodash@4.14.202': {} '@types/mdast@4.0.3': @@ -5109,6 +5248,9 @@ snapshots: dependencies: '@types/connect': 3.4.38 + '@zxing/text-encoding@0.9.0': + optional: true + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -5195,6 +5337,10 @@ snapshots: postcss: 8.4.47 postcss-value-parser: 4.2.0 + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + axobject-query@4.1.0: {} babel-walk@3.0.0-canary-5: @@ -5240,6 +5386,10 @@ snapshots: blake3-wasm@2.1.5: {} + block-stream2@2.1.0: + dependencies: + readable-stream: 3.6.2 + bluebird@3.7.2: {} body-parser@1.20.3: @@ -5274,6 +5424,8 @@ snapshots: dependencies: fill-range: 7.1.1 + browser-or-node@2.1.1: {} + browserslist@4.24.0: dependencies: caniuse-lite: 1.0.30001667 @@ -5290,6 +5442,8 @@ snapshots: buffer-crc32@0.2.13: {} + buffer-crc32@1.0.0: {} + buffer-fill@1.0.0: {} buffer@5.7.1: @@ -5463,12 +5617,6 @@ snapshots: shebang-command: 1.2.0 which: 1.3.1 - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - cross-spawn@7.0.5: dependencies: path-key: 3.1.1 @@ -5555,6 +5703,8 @@ snapshots: dependencies: character-entities: 2.0.2 + decode-uri-component@0.2.2: {} + decompress-bzip2@4.0.0: dependencies: file-type: 4.4.0 @@ -5861,6 +6011,8 @@ snapshots: eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} + eventsource@2.0.2(patch_hash=tygaxpd33h24mrpcadqkqji6vy): {} exit-hook@2.2.1: {} @@ -5933,6 +6085,10 @@ snapshots: fast-uri@3.0.2: {} + fast-xml-parser@4.5.0: + dependencies: + strnum: 1.0.5 + fastparse@1.1.2: {} fastq@1.17.1: @@ -5978,6 +6134,8 @@ snapshots: dependencies: to-regex-range: 5.0.1 + filter-obj@1.1.0: {} + finalhandler@1.3.1: dependencies: debug: 2.6.9 @@ -6007,9 +6165,13 @@ snapshots: optionalDependencies: debug: 4.3.7 + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + foreground-child@3.1.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.5 signal-exit: 4.1.0 foreground-child@3.3.0: @@ -6029,6 +6191,12 @@ snapshots: fs-constants@1.0.0: {} + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -6191,7 +6359,6 @@ snapshots: has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 - optional: true hasown@2.0.2: dependencies: @@ -6266,12 +6433,21 @@ snapshots: ipaddr.js@1.9.1: {} + ipaddr.js@2.2.0: {} + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + is-arrayish@0.3.2: {} is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 + is-callable@1.2.7: {} + is-core-module@2.15.1: dependencies: hasown: 2.0.2 @@ -6286,6 +6462,10 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -6319,6 +6499,10 @@ snapshots: dependencies: better-path-resolve: 1.0.0 + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + is-valid-domain@0.1.6: dependencies: punycode: 2.3.1 @@ -6368,6 +6552,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jstransformer@1.0.0: dependencies: is-promise: 2.2.2 @@ -6679,6 +6869,23 @@ snapshots: minimist@1.2.8: {} + minio@8.0.2: + dependencies: + async: 3.2.4 + block-stream2: 2.1.0 + browser-or-node: 2.1.1 + buffer-crc32: 1.0.0 + eventemitter3: 5.0.1 + fast-xml-parser: 4.5.0 + ipaddr.js: 2.2.0 + lodash: 4.17.21 + mime-types: 2.1.35 + query-string: 7.1.3 + stream-json: 1.9.1 + through2: 4.0.2 + web-encoding: 1.1.5 + xml2js: 0.6.2 + minipass@7.1.2: {} mkdirp-classic@0.5.3: {} @@ -6810,7 +7017,7 @@ snapshots: password-prompt@1.1.3: dependencies: ansi-escapes: 4.3.2 - cross-spawn: 7.0.3 + cross-spawn: 7.0.5 path-exists@4.0.0: {} @@ -6874,6 +7081,8 @@ snapshots: pocketbase@0.21.5: {} + possible-typed-array-names@1.0.0: {} + postcss-import@15.1.0(postcss@8.4.47): dependencies: postcss: 8.4.47 @@ -7073,6 +7282,13 @@ snapshots: dependencies: side-channel: 1.0.6 + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + queue-microtask@1.2.3: {} range-parser@1.2.1: {} @@ -7226,6 +7442,8 @@ snapshots: immutable: 4.3.7 source-map-js: 1.2.1 + sax@1.4.1: {} + seek-bzip@1.0.6: dependencies: commander: 2.20.3 @@ -7371,6 +7589,8 @@ snapshots: split-ca@1.0.1: {} + split-on-first@1.1.0: {} + sprintf-js@1.0.3: {} sprintf-js@1.1.3: {} @@ -7394,6 +7614,14 @@ snapshots: stoppable@1.1.0: {} + stream-chain@2.2.5: {} + + stream-json@1.9.1: + dependencies: + stream-chain: 2.2.5 + + strict-uri-encode@2.0.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -7430,6 +7658,8 @@ snapshots: strip-json-comments@2.0.1: {} + strnum@1.0.5: {} + strtok3@7.0.0: dependencies: '@tokenizer/token': 0.3.0 @@ -7591,6 +7821,10 @@ snapshots: dependencies: any-promise: 1.3.0 + through2@4.0.2: + dependencies: + readable-stream: 3.6.2 + through@2.3.8: {} tiny-glob@0.2.9: @@ -7743,6 +7977,8 @@ snapshots: universalify@0.1.2: {} + universalify@2.0.1: {} + unpipe@1.0.0: {} update-browserslist-db@1.1.1(browserslist@4.24.0): @@ -7753,6 +7989,14 @@ snapshots: util-deprecate@1.0.2: {} + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.15 + utility-types@3.10.0: {} utils-merge@1.0.1: {} @@ -7793,6 +8037,12 @@ snapshots: void-elements@3.1.0: optional: true + web-encoding@1.1.5: + dependencies: + util: 0.12.5 + optionalDependencies: + '@zxing/text-encoding': 0.9.0 + web-streams-polyfill@3.2.1: {} webidl-conversions@4.0.2: {} @@ -7805,6 +8055,14 @@ snapshots: which-module@2.0.1: {} + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + which@1.3.1: dependencies: isexe: 2.0.0 @@ -7899,6 +8157,11 @@ snapshots: ws@8.18.0: {} + xml2js@0.6.2: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + xmlbuilder2@3.1.1: dependencies: '@oozcitak/dom': 1.15.10 @@ -7906,6 +8169,8 @@ snapshots: '@oozcitak/util': 8.3.8 js-yaml: 3.14.1 + xmlbuilder@11.0.1: {} + xtend@4.0.2: {} xxhash-wasm@1.0.2: {}