@rvoh/psychic 1.1.7 → 1.1.8

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/CHANGELOG.md CHANGED
@@ -66,3 +66,7 @@ Fix route printing regression causing route printouts to show the path instead o
66
66
  ## 1.1.7
67
67
 
68
68
  - Add support for middleware arrays, enabling express plugins like passport
69
+
70
+ ## 1.1.8
71
+
72
+ - Tap into CliFileWriter provided by dream to tap into file reversion for sync files, since the auto-sync function in psychic can fail and leave your file tree in a bad state.
@@ -28,7 +28,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.default = generateRouteTypes;
30
30
  const dream_1 = require("@rvoh/dream");
31
- const fs = __importStar(require("node:fs/promises"));
32
31
  const path = __importStar(require("node:path"));
33
32
  const index_js_1 = __importDefault(require("../../psychic-app/index.js"));
34
33
  async function generateRouteTypes(routes) {
@@ -38,5 +37,5 @@ async function generateRouteTypes(routes) {
38
37
  `;
39
38
  const psychicApp = index_js_1.default.getOrFail();
40
39
  const routeTypesPath = path.join(psychicApp.apiRoot, 'src', 'conf', 'routeTypes.ts');
41
- await fs.writeFile(routeTypesPath, fileStr);
40
+ await dream_1.CliFileWriter.write(routeTypesPath, fileStr);
42
41
  }
@@ -74,22 +74,15 @@ class PsychicBin {
74
74
  dream_1.DreamCLI.logger.logEndProgress();
75
75
  }
76
76
  static async postSync() {
77
- const psychicApp = index_js_1.default.getOrFail();
78
- await PsychicBin.syncOpenapiJson();
79
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
80
- let output = {};
81
- for (const hook of psychicApp.specialHooks.cliSync) {
82
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
83
- const res = await hook();
84
- if ((0, isObject_js_1.default)(res)) {
85
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
86
- output = { ...output, ...res };
87
- }
77
+ try {
78
+ await this.syncOpenapiJson();
79
+ await this.runCliHooksAndUpdatePsychicTypesFileWithOutput();
80
+ await this.syncTypescriptOpenapiFiles();
88
81
  }
89
- if (Object.keys(output).length) {
90
- await PsychicBin.syncTypes(output);
82
+ catch (error) {
83
+ console.error(error);
84
+ await dream_1.CliFileWriter.revert();
91
85
  }
92
- await this.syncTypescriptOpenapiFiles();
93
86
  }
94
87
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
88
  static async syncTypes(customTypes = undefined) {
@@ -125,8 +118,34 @@ class PsychicBin {
125
118
  catch {
126
119
  // noop
127
120
  }
128
- await fs.writeFile(outfile, enumsStr, {});
121
+ await dream_1.CliFileWriter.write(outfile, enumsStr);
129
122
  dream_1.DreamCLI.logger.logEndProgress();
130
123
  }
124
+ /**
125
+ * @internal
126
+ *
127
+ * runs all the custom cli hooks provided for the user's application.
128
+ * if any of the cli hooks returns an object-based output, we will splat
129
+ * it all together into a single `output` variable, which we then
130
+ * feed into the `syncTypes` method to provide custom type data.
131
+ * This enables psychic plugins to add custom types to the psychic type
132
+ * bindings.
133
+ */
134
+ static async runCliHooksAndUpdatePsychicTypesFileWithOutput() {
135
+ const psychicApp = index_js_1.default.getOrFail();
136
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
+ let output = {};
138
+ for (const hook of psychicApp.specialHooks.cliSync) {
139
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
140
+ const res = await hook();
141
+ if ((0, isObject_js_1.default)(res)) {
142
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
143
+ output = { ...output, ...res };
144
+ }
145
+ }
146
+ if (Object.keys(output).length) {
147
+ await PsychicBin.syncTypes(output);
148
+ }
149
+ }
131
150
  }
132
151
  exports.default = PsychicBin;
@@ -27,7 +27,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const dream_1 = require("@rvoh/dream");
30
- const fs = __importStar(require("node:fs/promises"));
31
30
  const path = __importStar(require("node:path"));
32
31
  const index_js_1 = __importDefault(require("../../psychic-app/index.js"));
33
32
  class TypesBuilder {
@@ -35,7 +34,7 @@ class TypesBuilder {
35
34
  static async sync(customTypes = undefined) {
36
35
  const dreamApp = dream_1.DreamApp.getOrFail();
37
36
  const schemaPath = path.join(dreamApp.projectRoot, dreamApp.paths.types, 'psychic.ts');
38
- await fs.writeFile(schemaPath, this.build(customTypes));
37
+ await dream_1.CliFileWriter.write(schemaPath, this.build(customTypes));
39
38
  }
40
39
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
40
  static build(customTypes = undefined) {
@@ -1,33 +1,9 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
6
  const dream_1 = require("@rvoh/dream");
30
- const fs = __importStar(require("node:fs/promises"));
31
7
  const node_util_1 = require("node:util");
32
8
  const UnexpectedUndefined_js_1 = __importDefault(require("../error/UnexpectedUndefined.js"));
33
9
  const openapiJsonPath_js_1 = __importDefault(require("../helpers/openapiJsonPath.js"));
@@ -49,9 +25,7 @@ class OpenapiAppRenderer {
49
25
  const psychicApp = index_js_1.default.getOrFail();
50
26
  const asyncWriteOpenapiFile = async (key) => {
51
27
  const jsonPath = (0, openapiJsonPath_js_1.default)(key);
52
- await fs.writeFile(jsonPath, JSON.stringify(openapiContents[key], null, 2), {
53
- flag: 'w+',
54
- });
28
+ await dream_1.CliFileWriter.write(jsonPath, JSON.stringify(openapiContents[key], null, 2), { flag: 'w+' });
55
29
  };
56
30
  await Promise.all(Object.keys(psychicApp.openapi).map(key => asyncWriteOpenapiFile(key)));
57
31
  }
@@ -1,5 +1,4 @@
1
- import { uniq } from '@rvoh/dream';
2
- import * as fs from 'node:fs/promises';
1
+ import { CliFileWriter, uniq } from '@rvoh/dream';
3
2
  import * as path from 'node:path';
4
3
  import PsychicApp from '../../psychic-app/index.js';
5
4
  export default async function generateRouteTypes(routes) {
@@ -9,5 +8,5 @@ export default async function generateRouteTypes(routes) {
9
8
  `;
10
9
  const psychicApp = PsychicApp.getOrFail();
11
10
  const routeTypesPath = path.join(psychicApp.apiRoot, 'src', 'conf', 'routeTypes.ts');
12
- await fs.writeFile(routeTypesPath, fileStr);
11
+ await CliFileWriter.write(routeTypesPath, fileStr);
13
12
  }
@@ -1,4 +1,4 @@
1
- import { DreamBin, DreamCLI } from '@rvoh/dream';
1
+ import { CliFileWriter, DreamBin, DreamCLI } from '@rvoh/dream';
2
2
  import * as fs from 'node:fs/promises';
3
3
  import * as path from 'node:path';
4
4
  import TypesBuilder from '../cli/helpers/TypesBuilder.js';
@@ -46,22 +46,15 @@ export default class PsychicBin {
46
46
  DreamCLI.logger.logEndProgress();
47
47
  }
48
48
  static async postSync() {
49
- const psychicApp = PsychicApp.getOrFail();
50
- await PsychicBin.syncOpenapiJson();
51
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
- let output = {};
53
- for (const hook of psychicApp.specialHooks.cliSync) {
54
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
55
- const res = await hook();
56
- if (isObject(res)) {
57
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
58
- output = { ...output, ...res };
59
- }
49
+ try {
50
+ await this.syncOpenapiJson();
51
+ await this.runCliHooksAndUpdatePsychicTypesFileWithOutput();
52
+ await this.syncTypescriptOpenapiFiles();
60
53
  }
61
- if (Object.keys(output).length) {
62
- await PsychicBin.syncTypes(output);
54
+ catch (error) {
55
+ console.error(error);
56
+ await CliFileWriter.revert();
63
57
  }
64
- await this.syncTypescriptOpenapiFiles();
65
58
  }
66
59
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
60
  static async syncTypes(customTypes = undefined) {
@@ -97,7 +90,33 @@ export default class PsychicBin {
97
90
  catch {
98
91
  // noop
99
92
  }
100
- await fs.writeFile(outfile, enumsStr, {});
93
+ await CliFileWriter.write(outfile, enumsStr);
101
94
  DreamCLI.logger.logEndProgress();
102
95
  }
96
+ /**
97
+ * @internal
98
+ *
99
+ * runs all the custom cli hooks provided for the user's application.
100
+ * if any of the cli hooks returns an object-based output, we will splat
101
+ * it all together into a single `output` variable, which we then
102
+ * feed into the `syncTypes` method to provide custom type data.
103
+ * This enables psychic plugins to add custom types to the psychic type
104
+ * bindings.
105
+ */
106
+ static async runCliHooksAndUpdatePsychicTypesFileWithOutput() {
107
+ const psychicApp = PsychicApp.getOrFail();
108
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
+ let output = {};
110
+ for (const hook of psychicApp.specialHooks.cliSync) {
111
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
112
+ const res = await hook();
113
+ if (isObject(res)) {
114
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
115
+ output = { ...output, ...res };
116
+ }
117
+ }
118
+ if (Object.keys(output).length) {
119
+ await PsychicBin.syncTypes(output);
120
+ }
121
+ }
103
122
  }
@@ -1,5 +1,4 @@
1
- import { DreamApp } from '@rvoh/dream';
2
- import * as fs from 'node:fs/promises';
1
+ import { CliFileWriter, DreamApp } from '@rvoh/dream';
3
2
  import * as path from 'node:path';
4
3
  import PsychicApp from '../../psychic-app/index.js';
5
4
  export default class TypesBuilder {
@@ -7,7 +6,7 @@ export default class TypesBuilder {
7
6
  static async sync(customTypes = undefined) {
8
7
  const dreamApp = DreamApp.getOrFail();
9
8
  const schemaPath = path.join(dreamApp.projectRoot, dreamApp.paths.types, 'psychic.ts');
10
- await fs.writeFile(schemaPath, this.build(customTypes));
9
+ await CliFileWriter.write(schemaPath, this.build(customTypes));
11
10
  }
12
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
12
  static build(customTypes = undefined) {
@@ -1,5 +1,4 @@
1
- import { compact, groupBy, sortObjectByKey } from '@rvoh/dream';
2
- import * as fs from 'node:fs/promises';
1
+ import { CliFileWriter, compact, groupBy, sortObjectByKey } from '@rvoh/dream';
3
2
  import { debuglog } from 'node:util';
4
3
  import UnexpectedUndefined from '../error/UnexpectedUndefined.js';
5
4
  import openapiJsonPath from '../helpers/openapiJsonPath.js';
@@ -21,9 +20,7 @@ export default class OpenapiAppRenderer {
21
20
  const psychicApp = PsychicApp.getOrFail();
22
21
  const asyncWriteOpenapiFile = async (key) => {
23
22
  const jsonPath = openapiJsonPath(key);
24
- await fs.writeFile(jsonPath, JSON.stringify(openapiContents[key], null, 2), {
25
- flag: 'w+',
26
- });
23
+ await CliFileWriter.write(jsonPath, JSON.stringify(openapiContents[key], null, 2), { flag: 'w+' });
27
24
  };
28
25
  await Promise.all(Object.keys(psychicApp.openapi).map(key => asyncWriteOpenapiFile(key)));
29
26
  }
@@ -17,4 +17,15 @@ export default class PsychicBin {
17
17
  static syncOpenapiJson(): Promise<void>;
18
18
  static syncRoutes(): Promise<void>;
19
19
  static syncClientEnums(outfile: string): Promise<void>;
20
+ /**
21
+ * @internal
22
+ *
23
+ * runs all the custom cli hooks provided for the user's application.
24
+ * if any of the cli hooks returns an object-based output, we will splat
25
+ * it all together into a single `output` variable, which we then
26
+ * feed into the `syncTypes` method to provide custom type data.
27
+ * This enables psychic plugins to add custom types to the psychic type
28
+ * bindings.
29
+ */
30
+ private static runCliHooksAndUpdatePsychicTypesFileWithOutput;
20
31
  }
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.1.7",
5
+ "version": "1.1.8",
6
6
  "author": "RVOHealth",
7
7
  "repository": {
8
8
  "type": "git",
@@ -59,7 +59,7 @@
59
59
  "devDependencies": {
60
60
  "@eslint/js": "^9.19.0",
61
61
  "@jest-mock/express": "^3.0.0",
62
- "@rvoh/dream": "^1.0.2",
62
+ "@rvoh/dream": "^1.1.2",
63
63
  "@rvoh/dream-spec-helpers": "^1.0.0",
64
64
  "@rvoh/psychic-spec-helpers": "^1.0.0",
65
65
  "@types/express": "^5.0.1",
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadFile = loadFile;
4
- exports.writeFile = writeFile;
5
- const node_fs_1 = require("node:fs");
6
- async function loadFile(filepath) {
7
- return await node_fs_1.promises.readFile(filepath);
8
- }
9
- async function writeFile(filepath, contents) {
10
- return await node_fs_1.promises.writeFile(filepath, contents);
11
- }
@@ -1,7 +0,0 @@
1
- import { promises as fs } from 'node:fs';
2
- export async function loadFile(filepath) {
3
- return await fs.readFile(filepath);
4
- }
5
- export async function writeFile(filepath, contents) {
6
- return await fs.writeFile(filepath, contents);
7
- }
@@ -1,2 +0,0 @@
1
- export declare function loadFile(filepath: string): Promise<Buffer>;
2
- export declare function writeFile(filepath: string, contents: string): Promise<void>;