@rvoh/psychic 2.0.4 → 2.2.0

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 (34) hide show
  1. package/dist/cjs/src/bin/helpers/OpenApiSpecDiff.js +341 -0
  2. package/dist/cjs/src/bin/index.js +12 -9
  3. package/dist/cjs/src/cli/helpers/ASTBuilder.js +175 -0
  4. package/dist/cjs/src/cli/helpers/ASTPsychicTypesBuilder.js +59 -0
  5. package/dist/cjs/src/cli/index.js +22 -1
  6. package/dist/cjs/src/controller/index.js +1 -1
  7. package/dist/cjs/src/devtools/helpers/launchDevServer.js +1 -1
  8. package/dist/cjs/src/error/psychic-app/init-missing-package-manager.js +1 -1
  9. package/dist/cjs/src/generate/helpers/generateResourceControllerSpecContent.js +5 -3
  10. package/dist/cjs/src/generate/helpers/syncOpenapiTypescript/installOpenapiTypescript.js +1 -1
  11. package/dist/cjs/src/openapi-renderer/SerializerOpenapiRenderer.js +1 -0
  12. package/dist/cjs/src/openapi-renderer/app.js +1 -1
  13. package/dist/esm/src/bin/helpers/OpenApiSpecDiff.js +341 -0
  14. package/dist/esm/src/bin/index.js +12 -9
  15. package/dist/esm/src/cli/helpers/ASTBuilder.js +175 -0
  16. package/dist/esm/src/cli/helpers/ASTPsychicTypesBuilder.js +59 -0
  17. package/dist/esm/src/cli/index.js +22 -1
  18. package/dist/esm/src/controller/index.js +1 -1
  19. package/dist/esm/src/devtools/helpers/launchDevServer.js +1 -1
  20. package/dist/esm/src/error/psychic-app/init-missing-package-manager.js +1 -1
  21. package/dist/esm/src/generate/helpers/generateResourceControllerSpecContent.js +5 -3
  22. package/dist/esm/src/generate/helpers/syncOpenapiTypescript/installOpenapiTypescript.js +1 -1
  23. package/dist/esm/src/openapi-renderer/SerializerOpenapiRenderer.js +1 -0
  24. package/dist/esm/src/openapi-renderer/app.js +1 -1
  25. package/dist/types/src/bin/helpers/OpenApiSpecDiff.d.ts +138 -0
  26. package/dist/types/src/bin/index.d.ts +3 -1
  27. package/dist/types/src/cli/helpers/ASTBuilder.d.ts +89 -0
  28. package/dist/types/src/cli/helpers/ASTPsychicTypesBuilder.d.ts +28 -0
  29. package/dist/types/src/controller/index.d.ts +1 -1
  30. package/dist/types/src/psychic-app/index.d.ts +28 -0
  31. package/package.json +19 -16
  32. package/dist/cjs/src/cli/helpers/TypesBuilder.js +0 -23
  33. package/dist/esm/src/cli/helpers/TypesBuilder.js +0 -23
  34. package/dist/types/src/cli/helpers/TypesBuilder.d.ts +0 -7
@@ -1,5 +1,5 @@
1
1
  import { DreamCLI } from '@rvoh/dream/system';
2
- import PsychicBin from '../bin/index.js';
2
+ import PsychicBin, { BreakingChangesDetectedInOpenApiSpecError } from '../bin/index.js';
3
3
  import generateController from '../generate/controller.js';
4
4
  import generateSyncEnumsInitializer from '../generate/initializer/syncEnums.js';
5
5
  import generateSyncOpenapiTypescriptInitializer from '../generate/initializer/syncOpenapiTypescript.js';
@@ -196,6 +196,27 @@ export default class PsychicCLI {
196
196
  await PsychicBin.syncOpenapiJson();
197
197
  process.exit();
198
198
  });
199
+ program
200
+ .command('diff:openapi')
201
+ .description('compares the current branch open api spec file(s) with the main/master/head branch open api spec file(s)')
202
+ .option('-f', '--fail-on-breaking', 'fail on spec changes that are breaking')
203
+ .action(async (options) => {
204
+ await initializePsychicApp();
205
+ try {
206
+ PsychicBin.openapiDiff();
207
+ }
208
+ catch (error) {
209
+ if (error instanceof BreakingChangesDetectedInOpenApiSpecError) {
210
+ if (options.failOnBreaking) {
211
+ console.error(error.message);
212
+ process.exit(1);
213
+ }
214
+ }
215
+ else {
216
+ throw error;
217
+ }
218
+ }
219
+ });
199
220
  }
200
221
  /**
201
222
  * @internal
@@ -131,7 +131,7 @@ export default class PsychicController {
131
131
  /**
132
132
  * @internal
133
133
  *
134
- * Used for displaying routes when running `yarn psy routes`
134
+ * Used for displaying routes when running `pnpm psy routes`
135
135
  * cli command
136
136
  */
137
137
  static get disaplayName() {
@@ -6,7 +6,7 @@ import UnexpectedUndefined from '../../error/UnexpectedUndefined.js';
6
6
  import PsychicApp from '../../psychic-app/index.js';
7
7
  const devServerProcesses = {};
8
8
  const debugEnabled = debuglog('psychic').enabled;
9
- export async function launchDevServer(key, { port = 3000, cmd = 'yarn client', timeout = 5000 } = {}) {
9
+ export async function launchDevServer(key, { port = 3000, cmd = 'pnpm client', timeout = 5000 } = {}) {
10
10
  if (devServerProcesses[key])
11
11
  return;
12
12
  if (debugEnabled)
@@ -10,7 +10,7 @@ within conf/app.ts, you must have a call to "#set('packageManager', '<YOUR_CHOSE
10
10
 
11
11
  // conf/app.ts
12
12
  export default async (psy: PsychicApp) => {
13
- psy.set('packageManager', 'yarn')
13
+ psy.set('packageManager', 'pnpm')
14
14
  }
15
15
  `;
16
16
  }
@@ -87,8 +87,9 @@ function parseAttribute(attribute) {
87
87
  const [rawAttributeName, rawAttributeType, , enumValues] = attribute.split(':');
88
88
  if (!rawAttributeName || !rawAttributeType)
89
89
  return null;
90
+ const sanitizedAttrType = camelize(rawAttributeType)?.toLowerCase();
90
91
  // Handle belongs_to relationships
91
- if (rawAttributeType === 'belongs_to') {
92
+ if (sanitizedAttrType === 'belongsto') {
92
93
  // For belongs_to relationships, convert "Ticketing/Ticket" to "ticket"
93
94
  const attributeName = camelize(rawAttributeName.split('/').pop());
94
95
  return { attributeName, attributeType: 'belongs_to', isArray: false, enumValues };
@@ -105,8 +106,9 @@ function parseAttribute(attribute) {
105
106
  return { attributeName, attributeType, isArray, enumValues };
106
107
  }
107
108
  function processAttributeByType({ attributeType, attributeName, isArray, enumValues, dotNotationVariable, fullyQualifiedModelName, attributeData, }) {
108
- switch (attributeType) {
109
- case 'belongs_to':
109
+ const sanitizedAttributeType = camelize(attributeType).toLowerCase();
110
+ switch (sanitizedAttributeType) {
111
+ case 'belongsto':
110
112
  // belongs_to relationships are NOT included in comparable attributes or create/update data
111
113
  // They are only tracked for original values in update contexts
112
114
  break;
@@ -8,7 +8,7 @@ export default async function installOpenapiTypescript() {
8
8
  try {
9
9
  await DreamCLI.spawn(cmd);
10
10
  }
11
- catch (err) {
11
+ catch {
12
12
  console.log(`Failed to install openapi-typescript as a dev dependency. Please make sure the following command succeeds:
13
13
 
14
14
  "${cmd}"
@@ -298,6 +298,7 @@ function associationOpenapi(attribute, DataTypeForOpenapi, alreadyExtractedDesce
298
298
  if (associatedClass === undefined) {
299
299
  let serializerCheck;
300
300
  try {
301
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
301
302
  ;
302
303
  DataTypeForOpenapi?.prototype?.serializers;
303
304
  }
@@ -57,7 +57,7 @@ export default class OpenapiAppRenderer {
57
57
  openapi: '3.1.0',
58
58
  info: {
59
59
  version: openapiConfig?.info?.version || 'unknown version',
60
- title: openapiConfig?.info?.title || 'unknown title',
60
+ title: openapiConfig?.info?.title || `${psychicApp.appName} | ${openapiName}`,
61
61
  description: openapiConfig?.info?.description || 'The autogenerated openapi spec for your app',
62
62
  },
63
63
  paths: {},
@@ -0,0 +1,138 @@
1
+ import type { DefaultPsychicOpenapiOptions } from '../../psychic-app/index.js';
2
+ /**
3
+ * Interface to hold the result of a comparison
4
+ * between the current local OpenAPI specification and the head branch
5
+ * for a given OpenAPI file
6
+ */
7
+ export interface ComparisonResult {
8
+ file: string;
9
+ hasChanges: boolean;
10
+ breaking: string[];
11
+ changelog: string[];
12
+ error?: string;
13
+ }
14
+ /**
15
+ * Interface to hold the configuration for oasdiff
16
+ */
17
+ export interface OasDiffConfig {
18
+ command: string;
19
+ baseArgs: string[];
20
+ headBranch: string;
21
+ }
22
+ export type PsychicOpenapiConfig = DefaultPsychicOpenapiOptions;
23
+ /**
24
+ * Class-based OpenAPI specification diff tool
25
+ *
26
+ * Compares current OpenAPI specs against the head branch using oasdiff
27
+ *
28
+ * Example usages:
29
+ *
30
+ * Instance-based usage
31
+ * const diffTool = new OpenApiSpecDiff()
32
+ * diffTool.compare(openapiConfigs)
33
+ *
34
+ * Factory method usage
35
+ * const diffTool = OpenApiSpecDiff.create()
36
+ * diffTool.compare(openapiConfigs)
37
+ *
38
+ * Static method usage (backward compatibility)
39
+ * OpenApiSpecDiff.compare(openapiConfigs)
40
+ */
41
+ export declare class OpenApiSpecDiff {
42
+ /**
43
+ * The configuration for the oasdiff command
44
+ */
45
+ private oasdiffConfig?;
46
+ /**
47
+ * Compares a list of OpenAPI specifications between the current branch and the head branch.
48
+ *
49
+ * Uses `oasdiff` under the hood to detect breaking and non-breaking changes for each file,
50
+ * helping you review and validate API updates with confidence before merging.
51
+ *
52
+ * This tool only runs for configurations where `checkDiffs` is enabled.
53
+ *
54
+ * @param openapiConfigs - An array of tuples containing the OpenAPI file name and its configuration.
55
+ * @example
56
+ * ```ts
57
+ * const openapiConfigs: [string, PsychicOpenapiConfig][] = [
58
+ * ['openapi', { outputFilepath: 'openapi.json' }],
59
+ * ]
60
+ * OpenApiSpecDiff.compare(openapiConfigs)
61
+ * ```
62
+ */
63
+ compare(openapiConfigs: [string, PsychicOpenapiConfig][]): void;
64
+ /**
65
+ * Checks if oasdiff is installed locally
66
+ */
67
+ private hasOasDiffInstalled;
68
+ /**
69
+ * Fetch the head branch of a remote using git remote show origin
70
+ * default to main if not set
71
+ */
72
+ private getHeadBranch;
73
+ /**
74
+ * Validates that oasdiff is installed and builds the oasdiff config
75
+ */
76
+ private getOasDiffConfig;
77
+ /**
78
+ * Runs oasdiff command and returns the output
79
+ */
80
+ private runOasDiffCommand;
81
+ /**
82
+ * Compares two OpenAPI files using oasdiff
83
+ */
84
+ private compareSpecs;
85
+ /**
86
+ * Creates a temporary file path for the head branch content
87
+ */
88
+ private createTempFilePath;
89
+ /**
90
+ * Retrieves head branch content for a file
91
+ */
92
+ private getHeadBranchContent;
93
+ /**
94
+ * Compares a single OpenAPI file against head branch
95
+ */
96
+ private compareConfig;
97
+ /**
98
+ * Process and display the comparison results
99
+ */
100
+ private processResults;
101
+ /**
102
+ * Log error for a comparison result
103
+ */
104
+ private logError;
105
+ /**
106
+ * Log changes for a comparison result
107
+ */
108
+ private logChanges;
109
+ /**
110
+ * Log breaking changes for a comparison result
111
+ */
112
+ private logBreakingChanges;
113
+ /**
114
+ * Log changelog for a comparison result
115
+ */
116
+ private logChangelog;
117
+ /**
118
+ * Log no changes for a comparison result
119
+ */
120
+ private logNoChanges;
121
+ /**
122
+ * Log final summary and handle exit conditions
123
+ */
124
+ private logSummary;
125
+ /**
126
+ * Static factory method for convenience
127
+ */
128
+ static create(): OpenApiSpecDiff;
129
+ /**
130
+ * Static method to maintain compatibility with functional approach
131
+ */
132
+ static compare(openapiConfigs: [string, PsychicOpenapiConfig][]): void;
133
+ }
134
+ export declare class BreakingChangesDetectedInOpenApiSpecError extends Error {
135
+ private readonly oasdiffConfig;
136
+ constructor(oasdiffConfig: OasDiffConfig);
137
+ get message(): string;
138
+ }
@@ -1,3 +1,4 @@
1
+ export { BreakingChangesDetectedInOpenApiSpecError } from './helpers/OpenApiSpecDiff.js';
1
2
  export default class PsychicBin {
2
3
  static generateController(controllerName: string, actions: string[]): Promise<void>;
3
4
  static generateResource(route: string, fullyQualifiedModelName: string, columnsWithTypes: string[], options: {
@@ -13,7 +14,8 @@ export default class PsychicBin {
13
14
  schemaOnly?: boolean;
14
15
  }): Promise<void>;
15
16
  static postSync(): Promise<void>;
16
- static syncTypes(customTypes?: any): Promise<void>;
17
+ static syncTypes(): Promise<void>;
18
+ static openapiDiff(): void;
17
19
  static syncOpenapiTypescriptFiles(): Promise<void>;
18
20
  static syncOpenapiJson(): Promise<void>;
19
21
  static syncRoutes(): Promise<void>;
@@ -0,0 +1,89 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * @internal
4
+ *
5
+ * This is a base class, which is inherited by the ASTSchemaBuilder,
6
+ * the ASTKyselyCodegenEnhancer, and the ASTGlobalSchemaBuilder,
7
+ * each of which is responsible for building up the output of the various
8
+ * type files consumed by dream internally.
9
+ *
10
+ * This base class is just a container for common methods used by all
11
+ * classes.
12
+ */
13
+ export default class ASTBuilder {
14
+ /**
15
+ * @internal
16
+ *
17
+ * builds a new line, useful for injecting new lines into AST statements
18
+ */
19
+ protected newLine(): ts.Identifier;
20
+ /**
21
+ * @internal
22
+ *
23
+ * given an interface declaration, it will extrace the relevant property statement
24
+ * by the given property name.
25
+ */
26
+ protected getPropertyFromInterface(interfaceNode: ts.InterfaceDeclaration, propertyName: string): ts.PropertySignature | null;
27
+ /**
28
+ * @internal
29
+ *
30
+ * returns an array of string type literals which were extracted from
31
+ * either a type or type union, depending on what is provided
32
+ * for the typeAlias. this allows you to safely and easily collect
33
+ * an array of types given an alias
34
+ */
35
+ protected extractStringLiteralTypeNodesFromTypeOrUnion(typeAlias: ts.TypeAliasDeclaration): (ts.LiteralTypeNode & {
36
+ literal: {
37
+ text: string;
38
+ };
39
+ })[];
40
+ /**
41
+ * @internal
42
+ *
43
+ * returns an array of type literals which were extracted from
44
+ * either a type or type union, depending on what is provided
45
+ * for the typeAlias. this allows you to safely and easily collect
46
+ * an array of types given an alias
47
+ */
48
+ protected extractTypeNodesFromTypeOrUnion(typeAlias: ts.TypeAliasDeclaration | ts.PropertySignature): ts.TypeNode[];
49
+ /**
50
+ * @internal
51
+ *
52
+ * returns the provided node iff
53
+ * a.) the node is an exported type alias
54
+ * b.) the exported name matches the provided name (or else there was no name provided)
55
+ *
56
+ * otherwise, returns null
57
+ */
58
+ protected exportedTypeAliasOrNull(node: ts.Node, exportName?: string): ts.TypeAliasDeclaration | null;
59
+ /**
60
+ * @internal
61
+ *
62
+ * returns the provided node iff
63
+ * a.) the node is an exported interface
64
+ * b.) the exported name matches the provided name (or else there was no name provided)
65
+ *
66
+ * otherwise, returns null
67
+ */
68
+ protected exportedInterfaceOrNull(node: ts.Node, exportName?: string): ts.InterfaceDeclaration | null;
69
+ /**
70
+ * @internal
71
+ *
72
+ * returns the path to the dream.globals.ts file
73
+ */
74
+ protected psychicTypesPath(): string;
75
+ /**
76
+ * @internal
77
+ *
78
+ * safely runs prettier against the provided output. If prettier
79
+ * is not installed, then the original output is returned
80
+ */
81
+ protected prettier(output: string): Promise<string>;
82
+ /**
83
+ * @internal
84
+ *
85
+ * given a type node, it will send back the first found generic
86
+ * provided to that type.
87
+ */
88
+ protected getFirstGenericType(node: ts.Node): ts.TypeNode | null;
89
+ }
@@ -0,0 +1,28 @@
1
+ import ASTBuilder from './ASTBuilder.js';
2
+ /**
3
+ * Responsible for building dream globals, which can be found at
4
+ * types/dream.globals.ts.
5
+ *
6
+ * This class leverages internal AST building mechanisms built into
7
+ * typescript to manually build up object literals and interfaces
8
+ * for our app to consume.
9
+ */
10
+ export default class ASTPsychicTypesBuilder extends ASTBuilder {
11
+ build(): Promise<void>;
12
+ /**
13
+ * @internal
14
+ *
15
+ * builds up the `export const psychicTypes = ...` statement within the types/psychic.ts
16
+ * file. It does this by leveraging low-level AST utils built into typescript
17
+ * to manually build up an object literal, cast it as a const, and write it to
18
+ * an exported variable.
19
+ */
20
+ private buildPsychicTypes;
21
+ /**
22
+ * @internal
23
+ *
24
+ * writes the compiled statements to string.
25
+ *
26
+ */
27
+ private printStatements;
28
+ }
@@ -76,7 +76,7 @@ export default class PsychicController {
76
76
  /**
77
77
  * @internal
78
78
  *
79
- * Used for displaying routes when running `yarn psy routes`
79
+ * Used for displaying routes when running `pnpm psy routes`
80
80
  * cli command
81
81
  */
82
82
  static get disaplayName(): string;
@@ -491,6 +491,34 @@ interface PsychicOpenapiBaseOptions {
491
491
  * ```
492
492
  */
493
493
  validate?: OpenapiValidateOption;
494
+ /**
495
+ * Enables automatic comparison of OpenAPI specifications between the current
496
+ * working branch and the main/master/head branch.
497
+ *
498
+ * When set to `true`, Psychic will perform a diff check between the OpenAPI spec
499
+ * in the current branch and the one in the main/master/head branch. This is done using the
500
+ * `OpenApiSpecDiff` tool, which analyzes structural and semantic differences
501
+ * between the two specs.
502
+ *
503
+ * This feature is useful for catching unintended changes to your API contract
504
+ * before they are merged, especially breaking changes that could affect downstream
505
+ * consumers or integrations.
506
+ *
507
+ * Typical use cases include CI/CD validation, pull request checks, or local
508
+ * development sanity checks.
509
+ *
510
+ * Example usage:
511
+ * ```ts
512
+ * psy.set('openapi', {
513
+ * ...
514
+ * checkDiffs: true,
515
+ * ...
516
+ * });
517
+ * ```
518
+ *
519
+
520
+ */
521
+ checkDiffs?: boolean;
494
522
  }
495
523
  interface PsychicOpenapiInfo {
496
524
  version: 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": "2.0.4",
5
+ "version": "2.2.0",
6
6
  "author": "RVOHealth",
7
7
  "repository": {
8
8
  "type": "git",
@@ -48,28 +48,29 @@
48
48
  "dist/**/*"
49
49
  ],
50
50
  "scripts": {
51
- "client": "yarn --cwd=./client start",
52
- "client:fspec": "VITE_PSYCHIC_ENV=test BROWSER=none yarn --cwd=./client start",
53
- "psy": "NODE_ENV=${NODE_ENV:-test} yarn psyts",
51
+ "client": "cd client && pnpm start",
52
+ "client:fspec": "cd client && VITE_PSYCHIC_ENV=test BROWSER=none pnpm start",
53
+ "psy": "NODE_ENV=${NODE_ENV:-test} pnpm psyts",
54
54
  "psyjs": "node ./dist/test-app/src/cli/index.js",
55
55
  "psyts": "NODE_ENV=${NODE_ENV:-test} tsx ./test-app/src/cli/index.ts",
56
56
  "gpsy": "tsx ./global-cli/main.ts",
57
57
  "build": "echo \"building cjs...\" && rm -rf dist && npx tsc -p ./tsconfig.cjs.build.json && echo \"building esm...\" && npx tsc -p ./tsconfig.esm.build.json",
58
58
  "build:test-app": "rm -rf dist && echo \"building test app to esm...\" && npx tsc -p ./tsconfig.esm.build.test-app.json && echo \"building test app to cjs...\" && npx tsc -p ./tsconfig.cjs.build.test-app.json",
59
- "types:esm:trace": "rm -rf dist && npx tsc -p ./tsconfig.esm.build.json --generateTrace ./typetrace --diagnostics && yarn analyze-trace ./typetrace --skipMillis 100 --forceMillis 300",
59
+ "types:esm:trace": "rm -rf dist && npx tsc -p ./tsconfig.esm.build.json --generateTrace ./typetrace --diagnostics && pnpm analyze-trace ./typetrace --skipMillis 100 --forceMillis 300",
60
60
  "dev": "nodemon --quiet --no-stdin",
61
61
  "console": "tsx ./test-app/src/conf/repl.ts",
62
62
  "uspec": "vitest --config ./spec/unit/vite.config.ts",
63
63
  "fspec": "vitest run --config=./spec/features/vite.config.ts",
64
- "format": "yarn run prettier . --write",
65
- "lint": "yarn run eslint --no-warn-ignored \"src/**/*.ts\" \"spec/**/*.ts\" \"test-app/**/*.ts\" && yarn run prettier . --check",
66
- "prepack": "yarn build"
64
+ "format": "pnpm prettier . --write",
65
+ "lint": "pnpm eslint --no-warn-ignored \"src/**/*.ts\" \"spec/**/*.ts\" \"test-app/**/*.ts\" && pnpm prettier . --check",
66
+ "prepack": "pnpm build"
67
67
  },
68
68
  "dependencies": {
69
69
  "@types/cookie-parser": "^1.4.8",
70
70
  "@types/cors": "^2.8.17",
71
71
  "ajv": "^8.17.1",
72
72
  "ajv-formats": "^3.0.1",
73
+ "body-parser": "^2.2.1",
73
74
  "commander": "^12.1.0",
74
75
  "cookie-parser": "^1.4.7",
75
76
  "cors": "^2.8.5",
@@ -81,29 +82,31 @@
81
82
  "@rvoh/dream": "^2.0.3",
82
83
  "@types/express": "^5.0.1",
83
84
  "commander": "^12.1.0",
84
- "express": "^5.1.0",
85
+ "express": "^5.2.1",
85
86
  "openapi-typescript": "^7.8.0"
86
87
  },
87
88
  "devDependencies": {
88
- "@eslint/js": "^9.19.0",
89
+ "@eslint/js": "^9.39.1",
89
90
  "@jest-mock/express": "^3.0.0",
90
91
  "@rvoh/dream": "^2.0.3",
91
92
  "@rvoh/dream-spec-helpers": "^2.0.0",
92
93
  "@rvoh/psychic-spec-helpers": "^2.0.0",
93
- "@types/express": "^5.0.1",
94
+ "@types/body-parser": "^1.19.6",
95
+ "@types/express": "^5.0.6",
94
96
  "@types/express-session": "^1.18.2",
95
97
  "@types/node": "^22.17.1",
96
98
  "@types/passport": "^0",
97
99
  "@types/passport-local": "^1",
98
100
  "@types/pg": "^8.11.8",
99
101
  "@types/supertest": "^6.0.3",
102
+ "@typescript-eslint/parser": "^8.48.1",
100
103
  "@typescript/analyze-trace": "^0.10.1",
101
- "eslint": "^9.19.0",
102
- "express": "^5.1.0",
104
+ "eslint": "^9.39.1",
105
+ "express": "^5.2.1",
103
106
  "express-session": "^1.18.2",
104
107
  "jsdom": "^26.1.0",
105
108
  "kysely": "^0.28.5",
106
- "kysely-codegen": "~0.17.0",
109
+ "kysely-codegen": "~0.19.0",
107
110
  "luxon-jest-matchers": "^0.1.14",
108
111
  "nodemon": "^3.1.11",
109
112
  "openapi-typescript": "^7.8.0",
@@ -117,9 +120,9 @@
117
120
  "tsx": "^4.19.3",
118
121
  "typedoc": "^0.26.6",
119
122
  "typescript": "^5.5.4",
120
- "typescript-eslint": "=7.18.0",
123
+ "typescript-eslint": "^8.48.1",
121
124
  "vitest": "^4.0.9",
122
125
  "winston": "^3.14.2"
123
126
  },
124
- "packageManager": "yarn@4.7.0"
127
+ "packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a"
125
128
  }
@@ -1,23 +0,0 @@
1
- import { DreamApp } from '@rvoh/dream';
2
- import { CliFileWriter } from '@rvoh/dream/system';
3
- import * as path from 'node:path';
4
- import PsychicApp from '../../psychic-app/index.js';
5
- export default class TypesBuilder {
6
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
- static async sync(customTypes = undefined) {
8
- const dreamApp = DreamApp.getOrFail();
9
- const schemaPath = path.join(dreamApp.projectRoot, dreamApp.paths.types, 'psychic.ts');
10
- await CliFileWriter.write(schemaPath, this.build(customTypes));
11
- }
12
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
- static build(customTypes = undefined) {
14
- const psychicApp = PsychicApp.getOrFail();
15
- const output = {
16
- openapiNames: Object.keys(psychicApp.openapi),
17
- ...(customTypes || {}),
18
- };
19
- return `const psychicTypes = ${JSON.stringify(output, null, 2)} as const
20
-
21
- export default psychicTypes`;
22
- }
23
- }
@@ -1,23 +0,0 @@
1
- import { DreamApp } from '@rvoh/dream';
2
- import { CliFileWriter } from '@rvoh/dream/system';
3
- import * as path from 'node:path';
4
- import PsychicApp from '../../psychic-app/index.js';
5
- export default class TypesBuilder {
6
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
- static async sync(customTypes = undefined) {
8
- const dreamApp = DreamApp.getOrFail();
9
- const schemaPath = path.join(dreamApp.projectRoot, dreamApp.paths.types, 'psychic.ts');
10
- await CliFileWriter.write(schemaPath, this.build(customTypes));
11
- }
12
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
- static build(customTypes = undefined) {
14
- const psychicApp = PsychicApp.getOrFail();
15
- const output = {
16
- openapiNames: Object.keys(psychicApp.openapi),
17
- ...(customTypes || {}),
18
- };
19
- return `const psychicTypes = ${JSON.stringify(output, null, 2)} as const
20
-
21
- export default psychicTypes`;
22
- }
23
- }
@@ -1,7 +0,0 @@
1
- export default class TypesBuilder {
2
- static sync(customTypes?: any): Promise<void>;
3
- static build(customTypes?: any): string;
4
- }
5
- export interface PsychicTypeSync {
6
- openapiNames: string[];
7
- }