@rvoh/psychic 1.2.0 → 1.2.2

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.
@@ -31,6 +31,7 @@ const dream_1 = require("@rvoh/dream");
31
31
  const node_fs_1 = require("node:fs");
32
32
  const fs = __importStar(require("node:fs/promises"));
33
33
  const UnexpectedUndefined_js_1 = __importDefault(require("../error/UnexpectedUndefined.js"));
34
+ const addImportSuffix_js_1 = __importDefault(require("../helpers/path/addImportSuffix.js"));
34
35
  const psychicFileAndDirPaths_js_1 = __importDefault(require("../helpers/path/psychicFileAndDirPaths.js"));
35
36
  const psychicPath_js_1 = __importDefault(require("../helpers/path/psychicPath.js"));
36
37
  const generateControllerContent_js_1 = __importDefault(require("./helpers/generateControllerContent.js"));
@@ -120,9 +121,18 @@ function baseAncestorNameAndImport(controllerNameParts, forAdmin, { forBaseContr
120
121
  const dotFiles = forBaseController ? '..' : '.';
121
122
  return controllerNameParts.length === (forAdmin ? 2 : 1)
122
123
  ? forAdmin
123
- ? [`AdminAuthedController`, `import AdminAuthedController from '${dotFiles}/AuthedController.js'`]
124
- : [`AuthedController`, `import AuthedController from '${dotFiles}/AuthedController.js'`]
125
- : [maybeAncestorNameForBase, `import ${maybeAncestorNameForBase} from '${dotFiles}/BaseController.js'`];
124
+ ? [
125
+ `AdminAuthedController`,
126
+ `import AdminAuthedController from '${dotFiles}/${(0, addImportSuffix_js_1.default)('AuthedController.js')}'`,
127
+ ]
128
+ : [
129
+ `AuthedController`,
130
+ `import AuthedController from '${dotFiles}/${(0, addImportSuffix_js_1.default)('AuthedController.js')}'`,
131
+ ]
132
+ : [
133
+ maybeAncestorNameForBase,
134
+ `import ${maybeAncestorNameForBase} from '${dotFiles}/${(0, addImportSuffix_js_1.default)('BaseController.js')}'`,
135
+ ];
126
136
  }
127
137
  async function generateControllerSpec({ fullyQualifiedControllerName, route, fullyQualifiedModelName, columnsWithTypes, resourceSpecs, owningModel, forAdmin, singular, actions, }) {
128
138
  const { relFilePath, absDirPath, absFilePath } = (0, psychicFileAndDirPaths_js_1.default)((0, psychicPath_js_1.default)('controllerSpecs'), fullyQualifiedControllerName + `.spec.ts`);
@@ -8,6 +8,7 @@ const dream_1 = require("@rvoh/dream");
8
8
  const relativePsychicPath_js_1 = __importDefault(require("../../helpers/path/relativePsychicPath.js"));
9
9
  const updirsFromPath_js_1 = __importDefault(require("../../helpers/path/updirsFromPath.js"));
10
10
  const index_js_1 = require("../../index.js");
11
+ const addImportSuffix_js_1 = __importDefault(require("../../helpers/path/addImportSuffix.js"));
11
12
  function generateResourceControllerSpecContent({ fullyQualifiedControllerName, route, fullyQualifiedModelName, columnsWithTypes, owningModel, forAdmin, singular, actions, }) {
12
13
  fullyQualifiedModelName = (0, dream_1.standardizeFullyQualifiedModelName)(fullyQualifiedModelName);
13
14
  const modelClassName = (0, dream_1.globalClassNameFromFullyQualifiedModelName)(fullyQualifiedModelName);
@@ -134,7 +135,7 @@ function generateResourceControllerSpecContent({ fullyQualifiedControllerName, r
134
135
  const omitDestroy = !actions.includes('destroy');
135
136
  return `\
136
137
  import { ${(0, dream_1.uniq)(dreamImports).join(', ')} } from '@rvoh/dream'${(0, dream_1.uniq)(importStatements).join('')}
137
- import { session, SpecRequestType } from '${specUnitUpdirs}helpers/authentication.js'
138
+ import { session, SpecRequestType } from '${specUnitUpdirs}helpers/${(0, addImportSuffix_js_1.default)('authentication.js')}'
138
139
 
139
140
  describe('${fullyQualifiedControllerName}', () => {
140
141
  let request: SpecRequestType
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = addImportSuffix;
7
+ const index_js_1 = __importDefault(require("../../psychic-app/index.js"));
8
+ function addImportSuffix(filepath) {
9
+ return `${filepath.replace(/(\.ts|\.js)$/, '')}${suffix()}`;
10
+ }
11
+ function suffix() {
12
+ switch (index_js_1.default.getOrFail().importExtension) {
13
+ case '.js':
14
+ return '.js';
15
+ case '.ts':
16
+ return '.ts';
17
+ case 'none':
18
+ return '';
19
+ }
20
+ }
@@ -8,6 +8,7 @@ exports.psychicPathTypeRelativePath = psychicPathTypeRelativePath;
8
8
  const dream_1 = require("@rvoh/dream");
9
9
  const psychicPath_js_1 = __importDefault(require("./psychicPath.js"));
10
10
  const updirsFromPath_js_1 = __importDefault(require("./updirsFromPath.js"));
11
+ const addImportSuffix_js_1 = __importDefault(require("./addImportSuffix.js"));
11
12
  function default_1(originDreamPathType, destinationDreamPathType, fullyQualifiedOriginModelName, fullyQualifiedDestinationModelName = fullyQualifiedOriginModelName) {
12
13
  fullyQualifiedOriginModelName = (0, dream_1.standardizeFullyQualifiedModelName)(fullyQualifiedOriginModelName);
13
14
  fullyQualifiedDestinationModelName = (0, dream_1.pascalize)(fullyQualifiedDestinationModelName);
@@ -30,11 +31,11 @@ function default_1(originDreamPathType, destinationDreamPathType, fullyQualified
30
31
  case 'db':
31
32
  return destinationPath;
32
33
  case 'factories':
33
- return `${destinationPath}${fullyQualifiedDestinationModelName}Factory.js`;
34
+ return (0, addImportSuffix_js_1.default)(`${destinationPath}${fullyQualifiedDestinationModelName}Factory.js`);
34
35
  case 'serializers':
35
- return `${destinationPath}${fullyQualifiedDestinationModelName}Serializer.js`;
36
+ return (0, addImportSuffix_js_1.default)(`${destinationPath}${fullyQualifiedDestinationModelName}Serializer.js`);
36
37
  default:
37
- return `${destinationPath}${fullyQualifiedDestinationModelName}.js`;
38
+ return (0, addImportSuffix_js_1.default)(`${destinationPath}${fullyQualifiedDestinationModelName}.js`);
38
39
  }
39
40
  }
40
41
  function psychicPathTypeRelativePath(originDreamPathType, destinationDreamPathType) {
@@ -26,6 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.GeneratorImportStyles = void 0;
29
30
  const dream_1 = require("@rvoh/dream");
30
31
  const PackageManager_js_1 = __importDefault(require("../cli/helpers/PackageManager.js"));
31
32
  const init_missing_api_root_js_1 = __importDefault(require("../error/psychic-app/init-missing-api-root.js"));
@@ -183,6 +184,10 @@ Try setting it to something valid, like:
183
184
  get packageManager() {
184
185
  return this._packageManager;
185
186
  }
187
+ _importExtension = '.js';
188
+ get importExtension() {
189
+ return this._importExtension;
190
+ }
186
191
  _routesCb;
187
192
  get routesCb() {
188
193
  return this._routesCb;
@@ -360,6 +365,9 @@ Try setting it to something valid, like:
360
365
  case 'apiRoot':
361
366
  this._apiRoot = value;
362
367
  break;
368
+ case 'importExtension':
369
+ this._importExtension = value;
370
+ break;
363
371
  case 'clientRoot':
364
372
  this._clientRoot = value;
365
373
  break;
@@ -439,3 +447,7 @@ Try setting it to something valid, like:
439
447
  }
440
448
  }
441
449
  exports.default = PsychicApp;
450
+ // GeneratorImportStyles are used by CLI generators to determine how
451
+ // to style import suffixes. When integrating with other apps, this
452
+ // suffix style can change, and may need to be configured.
453
+ exports.GeneratorImportStyles = ['.js', '.ts', 'none'];
@@ -2,6 +2,7 @@ import { hyphenize, standardizeFullyQualifiedModelName } from '@rvoh/dream';
2
2
  import { existsSync } from 'node:fs';
3
3
  import * as fs from 'node:fs/promises';
4
4
  import UnexpectedUndefined from '../error/UnexpectedUndefined.js';
5
+ import addImportSuffix from '../helpers/path/addImportSuffix.js';
5
6
  import psychicFileAndDirPaths from '../helpers/path/psychicFileAndDirPaths.js';
6
7
  import psychicPath from '../helpers/path/psychicPath.js';
7
8
  import generateControllerContent from './helpers/generateControllerContent.js';
@@ -91,9 +92,18 @@ function baseAncestorNameAndImport(controllerNameParts, forAdmin, { forBaseContr
91
92
  const dotFiles = forBaseController ? '..' : '.';
92
93
  return controllerNameParts.length === (forAdmin ? 2 : 1)
93
94
  ? forAdmin
94
- ? [`AdminAuthedController`, `import AdminAuthedController from '${dotFiles}/AuthedController.js'`]
95
- : [`AuthedController`, `import AuthedController from '${dotFiles}/AuthedController.js'`]
96
- : [maybeAncestorNameForBase, `import ${maybeAncestorNameForBase} from '${dotFiles}/BaseController.js'`];
95
+ ? [
96
+ `AdminAuthedController`,
97
+ `import AdminAuthedController from '${dotFiles}/${addImportSuffix('AuthedController.js')}'`,
98
+ ]
99
+ : [
100
+ `AuthedController`,
101
+ `import AuthedController from '${dotFiles}/${addImportSuffix('AuthedController.js')}'`,
102
+ ]
103
+ : [
104
+ maybeAncestorNameForBase,
105
+ `import ${maybeAncestorNameForBase} from '${dotFiles}/${addImportSuffix('BaseController.js')}'`,
106
+ ];
97
107
  }
98
108
  async function generateControllerSpec({ fullyQualifiedControllerName, route, fullyQualifiedModelName, columnsWithTypes, resourceSpecs, owningModel, forAdmin, singular, actions, }) {
99
109
  const { relFilePath, absDirPath, absFilePath } = psychicFileAndDirPaths(psychicPath('controllerSpecs'), fullyQualifiedControllerName + `.spec.ts`);
@@ -2,6 +2,7 @@ import { camelize, capitalize, compact, globalClassNameFromFullyQualifiedModelNa
2
2
  import relativePsychicPath from '../../helpers/path/relativePsychicPath.js';
3
3
  import updirsFromPath from '../../helpers/path/updirsFromPath.js';
4
4
  import { pluralize } from '../../index.js';
5
+ import addImportSuffix from '../../helpers/path/addImportSuffix.js';
5
6
  export default function generateResourceControllerSpecContent({ fullyQualifiedControllerName, route, fullyQualifiedModelName, columnsWithTypes, owningModel, forAdmin, singular, actions, }) {
6
7
  fullyQualifiedModelName = standardizeFullyQualifiedModelName(fullyQualifiedModelName);
7
8
  const modelClassName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedModelName);
@@ -128,7 +129,7 @@ export default function generateResourceControllerSpecContent({ fullyQualifiedCo
128
129
  const omitDestroy = !actions.includes('destroy');
129
130
  return `\
130
131
  import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'${uniq(importStatements).join('')}
131
- import { session, SpecRequestType } from '${specUnitUpdirs}helpers/authentication.js'
132
+ import { session, SpecRequestType } from '${specUnitUpdirs}helpers/${addImportSuffix('authentication.js')}'
132
133
 
133
134
  describe('${fullyQualifiedControllerName}', () => {
134
135
  let request: SpecRequestType
@@ -0,0 +1,14 @@
1
+ import PsychicApp from '../../psychic-app/index.js';
2
+ export default function addImportSuffix(filepath) {
3
+ return `${filepath.replace(/(\.ts|\.js)$/, '')}${suffix()}`;
4
+ }
5
+ function suffix() {
6
+ switch (PsychicApp.getOrFail().importExtension) {
7
+ case '.js':
8
+ return '.js';
9
+ case '.ts':
10
+ return '.ts';
11
+ case 'none':
12
+ return '';
13
+ }
14
+ }
@@ -1,6 +1,7 @@
1
1
  import { pascalize, sharedPathPrefix, standardizeFullyQualifiedModelName } from '@rvoh/dream';
2
2
  import psychicPath from './psychicPath.js';
3
3
  import updirsFromPath from './updirsFromPath.js';
4
+ import addImportSuffix from './addImportSuffix.js';
4
5
  export default function (originDreamPathType, destinationDreamPathType, fullyQualifiedOriginModelName, fullyQualifiedDestinationModelName = fullyQualifiedOriginModelName) {
5
6
  fullyQualifiedOriginModelName = standardizeFullyQualifiedModelName(fullyQualifiedOriginModelName);
6
7
  fullyQualifiedDestinationModelName = pascalize(fullyQualifiedDestinationModelName);
@@ -23,11 +24,11 @@ export default function (originDreamPathType, destinationDreamPathType, fullyQua
23
24
  case 'db':
24
25
  return destinationPath;
25
26
  case 'factories':
26
- return `${destinationPath}${fullyQualifiedDestinationModelName}Factory.js`;
27
+ return addImportSuffix(`${destinationPath}${fullyQualifiedDestinationModelName}Factory.js`);
27
28
  case 'serializers':
28
- return `${destinationPath}${fullyQualifiedDestinationModelName}Serializer.js`;
29
+ return addImportSuffix(`${destinationPath}${fullyQualifiedDestinationModelName}Serializer.js`);
29
30
  default:
30
- return `${destinationPath}${fullyQualifiedDestinationModelName}.js`;
31
+ return addImportSuffix(`${destinationPath}${fullyQualifiedDestinationModelName}.js`);
31
32
  }
32
33
  }
33
34
  export function psychicPathTypeRelativePath(originDreamPathType, destinationDreamPathType) {
@@ -155,6 +155,10 @@ Try setting it to something valid, like:
155
155
  get packageManager() {
156
156
  return this._packageManager;
157
157
  }
158
+ _importExtension = '.js';
159
+ get importExtension() {
160
+ return this._importExtension;
161
+ }
158
162
  _routesCb;
159
163
  get routesCb() {
160
164
  return this._routesCb;
@@ -332,6 +336,9 @@ Try setting it to something valid, like:
332
336
  case 'apiRoot':
333
337
  this._apiRoot = value;
334
338
  break;
339
+ case 'importExtension':
340
+ this._importExtension = value;
341
+ break;
335
342
  case 'clientRoot':
336
343
  this._clientRoot = value;
337
344
  break;
@@ -410,3 +417,7 @@ Try setting it to something valid, like:
410
417
  }
411
418
  }
412
419
  }
420
+ // GeneratorImportStyles are used by CLI generators to determine how
421
+ // to style import suffixes. When integrating with other apps, this
422
+ // suffix style can change, and may need to be configured.
423
+ export const GeneratorImportStyles = ['.js', '.ts', 'none'];
@@ -0,0 +1 @@
1
+ export default function addImportSuffix(filepath: string): string;
@@ -59,6 +59,8 @@ export default class PsychicApp {
59
59
  get saltRounds(): number | undefined;
60
60
  private _packageManager;
61
61
  get packageManager(): "yarn" | "npm" | "pnpm";
62
+ private _importExtension;
63
+ get importExtension(): "none" | ".js" | ".ts";
62
64
  private _routesCb;
63
65
  get routesCb(): (r: PsychicRouter) => void | Promise<void>;
64
66
  private _openapi;
@@ -95,10 +97,10 @@ export default class PsychicApp {
95
97
  plugin(cb: (app: PsychicApp) => void | Promise<void>): void;
96
98
  on<T extends PsychicHookEventType>(hookEventType: T, cb: T extends 'server:error' ? (err: Error, req: Request, res: Response) => void | Promise<void> : T extends 'server:init:before-middleware' ? (psychicServer: PsychicServer) => void | Promise<void> : T extends 'server:init:after-middleware' ? (psychicServer: PsychicServer) => void | Promise<void> : T extends 'server:start' ? (psychicServer: PsychicServer) => void | Promise<void> : T extends 'server:shutdown' ? (psychicServer: PsychicServer) => void | Promise<void> : T extends 'server:init:after-routes' ? (psychicServer: PsychicServer) => void | Promise<void> : T extends 'cli:start' ? (program: Command) => void | Promise<void> : T extends 'cli:sync' ? () => any : (conf: PsychicApp) => void | Promise<void>): void;
97
99
  set(option: 'openapi', name: string, value: NamedPsychicOpenapiOptions): void;
98
- set<Opt extends PsychicAppOption>(option: Opt, value: Opt extends 'appName' ? string : Opt extends 'apiOnly' ? boolean : Opt extends 'defaultResponseHeaders' ? Record<string, string | null> : Opt extends 'encryption' ? PsychicAppEncryptionOptions : Opt extends 'cors' ? CorsOptions : Opt extends 'cookie' ? CustomCookieOptions : Opt extends 'apiRoot' ? string : Opt extends 'sessionCookieName' ? string : Opt extends 'clientRoot' ? string : Opt extends 'json' ? bodyParser.Options : Opt extends 'logger' ? PsychicLogger : Opt extends 'client' ? PsychicClientOptions : Opt extends 'ssl' ? PsychicSslCredentials : Opt extends 'openapi' ? DefaultPsychicOpenapiOptions : Opt extends 'paths' ? PsychicPathOptions : Opt extends 'port' ? number : Opt extends 'saltRounds' ? number : Opt extends 'packageManager' ? DreamAppAllowedPackageManagersEnum : Opt extends 'inflections' ? () => void | Promise<void> : Opt extends 'routes' ? (r: PsychicRouter) => void | Promise<void> : never): void;
100
+ set<Opt extends PsychicAppOption>(option: Opt, value: Opt extends 'appName' ? string : Opt extends 'apiOnly' ? boolean : Opt extends 'defaultResponseHeaders' ? Record<string, string | null> : Opt extends 'encryption' ? PsychicAppEncryptionOptions : Opt extends 'cors' ? CorsOptions : Opt extends 'cookie' ? CustomCookieOptions : Opt extends 'apiRoot' ? string : Opt extends 'importExtension' ? GeneratorImportStyle : Opt extends 'sessionCookieName' ? string : Opt extends 'clientRoot' ? string : Opt extends 'json' ? bodyParser.Options : Opt extends 'logger' ? PsychicLogger : Opt extends 'client' ? PsychicClientOptions : Opt extends 'ssl' ? PsychicSslCredentials : Opt extends 'openapi' ? DefaultPsychicOpenapiOptions : Opt extends 'paths' ? PsychicPathOptions : Opt extends 'port' ? number : Opt extends 'saltRounds' ? number : Opt extends 'packageManager' ? DreamAppAllowedPackageManagersEnum : Opt extends 'inflections' ? () => void | Promise<void> : Opt extends 'routes' ? (r: PsychicRouter) => void | Promise<void> : never): void;
99
101
  override<Override extends keyof PsychicAppOverrides>(override: Override, value: PsychicAppOverrides[Override]): void;
100
102
  }
101
- export type PsychicAppOption = 'appName' | 'apiOnly' | 'apiRoot' | 'encryption' | 'sessionCookieName' | 'client' | 'clientRoot' | 'cookie' | 'cors' | 'defaultResponseHeaders' | 'inflections' | 'json' | 'logger' | 'openapi' | 'packageManager' | 'paths' | 'port' | 'routes' | 'saltRounds' | 'ssl';
103
+ export type PsychicAppOption = 'appName' | 'apiOnly' | 'apiRoot' | 'importExtension' | 'encryption' | 'sessionCookieName' | 'client' | 'clientRoot' | 'cookie' | 'cors' | 'defaultResponseHeaders' | 'inflections' | 'json' | 'logger' | 'openapi' | 'packageManager' | 'paths' | 'port' | 'routes' | 'saltRounds' | 'ssl';
102
104
  export interface PsychicAppSpecialHooks {
103
105
  cliSync: (() => any)[];
104
106
  serverInitBeforeMiddleware: ((server: PsychicServer) => void | Promise<void>)[];
@@ -359,4 +361,6 @@ interface SegmentedEncryptionOptions {
359
361
  current: EncryptOptions;
360
362
  legacy?: EncryptOptions;
361
363
  }
364
+ export declare const GeneratorImportStyles: readonly [".js", ".ts", "none"];
365
+ export type GeneratorImportStyle = (typeof GeneratorImportStyles)[number];
362
366
  export {};
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": "1.2.0",
5
+ "version": "1.2.2",
6
6
  "author": "RVOHealth",
7
7
  "repository": {
8
8
  "type": "git",
@@ -63,7 +63,7 @@
63
63
  "@rvoh/dream-spec-helpers": "^1.1.0",
64
64
  "@rvoh/psychic-spec-helpers": "^1.0.0",
65
65
  "@types/express": "^5.0.1",
66
- "@types/express-session": "^1",
66
+ "@types/express-session": "^1.18.2",
67
67
  "@types/node": "^22.5.1",
68
68
  "@types/passport": "^0",
69
69
  "@types/passport-local": "^1",
@@ -72,8 +72,8 @@
72
72
  "@typescript/analyze-trace": "^0.10.1",
73
73
  "eslint": "^9.19.0",
74
74
  "express": "^5.1.0",
75
- "express-session": "^1.18.1",
76
- "jsdom": "^26.0.0",
75
+ "express-session": "^1.18.2",
76
+ "jsdom": "^26.1.0",
77
77
  "kysely": "^0.27.4",
78
78
  "kysely-codegen": "~0.17.0",
79
79
  "luxon-jest-matchers": "^0.1.14",
@@ -83,7 +83,7 @@
83
83
  "pg": "^8.12.0",
84
84
  "prettier": "^3.3.3",
85
85
  "puppeteer": "^24.4.0",
86
- "supertest": "^7.0.0",
86
+ "supertest": "^7.1.4",
87
87
  "tslib": "^2.7.0",
88
88
  "tsx": "^4.19.3",
89
89
  "typedoc": "^0.26.6",