@rvoh/psychic 3.0.2 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/cjs/src/bin/index.js +5 -13
  2. package/dist/cjs/src/cli/index.js +194 -46
  3. package/dist/cjs/src/devtools/helpers/launchDevServer.js +20 -45
  4. package/dist/cjs/src/generate/helpers/reduxBindings/writeInitializer.js +8 -8
  5. package/dist/cjs/src/generate/helpers/syncOpenapiTypescript/generateInitializer.js +3 -3
  6. package/dist/cjs/src/generate/helpers/zustandBindings/printFinalStepsMessage.js +47 -0
  7. package/dist/cjs/src/generate/helpers/zustandBindings/promptForOptions.js +61 -0
  8. package/dist/cjs/src/generate/helpers/zustandBindings/writeClientConfigFile.js +43 -0
  9. package/dist/cjs/src/generate/helpers/zustandBindings/writeInitializer.js +46 -0
  10. package/dist/cjs/src/generate/initializer/syncEnums.js +3 -3
  11. package/dist/cjs/src/generate/openapi/zustandBindings.js +27 -0
  12. package/dist/cjs/src/generate/resource.js +1 -0
  13. package/dist/esm/src/bin/index.js +5 -13
  14. package/dist/esm/src/cli/index.js +194 -46
  15. package/dist/esm/src/devtools/helpers/launchDevServer.js +20 -45
  16. package/dist/esm/src/generate/helpers/reduxBindings/writeInitializer.js +8 -8
  17. package/dist/esm/src/generate/helpers/syncOpenapiTypescript/generateInitializer.js +3 -3
  18. package/dist/esm/src/generate/helpers/zustandBindings/printFinalStepsMessage.js +47 -0
  19. package/dist/esm/src/generate/helpers/zustandBindings/promptForOptions.js +61 -0
  20. package/dist/esm/src/generate/helpers/zustandBindings/writeClientConfigFile.js +43 -0
  21. package/dist/esm/src/generate/helpers/zustandBindings/writeInitializer.js +46 -0
  22. package/dist/esm/src/generate/initializer/syncEnums.js +3 -3
  23. package/dist/esm/src/generate/openapi/zustandBindings.js +27 -0
  24. package/dist/esm/src/generate/resource.js +1 -0
  25. package/dist/types/src/cli/index.d.ts +1 -0
  26. package/dist/types/src/generate/helpers/zustandBindings/printFinalStepsMessage.d.ts +2 -0
  27. package/dist/types/src/generate/helpers/zustandBindings/promptForOptions.d.ts +2 -0
  28. package/dist/types/src/generate/helpers/zustandBindings/writeClientConfigFile.d.ts +3 -0
  29. package/dist/types/src/generate/helpers/zustandBindings/writeInitializer.d.ts +5 -0
  30. package/dist/types/src/generate/openapi/zustandBindings.d.ts +21 -0
  31. package/dist/types/src/generate/resource.d.ts +1 -0
  32. package/package.json +13 -16
  33. /package/dist/cjs/{spec → src/devtools}/helpers/sleep.js +0 -0
  34. /package/dist/esm/{spec → src/devtools}/helpers/sleep.js +0 -0
  35. /package/dist/types/{spec → src/devtools}/helpers/sleep.d.ts +0 -0
@@ -1,12 +1,11 @@
1
1
  import { spawn } from 'child_process';
2
- import { createServer } from 'net';
3
2
  import { debuglog } from 'node:util';
4
- import sleep from '../../../spec/helpers/sleep.js';
5
3
  import UnexpectedUndefined from '../../error/UnexpectedUndefined.js';
6
4
  import PsychicApp from '../../psychic-app/index.js';
5
+ import sleep from './sleep.js';
7
6
  const devServerProcesses = {};
8
7
  const debugEnabled = debuglog('psychic').enabled;
9
- export async function launchDevServer(key, { port = 3000, cmd = 'pnpm client', timeout = 5000, onStdOut } = {}) {
8
+ export async function launchDevServer(key, { port = 3000, cmd = 'pnpm client', timeout = 20000, onStdOut } = {}) {
10
9
  if (devServerProcesses[key])
11
10
  return;
12
11
  if (debugEnabled)
@@ -34,16 +33,7 @@ export async function launchDevServer(key, { port = 3000, cmd = 'pnpm client', t
34
33
  console.log(txt);
35
34
  }
36
35
  });
37
- devServerProcesses[key] = proc;
38
- await waitForPort(key, port, timeout);
39
- proc.on('error', err => {
40
- throw err;
41
- });
42
- proc.stdout.on('data', data => {
43
- if (debugEnabled)
44
- PsychicApp.log(`Server output: ${data}`);
45
- });
46
- proc.stderr.on('data', data => {
36
+ proc.stderr?.on('data', data => {
47
37
  if (debugEnabled)
48
38
  PsychicApp.logWithLevel('error', `Server error: ${data}`);
49
39
  });
@@ -54,6 +44,8 @@ export async function launchDevServer(key, { port = 3000, cmd = 'pnpm client', t
54
44
  if (debugEnabled)
55
45
  PsychicApp.log(`Server process exited with code ${code}`);
56
46
  });
47
+ devServerProcesses[key] = proc;
48
+ await waitForHttpServer(proc, key, port, timeout);
57
49
  }
58
50
  export function stopDevServer(key) {
59
51
  const proc = devServerProcesses[key];
@@ -80,40 +72,23 @@ export function stopDevServers() {
80
72
  stopDevServer(key);
81
73
  });
82
74
  }
83
- async function isPortAvailable(port) {
84
- return new Promise(resolve => {
85
- const server = createServer()
86
- .once('error', err => {
87
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
88
- if (err.code === 'EADDRINUSE') {
89
- resolve(false);
90
- }
91
- else {
92
- resolve(true);
93
- }
94
- })
95
- .once('listening', () => {
96
- server.close();
97
- resolve(true);
98
- })
99
- .listen(port, '127.0.0.1');
100
- });
101
- }
102
- async function waitForPort(key, port, timeout = 5000) {
103
- if (await isPortAvailable(port)) {
104
- return true;
105
- }
75
+ async function waitForHttpServer(proc, key, port, timeout = 20000) {
106
76
  const startTime = Date.now();
107
- async function recursiveWaitForPort() {
108
- if (await isPortAvailable(port)) {
109
- return true;
77
+ while (Date.now() - startTime < timeout) {
78
+ if (proc.exitCode != null) {
79
+ delete devServerProcesses[key];
80
+ throw new Error(`dev server exited with code ${proc.exitCode} before becoming ready on port ${port}`);
110
81
  }
111
- if (Date.now() > startTime + timeout) {
112
- stopDevServer(key);
113
- throw new Error('waited too long for port: ' + port);
82
+ try {
83
+ const response = await fetch(`http://localhost:${port}`, { redirect: 'manual' });
84
+ if (response.status > 0)
85
+ return;
86
+ }
87
+ catch {
88
+ // server not ready yet, keep waiting
114
89
  }
115
- await sleep(50);
116
- return await recursiveWaitForPort();
90
+ await sleep(100);
117
91
  }
118
- return await recursiveWaitForPort();
92
+ stopDevServer(key);
93
+ throw new Error(`waited too long for dev server on port ${port}`);
119
94
  }
@@ -30,15 +30,15 @@ import AppEnv from '../../AppEnv.js'
30
30
  export default function initialize${pascalized}(psy: PsychicApp) {
31
31
  psy.on('cli:sync', async () => {
32
32
  if (AppEnv.isDevelopmentOrTest) {
33
- DreamCLI.logger.logStartProgress(\`[${camelized}] syncing...\`)
34
- await DreamCLI.spawn('npx @rtk-query/codegen-openapi ${filePath}', {
35
- onStdout: message => {
36
- DreamCLI.logger.logContinueProgress(\`[${camelized}]\` + ' ' + message, {
37
- logPrefixColor: 'green',
38
- })
39
- },
33
+ await DreamCLI.logger.logProgress(\`[${camelized}] syncing...\`, async () => {
34
+ await DreamCLI.spawn('npx @rtk-query/codegen-openapi ${filePath}', {
35
+ onStdout: message => {
36
+ DreamCLI.logger.logContinueProgress(\`[${camelized}]\` + ' ' + message, {
37
+ logPrefixColor: 'green',
38
+ })
39
+ },
40
+ })
40
41
  })
41
- DreamCLI.logger.logEndProgress()
42
42
  }
43
43
  })
44
44
  }\
@@ -23,9 +23,9 @@ import AppEnv from '../AppEnv.js'
23
23
  export default (psy: PsychicApp) => {
24
24
  psy.on('cli:sync', async () => {
25
25
  if (AppEnv.isDevelopmentOrTest) {
26
- DreamCLI.logger.logStartProgress(\`[${hyphenized}] extracting types from ${openapiFilepath} to ${outfile}...\`)
27
- await DreamCLI.spawn('npx openapi-typescript ${openapiFilepath} -o ${outfile}')
28
- DreamCLI.logger.logEndProgress()
26
+ await DreamCLI.logger.logProgress(\`[${hyphenized}] extracting types from ${openapiFilepath} to ${outfile}...\`, async () => {
27
+ await DreamCLI.spawn('npx openapi-typescript ${openapiFilepath} -o ${outfile}')
28
+ })
29
29
  }
30
30
  })
31
31
  }\
@@ -0,0 +1,47 @@
1
+ import { DreamCLI } from '@rvoh/dream/system';
2
+ import colorize from '../../../cli/helpers/colorize.js';
3
+ export default function printFinalStepsMessage(opts) {
4
+ const importLine = colorize(`+ import '${opts.clientConfigFile}'`, { color: 'green' });
5
+ const sdkImportLine = colorize(`+ import { getAdminCities, postAdminCities } from '${opts.outputDir}/sdk.gen'`, {
6
+ color: 'green',
7
+ });
8
+ const usageLine = colorize(` const { data, error } = await getAdminCities()`, {
9
+ color: 'green',
10
+ });
11
+ const zustandLine = colorize(` const { data } = await getAdminCities()
12
+ set({ cities: data?.results })`, { color: 'green' });
13
+ DreamCLI.logger.log(`
14
+ Finished generating @hey-api/openapi-ts bindings for your application.
15
+
16
+ First, you will need to be sure to sync, so that the typed API functions
17
+ are generated from your openapi schema:
18
+
19
+ pnpm psy sync
20
+
21
+ This will generate typed API functions and types in ${opts.outputDir}/
22
+
23
+ To use the generated API, first import the client config at your app's
24
+ entry point to configure the base URL and credentials:
25
+
26
+ ${importLine}
27
+
28
+ Then import and use the generated typed functions anywhere:
29
+
30
+ ${sdkImportLine}
31
+
32
+ // all functions are fully typed with request params and response types
33
+ ${usageLine}
34
+
35
+ To use with a Zustand store:
36
+
37
+ import { create } from 'zustand'
38
+ ${sdkImportLine}
39
+
40
+ const useCitiesStore = create((set) => ({
41
+ cities: [],
42
+ fetchCities: async () => {
43
+ ${zustandLine}
44
+ },
45
+ }))
46
+ `, { logPrefix: '' });
47
+ }
@@ -0,0 +1,61 @@
1
+ import { camelize } from '@rvoh/dream/utils';
2
+ import cliPrompt from '../../../cli/helpers/cli-prompt.js';
3
+ import PsychicApp from '../../../psychic-app/index.js';
4
+ export default async function promptForOptions(options) {
5
+ if (!options.schemaFile) {
6
+ const defaultVal = './src/openapi/openapi.json';
7
+ const answer = await cliPrompt(`\
8
+ What would you like the schemaFile to be?
9
+
10
+ The schemaFile is the openapi file that @hey-api/openapi-ts will read to produce
11
+ all of its typed API functions and types. If not provided, it will default to
12
+
13
+ ${defaultVal}
14
+ `);
15
+ options.schemaFile = answer || defaultVal;
16
+ }
17
+ if (!options.exportName) {
18
+ const defaultVal = `${camelize(PsychicApp.getOrFail().appName)}Api`;
19
+ const answer = await cliPrompt(`\
20
+ What would you like the exportName to be?
21
+
22
+ The exportName is used to name the generated API output. It will be used to name
23
+ the initializer and config files. We recommend naming it something like the name
24
+ of your app, i.e.
25
+
26
+ ${defaultVal}
27
+ `);
28
+ options.exportName = answer || defaultVal;
29
+ }
30
+ if (!options.outputDir) {
31
+ const defaultVal = `../client/app/api/${camelize(options.exportName)}`;
32
+ const answer = await cliPrompt(`\
33
+ What would you like the outputDir to be?
34
+
35
+ The outputDir is the directory where @hey-api/openapi-ts will generate the typed
36
+ API functions and types. It will contain files like types.gen.ts and sdk.gen.ts.
37
+ If not provided, it will default to:
38
+
39
+ ${defaultVal}
40
+ `);
41
+ options.outputDir = answer || defaultVal;
42
+ }
43
+ if (!options.clientConfigFile) {
44
+ const defaultVal = `../client/app/api/${camelize(options.exportName)}/client.ts`;
45
+ const answer = await cliPrompt(`\
46
+ What would you like the path to your clientConfigFile to be?
47
+
48
+ The clientConfigFile specifies where to generate the client configuration file
49
+ that configures @hey-api/client-fetch with your base URL, credentials, and
50
+ other request options.
51
+
52
+ We expect you to provide this path with the api root in mind, so you will need
53
+ to consider how to travel to the desired filepath from within your psychic
54
+ project, i.e.
55
+
56
+ ${defaultVal}
57
+ `);
58
+ options.clientConfigFile = answer || defaultVal;
59
+ }
60
+ return options;
61
+ }
@@ -0,0 +1,43 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ export default async function writeClientConfigFile({ clientConfigFile }) {
4
+ const destDir = path.dirname(clientConfigFile);
5
+ try {
6
+ await fs.access(clientConfigFile);
7
+ return; // early return if the file already exists
8
+ }
9
+ catch {
10
+ // noop
11
+ }
12
+ try {
13
+ await fs.access(destDir);
14
+ }
15
+ catch {
16
+ await fs.mkdir(destDir, { recursive: true });
17
+ }
18
+ const contents = `\
19
+ import { client } from '@hey-api/client-fetch'
20
+
21
+ function baseUrl() {
22
+ // add custom code here for determining your application's baseUrl
23
+ // this would generally be something different, depending on if you
24
+ // are in dev/test/production environments. For dev, you might want
25
+ // http://localhost:7777, while test may be http://localhost:7778, or
26
+ // some other port, depending on how you have your spec hooks configured.
27
+ // for production, it should be the real host for your application, i.e.
28
+ // https://myapi.com
29
+
30
+ return 'http://localhost:7777'
31
+ }
32
+
33
+ client.setConfig({
34
+ baseUrl: baseUrl(),
35
+ credentials: 'include',
36
+
37
+ // you can customize headers here, for example to add auth tokens:
38
+ // headers: {
39
+ // Authorization: \`Bearer \${getToken()}\`,
40
+ // },
41
+ })`;
42
+ await fs.writeFile(clientConfigFile, contents);
43
+ }
@@ -0,0 +1,46 @@
1
+ import { camelize, pascalize } from '@rvoh/dream/utils';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import psychicPath from '../../../helpers/path/psychicPath.js';
5
+ export default async function writeInitializer({ exportName, schemaFile, outputDir, }) {
6
+ const pascalized = pascalize(exportName);
7
+ const camelized = camelize(exportName);
8
+ const destDir = path.join(psychicPath('conf'), 'initializers', 'openapi');
9
+ const initializerFilename = `${camelized}.ts`;
10
+ const initializerPath = path.join(destDir, initializerFilename);
11
+ try {
12
+ await fs.access(initializerPath);
13
+ return; // early return if the file already exists
14
+ }
15
+ catch {
16
+ // noop
17
+ }
18
+ try {
19
+ await fs.access(destDir);
20
+ }
21
+ catch {
22
+ await fs.mkdir(destDir, { recursive: true });
23
+ }
24
+ const contents = `\
25
+ import { DreamCLI } from '@rvoh/dream/system'
26
+ import { PsychicApp } from '@rvoh/psychic'
27
+ import AppEnv from '../../AppEnv.js'
28
+
29
+ export default function initialize${pascalized}(psy: PsychicApp) {
30
+ psy.on('cli:sync', async () => {
31
+ if (AppEnv.isDevelopmentOrTest) {
32
+ await DreamCLI.logger.logProgress(\`[${camelized}] syncing...\`, async () => {
33
+ await DreamCLI.spawn('npx @hey-api/openapi-ts -i ${schemaFile} -o ${outputDir}', {
34
+ onStdout: message => {
35
+ DreamCLI.logger.logContinueProgress(\`[${camelized}]\` + ' ' + message, {
36
+ logPrefixColor: 'green',
37
+ })
38
+ },
39
+ })
40
+ })
41
+ }
42
+ })
43
+ }\
44
+ `;
45
+ await fs.writeFile(initializerPath, contents);
46
+ }
@@ -29,9 +29,9 @@ import AppEnv from '../AppEnv.js'
29
29
  export default function ${camelized}(psy: PsychicApp) {
30
30
  psy.on('cli:sync', async () => {
31
31
  if (AppEnv.isDevelopmentOrTest) {
32
- DreamCLI.logger.logStartProgress(\`[${camelized}] syncing enums to ${outfile}...\`)
33
- await PsychicBin.syncClientEnums('${outfile}')
34
- DreamCLI.logger.logEndProgress()
32
+ await DreamCLI.logger.logProgress(\`[${camelized}] syncing enums to ${outfile}...\`, async () => {
33
+ await PsychicBin.syncClientEnums('${outfile}')
34
+ })
35
35
  }
36
36
  })
37
37
  }\
@@ -0,0 +1,27 @@
1
+ import { DreamCLI } from '@rvoh/dream/system';
2
+ import PackageManager from '../../cli/helpers/PackageManager.js';
3
+ import printFinalStepsMessage from '../helpers/zustandBindings/printFinalStepsMessage.js';
4
+ import promptForOptions from '../helpers/zustandBindings/promptForOptions.js';
5
+ import writeClientConfigFile from '../helpers/zustandBindings/writeClientConfigFile.js';
6
+ import writeInitializer from '../helpers/zustandBindings/writeInitializer.js';
7
+ /**
8
+ * @internal
9
+ *
10
+ * used by the psychic CLI to generate boilerplate
11
+ * that can be used to integrate a specific openapi.json
12
+ * file with a client using @hey-api/openapi-ts.
13
+ *
14
+ * * generates the client config file if it does not exist
15
+ * * generates an initializer, which taps into the sync hooks
16
+ * to automatically run the @hey-api/openapi-ts CLI util
17
+ * * prints a helpful message, instructing devs on the final
18
+ * steps for using the generated typed API functions
19
+ * within their client application.
20
+ */
21
+ export default async function generateOpenapiZustandBindings(options = {}) {
22
+ const opts = await promptForOptions(options);
23
+ await writeClientConfigFile(opts);
24
+ await writeInitializer(opts);
25
+ await DreamCLI.spawn(PackageManager.add(['@hey-api/openapi-ts', '@hey-api/client-fetch'], { dev: true }));
26
+ printFinalStepsMessage(opts);
27
+ }
@@ -27,6 +27,7 @@ export default async function generateResource({ route, fullyQualifiedModelName,
27
27
  includeAdminSerializers: forAdmin,
28
28
  includeInternalSerializers: forInternal,
29
29
  connectionName: options.connectionName,
30
+ tableName: options.tableName,
30
31
  modelName: options.modelName,
31
32
  },
32
33
  });
@@ -29,6 +29,7 @@ export default class PsychicCLI {
29
29
  stiBaseSerializer: boolean;
30
30
  owningModel?: string;
31
31
  connectionName: string;
32
+ tableName?: string;
32
33
  modelName?: string;
33
34
  };
34
35
  columnsWithTypes: string[];
@@ -0,0 +1,2 @@
1
+ import { OpenapiZustandBindingsOptions } from '../../openapi/zustandBindings.js';
2
+ export default function printFinalStepsMessage(opts: Required<OpenapiZustandBindingsOptions>): void;
@@ -0,0 +1,2 @@
1
+ import { OpenapiZustandBindingsOptions } from '../../openapi/zustandBindings.js';
2
+ export default function promptForOptions(options: OpenapiZustandBindingsOptions): Promise<Required<OpenapiZustandBindingsOptions>>;
@@ -0,0 +1,3 @@
1
+ export default function writeClientConfigFile({ clientConfigFile }: {
2
+ clientConfigFile: string;
3
+ }): Promise<void>;
@@ -0,0 +1,5 @@
1
+ export default function writeInitializer({ exportName, schemaFile, outputDir, }: {
2
+ exportName: string;
3
+ schemaFile: string;
4
+ outputDir: string;
5
+ }): Promise<void>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @internal
3
+ *
4
+ * used by the psychic CLI to generate boilerplate
5
+ * that can be used to integrate a specific openapi.json
6
+ * file with a client using @hey-api/openapi-ts.
7
+ *
8
+ * * generates the client config file if it does not exist
9
+ * * generates an initializer, which taps into the sync hooks
10
+ * to automatically run the @hey-api/openapi-ts CLI util
11
+ * * prints a helpful message, instructing devs on the final
12
+ * steps for using the generated typed API functions
13
+ * within their client application.
14
+ */
15
+ export default function generateOpenapiZustandBindings(options?: OpenapiZustandBindingsOptions): Promise<void>;
16
+ export interface OpenapiZustandBindingsOptions {
17
+ exportName?: string;
18
+ schemaFile?: string;
19
+ outputDir?: string;
20
+ clientConfigFile?: string;
21
+ }
@@ -9,6 +9,7 @@ export default function generateResource({ route, fullyQualifiedModelName, optio
9
9
  stiBaseSerializer: boolean;
10
10
  owningModel?: string;
11
11
  connectionName: string;
12
+ tableName?: string;
12
13
  modelName?: string;
13
14
  };
14
15
  columnsWithTypes: string[];
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "name": "@rvoh/psychic",
4
4
  "description": "Typescript web framework",
5
- "version": "3.0.2",
5
+ "version": "3.0.4",
6
6
  "author": "RVOHealth",
7
7
  "repository": {
8
8
  "type": "git",
@@ -76,15 +76,15 @@
76
76
  "@koa/etag": "^5.0.2",
77
77
  "@koa/router": "^15.3.0",
78
78
  "@rvoh/dream": "^2.4.0",
79
- "@types/koa__cors": "^5.0.0",
80
- "@types/koa__router": "^12.0.5",
79
+ "@types/koa": "^3.0.1",
81
80
  "@types/koa-bodyparser": "^4.3.12",
82
81
  "@types/koa-conditional-get": "^2.0.3",
83
82
  "@types/koa-etag": "^3.0.3",
84
- "@types/koa": "^3.0.1",
83
+ "@types/koa__cors": "^5.0.0",
84
+ "@types/koa__router": "^12.0.5",
85
+ "koa": "^3.1.2",
85
86
  "koa-bodyparser": "^4.4.1",
86
87
  "koa-conditional-get": "^3.0.0",
87
- "koa": "^3.1.2",
88
88
  "openapi-typescript": "^7.8.0"
89
89
  },
90
90
  "devDependencies": {
@@ -107,18 +107,18 @@
107
107
  "@types/passport-local": "^1",
108
108
  "@types/pg": "^8.11.8",
109
109
  "@types/supertest": "^6.0.3",
110
- "@typescript-eslint/parser": "^8.48.1",
110
+ "@typescript-eslint/parser": "^8.57.1",
111
111
  "@typescript/analyze-trace": "^0.10.1",
112
112
  "commander": "^14.0.3",
113
113
  "dotenv": "^16.4.5",
114
- "eslint": "^9.39.1",
114
+ "eslint": "^9.39.4",
115
115
  "jsdom": "^26.1.0",
116
116
  "koa": "^3.1.2",
117
117
  "koa-bodyparser": "^4.4.1",
118
118
  "koa-conditional-get": "^3.0.0",
119
119
  "koa-passport": "^6.0.0",
120
120
  "koa-session": "^7.0.2",
121
- "kysely": "^0.28.5",
121
+ "kysely": "^0.28.13",
122
122
  "kysely-codegen": "~0.19.0",
123
123
  "luxon-jest-matchers": "^0.1.14",
124
124
  "nodemon": "^3.1.11",
@@ -128,23 +128,20 @@
128
128
  "pg": "^8.12.0",
129
129
  "pluralize-esm": "^9.0.5",
130
130
  "prettier": "^3.3.3",
131
- "puppeteer": "^24.22.3",
132
- "supertest": "^7.1.4",
131
+ "puppeteer": "^24.39.1",
132
+ "supertest": "^7.2.2",
133
133
  "tslib": "^2.7.0",
134
134
  "tsx": "^4.21.0",
135
135
  "typedoc": "^0.28.17",
136
136
  "typescript": "^5.9.3",
137
- "typescript-eslint": "^8.48.1",
138
- "vitest": "^4.0.9",
137
+ "typescript-eslint": "^8.57.1",
138
+ "vitest": "^4.1.0",
139
139
  "winston": "^3.14.2"
140
140
  },
141
141
  "packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402",
142
142
  "pnpm": {
143
143
  "overrides": {
144
- "diff": ">=8.0.3",
145
- "minimatch@3": "3.1.3",
146
- "minimatch@5": "5.1.7",
147
- "minimatch@9": "9.0.6"
144
+ "diff": ">=8.0.3"
148
145
  }
149
146
  }
150
147
  }