@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 +6 -4
- package/dist/cjs/src/bin/index.js +14 -0
- package/dist/cjs/src/cli/index.js +8 -0
- package/dist/cjs/src/error/psychic-application/init-missing-package-manager.js +20 -0
- package/dist/cjs/src/psychic-application/index.js +47 -2
- package/dist/esm/src/bin/index.js +14 -0
- package/dist/esm/src/cli/index.js +8 -0
- package/dist/esm/src/error/psychic-application/init-missing-package-manager.js +17 -0
- package/dist/esm/src/psychic-application/index.js +46 -2
- package/dist/types/src/bin/index.d.ts +1 -0
- package/dist/types/src/error/psychic-application/init-missing-package-manager.d.ts +4 -0
- package/dist/types/src/psychic-application/index.d.ts +25 -4
- package/package.json +5 -6
- package/dist/cjs/src/helpers/sspawn.js +0 -26
- package/dist/esm/src/helpers/sspawn.js +0 -22
- package/dist/types/src/helpers/sspawn.d.ts +0 -2
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
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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>;
|
|
@@ -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.
|
|
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
|
-
"
|
|
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.
|
|
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
|
-
}
|