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:
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
}),
|
||||
}),
|
||||
});
|
||||
@@ -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(),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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 });
|
||||
});
|
||||
});
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Generated
+1000
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user