@rvoh/psychic 0.27.0 → 0.27.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.
package/README.md CHANGED
@@ -1,12 +1,14 @@
1
- > ATTENTION: we are currently in the process of releasing this code to the world, as of the afternoon of March 10th, 2025. This notice will be removed, and the version of this repo will be bumped to 1.0.0, once all of the repos have been migrated to the new spaces and we can verify that it is all working. This is anticipated to take 1 day.
1
+ > ATTENTION: we are currently in the process of releasing this code to the world, as of the afternoon of March 10th, 2025. This notice will be removed, and the version of this repo will be bumped to 1.0.0, once all of the repos have been migrated to the new spaces and we can verify that it is all working. This is anticipated to be done in early April, 2025.
2
2
 
3
3
  # Psychic
4
4
 
5
- Psychic is a typescript first Node framework built on top of [kysely](http://kysely.dev) and heavily inspired by Ruby on Rails. It provides a light-weight routing layer around [expressjs](https://expressjs.com) to create a familiar MVC pattern for those coming from a conventional MVC framework, a type-safe ORM with an incredibly powerful autocomplete API, elegant redis and socket.io bindings for distributed websocket applications, the ability to couple with a front-end framework (like react, angular, etc...) and write specs that drive through your front end, while still maintaining a back end-centric context from which to write specs.
5
+ Psychic is a typescript first Node framework built on top of [kysely](http://kysely.dev) and heavily inspired by Ruby on Rails. It provides a light-weight routing layer around [expressjs](https://expressjs.com) to create a familiar MVC pattern for those coming from a conventional MVC framework, and...
6
6
 
7
- For more comprehensive documentation, please see [The official Psychic guides](https://psychicframework.com). We will also be publishing api docs shortly, but the Psychic guides should be comprehensive enough to provide an understanding of the technology and how to use it.
7
+ Introducing [dream](https://psychicframework.com/docs/models/overview)!, a robust, type-safe ORM with an incredibly powerful autocomplete API, through associations, polymorphism, single table inheritence, deep OpenAPI integration, and much more.
8
+
9
+ In addition, psychic also provides elegant redis and socket.io bindings for distributed websocket applications, a powerful background job system integrated with bullmq to enable you to easily send any of your application code into redis for background processing, the ability to couple with a front-end framework (like nextjs, react, angular etc...) and write specs that drive through your front end, while still maintaining a back end-centric context from which to compose, and much more!
8
10
 
9
- NOTE: doing so will create the new app in the psychic folder, so once done testing remember to remove it.
11
+ For more comprehensive documentation, please see [The official Psychic guides](https://psychicframework.com). We will also be publishing api docs shortly, but the Psychic guides should be comprehensive enough to provide an understanding of the technology and how to use it.
10
12
 
11
13
  ## Questions?
12
14
 
@@ -27,6 +27,20 @@ class PsychicBin {
27
27
  if (!bypassDreamSync)
28
28
  await dream_1.DreamBin.sync(() => { });
29
29
  await PsychicBin.syncTypes();
30
+ const psychicApp = index_js_1.default.getOrFail();
31
+ dream_1.DreamCLI.logger.logStartProgress('running post-sync operations...');
32
+ // call post-sync command in a separate process, so that newly-generated
33
+ // types can be reloaded and brought into all classes.
34
+ await dream_1.DreamCLI.spawn(psychicApp.psyCmd('post-sync'), {
35
+ onStdout: message => {
36
+ dream_1.DreamCLI.logger.logContinueProgress(`[post-sync]` + ' ' + message, {
37
+ logPrefixColor: 'cyan',
38
+ });
39
+ },
40
+ });
41
+ dream_1.DreamCLI.logger.logEndProgress();
42
+ }
43
+ static async postSync() {
30
44
  const psychicApp = index_js_1.default.getOrFail();
31
45
  await PsychicBin.syncOpenapiJson();
32
46
  if (psychicApp.openapi?.syncEnumsToClient) {
@@ -50,6 +50,14 @@ class PsychicCLI {
50
50
  await index_js_1.default.sync();
51
51
  process.exit();
52
52
  });
53
+ program
54
+ .command('post-sync')
55
+ .description('an internal command that runs as the second stage of the `sync` command, since after types are rebuit, the application needs to be reloaded before autogenerating certain files, since those files will need to leverage the updated types')
56
+ .action(async () => {
57
+ await initializePsychicApplication();
58
+ await index_js_1.default.postSync();
59
+ process.exit();
60
+ });
53
61
  program
54
62
  .command('sync:routes')
55
63
  .description('reads the routes generated by your app and generates a cache file, which is then used to give autocomplete support to the route helper, amoongst other things.')
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class PsychicApplicationInitMissingPackageManager extends Error {
4
+ constructor() {
5
+ super();
6
+ }
7
+ get message() {
8
+ return `
9
+ must set packageManager when initializing a new PsychicApplication.
10
+
11
+ within conf/app.ts, you must have a call to "#set('packageManager', '<YOUR_CHOSEN_PACKAGE_MANAGER>')", i.e.
12
+
13
+ // conf/app.ts
14
+ export default async (app: PsychicApplication) => {
15
+ await app.set('packageManager', 'yarn')
16
+ }
17
+ `;
18
+ }
19
+ }
20
+ exports.default = PsychicApplicationInitMissingPackageManager;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsychicApplicationAllowedPackageManagersEnumValues = void 0;
3
4
  const dream_1 = require("@rvoh/dream");
4
5
  const init_missing_api_root_js_1 = require("../error/psychic-application/init-missing-api-root.js");
5
6
  const init_missing_call_to_load_controllers_js_1 = require("../error/psychic-application/init-missing-call-to-load-controllers.js");
@@ -9,6 +10,7 @@ const EnvInternal_js_1 = require("../helpers/EnvInternal.js");
9
10
  const cache_js_1 = require("./cache.js");
10
11
  const importControllers_js_1 = require("./helpers/import/importControllers.js");
11
12
  const lookupClassByGlobalName_js_1 = require("./helpers/lookupClassByGlobalName.js");
13
+ const init_missing_package_manager_js_1 = require("../error/psychic-application/init-missing-package-manager.js");
12
14
  class PsychicApplication {
13
15
  static async init(cb, dreamCb, opts = {}) {
14
16
  let psychicApp;
@@ -21,11 +23,16 @@ class PsychicApplication {
21
23
  throw new init_missing_api_root_js_1.default();
22
24
  if (!psychicApp.routesCb)
23
25
  throw new init_missing_routes_callback_js_1.default();
26
+ if (!exports.PsychicApplicationAllowedPackageManagersEnumValues.includes(psychicApp.packageManager))
27
+ throw new init_missing_package_manager_js_1.default();
24
28
  if (psychicApp.encryption?.cookies?.current)
25
29
  this.checkKey('cookies', psychicApp.encryption.cookies.current.key, psychicApp.encryption.cookies.current.algorithm);
26
30
  await psychicApp.inflections?.();
27
31
  dreamApp.set('projectRoot', psychicApp.apiRoot);
28
32
  dreamApp.set('logger', psychicApp.logger);
33
+ for (const plugin of psychicApp.plugins) {
34
+ await plugin(psychicApp);
35
+ }
29
36
  (0, cache_js_1.cachePsychicApplication)(psychicApp);
30
37
  });
31
38
  return psychicApp;
@@ -34,6 +41,29 @@ class PsychicApplication {
34
41
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
35
42
  return (0, lookupClassByGlobalName_js_1.default)(name);
36
43
  }
44
+ /**
45
+ * @internal
46
+ *
47
+ * used to provide the correct package manager syntax for running a script
48
+ * inside of the package.json "scripts" section.
49
+ */
50
+ packageManagerRunCmd(cmd) {
51
+ switch (this.packageManager) {
52
+ case 'npm':
53
+ return `npm run ${cmd}`;
54
+ default:
55
+ return `${this.packageManager} ${cmd}`;
56
+ }
57
+ }
58
+ /**
59
+ * @internal
60
+ *
61
+ * adds the necessary package manager prefix to the psy command provided
62
+ * i.e. `psyCmd('sync')`
63
+ */
64
+ psyCmd(cmd) {
65
+ return this.packageManagerRunCmd(`psy ${cmd}`);
66
+ }
37
67
  static checkKey(encryptionIdentifier, key, algorithm) {
38
68
  if (!dream_1.Encrypt.validateKey(key, algorithm))
39
69
  console.warn(`
@@ -108,14 +138,18 @@ Try setting it to something valid, like:
108
138
  get logger() {
109
139
  return this._logger;
110
140
  }
111
- _sslCredentials;
141
+ _sslCredentials = undefined;
112
142
  get sslCredentials() {
113
143
  return this._sslCredentials;
114
144
  }
115
- _saltRounds;
145
+ _saltRounds = undefined;
116
146
  get saltRounds() {
117
147
  return this._saltRounds;
118
148
  }
149
+ _packageManager;
150
+ get packageManager() {
151
+ return this._packageManager;
152
+ }
119
153
  _routesCb;
120
154
  get routesCb() {
121
155
  return this._routesCb;
@@ -196,6 +230,10 @@ Try setting it to something valid, like:
196
230
  get controllers() {
197
231
  return (0, importControllers_js_1.getControllersOrFail)();
198
232
  }
233
+ _plugins = [];
234
+ get plugins() {
235
+ return this._plugins;
236
+ }
199
237
  async load(resourceType, resourcePath,
200
238
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
201
239
  importCb) {
@@ -226,6 +264,9 @@ Try setting it to something valid, like:
226
264
  await this.inflections?.();
227
265
  this.booted = true;
228
266
  }
267
+ plugin(cb) {
268
+ this._plugins.push(cb);
269
+ }
229
270
  on(hookEventType, cb) {
230
271
  switch (hookEventType) {
231
272
  case 'server:error':
@@ -306,6 +347,9 @@ Try setting it to something valid, like:
306
347
  case 'port':
307
348
  this._port = value;
308
349
  break;
350
+ case 'packageManager':
351
+ this._packageManager = value;
352
+ break;
309
353
  case 'saltRounds':
310
354
  this._saltRounds = value;
311
355
  break;
@@ -344,3 +388,4 @@ Try setting it to something valid, like:
344
388
  }
345
389
  }
346
390
  exports.default = PsychicApplication;
391
+ exports.PsychicApplicationAllowedPackageManagersEnumValues = ['yarn', 'npm', 'pnpm'];
@@ -25,6 +25,20 @@ export default class PsychicBin {
25
25
  if (!bypassDreamSync)
26
26
  await DreamBin.sync(() => { });
27
27
  await PsychicBin.syncTypes();
28
+ const psychicApp = PsychicApplication.getOrFail();
29
+ DreamCLI.logger.logStartProgress('running post-sync operations...');
30
+ // call post-sync command in a separate process, so that newly-generated
31
+ // types can be reloaded and brought into all classes.
32
+ await DreamCLI.spawn(psychicApp.psyCmd('post-sync'), {
33
+ onStdout: message => {
34
+ DreamCLI.logger.logContinueProgress(`[post-sync]` + ' ' + message, {
35
+ logPrefixColor: 'cyan',
36
+ });
37
+ },
38
+ });
39
+ DreamCLI.logger.logEndProgress();
40
+ }
41
+ static async postSync() {
28
42
  const psychicApp = PsychicApplication.getOrFail();
29
43
  await PsychicBin.syncOpenapiJson();
30
44
  if (psychicApp.openapi?.syncEnumsToClient) {
@@ -48,6 +48,14 @@ export default class PsychicCLI {
48
48
  await PsychicBin.sync();
49
49
  process.exit();
50
50
  });
51
+ program
52
+ .command('post-sync')
53
+ .description('an internal command that runs as the second stage of the `sync` command, since after types are rebuit, the application needs to be reloaded before autogenerating certain files, since those files will need to leverage the updated types')
54
+ .action(async () => {
55
+ await initializePsychicApplication();
56
+ await PsychicBin.postSync();
57
+ process.exit();
58
+ });
51
59
  program
52
60
  .command('sync:routes')
53
61
  .description('reads the routes generated by your app and generates a cache file, which is then used to give autocomplete support to the route helper, amoongst other things.')
@@ -0,0 +1,17 @@
1
+ export default class PsychicApplicationInitMissingPackageManager extends Error {
2
+ constructor() {
3
+ super();
4
+ }
5
+ get message() {
6
+ return `
7
+ must set packageManager when initializing a new PsychicApplication.
8
+
9
+ within conf/app.ts, you must have a call to "#set('packageManager', '<YOUR_CHOSEN_PACKAGE_MANAGER>')", i.e.
10
+
11
+ // conf/app.ts
12
+ export default async (app: PsychicApplication) => {
13
+ await app.set('packageManager', 'yarn')
14
+ }
15
+ `;
16
+ }
17
+ }
@@ -7,6 +7,7 @@ import EnvInternal from '../helpers/EnvInternal.js';
7
7
  import { cachePsychicApplication, getCachedPsychicApplicationOrFail } from './cache.js';
8
8
  import importControllers, { getControllersOrFail } from './helpers/import/importControllers.js';
9
9
  import lookupClassByGlobalName from './helpers/lookupClassByGlobalName.js';
10
+ import PsychicApplicationInitMissingPackageManager from '../error/psychic-application/init-missing-package-manager.js';
10
11
  export default class PsychicApplication {
11
12
  static async init(cb, dreamCb, opts = {}) {
12
13
  let psychicApp;
@@ -19,11 +20,16 @@ export default class PsychicApplication {
19
20
  throw new PsychicApplicationInitMissingApiRoot();
20
21
  if (!psychicApp.routesCb)
21
22
  throw new PsychicApplicationInitMissingRoutesCallback();
23
+ if (!PsychicApplicationAllowedPackageManagersEnumValues.includes(psychicApp.packageManager))
24
+ throw new PsychicApplicationInitMissingPackageManager();
22
25
  if (psychicApp.encryption?.cookies?.current)
23
26
  this.checkKey('cookies', psychicApp.encryption.cookies.current.key, psychicApp.encryption.cookies.current.algorithm);
24
27
  await psychicApp.inflections?.();
25
28
  dreamApp.set('projectRoot', psychicApp.apiRoot);
26
29
  dreamApp.set('logger', psychicApp.logger);
30
+ for (const plugin of psychicApp.plugins) {
31
+ await plugin(psychicApp);
32
+ }
27
33
  cachePsychicApplication(psychicApp);
28
34
  });
29
35
  return psychicApp;
@@ -32,6 +38,29 @@ export default class PsychicApplication {
32
38
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
33
39
  return lookupClassByGlobalName(name);
34
40
  }
41
+ /**
42
+ * @internal
43
+ *
44
+ * used to provide the correct package manager syntax for running a script
45
+ * inside of the package.json "scripts" section.
46
+ */
47
+ packageManagerRunCmd(cmd) {
48
+ switch (this.packageManager) {
49
+ case 'npm':
50
+ return `npm run ${cmd}`;
51
+ default:
52
+ return `${this.packageManager} ${cmd}`;
53
+ }
54
+ }
55
+ /**
56
+ * @internal
57
+ *
58
+ * adds the necessary package manager prefix to the psy command provided
59
+ * i.e. `psyCmd('sync')`
60
+ */
61
+ psyCmd(cmd) {
62
+ return this.packageManagerRunCmd(`psy ${cmd}`);
63
+ }
35
64
  static checkKey(encryptionIdentifier, key, algorithm) {
36
65
  if (!Encrypt.validateKey(key, algorithm))
37
66
  console.warn(`
@@ -106,14 +135,18 @@ Try setting it to something valid, like:
106
135
  get logger() {
107
136
  return this._logger;
108
137
  }
109
- _sslCredentials;
138
+ _sslCredentials = undefined;
110
139
  get sslCredentials() {
111
140
  return this._sslCredentials;
112
141
  }
113
- _saltRounds;
142
+ _saltRounds = undefined;
114
143
  get saltRounds() {
115
144
  return this._saltRounds;
116
145
  }
146
+ _packageManager;
147
+ get packageManager() {
148
+ return this._packageManager;
149
+ }
117
150
  _routesCb;
118
151
  get routesCb() {
119
152
  return this._routesCb;
@@ -194,6 +227,10 @@ Try setting it to something valid, like:
194
227
  get controllers() {
195
228
  return getControllersOrFail();
196
229
  }
230
+ _plugins = [];
231
+ get plugins() {
232
+ return this._plugins;
233
+ }
197
234
  async load(resourceType, resourcePath,
198
235
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
236
  importCb) {
@@ -224,6 +261,9 @@ Try setting it to something valid, like:
224
261
  await this.inflections?.();
225
262
  this.booted = true;
226
263
  }
264
+ plugin(cb) {
265
+ this._plugins.push(cb);
266
+ }
227
267
  on(hookEventType, cb) {
228
268
  switch (hookEventType) {
229
269
  case 'server:error':
@@ -304,6 +344,9 @@ Try setting it to something valid, like:
304
344
  case 'port':
305
345
  this._port = value;
306
346
  break;
347
+ case 'packageManager':
348
+ this._packageManager = value;
349
+ break;
307
350
  case 'saltRounds':
308
351
  this._saltRounds = value;
309
352
  break;
@@ -341,3 +384,4 @@ Try setting it to something valid, like:
341
384
  }
342
385
  }
343
386
  }
387
+ export const PsychicApplicationAllowedPackageManagersEnumValues = ['yarn', 'npm', 'pnpm'];
@@ -5,6 +5,7 @@ export default class PsychicBin {
5
5
  static sync({ bypassDreamSync }?: {
6
6
  bypassDreamSync?: boolean;
7
7
  }): Promise<void>;
8
+ static postSync(): Promise<void>;
8
9
  static syncTypes(customTypes?: any): Promise<void>;
9
10
  static syncOpenapiJson(): Promise<void>;
10
11
  static syncRoutes(): Promise<void>;
@@ -0,0 +1,4 @@
1
+ export default class PsychicApplicationInitMissingPackageManager extends Error {
2
+ constructor();
3
+ get message(): string;
4
+ }
@@ -11,6 +11,20 @@ import { PsychicHookEventType, PsychicHookLoadEventTypes } from './types.js';
11
11
  export default class PsychicApplication {
12
12
  static init(cb: (app: PsychicApplication) => void | Promise<void>, dreamCb: (app: DreamApplication) => void | Promise<void>, opts?: PsychicApplicationInitOptions): Promise<PsychicApplication>;
13
13
  static lookupClassByGlobalName(name: string): any;
14
+ /**
15
+ * @internal
16
+ *
17
+ * used to provide the correct package manager syntax for running a script
18
+ * inside of the package.json "scripts" section.
19
+ */
20
+ packageManagerRunCmd(cmd: string): string;
21
+ /**
22
+ * @internal
23
+ *
24
+ * adds the necessary package manager prefix to the psy command provided
25
+ * i.e. `psyCmd('sync')`
26
+ */
27
+ psyCmd(cmd: string): string;
14
28
  private static checkKey;
15
29
  /**
16
30
  * Returns the cached psychic application if it has been set.
@@ -45,10 +59,12 @@ export default class PsychicApplication {
45
59
  };
46
60
  private _logger;
47
61
  get logger(): DreamLogger;
48
- private _sslCredentials?;
62
+ private _sslCredentials;
49
63
  get sslCredentials(): PsychicSslCredentials | undefined;
50
- private _saltRounds?;
64
+ private _saltRounds;
51
65
  get saltRounds(): number | undefined;
66
+ private _packageManager;
67
+ get packageManager(): "yarn" | "npm" | "pnpm";
52
68
  private _routesCb;
53
69
  get routesCb(): (r: PsychicRouter) => void | Promise<void>;
54
70
  private _openapi;
@@ -73,16 +89,21 @@ export default class PsychicApplication {
73
89
  [x: string]: string | null;
74
90
  };
75
91
  get controllers(): Record<string, typeof import("../index.js").PsychicController>;
92
+ private _plugins;
93
+ get plugins(): ((app: PsychicApplication) => void | Promise<void>)[];
76
94
  load<RT extends 'controllers'>(resourceType: RT, resourcePath: string, importCb: (path: string) => Promise<any>): Promise<void>;
77
95
  private booted;
78
96
  boot(force?: boolean): Promise<void>;
97
+ plugin(cb: (app: PsychicApplication) => void | Promise<void>): void;
79
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' ? (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 'sync' ? () => any : (conf: PsychicApplication) => void | Promise<void>): void;
80
99
  set(option: 'openapi', name: string, value: NamedPsychicOpenapiOptions): void;
81
- set<Opt extends PsychicApplicationOption>(option: Opt, value: Opt extends 'appName' ? string : Opt extends 'apiOnly' ? boolean : Opt extends 'defaultResponseHeaders' ? Record<string, string | null> : Opt extends 'encryption' ? PsychicApplicationEncryptionOptions : 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 'inflections' ? () => void | Promise<void> : Opt extends 'routes' ? (r: PsychicRouter) => void | Promise<void> : never): void;
100
+ set<Opt extends PsychicApplicationOption>(option: Opt, value: Opt extends 'appName' ? string : Opt extends 'apiOnly' ? boolean : Opt extends 'defaultResponseHeaders' ? Record<string, string | null> : Opt extends 'encryption' ? PsychicApplicationEncryptionOptions : 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' ? PsychicApplicationAllowedPackageManagersEnum : Opt extends 'inflections' ? () => void | Promise<void> : Opt extends 'routes' ? (r: PsychicRouter) => void | Promise<void> : never): void;
82
101
  override<Override extends keyof PsychicApplicationOverrides>(override: Override, value: PsychicApplicationOverrides[Override]): void;
83
102
  private runHooksFor;
84
103
  }
85
- export type PsychicApplicationOption = 'appName' | 'apiOnly' | 'apiRoot' | 'encryption' | 'sessionCookieName' | 'client' | 'clientRoot' | 'cookie' | 'cors' | 'defaultResponseHeaders' | 'inflections' | 'json' | 'logger' | 'openapi' | 'paths' | 'port' | 'routes' | 'saltRounds' | 'ssl';
104
+ export type PsychicApplicationOption = 'appName' | 'apiOnly' | 'apiRoot' | 'encryption' | 'sessionCookieName' | 'client' | 'clientRoot' | 'cookie' | 'cors' | 'defaultResponseHeaders' | 'inflections' | 'json' | 'logger' | 'openapi' | 'packageManager' | 'paths' | 'port' | 'routes' | 'saltRounds' | 'ssl';
105
+ export declare const PsychicApplicationAllowedPackageManagersEnumValues: readonly ["yarn", "npm", "pnpm"];
106
+ export type PsychicApplicationAllowedPackageManagersEnum = (typeof PsychicApplicationAllowedPackageManagersEnumValues)[number];
86
107
  export interface PsychicApplicationSpecialHooks {
87
108
  sync: (() => any)[];
88
109
  serverInit: ((server: PsychicServer) => void | Promise<void>)[];
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": "0.27.0",
5
+ "version": "0.27.2",
6
6
  "author": "RVOHealth",
7
7
  "repository": {
8
8
  "type": "git",
@@ -24,11 +24,10 @@
24
24
  ],
25
25
  "scripts": {
26
26
  "client": "yarn --cwd=./client start",
27
- "psy": "NODE_ENV=${NODE_ENV:-test} yarn psyts",
27
+ "psy": "PSYCHIC_CORE_DEVELOPMENT=1 NODE_ENV=${NODE_ENV:-test} yarn psyts",
28
28
  "psyjs": "node ./dist/test-app/src/cli/index.js",
29
29
  "psyts": "NODE_ENV=${NODE_ENV:-test} tsx ./test-app/src/cli/index.ts",
30
- "psycore": "PSYCHIC_CORE_DEVELOPMENT=1 yarn psyts",
31
- "gpsycore": "PSYCHIC_CORE_DEVELOPMENT=1 tsx ./global-cli/main.ts",
30
+ "gpsy": "PSYCHIC_CORE_DEVELOPMENT=1 tsx ./global-cli/main.ts",
32
31
  "build": "echo \"building cjs...\" && rm -rf dist && npx tsc -p ./tsconfig.cjs.build.json && echo \"building esm...\" && npx tsc -p ./tsconfig.esm.build.json",
33
32
  "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",
34
33
  "dev": "PSYCHIC_CORE_DEVELOPMENT=1 NODE_ENV=development tsx ./test-app/main.ts",
@@ -63,7 +62,7 @@
63
62
  "devDependencies": {
64
63
  "@eslint/js": "^9.19.0",
65
64
  "@jest-mock/express": "^3.0.0",
66
- "@rvoh/dream": "^0.31.3",
65
+ "@rvoh/dream": "^0.32.3",
67
66
  "@rvoh/dream-spec-helpers": "=0.1.0",
68
67
  "@rvoh/psychic-spec-helpers": "=0.2.0",
69
68
  "@types/express": "^4.17.21",
@@ -93,4 +92,4 @@
93
92
  "winston": "^3.14.2"
94
93
  },
95
94
  "packageManager": "yarn@4.7.0"
96
- }
95
+ }
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = sspawn;
4
- exports.ssspawn = ssspawn;
5
- const child_process_1 = require("child_process");
6
- function sspawn(command,
7
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
- opts = {}) {
9
- return new Promise((accept, reject) => {
10
- ssspawn(command, opts).on('close', code => {
11
- if (code !== 0)
12
- reject(new Error(code?.toString()));
13
- accept({});
14
- });
15
- });
16
- }
17
- function ssspawn(command,
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- opts = {}) {
20
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
21
- return (0, child_process_1.spawn)(command, {
22
- stdio: 'inherit',
23
- shell: true,
24
- ...opts,
25
- });
26
- }
@@ -1,22 +0,0 @@
1
- import { spawn } from 'child_process';
2
- export default function sspawn(command,
3
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
- opts = {}) {
5
- return new Promise((accept, reject) => {
6
- ssspawn(command, opts).on('close', code => {
7
- if (code !== 0)
8
- reject(new Error(code?.toString()));
9
- accept({});
10
- });
11
- });
12
- }
13
- export function ssspawn(command,
14
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- opts = {}) {
16
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
17
- return spawn(command, {
18
- stdio: 'inherit',
19
- shell: true,
20
- ...opts,
21
- });
22
- }
@@ -1,2 +0,0 @@
1
- export default function sspawn(command: string, opts?: any): Promise<unknown>;
2
- export declare function ssspawn(command: string, opts?: any): import("child_process").ChildProcessWithoutNullStreams;