feat: Implement admin router and orchestrator for managing profiles and builds

- Added `adminRouter` for handling profile management, including listing, upserting, and updating statuses.
- Introduced `BuildRunner` interface and `PnpmBuildRunner` class for executing build commands.
- Created `GatewayOrchestrator` to manage profile states, reconcile processes, and handle build queues.
- Implemented `Pm2ProcessManager` for managing processes using PM2.
- Developed `GatewayProfileRepository` for interacting with the database to manage profiles.
- Added utility functions for resolving workspace roots and managing process definitions.
- Included tests for profile reconciliation logic.
This commit is contained in:
2026-01-01 10:38:28 +00:00
parent 79819c4a1b
commit b46249dcbc
18 changed files with 2151 additions and 7 deletions
+1
View File
@@ -23,6 +23,7 @@
"@trpc/server": "^11.4.4",
"date-fns": "^4.1.0",
"fastify": "^5.3.3",
"pm2": "^5.4.3",
"redis": "^5.10.0",
"zod": "^4.2.1"
}
+130
View File
@@ -0,0 +1,130 @@
import { TRPCError } from '@trpc/server';
import { z } from 'zod';
import { procedure, router } from './trpc.js';
import {
GATEWAY_BUILD_STATUSES,
GATEWAY_PROFILE_STATUSES,
} from './orchestrator/profileRepository.js';
const zProfileStatus = z.enum(GATEWAY_PROFILE_STATUSES);
const zBuildStatus = z.enum(GATEWAY_BUILD_STATUSES);
const adminProcedure = procedure.use(({ ctx, next }) => {
if (!ctx.adminToken) {
throw new TRPCError({
code: 'FORBIDDEN',
message: 'Admin token is not configured.',
});
}
const provided =
ctx.requestHeaders['x-admin-token'] ??
ctx.requestHeaders['authorization'] ??
'';
const token =
Array.isArray(provided) ? provided[0] ?? '' : (provided as string);
if (!token || token !== ctx.adminToken) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'Invalid admin token.',
});
}
return next();
});
export const adminRouter = router({
profiles: router({
list: adminProcedure.query(async ({ ctx }) => {
const profiles = await ctx.profiles.listProfiles();
const runtimeStates = await ctx.orchestrator.listRuntimeStates(
profiles.map((profile) => profile.profileName)
);
const runtimeMap = new Map(
runtimeStates.map((state) => [state.profileName, state])
);
return profiles.map((profile) => ({
...profile,
runtime: runtimeMap.get(profile.profileName) ?? {
profileName: profile.profileName,
apiRunning: false,
daemonRunning: false,
},
}));
}),
upsert: adminProcedure
.input(
z.object({
profile: z.string().min(1).max(32),
scenario: z.string().min(1).max(64),
apiPort: z.number().int().min(1).max(65535),
status: zProfileStatus.optional(),
scheduledStartAt: z.string().datetime().optional(),
})
)
.mutation(async ({ ctx, input }) => {
const status = input.status ?? 'STOPPED';
return ctx.profiles.upsertProfile({
profile: input.profile,
scenario: input.scenario,
apiPort: input.apiPort,
status,
scheduledStartAt: input.scheduledStartAt,
});
}),
setStatus: adminProcedure
.input(
z.object({
profileName: z.string().min(1),
status: zProfileStatus,
scheduledStartAt: z.string().datetime().optional(),
})
)
.mutation(async ({ ctx, input }) => {
if (input.status === 'RESERVED' && !input.scheduledStartAt) {
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'scheduledStartAt is required for RESERVED status.',
});
}
const result = await ctx.profiles.updateStatus(
input.profileName,
input.status,
input.status === 'RESERVED' ? input.scheduledStartAt : null
);
await ctx.orchestrator.reconcileNow();
return result;
}),
requestBuild: adminProcedure
.input(
z.object({
profileName: z.string().min(1),
})
)
.mutation(async ({ ctx, input }) => {
const requestedAt = new Date().toISOString();
const result = await ctx.profiles.updateBuildStatus(
input.profileName,
'QUEUED',
{
requestedAt,
error: null,
}
);
return result;
}),
setBuildStatus: adminProcedure
.input(
z.object({
profileName: z.string().min(1),
status: zBuildStatus,
})
)
.mutation(async ({ ctx, input }) =>
ctx.profiles.updateBuildStatus(input.profileName, input.status)
),
reconcileNow: adminProcedure.mutation(async ({ ctx }) => {
await ctx.orchestrator.reconcileNow();
return { ok: true };
}),
}),
});
+38
View File
@@ -12,6 +12,12 @@ export interface GatewayApiConfig {
kakaoAdminKey?: string;
kakaoRedirectUri: string;
publicBaseUrl: string;
adminToken?: string;
orchestratorEnabled: boolean;
orchestratorReconcileIntervalMs: number;
orchestratorScheduleIntervalMs: number;
orchestratorBuildIntervalMs: number;
workspaceRootHint: string;
}
const parseNumber = (value: string | undefined, fallback: number, label: string): number => {
@@ -25,6 +31,20 @@ const parseNumber = (value: string | undefined, fallback: number, label: string)
return parsed;
};
const parseBoolean = (value: string | undefined, fallback: boolean): boolean => {
if (!value) {
return fallback;
}
const normalized = value.trim().toLowerCase();
if (['1', 'true', 'yes', 'y', 'on'].includes(normalized)) {
return true;
}
if (['0', 'false', 'no', 'n', 'off'].includes(normalized)) {
return false;
}
return fallback;
};
export const resolveGatewayApiConfigFromEnv = (
env: NodeJS.ProcessEnv = process.env
): GatewayApiConfig => {
@@ -61,5 +81,23 @@ export const resolveGatewayApiConfigFromEnv = (
kakaoAdminKey: env.KAKAO_ADMIN_KEY,
kakaoRedirectUri,
publicBaseUrl,
adminToken: env.GATEWAY_ADMIN_TOKEN,
orchestratorEnabled: parseBoolean(env.GATEWAY_ORCHESTRATOR_ENABLED, true),
orchestratorReconcileIntervalMs: parseNumber(
env.GATEWAY_ORCHESTRATOR_RECONCILE_MS,
15000,
'GATEWAY_ORCHESTRATOR_RECONCILE_MS'
),
orchestratorScheduleIntervalMs: parseNumber(
env.GATEWAY_ORCHESTRATOR_SCHEDULE_MS,
5000,
'GATEWAY_ORCHESTRATOR_SCHEDULE_MS'
),
orchestratorBuildIntervalMs: parseNumber(
env.GATEWAY_ORCHESTRATOR_BUILD_MS,
10000,
'GATEWAY_ORCHESTRATOR_BUILD_MS'
),
workspaceRootHint: env.GATEWAY_WORKSPACE_ROOT ?? process.cwd(),
};
};
+14
View File
@@ -3,6 +3,8 @@ import type { GatewaySessionService } from './auth/sessionService.js';
import type { UserRepository } from './auth/userRepository.js';
import type { KakaoOAuthClient } from './auth/kakaoClient.js';
import type { OAuthSessionStore } from './auth/oauthSessionStore.js';
import type { GatewayProfileRepository } from './orchestrator/profileRepository.js';
import type { GatewayOrchestratorHandle } from './orchestrator/gatewayOrchestrator.js';
export interface GatewayApiContext {
users: UserRepository;
@@ -13,6 +15,10 @@ export interface GatewayApiContext {
kakaoClient: KakaoOAuthClient;
oauthSessions: OAuthSessionStore;
publicBaseUrl: string;
profiles: GatewayProfileRepository;
orchestrator: GatewayOrchestratorHandle;
adminToken?: string;
requestHeaders: Record<string, string | string[] | undefined>;
}
export const createGatewayApiContext = (options: {
@@ -24,6 +30,10 @@ export const createGatewayApiContext = (options: {
kakaoClient: KakaoOAuthClient;
oauthSessions: OAuthSessionStore;
publicBaseUrl: string;
profiles: GatewayProfileRepository;
orchestrator: GatewayOrchestratorHandle;
adminToken?: string;
requestHeaders?: Record<string, string | string[] | undefined>;
}): GatewayApiContext => ({
users: options.users,
sessions: options.sessions,
@@ -33,4 +43,8 @@ export const createGatewayApiContext = (options: {
kakaoClient: options.kakaoClient,
oauthSessions: options.oauthSessions,
publicBaseUrl: options.publicBaseUrl,
profiles: options.profiles,
orchestrator: options.orchestrator,
adminToken: options.adminToken,
requestHeaders: options.requestHeaders ?? {},
});
@@ -0,0 +1,63 @@
import { spawn } from 'node:child_process';
export interface BuildCommand {
command: string;
args: string[];
cwd: string;
env?: Record<string, string>;
}
export interface BuildResult {
ok: boolean;
exitCode: number | null;
output: string;
}
export interface BuildRunner {
run(commands: BuildCommand[]): Promise<BuildResult>;
}
const runCommand = (command: BuildCommand): Promise<BuildResult> =>
new Promise((resolve) => {
const child = spawn(command.command, command.args, {
cwd: command.cwd,
env: command.env,
stdio: ['ignore', 'pipe', 'pipe'],
});
let output = '';
child.stdout.on('data', (chunk) => {
output += chunk.toString();
});
child.stderr.on('data', (chunk) => {
output += chunk.toString();
});
child.on('close', (code) => {
resolve({
ok: code === 0,
exitCode: code,
output,
});
});
});
export class PnpmBuildRunner implements BuildRunner {
async run(commands: BuildCommand[]): Promise<BuildResult> {
let mergedOutput = '';
for (const command of commands) {
const result = await runCommand(command);
mergedOutput += result.output;
if (!result.ok) {
return {
ok: false,
exitCode: result.exitCode,
output: mergedOutput,
};
}
}
return {
ok: true,
exitCode: 0,
output: mergedOutput,
};
}
}
@@ -0,0 +1,328 @@
import path from 'node:path';
import type { BuildRunner } from './buildRunner.js';
import type { ProcessManager } from './processManager.js';
import type {
GatewayProfileRecord,
GatewayProfileRepository,
GatewayProfileStatus,
} from './profileRepository.js';
export interface GatewayProcessConfig {
workspaceRoot: string;
redisKeyPrefix: string;
gameTokenSecret: string;
baseEnv?: Record<string, string>;
}
export interface GatewayOrchestratorOptions {
repository: GatewayProfileRepository;
processManager: ProcessManager;
buildRunner: BuildRunner;
processConfig: GatewayProcessConfig;
reconcileIntervalMs: number;
scheduleIntervalMs: number;
buildIntervalMs: number;
now?: () => Date;
}
export interface ProfileRuntimeState {
apiRunning: boolean;
daemonRunning: boolean;
}
export interface ProfileRuntimeSnapshot extends ProfileRuntimeState {
profileName: string;
}
export interface GatewayOrchestratorHandle {
start(): void;
stop(): Promise<void>;
reconcileNow(): Promise<void>;
runScheduleNow(): Promise<void>;
runBuildQueueNow(): Promise<void>;
listRuntimeStates(profileNames: string[]): Promise<ProfileRuntimeSnapshot[]>;
}
export const planProfileReconcile = (
status: GatewayProfileStatus,
runtime: ProfileRuntimeState
): { shouldStart: boolean; shouldStop: boolean } => {
if (status === 'RUNNING') {
return {
shouldStart: !(runtime.apiRunning && runtime.daemonRunning),
shouldStop: false,
};
}
return {
shouldStart: false,
shouldStop: runtime.apiRunning || runtime.daemonRunning,
};
};
const buildProcessName = (profileName: string, role: 'api' | 'daemon'): string =>
`sammo:${profileName}:${role === 'api' ? 'game-api' : 'turn-daemon'}`;
const buildProcessDefinitions = (
profile: GatewayProfileRecord,
config: GatewayProcessConfig
): { api: { name: string; script: string; cwd: string; env: Record<string, string> };
daemon: { name: string; script: string; cwd: string; env: Record<string, string> } } => {
const baseEnv = { ...(config.baseEnv ?? {}) };
const apiName = buildProcessName(profile.profileName, 'api');
const daemonName = buildProcessName(profile.profileName, 'daemon');
const apiCwd = path.join(config.workspaceRoot, 'app', 'game-api');
const daemonCwd = path.join(config.workspaceRoot, 'app', 'game-engine');
const apiScript = path.join(apiCwd, 'dist', 'index.js');
const daemonScript = path.join(daemonCwd, 'dist', 'index.js');
const apiEnv = {
...baseEnv,
PROFILE: profile.profile,
SCENARIO: profile.scenario,
GAME_API_PORT: String(profile.apiPort),
GATEWAY_REDIS_PREFIX: config.redisKeyPrefix,
GAME_TOKEN_SECRET: config.gameTokenSecret,
};
const daemonEnv = {
...baseEnv,
TURN_PROFILE: profile.profile,
PROFILE: profile.profile,
SCENARIO: profile.scenario,
};
return {
api: {
name: apiName,
script: apiScript,
cwd: apiCwd,
env: apiEnv,
},
daemon: {
name: daemonName,
script: daemonScript,
cwd: daemonCwd,
env: daemonEnv,
},
};
};
const mapRuntimeStates = (
profileNames: string[],
processNames: Map<string, boolean>
): ProfileRuntimeSnapshot[] =>
profileNames.map((profileName) => {
const apiName = buildProcessName(profileName, 'api');
const daemonName = buildProcessName(profileName, 'daemon');
return {
profileName,
apiRunning: processNames.get(apiName) ?? false,
daemonRunning: processNames.get(daemonName) ?? false,
};
});
export class GatewayOrchestrator implements GatewayOrchestratorHandle {
private readonly repository: GatewayProfileRepository;
private readonly processManager: ProcessManager;
private readonly buildRunner: BuildRunner;
private readonly processConfig: GatewayProcessConfig;
private readonly reconcileIntervalMs: number;
private readonly scheduleIntervalMs: number;
private readonly buildIntervalMs: number;
private readonly now: () => Date;
private reconcileTimer?: NodeJS.Timeout;
private scheduleTimer?: NodeJS.Timeout;
private buildTimer?: NodeJS.Timeout;
private reconcileInFlight = false;
private scheduleInFlight = false;
private buildInFlight = false;
constructor(options: GatewayOrchestratorOptions) {
this.repository = options.repository;
this.processManager = options.processManager;
this.buildRunner = options.buildRunner;
this.processConfig = options.processConfig;
this.reconcileIntervalMs = options.reconcileIntervalMs;
this.scheduleIntervalMs = options.scheduleIntervalMs;
this.buildIntervalMs = options.buildIntervalMs;
this.now = options.now ?? (() => new Date());
}
start(): void {
void this.reconcileNow();
this.reconcileTimer = setInterval(
() => void this.reconcileNow(),
this.reconcileIntervalMs
);
this.scheduleTimer = setInterval(
() => void this.runScheduleNow(),
this.scheduleIntervalMs
);
this.buildTimer = setInterval(
() => void this.runBuildQueueNow(),
this.buildIntervalMs
);
}
async stop(): Promise<void> {
if (this.reconcileTimer) {
clearInterval(this.reconcileTimer);
}
if (this.scheduleTimer) {
clearInterval(this.scheduleTimer);
}
if (this.buildTimer) {
clearInterval(this.buildTimer);
}
}
async listRuntimeStates(profileNames: string[]): Promise<ProfileRuntimeSnapshot[]> {
const processStates = await this.loadProcessStatusMap();
return mapRuntimeStates(profileNames, processStates);
}
async reconcileNow(): Promise<void> {
if (this.reconcileInFlight) {
return;
}
this.reconcileInFlight = true;
try {
const profiles = await this.repository.listProfiles();
if (!profiles.length) {
return;
}
const processStates = await this.loadProcessStatusMap();
for (const profile of profiles) {
const runtime = mapRuntimeStates([profile.profileName], processStates)[0];
const plan = planProfileReconcile(profile.status, runtime);
if (plan.shouldStart) {
await this.startProfile(profile);
} else if (plan.shouldStop) {
await this.stopProfile(profile);
}
}
} finally {
this.reconcileInFlight = false;
}
}
async runScheduleNow(): Promise<void> {
if (this.scheduleInFlight) {
return;
}
this.scheduleInFlight = true;
try {
const now = this.now();
const due = await this.repository.listReservedToStart(now);
for (const profile of due) {
try {
await this.repository.updateStatus(
profile.profileName,
'RUNNING',
null
);
await this.startProfile(profile);
} catch (error) {
await this.repository.updateLastError(
profile.profileName,
error instanceof Error ? error.message : 'Failed to start scheduled profile.'
);
}
}
} finally {
this.scheduleInFlight = false;
}
}
async runBuildQueueNow(): Promise<void> {
if (this.buildInFlight) {
return;
}
this.buildInFlight = true;
try {
const queued = await this.repository.findQueuedBuild();
if (!queued) {
return;
}
const startedAt = this.now().toISOString();
await this.repository.updateBuildStatus(queued.profileName, 'RUNNING', {
startedAt,
error: null,
});
const result = await this.buildRunner.run([
{
command: 'pnpm',
args: ['--filter', '@sammo-ts/game-api', 'build'],
cwd: this.processConfig.workspaceRoot,
env: this.processConfig.baseEnv,
},
{
command: 'pnpm',
args: ['--filter', '@sammo-ts/game-engine', 'build'],
cwd: this.processConfig.workspaceRoot,
env: this.processConfig.baseEnv,
},
]);
const completedAt = this.now().toISOString();
if (result.ok) {
await this.repository.updateBuildStatus(queued.profileName, 'SUCCEEDED', {
completedAt,
error: null,
});
if (queued.status !== 'RUNNING' && queued.status !== 'DISABLED') {
await this.repository.updateStatus(
queued.profileName,
'COMPLETED',
queued.scheduledStartAt ? queued.scheduledStartAt : null
);
}
} else {
await this.repository.updateBuildStatus(queued.profileName, 'FAILED', {
completedAt,
error: result.output.slice(-4000),
});
}
} finally {
this.buildInFlight = false;
}
}
private async startProfile(profile: GatewayProfileRecord): Promise<void> {
const definitions = buildProcessDefinitions(profile, this.processConfig);
try {
await this.processManager.start(definitions.api);
await this.processManager.start(definitions.daemon);
await this.repository.updateLastError(profile.profileName, null);
} catch (error) {
await this.repository.updateLastError(
profile.profileName,
error instanceof Error ? error.message : 'Failed to start processes.'
);
}
}
private async stopProfile(profile: GatewayProfileRecord): Promise<void> {
const apiName = buildProcessName(profile.profileName, 'api');
const daemonName = buildProcessName(profile.profileName, 'daemon');
try {
await this.processManager.stop(apiName);
} catch {
await this.processManager.delete(apiName);
}
try {
await this.processManager.stop(daemonName);
} catch {
await this.processManager.delete(daemonName);
}
}
private async loadProcessStatusMap(): Promise<Map<string, boolean>> {
const processes = await this.processManager.list();
const statusMap = new Map<string, boolean>();
for (const process of processes) {
const status = process.status.toLowerCase();
const running =
status === 'online' || status === 'launching' || status === 'stopping';
statusMap.set(process.name, running);
}
return statusMap;
}
}
@@ -0,0 +1,106 @@
import { createRequire } from 'node:module';
import type { ProcessManager, ManagedProcessInfo, ProcessDefinition } from './processManager.js';
type Pm2Module = typeof import('pm2');
const require = createRequire(import.meta.url);
const loadPm2 = (): Pm2Module => require('pm2') as Pm2Module;
const withPm2 = async <T>(handler: (pm2: Pm2Module) => Promise<T>): Promise<T> => {
const pm2 = loadPm2();
await new Promise<void>((resolve, reject) => {
pm2.connect((error) => {
if (error) {
reject(error);
return;
}
resolve();
});
});
try {
return await handler(pm2);
} finally {
pm2.disconnect();
}
};
export class Pm2ProcessManager implements ProcessManager {
async list(): Promise<ManagedProcessInfo[]> {
return withPm2(
(pm2) =>
new Promise<ManagedProcessInfo[]>((resolve, reject) => {
pm2.list((error, list) => {
if (error) {
reject(error);
return;
}
const normalized =
list?.map((item) => ({
name: item.name ?? 'unknown',
status: item.pm2_env?.status ?? 'unknown',
pid: item.pid ?? undefined,
})) ?? [];
resolve(normalized);
});
})
);
}
async start(definition: ProcessDefinition): Promise<void> {
await withPm2(
(pm2) =>
new Promise<void>((resolve, reject) => {
pm2.start(
{
name: definition.name,
script: definition.script,
cwd: definition.cwd,
args: definition.args,
env: definition.env,
autorestart: true,
time: true,
},
(error) => {
if (error) {
reject(error);
return;
}
resolve();
}
);
})
);
}
async stop(name: string): Promise<void> {
await withPm2(
(pm2) =>
new Promise<void>((resolve, reject) => {
pm2.stop(name, (error) => {
if (error) {
reject(error);
return;
}
resolve();
});
})
);
}
async delete(name: string): Promise<void> {
await withPm2(
(pm2) =>
new Promise<void>((resolve, reject) => {
pm2.delete(name, (error) => {
if (error) {
reject(error);
return;
}
resolve();
});
})
);
}
}
@@ -0,0 +1,20 @@
export interface ManagedProcessInfo {
name: string;
status: string;
pid?: number;
}
export interface ProcessDefinition {
name: string;
script: string;
cwd: string;
args?: string[];
env?: Record<string, string>;
}
export interface ProcessManager {
list(): Promise<ManagedProcessInfo[]>;
start(definition: ProcessDefinition): Promise<void>;
stop(name: string): Promise<void>;
delete(name: string): Promise<void>;
}
@@ -0,0 +1,235 @@
import { Prisma, type PrismaClient } from '@prisma/client';
export const GATEWAY_PROFILE_STATUSES = [
'COMPLETED',
'RESERVED',
'RUNNING',
'STOPPED',
'DISABLED',
] as const;
export type GatewayProfileStatus = (typeof GATEWAY_PROFILE_STATUSES)[number];
export const GATEWAY_BUILD_STATUSES = [
'IDLE',
'QUEUED',
'RUNNING',
'FAILED',
'SUCCEEDED',
] as const;
export type GatewayBuildStatus = (typeof GATEWAY_BUILD_STATUSES)[number];
export interface GatewayProfileRecord {
profileName: string;
profile: string;
scenario: string;
apiPort: number;
status: GatewayProfileStatus;
buildStatus: GatewayBuildStatus;
scheduledStartAt?: string;
buildRequestedAt?: string;
buildStartedAt?: string;
buildCompletedAt?: string;
buildError?: string;
lastError?: string;
meta: Prisma.JsonObject;
createdAt: string;
updatedAt: string;
}
export interface GatewayProfileUpsertInput {
profile: string;
scenario: string;
apiPort: number;
status?: GatewayProfileStatus;
scheduledStartAt?: string;
meta?: Prisma.JsonObject;
}
export interface GatewayProfileRepository {
listProfiles(): Promise<GatewayProfileRecord[]>;
getProfile(profileName: string): Promise<GatewayProfileRecord | null>;
upsertProfile(input: GatewayProfileUpsertInput): Promise<GatewayProfileRecord>;
updateStatus(
profileName: string,
status: GatewayProfileStatus,
scheduledStartAt?: string | null
): Promise<GatewayProfileRecord | null>;
updateBuildStatus(
profileName: string,
status: GatewayBuildStatus,
fields?: {
requestedAt?: string | null;
startedAt?: string | null;
completedAt?: string | null;
error?: string | null;
}
): Promise<GatewayProfileRecord | null>;
listReservedToStart(now: Date): Promise<GatewayProfileRecord[]>;
findQueuedBuild(): Promise<GatewayProfileRecord | null>;
updateLastError(profileName: string, lastError: string | null): Promise<void>;
}
const toIso = (value: Date | null): string | undefined =>
value ? value.toISOString() : undefined;
const mapProfile = (row: {
profileName: string;
profile: string;
scenario: string;
apiPort: number;
status: GatewayProfileStatus;
buildStatus: GatewayBuildStatus;
scheduledStartAt: Date | null;
buildRequestedAt: Date | null;
buildStartedAt: Date | null;
buildCompletedAt: Date | null;
buildError: string | null;
lastError: string | null;
meta: Prisma.JsonValue;
createdAt: Date;
updatedAt: Date;
}): GatewayProfileRecord => ({
profileName: row.profileName,
profile: row.profile,
scenario: row.scenario,
apiPort: row.apiPort,
status: row.status,
buildStatus: row.buildStatus,
scheduledStartAt: toIso(row.scheduledStartAt),
buildRequestedAt: toIso(row.buildRequestedAt),
buildStartedAt: toIso(row.buildStartedAt),
buildCompletedAt: toIso(row.buildCompletedAt),
buildError: row.buildError ?? undefined,
lastError: row.lastError ?? undefined,
meta: (row.meta ?? {}) as Prisma.JsonObject,
createdAt: row.createdAt.toISOString(),
updatedAt: row.updatedAt.toISOString(),
});
const buildProfileName = (profile: string, scenario: string): string =>
`${profile}:${scenario}`;
export const createGatewayProfileRepository = (
prisma: PrismaClient
): GatewayProfileRepository => ({
async listProfiles(): Promise<GatewayProfileRecord[]> {
const rows = await prisma.gatewayProfile.findMany({
orderBy: [{ profile: 'asc' }, { scenario: 'asc' }],
});
return rows.map(mapProfile);
},
async getProfile(profileName: string): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.findUnique({
where: { profileName },
});
return row ? mapProfile(row) : null;
},
async upsertProfile(input: GatewayProfileUpsertInput): Promise<GatewayProfileRecord> {
const profileName = buildProfileName(input.profile, input.scenario);
const row = await prisma.gatewayProfile.upsert({
where: { profileName },
create: {
profileName,
profile: input.profile,
scenario: input.scenario,
apiPort: input.apiPort,
status: input.status ?? 'STOPPED',
scheduledStartAt: input.scheduledStartAt
? new Date(input.scheduledStartAt)
: null,
meta: (input.meta ?? {}) as Prisma.JsonObject,
},
update: {
apiPort: input.apiPort,
status: input.status,
scheduledStartAt: input.scheduledStartAt
? new Date(input.scheduledStartAt)
: input.scheduledStartAt === null
? null
: undefined,
meta: input.meta ? (input.meta as Prisma.JsonObject) : undefined,
},
});
return mapProfile(row);
},
async updateStatus(
profileName: string,
status: GatewayProfileStatus,
scheduledStartAt?: string | null
): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.update({
where: { profileName },
data: {
status,
scheduledStartAt:
scheduledStartAt === undefined
? undefined
: scheduledStartAt
? new Date(scheduledStartAt)
: null,
},
});
return row ? mapProfile(row) : null;
},
async updateBuildStatus(
profileName: string,
status: GatewayBuildStatus,
fields?: {
requestedAt?: string | null;
startedAt?: string | null;
completedAt?: string | null;
error?: string | null;
}
): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.update({
where: { profileName },
data: {
buildStatus: status,
buildRequestedAt:
fields?.requestedAt === undefined
? undefined
: fields?.requestedAt
? new Date(fields.requestedAt)
: null,
buildStartedAt:
fields?.startedAt === undefined
? undefined
: fields?.startedAt
? new Date(fields.startedAt)
: null,
buildCompletedAt:
fields?.completedAt === undefined
? undefined
: fields?.completedAt
? new Date(fields.completedAt)
: null,
buildError: fields?.error === undefined ? undefined : fields.error,
},
});
return row ? mapProfile(row) : null;
},
async listReservedToStart(now: Date): Promise<GatewayProfileRecord[]> {
const rows = await prisma.gatewayProfile.findMany({
where: {
status: 'RESERVED',
scheduledStartAt: {
lte: now,
},
},
});
return rows.map(mapProfile);
},
async findQueuedBuild(): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.findFirst({
where: { buildStatus: 'QUEUED' },
orderBy: { buildRequestedAt: 'asc' },
});
return row ? mapProfile(row) : null;
},
async updateLastError(profileName: string, lastError: string | null): Promise<void> {
await prisma.gatewayProfile.update({
where: { profileName },
data: { lastError },
});
},
});
@@ -0,0 +1,25 @@
import fs from 'node:fs';
import path from 'node:path';
const WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'package.json'];
const hasWorkspaceMarker = (dir: string): boolean =>
WORKSPACE_MARKERS.some((marker) => fs.existsSync(path.join(dir, marker)));
export const resolveWorkspaceRoot = (
startDir: string,
maxDepth = 5
): string => {
let current = path.resolve(startDir);
for (let depth = 0; depth <= maxDepth; depth += 1) {
if (hasWorkspaceMarker(current)) {
return current;
}
const parent = path.dirname(current);
if (parent === current) {
break;
}
current = parent;
}
return path.resolve(startDir);
};
+2
View File
@@ -9,6 +9,7 @@ import { decryptGameSessionToken, encryptGameSessionToken } from '@sammo-ts/comm
import { procedure, router } from './trpc.js';
import { toPublicUser } from './auth/userRepository.js';
import type { UserOAuthInfo } from './auth/userRepository.js';
import { adminRouter } from './adminRouter.js';
const zUsername = z.string().min(2).max(32);
const zPassword = z.string().min(6).max(128);
@@ -27,6 +28,7 @@ export const appRouter = router({
now: new Date().toISOString(),
})),
}),
admin: adminRouter,
auth: router({
kakaoStart: procedure
.input(
+45 -2
View File
@@ -1,4 +1,4 @@
import fastify from 'fastify';
import fastify, { type FastifyRequest } from 'fastify';
import cors from '@fastify/cors';
import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
import type { PrismaClient } from '@prisma/client';
@@ -16,8 +16,20 @@ import { KakaoOAuthClient } from './auth/kakaoClient.js';
import { RedisOAuthSessionStore } from './auth/oauthSessionStore.js';
import { createPostgresUserRepository } from './auth/postgresUserRepository.js';
import { RedisGatewaySessionService } from './auth/redisSessionService.js';
import { createGatewayProfileRepository } from './orchestrator/profileRepository.js';
import { GatewayOrchestrator } from './orchestrator/gatewayOrchestrator.js';
import { Pm2ProcessManager } from './orchestrator/pm2ProcessManager.js';
import { PnpmBuildRunner } from './orchestrator/buildRunner.js';
import { resolveWorkspaceRoot } from './orchestrator/workspaceRoot.js';
import { appRouter } from './router.js';
const buildEnvMap = (env: NodeJS.ProcessEnv): Record<string, string> => {
const entries = Object.entries(env).filter(
(entry): entry is [string, string] => typeof entry[1] === 'string'
);
return Object.fromEntries(entries);
};
export const createGatewayApiServer = async () => {
const config = resolveGatewayApiConfigFromEnv();
const postgres = createPostgresConnector(resolvePostgresConfigFromEnv());
@@ -45,6 +57,28 @@ export const createGatewayApiServer = async () => {
config.oauthSessionTtlSeconds
);
const profiles = createGatewayProfileRepository(
postgres.prisma as PrismaClient
);
const workspaceRoot = resolveWorkspaceRoot(config.workspaceRootHint);
const processManager = new Pm2ProcessManager();
const buildRunner = new PnpmBuildRunner();
const baseEnv = buildEnvMap(process.env);
const orchestrator = new GatewayOrchestrator({
repository: profiles,
processManager,
buildRunner,
processConfig: {
workspaceRoot,
redisKeyPrefix: config.redisKeyPrefix,
gameTokenSecret: config.gameTokenSecret,
baseEnv,
},
reconcileIntervalMs: config.orchestratorReconcileIntervalMs,
scheduleIntervalMs: config.orchestratorScheduleIntervalMs,
buildIntervalMs: config.orchestratorBuildIntervalMs,
});
const app = fastify({
logger: true,
});
@@ -58,7 +92,7 @@ export const createGatewayApiServer = async () => {
prefix: config.trpcPath,
trpcOptions: {
router: appRouter,
createContext: () =>
createContext: ({ req }: { req: FastifyRequest }) =>
createGatewayApiContext({
users,
sessions,
@@ -68,6 +102,10 @@ export const createGatewayApiServer = async () => {
kakaoClient,
oauthSessions,
publicBaseUrl: config.publicBaseUrl,
profiles,
orchestrator,
adminToken: config.adminToken,
requestHeaders: req.headers,
}),
},
});
@@ -76,7 +114,12 @@ export const createGatewayApiServer = async () => {
ok: true,
}));
if (config.orchestratorEnabled) {
orchestrator.start();
}
app.addHook('onClose', async () => {
await orchestrator.stop();
await redis.disconnect();
await postgres.disconnect();
});
+23
View File
@@ -36,6 +36,26 @@ const buildCaller = () => {
}),
sendTalkMessage: async () => {},
};
const profiles = {
listProfiles: async () => [],
getProfile: async () => null,
upsertProfile: async () => {
throw new Error('not used');
},
updateStatus: async () => null,
updateBuildStatus: async () => null,
listReservedToStart: async () => [],
findQueuedBuild: async () => null,
updateLastError: async () => {},
};
const orchestrator = {
start: () => {},
stop: async () => {},
reconcileNow: async () => {},
runScheduleNow: async () => {},
runBuildQueueNow: async () => {},
listRuntimeStates: async () => [],
};
const caller = appRouter.createCaller(
createGatewayApiContext({
users,
@@ -46,6 +66,9 @@ const buildCaller = () => {
kakaoClient,
oauthSessions,
publicBaseUrl: 'http://localhost',
profiles,
orchestrator,
requestHeaders: {},
})
);
return { caller, oauthSessions };
@@ -0,0 +1,41 @@
import { describe, expect, it } from 'vitest';
import { planProfileReconcile } from '../src/orchestrator/gatewayOrchestrator.js';
describe('planProfileReconcile', () => {
it('starts missing processes for running profiles', () => {
expect(
planProfileReconcile('RUNNING', {
apiRunning: true,
daemonRunning: false,
})
).toEqual({ shouldStart: true, shouldStop: false });
});
it('does nothing when running profile is healthy', () => {
expect(
planProfileReconcile('RUNNING', {
apiRunning: true,
daemonRunning: true,
})
).toEqual({ shouldStart: false, shouldStop: false });
});
it('stops processes for non-running profiles', () => {
expect(
planProfileReconcile('STOPPED', {
apiRunning: false,
daemonRunning: true,
})
).toEqual({ shouldStart: false, shouldStop: true });
});
it('keeps reserved profiles off', () => {
expect(
planProfileReconcile('RESERVED', {
apiRunning: false,
daemonRunning: false,
})
).toEqual({ shouldStart: false, shouldStop: false });
});
});
+41
View File
@@ -17,6 +17,47 @@ selection is required because it drives unit sets and DB settings.
- Prefer `legacy/hwe/ts/util/LiteHashDRBG.ts` and `legacy/hwe/ts/util/RNG.ts`
- Seed composition should include hidden base seed plus action context
## Gateway Orchestration (Single Host Draft)
Gateway API is the single source of truth for profile state and reconciles
PM2-managed processes on boot and on a short interval. The DB owns the desired
state; PM2 is treated as the actuator. The runtime state is grouped so that
`game-api` + `turn-daemon` are either on together or off together.
### DB-Owned Profile State
Profiles are tracked by `profileName` (= `${profile}:${scenario}`).
Gateway loads the profile table on boot, then reconciles PM2 to match.
- `완료됨` (COMPLETED): build output exists; processes should be off.
- `예약됨` (RESERVED): start is scheduled for a timestamp; processes off.
- `가동중` (RUNNING): both `game-api` and `turn-daemon` should be on.
- `정지됨` (STOPPED): processes off; may be resumed later.
- `비활성화` (DISABLED): excluded from orchestration; start forbidden.
### Boot Reconciliation
1) Load profile rows from DB.
2) List PM2 processes and map `profileName -> running state`.
3) For each profile:
- If desired `RUNNING` and any process is missing, start missing processes.
- If desired not `RUNNING` and any process is running, stop both processes.
4) Persist errors to DB for audit.
### Internal Scheduler (Gateway Cron)
Gateway runs a lightweight cron loop (setInterval) that:
- Promotes `RESERVED` profiles whose `scheduledStartAt <= now` to `RUNNING`.
- Triggers a reconcile immediately after promotion.
- Optionally drains a build queue (see build workflow).
### Build Workflow (Admin)
- Admin triggers a build request for a profile.
- Gateway queues a build job, runs `pnpm --filter @sammo-ts/game-api build`
and `pnpm --filter @sammo-ts/game-engine build`, then marks build success/failure.
- On success, profile status remains `COMPLETED` (or stays `RUNNING` if already on).
## Current Implementation Status
- Turn daemon lifecycle + in-memory state live in `app/game-engine` with DB flush hooks.
+2 -1
View File
@@ -14,7 +14,6 @@ Move items into the main docs once they are finalized.
- [AI suggestion] Implement diplomacy/state transitions and monthly/command-based updates beyond read-only maps.
- [AI suggestion] Integrate war/battle pipeline into turn processing (troop movement/war resolution hooks, not just isolated sim jobs).
- [AI suggestion] Expand turn command catalog beyond the current subset (general/nation commands).
- [AI suggestion] Replace in-memory control queue with distributed control/lock primitives for multi-instance daemon operation.
## Runtime and Operations (Lower Priority)
@@ -23,6 +22,8 @@ Move items into the main docs once they are finalized.
- Document existing status/health endpoint requirements for ops and the current daemon loop behavior.
- Document tick budget settings (wall time, max generals, catch-up cap) and partial progress persistence.
- Document admin controls (pause/resume/manual run) and how they interact with lock/state.
- [AI suggestion] Define gateway admin build/daemon control approach (direct orchestration vs supervisor like systemd/pm2), security model, audit logging, and safe rollback/stop/start workflows.
- [AI suggestion] Specify single-host gateway orchestration: boot reconciliation from DB (완료/예약/가동중/정지됨/비활성화), desired-state mapping, and pm2-managed process lifecycles for api/daemon.
- Turn daemon vs API server priority policy under load
- Recovery behavior after partial flush or crash
- Observability: metrics, logs, and alerts for turn processing
+37
View File
@@ -27,6 +27,22 @@ enum OAuthType {
KAKAO
}
enum GatewayProfileStatus {
COMPLETED
RESERVED
RUNNING
STOPPED
DISABLED
}
enum GatewayBuildStatus {
IDLE
QUEUED
RUNNING
FAILED
SUCCEEDED
}
model AppUser {
id String @id @default(uuid())
loginId String @unique @map("login_id")
@@ -46,6 +62,27 @@ model AppUser {
@@map("app_user")
}
model GatewayProfile {
profileName String @id @map("profile_name")
profile String
scenario String
apiPort Int @map("api_port")
status GatewayProfileStatus
buildStatus GatewayBuildStatus @default(IDLE) @map("build_status")
scheduledStartAt DateTime? @map("scheduled_start_at")
buildRequestedAt DateTime? @map("build_requested_at")
buildStartedAt DateTime? @map("build_started_at")
buildCompletedAt DateTime? @map("build_completed_at")
buildError String? @map("build_error")
lastError String? @map("last_error")
meta Json @default(dbgenerated("'{}'::jsonb"))
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@unique([profile, scenario])
@@map("gateway_profile")
}
model WorldState {
id Int @id @default(autoincrement())
scenarioCode String @map("scenario_code")
+1000 -4
View File
@@ -60,9 +60,6 @@ importers:
app/game-engine:
dependencies:
'@prisma/client':
specifier: ^7.2.0
version: 7.2.0(prisma@7.2.0(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3)
'@sammo-ts/common':
specifier: workspace:*
version: link:../../packages/common
@@ -111,6 +108,9 @@ importers:
fastify:
specifier: ^5.3.3
version: 5.6.2
pm2:
specifier: ^5.4.3
version: 5.4.3
redis:
specifier: ^5.10.0
version: 5.10.0
@@ -459,6 +459,20 @@ packages:
'@pinojs/redact@0.4.0':
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
'@pm2/agent@2.0.4':
resolution: {integrity: sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==}
'@pm2/io@6.0.1':
resolution: {integrity: sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA==}
engines: {node: '>=6.0'}
'@pm2/js-api@0.8.0':
resolution: {integrity: sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==}
engines: {node: '>=4.0'}
'@pm2/pm2-version-check@1.0.4':
resolution: {integrity: sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==}
'@prisma/adapter-pg@7.2.0':
resolution: {integrity: sha512-euIdQ13cRB2wZ3jPsnDnFhINquo1PYFPCg6yVL8b2rp3EdinQHsX9EDdCtRr489D5uhphcRk463OdQAFlsCr0w==}
@@ -741,6 +755,9 @@ packages:
'@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
'@tootallnate/quickjs-emscripten@0.23.0':
resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
'@trpc/server@11.8.1':
resolution: {integrity: sha512-P4rzZRpEL7zDFgjxK65IdyH0e41FMFfTkQkuq0BA5tKcr7E6v9/v38DEklCpoDN6sPiB1Sigy/PUEzHENhswDA==}
peerDependencies:
@@ -799,6 +816,10 @@ packages:
abstract-logging@2.0.1:
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
agent-base@7.1.4:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'}
ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies:
@@ -810,10 +831,31 @@ packages:
ajv@8.17.1:
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
amp-message@0.1.2:
resolution: {integrity: sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==}
amp@0.3.1:
resolution: {integrity: sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==}
ansi-colors@4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansis@4.2.0:
resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==}
engines: {node: '>=14'}
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
assertion-error@2.0.1:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
@@ -822,6 +864,16 @@ packages:
resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==}
engines: {node: '>=20.19.0'}
ast-types@0.13.4:
resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
engines: {node: '>=4'}
async@2.6.4:
resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==}
async@3.2.6:
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
atomic-sleep@1.0.0:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
@@ -833,9 +885,32 @@ packages:
resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==}
engines: {node: '>= 6.0.0'}
basic-ftp@5.1.0:
resolution: {integrity: sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==}
engines: {node: '>=10.0.0'}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
birpc@4.0.0:
resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==}
blessed@0.1.81:
resolution: {integrity: sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==}
engines: {node: '>= 0.8.0'}
hasBin: true
bodec@0.1.0:
resolution: {integrity: sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
c12@3.1.0:
resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==}
peerDependencies:
@@ -852,9 +927,20 @@ packages:
resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
engines: {node: '>=18'}
chalk@3.0.0:
resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
engines: {node: '>=8'}
charm@0.1.2:
resolution: {integrity: sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==}
chevrotain@10.5.0:
resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
@@ -862,10 +948,24 @@ packages:
citty@0.1.6:
resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
cli-tableau@2.0.1:
resolution: {integrity: sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==}
engines: {node: '>=8.10.0'}
cluster-key-slot@1.1.2:
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
engines: {node: '>=0.10.0'}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
commander@2.15.1:
resolution: {integrity: sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==}
confbox@0.2.2:
resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==}
@@ -877,6 +977,9 @@ packages:
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
engines: {node: '>=18'}
croner@4.1.97:
resolution: {integrity: sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -884,9 +987,39 @@ packages:
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
culvert@0.1.2:
resolution: {integrity: sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==}
data-uri-to-buffer@6.0.2:
resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
engines: {node: '>= 14'}
date-fns@4.1.0:
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
dayjs@1.11.19:
resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==}
dayjs@1.8.36:
resolution: {integrity: sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==}
debug@3.2.7:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
debug@4.3.7:
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
@@ -903,6 +1036,10 @@ packages:
defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
degenerator@5.0.1:
resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
engines: {node: '>= 14'}
denque@2.1.0:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
engines: {node: '>=0.10'}
@@ -938,6 +1075,10 @@ packages:
resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==}
engines: {node: '>=14'}
enquirer@2.3.6:
resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==}
engines: {node: '>=8.6'}
es-module-lexer@1.7.0:
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
@@ -946,9 +1087,40 @@ packages:
engines: {node: '>=18'}
hasBin: true
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
escodegen@2.1.0:
resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
engines: {node: '>=6.0'}
hasBin: true
esprima@4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
estraverse@5.3.0:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
eventemitter2@0.4.14:
resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==}
eventemitter2@5.0.1:
resolution: {integrity: sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==}
eventemitter2@6.4.9:
resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==}
expect-type@1.3.0:
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
engines: {node: '>=12.0.0'}
@@ -956,6 +1128,9 @@ packages:
exsolve@1.0.8:
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
extrareqp2@1.0.0:
resolution: {integrity: sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==}
fast-check@3.23.2:
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
engines: {node: '>=8.0.0'}
@@ -966,6 +1141,9 @@ packages:
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-json-patch@3.1.1:
resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==}
fast-json-stringify@6.1.1:
resolution: {integrity: sha512-DbgptncYEXZqDUOEl4krff4mUiVrTZZVI7BBrQR/T3BqMj/eM1flTC1Uk2uUoLcWCxjT95xKulV/Lc6hhOZsBQ==}
@@ -984,6 +1162,9 @@ packages:
fastq@1.20.1:
resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
fclone@1.0.11:
resolution: {integrity: sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==}
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@@ -993,10 +1174,23 @@ packages:
picomatch:
optional: true
fill-range@7.1.1:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
find-my-way@9.3.0:
resolution: {integrity: sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==}
engines: {node: '>=20'}
follow-redirects@1.15.11:
resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
foreground-child@3.3.1:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
@@ -1006,6 +1200,9 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
generate-function@2.3.1:
resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
@@ -1015,10 +1212,29 @@ packages:
get-tsconfig@4.13.0:
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
get-uri@6.0.5:
resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==}
engines: {node: '>= 14'}
giget@2.0.0:
resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
hasBin: true
git-node-fs@1.0.0:
resolution: {integrity: sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==}
peerDependencies:
js-git: ^0.7.8
peerDependenciesMeta:
js-git:
optional: true
git-sha1@0.1.2:
resolution: {integrity: sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==}
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
globrex@0.1.2:
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
@@ -1028,6 +1244,14 @@ packages:
grammex@3.1.12:
resolution: {integrity: sha512-6ufJOsSA7LcQehIJNCO7HIBykfM7DXQual0Ny780/DEcJIpBlHRvcqEBWGPYd7hrXL2GJ3oJI1MIhaXjWmLQOQ==}
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
hasown@2.0.2:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
hono@4.10.6:
resolution: {integrity: sha512-BIdolzGpDO9MQ4nu3AUuDwHZZ+KViNm+EZ75Ae55eMXMqLVhDFqEMXxtUe9Qh8hjL+pIna/frs2j6Y2yD5Ua/g==}
engines: {node: '>=16.9.0'}
@@ -1035,9 +1259,21 @@ packages:
hookable@6.0.1:
resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==}
http-proxy-agent@7.0.2:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'}
http-status-codes@2.3.0:
resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==}
https-proxy-agent@7.0.6:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
iconv-lite@0.7.1:
resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==}
engines: {node: '>=0.10.0'}
@@ -1046,10 +1282,37 @@ packages:
resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==}
engines: {node: '>=20.19.0'}
ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
ip-address@10.1.0:
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
engines: {node: '>= 12'}
ipaddr.js@2.3.0:
resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==}
engines: {node: '>= 10'}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
is-core-module@2.16.1:
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
engines: {node: '>= 0.4'}
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
is-property@1.0.2:
resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==}
@@ -1060,9 +1323,16 @@ packages:
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
js-git@0.7.8:
resolution: {integrity: sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==}
js-sha512@0.9.0:
resolution: {integrity: sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==}
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
@@ -1074,6 +1344,13 @@ packages:
json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json-stringify-safe@5.0.1:
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
lazy@1.0.11:
resolution: {integrity: sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==}
engines: {node: '>=0.2.0'}
light-my-request@6.6.0:
resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==}
@@ -1087,6 +1364,14 @@ packages:
long@5.3.2:
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
lru-cache@6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
lru-cache@7.18.3:
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
engines: {node: '>=12'}
lru.min@1.1.3:
resolution: {integrity: sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q==}
engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'}
@@ -1094,9 +1379,20 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
hasBin: true
module-details-from-path@1.0.4:
resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==}
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
mute-stream@0.0.8:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
mysql2@3.15.3:
resolution: {integrity: sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==}
engines: {node: '>= 8.0'}
@@ -1110,9 +1406,26 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
needle@2.4.0:
resolution: {integrity: sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==}
engines: {node: '>= 4.4.x'}
hasBin: true
netmask@2.0.2:
resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
engines: {node: '>= 0.4.0'}
node-fetch-native@1.6.7:
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
nssocket@0.6.0:
resolution: {integrity: sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==}
engines: {node: '>= 0.10.x'}
nypm@0.6.2:
resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==}
engines: {node: ^14.16.0 || >=16.10.0}
@@ -1128,10 +1441,24 @@ packages:
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
engines: {node: '>=14.0.0'}
pac-proxy-agent@7.2.0:
resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==}
engines: {node: '>= 14'}
pac-resolver@7.0.1:
resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==}
engines: {node: '>= 14'}
pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
@@ -1175,10 +1502,22 @@ packages:
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
picomatch@4.0.3:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
pidusage@2.0.21:
resolution: {integrity: sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==}
engines: {node: '>=8'}
pidusage@3.0.2:
resolution: {integrity: sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==}
engines: {node: '>=10'}
pino-abstract-transport@2.0.0:
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
@@ -1192,6 +1531,29 @@ packages:
pkg-types@2.3.0:
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
pm2-axon-rpc@0.7.1:
resolution: {integrity: sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==}
engines: {node: '>=5'}
pm2-axon@4.0.1:
resolution: {integrity: sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==}
engines: {node: '>=5'}
pm2-deploy@1.0.2:
resolution: {integrity: sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==}
engines: {node: '>=4.0.0'}
pm2-multimeter@0.1.2:
resolution: {integrity: sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==}
pm2-sysmonit@1.2.8:
resolution: {integrity: sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==}
pm2@5.4.3:
resolution: {integrity: sha512-4/I1htIHzZk1Y67UgOCo4F1cJtas1kSds31N8zN0PybO230id1nigyjGuGFzUnGmUFPmrJ0On22fO1ChFlp7VQ==}
engines: {node: '>=12.0.0'}
hasBin: true
postcss@8.5.6:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
@@ -1239,9 +1601,19 @@ packages:
process-warning@5.0.0:
resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==}
promptly@2.2.0:
resolution: {integrity: sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==}
proper-lockfile@4.1.2:
resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==}
proxy-agent@6.3.1:
resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==}
engines: {node: '>= 14'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
pure-rand@6.1.0:
resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
@@ -1263,6 +1635,14 @@ packages:
resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==}
engines: {node: '>=0.10.0'}
read@1.0.7:
resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==}
engines: {node: '>=0.8'}
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
@@ -1285,9 +1665,18 @@ packages:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
require-in-the-middle@5.2.0:
resolution: {integrity: sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==}
engines: {node: '>=6'}
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
resolve@1.22.11:
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
engines: {node: '>= 0.4'}
hasBin: true
ret@0.5.0:
resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==}
engines: {node: '>=10'}
@@ -1332,6 +1721,12 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
run-series@1.1.9:
resolution: {integrity: sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==}
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
safe-regex2@5.0.0:
resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==}
@@ -1342,12 +1737,20 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
sax@1.4.3:
resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==}
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
secure-json-parse@4.1.0:
resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==}
semver@7.5.4:
resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
engines: {node: '>=10'}
hasBin: true
semver@7.7.3:
resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==}
engines: {node: '>=10'}
@@ -1367,6 +1770,9 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
shimmer@1.2.1:
resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==}
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
@@ -1377,6 +1783,18 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
smart-buffer@4.2.0:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
socks-proxy-agent@8.0.5:
resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==}
engines: {node: '>= 14'}
socks@2.8.7:
resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==}
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
sonic-boom@4.2.0:
resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==}
@@ -1384,10 +1802,20 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
split2@4.2.0:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
sprintf-js@1.1.2:
resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==}
sqlstring@2.3.3:
resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==}
engines: {node: '>= 0.6'}
@@ -1401,6 +1829,20 @@ packages:
std-env@3.9.0:
resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
systeminformation@5.28.8:
resolution: {integrity: sha512-W2rXK+tTIoa1svfOEfhKPzJTw2OnoJ2XS57CftQkzvwt9Hj7RC2pfHKFAk8cHH+UkDAlGMW9Sf31kdOu5PZNIA==}
engines: {node: '>=8.0.0'}
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
hasBin: true
thread-stream@3.1.0:
resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==}
@@ -1419,6 +1861,10 @@ packages:
resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==}
engines: {node: '>=14.0.0'}
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
toad-cache@3.7.0:
resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==}
engines: {node: '>=12'}
@@ -1462,9 +1908,19 @@ packages:
unplugin-unused:
optional: true
tslib@1.9.3:
resolution: {integrity: sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==}
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
tv4@1.3.0:
resolution: {integrity: sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==}
engines: {node: '>= 0.8.0'}
tx2@1.0.5:
resolution: {integrity: sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==}
type-fest@4.41.0:
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
engines: {node: '>=16'}
@@ -1580,6 +2036,10 @@ packages:
jsdom:
optional: true
vizion@2.2.1:
resolution: {integrity: sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==}
engines: {node: '>=4.0'}
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@@ -1590,10 +2050,25 @@ packages:
engines: {node: '>=8'}
hasBin: true
ws@7.5.10:
resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==}
engines: {node: '>=8.3.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
zeptomatch@2.0.2:
resolution: {integrity: sha512-H33jtSKf8Ijtb5BW6wua3G5DhnFjbFML36eFu+VdOoVY4HD9e7ggjqdM6639B+L87rjnR6Y+XeRzBXZdy52B/g==}
@@ -1804,6 +2279,57 @@ snapshots:
'@pinojs/redact@0.4.0': {}
'@pm2/agent@2.0.4':
dependencies:
async: 3.2.6
chalk: 3.0.0
dayjs: 1.8.36
debug: 4.3.7
eventemitter2: 5.0.1
fast-json-patch: 3.1.1
fclone: 1.0.11
nssocket: 0.6.0
pm2-axon: 4.0.1
pm2-axon-rpc: 0.7.1
proxy-agent: 6.3.1
semver: 7.5.4
ws: 7.5.10
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@pm2/io@6.0.1':
dependencies:
async: 2.6.4
debug: 4.3.7
eventemitter2: 6.4.9
require-in-the-middle: 5.2.0
semver: 7.5.4
shimmer: 1.2.1
signal-exit: 3.0.7
tslib: 1.9.3
transitivePeerDependencies:
- supports-color
'@pm2/js-api@0.8.0':
dependencies:
async: 2.6.4
debug: 4.3.7
eventemitter2: 6.4.9
extrareqp2: 1.0.0(debug@4.3.7)
ws: 7.5.10
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@pm2/pm2-version-check@1.0.4':
dependencies:
debug: 4.4.3
transitivePeerDependencies:
- supports-color
'@prisma/adapter-pg@7.2.0':
dependencies:
'@prisma/driver-adapter-utils': 7.2.0
@@ -2026,6 +2552,8 @@ snapshots:
'@standard-schema/spec@1.1.0': {}
'@tootallnate/quickjs-emscripten@0.23.0': {}
'@trpc/server@11.8.1(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
@@ -2099,6 +2627,8 @@ snapshots:
abstract-logging@2.0.1: {}
agent-base@7.1.4: {}
ajv-formats@3.0.1(ajv@8.17.1):
optionalDependencies:
ajv: 8.17.1
@@ -2110,8 +2640,27 @@ snapshots:
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
amp-message@0.1.2:
dependencies:
amp: 0.3.1
amp@0.3.1: {}
ansi-colors@4.1.3: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
ansis@4.2.0: {}
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
argparse@2.0.1: {}
assertion-error@2.0.1: {}
ast-kit@2.2.0:
@@ -2119,6 +2668,16 @@ snapshots:
'@babel/parser': 7.28.5
pathe: 2.0.3
ast-types@0.13.4:
dependencies:
tslib: 2.8.1
async@2.6.4:
dependencies:
lodash: 4.17.21
async@3.2.6: {}
atomic-sleep@1.0.0: {}
avvio@9.1.0:
@@ -2128,8 +2687,22 @@ snapshots:
aws-ssl-profiles@1.1.2: {}
basic-ftp@5.1.0: {}
binary-extensions@2.3.0: {}
birpc@4.0.0: {}
blessed@0.1.81: {}
bodec@0.1.0: {}
braces@3.0.3:
dependencies:
fill-range: 7.1.1
buffer-from@1.1.2: {}
c12@3.1.0:
dependencies:
chokidar: 4.0.3
@@ -2149,6 +2722,13 @@ snapshots:
chai@6.2.2: {}
chalk@3.0.0:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
charm@0.1.2: {}
chevrotain@10.5.0:
dependencies:
'@chevrotain/cst-dts-gen': 10.5.0
@@ -2158,6 +2738,18 @@ snapshots:
lodash: 4.17.21
regexp-to-ast: 0.5.0
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.3
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
@@ -2166,14 +2758,28 @@ snapshots:
dependencies:
consola: 3.4.2
cli-tableau@2.0.1:
dependencies:
chalk: 3.0.0
cluster-key-slot@1.1.2: {}
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
commander@2.15.1: {}
confbox@0.2.2: {}
consola@3.4.2: {}
cookie@1.1.1: {}
croner@4.1.97: {}
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@@ -2182,8 +2788,24 @@ snapshots:
csstype@3.2.3: {}
culvert@0.1.2: {}
data-uri-to-buffer@6.0.2: {}
date-fns@4.1.0: {}
dayjs@1.11.19: {}
dayjs@1.8.36: {}
debug@3.2.7:
dependencies:
ms: 2.1.3
debug@4.3.7:
dependencies:
ms: 2.1.3
debug@4.4.3:
dependencies:
ms: 2.1.3
@@ -2192,6 +2814,12 @@ snapshots:
defu@6.1.4: {}
degenerator@5.0.1:
dependencies:
ast-types: 0.13.4
escodegen: 2.1.0
esprima: 4.0.1
denque@2.1.0: {}
dequal@2.0.3: {}
@@ -2211,6 +2839,10 @@ snapshots:
empathic@2.0.0: {}
enquirer@2.3.6:
dependencies:
ansi-colors: 4.1.3
es-module-lexer@1.7.0: {}
esbuild@0.27.2:
@@ -2242,14 +2874,42 @@ snapshots:
'@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 0.27.2
escape-string-regexp@4.0.0: {}
escodegen@2.1.0:
dependencies:
esprima: 4.0.1
estraverse: 5.3.0
esutils: 2.0.3
optionalDependencies:
source-map: 0.6.1
esprima@4.0.1: {}
estraverse@5.3.0: {}
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.8
esutils@2.0.3: {}
eventemitter2@0.4.14: {}
eventemitter2@5.0.1: {}
eventemitter2@6.4.9: {}
expect-type@1.3.0: {}
exsolve@1.0.8: {}
extrareqp2@1.0.0(debug@4.3.7):
dependencies:
follow-redirects: 1.15.11(debug@4.3.7)
transitivePeerDependencies:
- debug
fast-check@3.23.2:
dependencies:
pure-rand: 6.1.0
@@ -2258,6 +2918,8 @@ snapshots:
fast-deep-equal@3.1.3: {}
fast-json-patch@3.1.1: {}
fast-json-stringify@6.1.1:
dependencies:
'@fastify/merge-json-schemas': 0.2.1
@@ -2297,16 +2959,26 @@ snapshots:
dependencies:
reusify: 1.1.0
fclone@1.0.11: {}
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
find-my-way@9.3.0:
dependencies:
fast-deep-equal: 3.1.3
fast-querystring: 1.1.2
safe-regex2: 5.0.0
follow-redirects@1.15.11(debug@4.3.7):
optionalDependencies:
debug: 4.3.7
foreground-child@3.3.1:
dependencies:
cross-spawn: 7.0.6
@@ -2315,6 +2987,8 @@ snapshots:
fsevents@2.3.3:
optional: true
function-bind@1.1.2: {}
generate-function@2.3.1:
dependencies:
is-property: 1.0.2
@@ -2325,6 +2999,14 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
get-uri@6.0.5:
dependencies:
basic-ftp: 5.1.0
data-uri-to-buffer: 6.0.2
debug: 4.4.3
transitivePeerDependencies:
- supports-color
giget@2.0.0:
dependencies:
citty: 0.1.6
@@ -2334,34 +3016,99 @@ snapshots:
nypm: 0.6.2
pathe: 2.0.3
git-node-fs@1.0.0(js-git@0.7.8):
optionalDependencies:
js-git: 0.7.8
git-sha1@0.1.2: {}
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
globrex@0.1.2: {}
graceful-fs@4.2.11: {}
grammex@3.1.12: {}
has-flag@4.0.0: {}
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
hono@4.10.6: {}
hookable@6.0.1: {}
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.4
debug: 4.4.3
transitivePeerDependencies:
- supports-color
http-status-codes@2.3.0: {}
https-proxy-agent@7.0.6:
dependencies:
agent-base: 7.1.4
debug: 4.4.3
transitivePeerDependencies:
- supports-color
iconv-lite@0.4.24:
dependencies:
safer-buffer: 2.1.2
iconv-lite@0.7.1:
dependencies:
safer-buffer: 2.1.2
import-without-cache@0.2.5: {}
ini@1.3.8: {}
ip-address@10.1.0: {}
ipaddr.js@2.3.0: {}
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
is-core-module@2.16.1:
dependencies:
hasown: 2.0.2
is-extglob@2.1.1: {}
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
is-number@7.0.0: {}
is-property@1.0.2: {}
isexe@2.0.0: {}
jiti@2.6.1: {}
js-git@0.7.8:
dependencies:
bodec: 0.1.0
culvert: 0.1.2
git-sha1: 0.1.2
pako: 0.2.9
js-sha512@0.9.0: {}
js-yaml@4.1.1:
dependencies:
argparse: 2.0.1
jsesc@3.1.0: {}
json-schema-ref-resolver@3.0.0:
@@ -2370,6 +3117,11 @@ snapshots:
json-schema-traverse@1.0.0: {}
json-stringify-safe@5.0.1:
optional: true
lazy@1.0.11: {}
light-my-request@6.6.0:
dependencies:
cookie: 1.1.1
@@ -2382,14 +3134,26 @@ snapshots:
long@5.3.2: {}
lru-cache@6.0.0:
dependencies:
yallist: 4.0.0
lru-cache@7.18.3: {}
lru.min@1.1.3: {}
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
mkdirp@1.0.4: {}
module-details-from-path@1.0.4: {}
ms@2.1.3: {}
mute-stream@0.0.8: {}
mysql2@3.15.3:
dependencies:
aws-ssl-profiles: 1.1.2
@@ -2408,8 +3172,25 @@ snapshots:
nanoid@3.3.11: {}
needle@2.4.0:
dependencies:
debug: 3.2.7
iconv-lite: 0.4.24
sax: 1.4.3
transitivePeerDependencies:
- supports-color
netmask@2.0.2: {}
node-fetch-native@1.6.7: {}
normalize-path@3.0.0: {}
nssocket@0.6.0:
dependencies:
eventemitter2: 0.4.14
lazy: 1.0.11
nypm@0.6.2:
dependencies:
citty: 0.1.6
@@ -2424,8 +3205,30 @@ snapshots:
on-exit-leak-free@2.1.2: {}
pac-proxy-agent@7.2.0:
dependencies:
'@tootallnate/quickjs-emscripten': 0.23.0
agent-base: 7.1.4
debug: 4.4.3
get-uri: 6.0.5
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
pac-resolver: 7.0.1
socks-proxy-agent: 8.0.5
transitivePeerDependencies:
- supports-color
pac-resolver@7.0.1:
dependencies:
degenerator: 5.0.1
netmask: 2.0.2
pako@0.2.9: {}
path-key@3.1.1: {}
path-parse@1.0.7: {}
pathe@2.0.3: {}
perfect-debounce@1.0.0: {}
@@ -2467,8 +3270,19 @@ snapshots:
picocolors@1.1.1: {}
picomatch@2.3.1: {}
picomatch@4.0.3: {}
pidusage@2.0.21:
dependencies:
safe-buffer: 5.2.1
optional: true
pidusage@3.0.2:
dependencies:
safe-buffer: 5.2.1
pino-abstract-transport@2.0.0:
dependencies:
split2: 4.2.0
@@ -2495,6 +3309,79 @@ snapshots:
exsolve: 1.0.8
pathe: 2.0.3
pm2-axon-rpc@0.7.1:
dependencies:
debug: 4.4.3
transitivePeerDependencies:
- supports-color
pm2-axon@4.0.1:
dependencies:
amp: 0.3.1
amp-message: 0.1.2
debug: 4.4.3
escape-string-regexp: 4.0.0
transitivePeerDependencies:
- supports-color
pm2-deploy@1.0.2:
dependencies:
run-series: 1.1.9
tv4: 1.3.0
pm2-multimeter@0.1.2:
dependencies:
charm: 0.1.2
pm2-sysmonit@1.2.8:
dependencies:
async: 3.2.6
debug: 4.4.3
pidusage: 2.0.21
systeminformation: 5.28.8
tx2: 1.0.5
transitivePeerDependencies:
- supports-color
optional: true
pm2@5.4.3:
dependencies:
'@pm2/agent': 2.0.4
'@pm2/io': 6.0.1
'@pm2/js-api': 0.8.0
'@pm2/pm2-version-check': 1.0.4
async: 3.2.6
blessed: 0.1.81
chalk: 3.0.0
chokidar: 3.6.0
cli-tableau: 2.0.1
commander: 2.15.1
croner: 4.1.97
dayjs: 1.11.19
debug: 4.4.3
enquirer: 2.3.6
eventemitter2: 5.0.1
fclone: 1.0.11
js-yaml: 4.1.1
mkdirp: 1.0.4
needle: 2.4.0
pidusage: 3.0.2
pm2-axon: 4.0.1
pm2-axon-rpc: 0.7.1
pm2-deploy: 1.0.2
pm2-multimeter: 0.1.2
promptly: 2.2.0
semver: 7.7.3
source-map-support: 0.5.21
sprintf-js: 1.1.2
vizion: 2.2.1
optionalDependencies:
pm2-sysmonit: 1.2.8
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
postcss@8.5.6:
dependencies:
nanoid: 3.3.11
@@ -2535,12 +3422,31 @@ snapshots:
process-warning@5.0.0: {}
promptly@2.2.0:
dependencies:
read: 1.0.7
proper-lockfile@4.1.2:
dependencies:
graceful-fs: 4.2.11
retry: 0.12.0
signal-exit: 3.0.7
proxy-agent@6.3.1:
dependencies:
agent-base: 7.1.4
debug: 4.4.3
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
lru-cache: 7.18.3
pac-proxy-agent: 7.2.0
proxy-from-env: 1.1.0
socks-proxy-agent: 8.0.5
transitivePeerDependencies:
- supports-color
proxy-from-env@1.1.0: {}
pure-rand@6.1.0: {}
quansync@1.0.0: {}
@@ -2559,6 +3465,14 @@ snapshots:
react@19.2.3: {}
read@1.0.7:
dependencies:
mute-stream: 0.0.8
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
readdirp@4.1.2: {}
real-require@0.2.0: {}
@@ -2579,8 +3493,22 @@ snapshots:
require-from-string@2.0.2: {}
require-in-the-middle@5.2.0:
dependencies:
debug: 4.4.3
module-details-from-path: 1.0.4
resolve: 1.22.11
transitivePeerDependencies:
- supports-color
resolve-pkg-maps@1.0.0: {}
resolve@1.22.11:
dependencies:
is-core-module: 2.16.1
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
ret@0.5.0: {}
retry@0.12.0: {}
@@ -2652,6 +3580,10 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.54.0
fsevents: 2.3.3
run-series@1.1.9: {}
safe-buffer@5.2.1: {}
safe-regex2@5.0.0:
dependencies:
ret: 0.5.0
@@ -2660,10 +3592,16 @@ snapshots:
safer-buffer@2.1.2: {}
sax@1.4.3: {}
scheduler@0.27.0: {}
secure-json-parse@4.1.0: {}
semver@7.5.4:
dependencies:
lru-cache: 6.0.0
semver@7.7.3: {}
seq-queue@0.0.5: {}
@@ -2676,20 +3614,46 @@ snapshots:
shebang-regex@3.0.0: {}
shimmer@1.2.1: {}
siginfo@2.0.0: {}
signal-exit@3.0.7: {}
signal-exit@4.1.0: {}
smart-buffer@4.2.0: {}
socks-proxy-agent@8.0.5:
dependencies:
agent-base: 7.1.4
debug: 4.4.3
socks: 2.8.7
transitivePeerDependencies:
- supports-color
socks@2.8.7:
dependencies:
ip-address: 10.1.0
smart-buffer: 4.2.0
sonic-boom@4.2.0:
dependencies:
atomic-sleep: 1.0.0
source-map-js@1.2.1: {}
source-map-support@0.5.21:
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
source-map@0.6.1: {}
split2@4.2.0: {}
sprintf-js@1.1.2: {}
sqlstring@2.3.3: {}
stackback@0.0.2: {}
@@ -2698,6 +3662,15 @@ snapshots:
std-env@3.9.0: {}
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
supports-preserve-symlinks-flag@1.0.0: {}
systeminformation@5.28.8:
optional: true
thread-stream@3.1.0:
dependencies:
real-require: 0.2.0
@@ -2713,6 +3686,10 @@ snapshots:
tinyrainbow@3.0.3: {}
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
toad-cache@3.7.0: {}
tree-kill@1.2.2: {}
@@ -2748,7 +3725,15 @@ snapshots:
- synckit
- vue-tsc
tslib@2.8.1:
tslib@1.9.3: {}
tslib@2.8.1: {}
tv4@1.3.0: {}
tx2@1.0.5:
dependencies:
json-stringify-safe: 5.0.1
optional: true
type-fest@4.41.0: {}
@@ -2831,6 +3816,13 @@ snapshots:
- tsx
- yaml
vizion@2.2.1:
dependencies:
async: 2.6.4
git-node-fs: 1.0.0(js-git@0.7.8)
ini: 1.3.8
js-git: 0.7.8
which@2.0.2:
dependencies:
isexe: 2.0.0
@@ -2840,8 +3832,12 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
ws@7.5.10: {}
xtend@4.0.2: {}
yallist@4.0.0: {}
zeptomatch@2.0.2:
dependencies:
grammex: 3.1.12