@rvoh/psychic-spec-helpers 1.1.5 → 1.1.6

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/esm/spec/features/setup/hooks.js +2 -2
  2. package/dist/esm/spec/unit/OpenapiSpecRequest/post.spec.js +11 -0
  3. package/dist/esm/spec/unit/OpenapiSpecSession/delete.spec.js +13 -0
  4. package/dist/esm/spec/unit/OpenapiSpecSession/get.spec.js +14 -0
  5. package/dist/esm/spec/unit/OpenapiSpecSession/patch.spec.js +17 -0
  6. package/dist/esm/spec/unit/OpenapiSpecSession/post.spec.js +16 -0
  7. package/dist/esm/spec/unit/OpenapiSpecSession/put.spec.js +18 -1
  8. package/dist/esm/spec/unit/setup/hooks.js +2 -2
  9. package/dist/esm/src/unit/OpenapiSpecSession.js +1 -1
  10. package/dist/esm/test-app/src/app/controllers/Users/BalloonsController.js +139 -0
  11. package/dist/esm/test-app/src/app/controllers/Users/BaseController.js +3 -0
  12. package/dist/esm/test-app/src/app/models/Balloon.js +67 -0
  13. package/dist/esm/test-app/src/app/models/User.js +68 -14
  14. package/dist/esm/test-app/src/app/serializers/BalloonSerializer.js +4 -0
  15. package/dist/esm/test-app/src/conf/app.js +0 -1
  16. package/dist/esm/test-app/src/conf/routes.js +5 -1
  17. package/dist/esm/test-app/src/db/migrations/1760239324666-create-balloon.js +18 -0
  18. package/dist/esm/test-app/src/types/db.js +6 -0
  19. package/dist/esm/test-app/src/types/dream.globals.js +6 -1
  20. package/dist/esm/test-app/src/types/dream.js +80 -1
  21. package/dist/types/test-app/src/app/controllers/Users/BalloonsController.d.ts +11 -0
  22. package/dist/types/test-app/src/app/controllers/Users/BaseController.d.ts +3 -0
  23. package/dist/types/test-app/src/app/models/ApplicationModel.d.ts +80 -2
  24. package/dist/types/test-app/src/app/models/Balloon.d.ts +13 -0
  25. package/dist/types/test-app/src/app/models/User.d.ts +2 -0
  26. package/dist/types/test-app/src/app/serializers/BalloonSerializer.d.ts +3 -0
  27. package/dist/types/test-app/src/db/migrations/1760239324666-create-balloon.d.ts +3 -0
  28. package/dist/types/test-app/src/types/db.d.ts +11 -0
  29. package/dist/types/test-app/src/types/dream.d.ts +80 -1
  30. package/dist/types/test-app/src/types/dream.globals.d.ts +1 -1
  31. package/package.json +8 -7
  32. package/src/unit/OpenapiSpecSession.ts +6 -1
  33. package/CHANGELOG.md +0 -15
  34. package/client/tsconfig.json +0 -7
@@ -1,10 +1,10 @@
1
- import { DreamApp } from '@rvoh/dream';
1
+ import { Dream, DreamApp } from '@rvoh/dream';
2
2
  import { provideDreamViteMatchers, truncate } from '@rvoh/dream-spec-helpers';
3
3
  import { PsychicServer } from '@rvoh/psychic';
4
4
  import { providePuppeteerViteMatchers } from '../../../src/index.js';
5
5
  import initializePsychicApp from '../../../test-app/src/cli/helpers/initializePsychicApp.js';
6
6
  import getPage from '../helpers/getPage.js';
7
- provideDreamViteMatchers();
7
+ provideDreamViteMatchers(Dream);
8
8
  providePuppeteerViteMatchers();
9
9
  global.context = describe;
10
10
  global.jest = vi;
@@ -54,4 +54,15 @@ describe('OpenapiSpecRequest#post', () => {
54
54
  });
55
55
  });
56
56
  });
57
+ context('with nested resources', () => {
58
+ it('correctly absorbs uri params from provided options', async () => {
59
+ const userId = '123';
60
+ await request.post('/users/{userId}/posts', 201, {
61
+ userId,
62
+ headers: {
63
+ hello: 'world',
64
+ },
65
+ });
66
+ });
67
+ });
57
68
  });
@@ -1,5 +1,6 @@
1
1
  import { PsychicServer } from '@rvoh/psychic';
2
2
  import { OpenapiSpecRequest } from '../../../src/unit/OpenapiSpecRequest.js';
3
+ import Balloon from '../../../test-app/src/app/models/Balloon.js';
3
4
  import User from '../../../test-app/src/app/models/User.js';
4
5
  const request = new OpenapiSpecRequest();
5
6
  describe('OpenapiSpecSession#delete', () => {
@@ -14,4 +15,16 @@ describe('OpenapiSpecSession#delete', () => {
14
15
  });
15
16
  expect(await User.count()).toEqual(0);
16
17
  });
18
+ context('nested resource', () => {
19
+ it('correctly interprets the nested resource id', async () => {
20
+ const user = await User.create({ email: 'abc@def' });
21
+ const balloon = await Balloon.create({ user, color: 'red' });
22
+ const session = await request.session('get', '/users', 200);
23
+ await session.delete('/users/{userId}/balloons/{id}', 204, {
24
+ userId: user.id,
25
+ id: balloon.id,
26
+ });
27
+ expect(await Balloon.count()).toEqual(0);
28
+ });
29
+ });
17
30
  });
@@ -1,5 +1,6 @@
1
1
  import { PsychicServer } from '@rvoh/psychic';
2
2
  import { OpenapiSpecRequest } from '../../../src/unit/OpenapiSpecRequest.js';
3
+ import Balloon from '../../../test-app/src/app/models/Balloon.js';
3
4
  import User from '../../../test-app/src/app/models/User.js';
4
5
  const request = new OpenapiSpecRequest();
5
6
  describe('OpenapiSpecSession#get', () => {
@@ -21,4 +22,17 @@ describe('OpenapiSpecSession#get', () => {
21
22
  expect(res.body).toEqual([{ id: user.id, email: 'abc@def' }]);
22
23
  });
23
24
  });
25
+ context('nested resource', () => {
26
+ it('correctly interprets the nested resource id', async () => {
27
+ const user = await User.create({ email: 'abc@def' });
28
+ const balloon = await Balloon.create({ user, color: 'red' });
29
+ const session = await request.session('get', '/users', 200);
30
+ const { body } = await session.get('/users/{userId}/balloons/{id}', 200, {
31
+ userId: user.id,
32
+ id: balloon.id,
33
+ });
34
+ expect(body.id).toEqual(balloon.id);
35
+ expect(body.color).toEqual('red');
36
+ });
37
+ });
24
38
  });
@@ -1,5 +1,6 @@
1
1
  import { PsychicServer } from '@rvoh/psychic';
2
2
  import { OpenapiSpecRequest } from '../../../src/unit/OpenapiSpecRequest.js';
3
+ import Balloon from '../../../test-app/src/app/models/Balloon.js';
3
4
  import User from '../../../test-app/src/app/models/User.js';
4
5
  const request = new OpenapiSpecRequest();
5
6
  describe('OpenapiSpecSession#put', () => {
@@ -17,4 +18,20 @@ describe('OpenapiSpecSession#put', () => {
17
18
  });
18
19
  await User.findOrFailBy({ email: 'how@yadoin' });
19
20
  });
21
+ context('nested resource', () => {
22
+ it('correctly interprets the nested resource id', async () => {
23
+ const user = await User.create({ email: 'abc@def' });
24
+ const balloon = await Balloon.create({ user, color: 'red' });
25
+ const session = await request.session('get', '/users', 200);
26
+ await session.patch('/users/{userId}/balloons/{id}', 204, {
27
+ userId: user.id,
28
+ id: balloon.id,
29
+ data: {
30
+ color: 'blue',
31
+ },
32
+ });
33
+ await balloon.reload();
34
+ expect(balloon.color).toEqual('blue');
35
+ });
36
+ });
20
37
  });
@@ -1,5 +1,6 @@
1
1
  import { PsychicServer } from '@rvoh/psychic';
2
2
  import { OpenapiSpecRequest } from '../../../src/unit/OpenapiSpecRequest.js';
3
+ import Balloon from '../../../test-app/src/app/models/Balloon.js';
3
4
  import User from '../../../test-app/src/app/models/User.js';
4
5
  const request = new OpenapiSpecRequest();
5
6
  describe('OpenapiSpecSession#post', () => {
@@ -15,4 +16,19 @@ describe('OpenapiSpecSession#post', () => {
15
16
  });
16
17
  await User.findOrFailBy({ email: 'how@yadoin' });
17
18
  });
19
+ context('nested resource', () => {
20
+ it('correctly interprets the nested resource id', async () => {
21
+ const user = await User.create({ email: 'abc@def' });
22
+ const session = await request.session('get', '/users', 200);
23
+ await session.post('/users/{userId}/balloons', 201, {
24
+ userId: user.id,
25
+ data: {
26
+ color: 'blue',
27
+ },
28
+ });
29
+ const balloon = await Balloon.preload('user').first();
30
+ expect(balloon?.color).toEqual('blue');
31
+ expect(balloon?.user).toMatchDreamModel(user);
32
+ });
33
+ });
18
34
  });
@@ -1,12 +1,13 @@
1
1
  import { PsychicServer } from '@rvoh/psychic';
2
2
  import { OpenapiSpecRequest } from '../../../src/unit/OpenapiSpecRequest.js';
3
+ import Balloon from '../../../test-app/src/app/models/Balloon.js';
3
4
  import User from '../../../test-app/src/app/models/User.js';
4
5
  const request = new OpenapiSpecRequest();
5
6
  describe('OpenapiSpecSession#put', () => {
6
7
  beforeEach(async () => {
7
8
  await request.init(PsychicServer);
8
9
  });
9
- it('issues a patch request to a controller endpoint, passing when the status matches', async () => {
10
+ it('issues a put request to a controller endpoint, passing when the status matches', async () => {
10
11
  const user = await User.create({ email: 'abc@def' });
11
12
  const session = await request.session('get', '/users', 200);
12
13
  await session.put('/users/{id}/update-put', 204, {
@@ -17,4 +18,20 @@ describe('OpenapiSpecSession#put', () => {
17
18
  });
18
19
  await User.findOrFailBy({ email: 'how@yadoin' });
19
20
  });
21
+ context('nested resource', () => {
22
+ it('correctly interprets the nested resource id', async () => {
23
+ const user = await User.create({ email: 'abc@def' });
24
+ const balloon = await Balloon.create({ user, color: 'red' });
25
+ const session = await request.session('get', '/users', 200);
26
+ await session.put('/users/{userId}/balloons/{id}/update-put', 204, {
27
+ userId: user.id,
28
+ id: balloon.id,
29
+ data: {
30
+ color: 'blue',
31
+ },
32
+ });
33
+ await balloon.reload();
34
+ expect(balloon.color).toEqual('blue');
35
+ });
36
+ });
20
37
  });
@@ -1,7 +1,7 @@
1
- import { DreamApp } from '@rvoh/dream';
1
+ import { Dream, DreamApp } from '@rvoh/dream';
2
2
  import { provideDreamViteMatchers, truncate } from '@rvoh/dream-spec-helpers';
3
3
  import initializePsychicApp from '../../../test-app/src/cli/helpers/initializePsychicApp.js';
4
- provideDreamViteMatchers();
4
+ provideDreamViteMatchers(Dream);
5
5
  global.context = describe;
6
6
  global.jest = vi;
7
7
  beforeEach(async () => {
@@ -129,7 +129,7 @@ export class OpenapiSpecSession {
129
129
  * (Optional)
130
130
  */
131
131
  opts) {
132
- return await this.makeRequest('post', uri, expectedStatus, opts);
132
+ return await this.makeRequest('post', fillOpenapiParams(uri, opts || {}), expectedStatus, opts);
133
133
  }
134
134
  async put(
135
135
  /**
@@ -0,0 +1,139 @@
1
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
+ var useValue = arguments.length > 2;
3
+ for (var i = 0; i < initializers.length; i++) {
4
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
+ }
6
+ return useValue ? value : void 0;
7
+ };
8
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
+ var _, done = false;
14
+ for (var i = decorators.length - 1; i >= 0; i--) {
15
+ var context = {};
16
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
+ if (kind === "accessor") {
21
+ if (result === void 0) continue;
22
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
+ if (_ = accept(result.get)) descriptor.get = _;
24
+ if (_ = accept(result.set)) descriptor.set = _;
25
+ if (_ = accept(result.init)) initializers.unshift(_);
26
+ }
27
+ else if (_ = accept(result)) {
28
+ if (kind === "field") initializers.unshift(_);
29
+ else descriptor[key] = _;
30
+ }
31
+ }
32
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
+ done = true;
34
+ };
35
+ import { OpenAPI } from '@rvoh/psychic';
36
+ import Balloon from '../../models/Balloon.js';
37
+ import User from '../../models/User.js';
38
+ import UsersBaseController from './BaseController.js';
39
+ const openApiTags = ['balloons'];
40
+ let UsersBalloonsController = (() => {
41
+ let _classSuper = UsersBaseController;
42
+ let _instanceExtraInitializers = [];
43
+ let _index_decorators;
44
+ let _show_decorators;
45
+ let _create_decorators;
46
+ let _update_decorators;
47
+ let _updatePut_decorators;
48
+ let _destroy_decorators;
49
+ return class UsersBalloonsController extends _classSuper {
50
+ static {
51
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
52
+ _index_decorators = [OpenAPI(Balloon, {
53
+ status: 200,
54
+ tags: openApiTags,
55
+ description: 'Fetch multiple Balloons',
56
+ many: true,
57
+ serializerKey: 'summary',
58
+ })];
59
+ _show_decorators = [OpenAPI(Balloon, {
60
+ status: 200,
61
+ tags: openApiTags,
62
+ description: 'Fetch a Balloon',
63
+ })];
64
+ _create_decorators = [OpenAPI(Balloon, {
65
+ status: 201,
66
+ tags: openApiTags,
67
+ description: 'Create a Balloon',
68
+ })];
69
+ _update_decorators = [OpenAPI(Balloon, {
70
+ status: 204,
71
+ tags: openApiTags,
72
+ description: 'Update a Balloon',
73
+ })];
74
+ _updatePut_decorators = [OpenAPI(Balloon, {
75
+ status: 204,
76
+ tags: openApiTags,
77
+ description: 'Update a Balloon',
78
+ })];
79
+ _destroy_decorators = [OpenAPI({
80
+ status: 204,
81
+ tags: openApiTags,
82
+ description: 'Destroy a Balloon',
83
+ })];
84
+ __esDecorate(this, null, _index_decorators, { kind: "method", name: "index", static: false, private: false, access: { has: obj => "index" in obj, get: obj => obj.index }, metadata: _metadata }, null, _instanceExtraInitializers);
85
+ __esDecorate(this, null, _show_decorators, { kind: "method", name: "show", static: false, private: false, access: { has: obj => "show" in obj, get: obj => obj.show }, metadata: _metadata }, null, _instanceExtraInitializers);
86
+ __esDecorate(this, null, _create_decorators, { kind: "method", name: "create", static: false, private: false, access: { has: obj => "create" in obj, get: obj => obj.create }, metadata: _metadata }, null, _instanceExtraInitializers);
87
+ __esDecorate(this, null, _update_decorators, { kind: "method", name: "update", static: false, private: false, access: { has: obj => "update" in obj, get: obj => obj.update }, metadata: _metadata }, null, _instanceExtraInitializers);
88
+ __esDecorate(this, null, _updatePut_decorators, { kind: "method", name: "updatePut", static: false, private: false, access: { has: obj => "updatePut" in obj, get: obj => obj.updatePut }, metadata: _metadata }, null, _instanceExtraInitializers);
89
+ __esDecorate(this, null, _destroy_decorators, { kind: "method", name: "destroy", static: false, private: false, access: { has: obj => "destroy" in obj, get: obj => obj.destroy }, metadata: _metadata }, null, _instanceExtraInitializers);
90
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
91
+ }
92
+ async index() {
93
+ const user = await this.user();
94
+ const balloons = await user.associationQuery('balloons').preloadFor('summary').all();
95
+ this.ok(balloons);
96
+ }
97
+ async show() {
98
+ const balloon = await this.balloon();
99
+ this.ok(balloon);
100
+ }
101
+ async create() {
102
+ const user = await this.user();
103
+ let balloon = await user.createAssociation('balloons', this.paramsFor(Balloon));
104
+ if (balloon.isPersisted)
105
+ balloon = await balloon.loadFor('default').execute();
106
+ this.created(balloon);
107
+ }
108
+ async update() {
109
+ const balloon = await this.balloon();
110
+ await balloon.update(this.paramsFor(Balloon));
111
+ this.noContent();
112
+ }
113
+ async updatePut() {
114
+ const balloon = await this.balloon();
115
+ await balloon.update(this.paramsFor(Balloon));
116
+ this.noContent();
117
+ }
118
+ async destroy() {
119
+ const balloon = await this.balloon();
120
+ await balloon.destroy();
121
+ this.noContent();
122
+ }
123
+ async user() {
124
+ return await User.findOrFail(this.castParam('userId', 'string'));
125
+ }
126
+ async balloon() {
127
+ const user = await this.user();
128
+ return await user
129
+ .associationQuery('balloons')
130
+ .preloadFor('default')
131
+ .findOrFail(this.castParam('id', 'string'));
132
+ }
133
+ constructor() {
134
+ super(...arguments);
135
+ __runInitializers(this, _instanceExtraInitializers);
136
+ }
137
+ };
138
+ })();
139
+ export default UsersBalloonsController;
@@ -0,0 +1,3 @@
1
+ import ApplicationController from '../ApplicationController.js';
2
+ export default class UsersBaseController extends ApplicationController {
3
+ }
@@ -0,0 +1,67 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { Decorators } from '@rvoh/dream';
36
+ import ApplicationModel from './ApplicationModel.js';
37
+ const deco = new Decorators();
38
+ let Balloon = (() => {
39
+ let _classSuper = ApplicationModel;
40
+ let _user_decorators;
41
+ let _user_initializers = [];
42
+ let _user_extraInitializers = [];
43
+ return class Balloon extends _classSuper {
44
+ static {
45
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
46
+ _user_decorators = [deco.BelongsTo('User', { on: 'userId' })];
47
+ __esDecorate(null, null, _user_decorators, { kind: "field", name: "user", static: false, private: false, access: { has: obj => "user" in obj, get: obj => obj.user, set: (obj, value) => { obj.user = value; } }, metadata: _metadata }, _user_initializers, _user_extraInitializers);
48
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
49
+ }
50
+ get table() {
51
+ return 'balloons';
52
+ }
53
+ get serializers() {
54
+ return {
55
+ default: 'BalloonSerializer',
56
+ summary: 'BalloonSummarySerializer',
57
+ };
58
+ }
59
+ id;
60
+ color;
61
+ createdAt;
62
+ updatedAt;
63
+ user = __runInitializers(this, _user_initializers, void 0);
64
+ userId = __runInitializers(this, _user_extraInitializers);
65
+ };
66
+ })();
67
+ export default Balloon;
@@ -1,16 +1,70 @@
1
- import ApplicationModel from './ApplicationModel.js';
2
- export default class User extends ApplicationModel {
3
- get table() {
4
- return 'users';
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
5
24
  }
6
- get serializers() {
7
- return {
8
- default: 'UserSerializer',
9
- summary: 'UserSummarySerializer',
10
- };
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
11
32
  }
12
- id;
13
- email;
14
- createdAt;
15
- updatedAt;
16
- }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { Decorators } from '@rvoh/dream';
36
+ import ApplicationModel from './ApplicationModel.js';
37
+ const deco = new Decorators();
38
+ let User = (() => {
39
+ let _classSuper = ApplicationModel;
40
+ let _balloons_decorators;
41
+ let _balloons_initializers = [];
42
+ let _balloons_extraInitializers = [];
43
+ return class User extends _classSuper {
44
+ static {
45
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
46
+ _balloons_decorators = [deco.HasMany('Balloon', { on: 'userId' })];
47
+ __esDecorate(null, null, _balloons_decorators, { kind: "field", name: "balloons", static: false, private: false, access: { has: obj => "balloons" in obj, get: obj => obj.balloons, set: (obj, value) => { obj.balloons = value; } }, metadata: _metadata }, _balloons_initializers, _balloons_extraInitializers);
48
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
49
+ }
50
+ get table() {
51
+ return 'users';
52
+ }
53
+ get serializers() {
54
+ return {
55
+ default: 'UserSerializer',
56
+ summary: 'UserSummarySerializer',
57
+ };
58
+ }
59
+ id;
60
+ email;
61
+ createdAt;
62
+ updatedAt;
63
+ balloons = __runInitializers(this, _balloons_initializers, void 0);
64
+ constructor() {
65
+ super(...arguments);
66
+ __runInitializers(this, _balloons_extraInitializers);
67
+ }
68
+ };
69
+ })();
70
+ export default User;
@@ -0,0 +1,4 @@
1
+ import { DreamSerializer } from '@rvoh/dream';
2
+ import Balloon from '../models/Balloon.js';
3
+ export const BalloonSummarySerializer = (balloon) => DreamSerializer(Balloon, balloon).attribute('id');
4
+ export const BalloonSerializer = (balloon) => BalloonSummarySerializer(balloon).attribute('color');
@@ -9,7 +9,6 @@ export default async (psy) => {
9
9
  psy.set('packageManager', 'yarn');
10
10
  psy.set('apiOnly', false);
11
11
  psy.set('apiRoot', srcPath('..', '..'));
12
- psy.set('clientRoot', srcPath('..', 'client'));
13
12
  psy.set('inflections', inflections);
14
13
  psy.set('routes', routesCb);
15
14
  psy.set('encryption', {
@@ -1,7 +1,8 @@
1
+ import HeadersController from '../app/controllers/HeadersController.js';
1
2
  import SpecRequestController from '../app/controllers/SpecRequestController.js';
2
3
  import UserController from '../app/controllers/UserController.js';
4
+ import UsersBalloonsController from '../app/controllers/Users/BalloonsController.js';
3
5
  import UsersController from '../app/controllers/UsersController.js';
4
- import HeadersController from '../app/controllers/HeadersController.js';
5
6
  export default (r) => {
6
7
  r.get('/spec-request/get-test', SpecRequestController, 'testGet');
7
8
  r.post('/spec-request/post-test', SpecRequestController, 'testPost');
@@ -15,6 +16,9 @@ export default (r) => {
15
16
  r.resources('users', r => {
16
17
  r.put('update-put', UsersController, 'updatePut');
17
18
  r.resources('posts');
19
+ r.resources('balloons', r => {
20
+ r.put('update-put', UsersBalloonsController, 'updatePut');
21
+ });
18
22
  });
19
23
  r.resource('user', r => {
20
24
  r.put('update-put', UserController, 'updatePut');
@@ -0,0 +1,18 @@
1
+ import { sql } from 'kysely';
2
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
+ export async function up(db) {
4
+ await db.schema.createType('balloon_colors_enum').asEnum(['blue', 'green', 'red']).execute();
5
+ await db.schema
6
+ .createTable('balloons')
7
+ .addColumn('id', 'bigserial', col => col.primaryKey())
8
+ .addColumn('user_id', 'bigint', col => col.references('users.id').onDelete('restrict').notNull())
9
+ .addColumn('color', sql `balloon_colors_enum`, col => col.notNull())
10
+ .addColumn('created_at', 'timestamp', col => col.notNull())
11
+ .addColumn('updated_at', 'timestamp', col => col.notNull())
12
+ .execute();
13
+ }
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ export async function down(db) {
16
+ await db.schema.dropTable('balloons').execute();
17
+ await db.schema.dropType('balloon_colors_enum').execute();
18
+ }
@@ -1,3 +1,9 @@
1
+ export const BalloonColorsEnumValues = [
2
+ "blue",
3
+ "green",
4
+ "red"
5
+ ];
1
6
  export class DBClass {
7
+ balloons;
2
8
  users;
3
9
  }
@@ -1,3 +1,8 @@
1
1
  export const globalTypeConfig = {
2
- serializers: ['UserSerializer', 'UserSummarySerializer'],
2
+ serializers: [
3
+ 'BalloonSerializer',
4
+ 'BalloonSummarySerializer',
5
+ 'UserSerializer',
6
+ 'UserSummarySerializer'
7
+ ],
3
8
  };
@@ -55,7 +55,75 @@ us humans, he says:
55
55
  "
56
56
 
57
57
  */
58
+ import { BalloonColorsEnumValues } from './db.js';
58
59
  export const schema = {
60
+ balloons: {
61
+ serializerKeys: ['default', 'summary'],
62
+ scopes: {
63
+ default: [],
64
+ named: [],
65
+ },
66
+ nonJsonColumnNames: ['color', 'createdAt', 'id', 'updatedAt', 'userId'],
67
+ columns: {
68
+ color: {
69
+ coercedType: {},
70
+ enumType: {},
71
+ enumArrayType: [],
72
+ enumValues: BalloonColorsEnumValues,
73
+ dbType: 'balloon_colors_enum',
74
+ allowNull: false,
75
+ isArray: false,
76
+ },
77
+ createdAt: {
78
+ coercedType: {},
79
+ enumType: null,
80
+ enumArrayType: null,
81
+ enumValues: null,
82
+ dbType: 'timestamp without time zone',
83
+ allowNull: false,
84
+ isArray: false,
85
+ },
86
+ id: {
87
+ coercedType: {},
88
+ enumType: null,
89
+ enumArrayType: null,
90
+ enumValues: null,
91
+ dbType: 'bigint',
92
+ allowNull: false,
93
+ isArray: false,
94
+ },
95
+ updatedAt: {
96
+ coercedType: {},
97
+ enumType: null,
98
+ enumArrayType: null,
99
+ enumValues: null,
100
+ dbType: 'timestamp without time zone',
101
+ allowNull: false,
102
+ isArray: false,
103
+ },
104
+ userId: {
105
+ coercedType: {},
106
+ enumType: null,
107
+ enumArrayType: null,
108
+ enumValues: null,
109
+ dbType: 'bigint',
110
+ allowNull: false,
111
+ isArray: false,
112
+ },
113
+ },
114
+ virtualColumns: [],
115
+ associations: {
116
+ user: {
117
+ type: 'BelongsTo',
118
+ foreignKey: 'userId',
119
+ foreignKeyTypeColumn: null,
120
+ tables: ['users'],
121
+ optional: false,
122
+ requiredAndClauses: null,
123
+ passthroughAndClauses: null,
124
+ },
125
+ },
126
+ },
59
127
  users: {
60
128
  serializerKeys: ['default', 'summary'],
61
129
  scopes: {
@@ -102,7 +170,17 @@ export const schema = {
102
170
  },
103
171
  },
104
172
  virtualColumns: [],
105
- associations: {},
173
+ associations: {
174
+ balloons: {
175
+ type: 'HasMany',
176
+ foreignKey: 'userId',
177
+ foreignKeyTypeColumn: null,
178
+ tables: ['balloons'],
179
+ optional: null,
180
+ requiredAndClauses: null,
181
+ passthroughAndClauses: null,
182
+ },
183
+ },
106
184
  },
107
185
  };
108
186
  export const connectionTypeConfig = {
@@ -110,6 +188,7 @@ export const connectionTypeConfig = {
110
188
  allDefaultScopeNames: [],
111
189
  globalNames: {
112
190
  models: {
191
+ 'Balloon': 'balloons',
113
192
  'User': 'users'
114
193
  },
115
194
  },
@@ -0,0 +1,11 @@
1
+ import UsersBaseController from './BaseController.js';
2
+ export default class UsersBalloonsController extends UsersBaseController {
3
+ index(): Promise<void>;
4
+ show(): Promise<void>;
5
+ create(): Promise<void>;
6
+ update(): Promise<void>;
7
+ updatePut(): Promise<void>;
8
+ destroy(): Promise<void>;
9
+ private user;
10
+ private balloon;
11
+ }
@@ -0,0 +1,3 @@
1
+ import ApplicationController from '../ApplicationController.js';
2
+ export default class UsersBaseController extends ApplicationController {
3
+ }
@@ -3,6 +3,73 @@ import { DBClass } from '../../types/db.js';
3
3
  export default class ApplicationModel extends Dream {
4
4
  DB: DBClass;
5
5
  get schema(): {
6
+ readonly balloons: {
7
+ readonly serializerKeys: readonly ["default", "summary"];
8
+ readonly scopes: {
9
+ readonly default: readonly [];
10
+ readonly named: readonly [];
11
+ };
12
+ readonly nonJsonColumnNames: readonly ["color", "createdAt", "id", "updatedAt", "userId"];
13
+ readonly columns: {
14
+ readonly color: {
15
+ readonly coercedType: import("../../types/db.js").BalloonColorsEnum;
16
+ readonly enumType: import("../../types/db.js").BalloonColorsEnum;
17
+ readonly enumArrayType: import("../../types/db.js").BalloonColorsEnum[];
18
+ readonly enumValues: readonly ["blue", "green", "red"];
19
+ readonly dbType: "balloon_colors_enum";
20
+ readonly allowNull: false;
21
+ readonly isArray: false;
22
+ };
23
+ readonly createdAt: {
24
+ readonly coercedType: import("@rvoh/dream").DateTime;
25
+ readonly enumType: null;
26
+ readonly enumArrayType: null;
27
+ readonly enumValues: null;
28
+ readonly dbType: "timestamp without time zone";
29
+ readonly allowNull: false;
30
+ readonly isArray: false;
31
+ };
32
+ readonly id: {
33
+ readonly coercedType: string;
34
+ readonly enumType: null;
35
+ readonly enumArrayType: null;
36
+ readonly enumValues: null;
37
+ readonly dbType: "bigint";
38
+ readonly allowNull: false;
39
+ readonly isArray: false;
40
+ };
41
+ readonly updatedAt: {
42
+ readonly coercedType: import("@rvoh/dream").DateTime;
43
+ readonly enumType: null;
44
+ readonly enumArrayType: null;
45
+ readonly enumValues: null;
46
+ readonly dbType: "timestamp without time zone";
47
+ readonly allowNull: false;
48
+ readonly isArray: false;
49
+ };
50
+ readonly userId: {
51
+ readonly coercedType: string;
52
+ readonly enumType: null;
53
+ readonly enumArrayType: null;
54
+ readonly enumValues: null;
55
+ readonly dbType: "bigint";
56
+ readonly allowNull: false;
57
+ readonly isArray: false;
58
+ };
59
+ };
60
+ readonly virtualColumns: readonly [];
61
+ readonly associations: {
62
+ readonly user: {
63
+ readonly type: "BelongsTo";
64
+ readonly foreignKey: "userId";
65
+ readonly foreignKeyTypeColumn: null;
66
+ readonly tables: readonly ["users"];
67
+ readonly optional: false;
68
+ readonly requiredAndClauses: null;
69
+ readonly passthroughAndClauses: null;
70
+ };
71
+ };
72
+ };
6
73
  readonly users: {
7
74
  readonly serializerKeys: readonly ["default", "summary"];
8
75
  readonly scopes: {
@@ -49,7 +116,17 @@ export default class ApplicationModel extends Dream {
49
116
  };
50
117
  };
51
118
  readonly virtualColumns: readonly [];
52
- readonly associations: {};
119
+ readonly associations: {
120
+ readonly balloons: {
121
+ readonly type: "HasMany";
122
+ readonly foreignKey: "userId";
123
+ readonly foreignKeyTypeColumn: null;
124
+ readonly tables: readonly ["balloons"];
125
+ readonly optional: null;
126
+ readonly requiredAndClauses: null;
127
+ readonly passthroughAndClauses: null;
128
+ };
129
+ };
53
130
  };
54
131
  };
55
132
  get connectionTypeConfig(): {
@@ -57,11 +134,12 @@ export default class ApplicationModel extends Dream {
57
134
  readonly allDefaultScopeNames: readonly [];
58
135
  readonly globalNames: {
59
136
  readonly models: {
137
+ readonly Balloon: "balloons";
60
138
  readonly User: "users";
61
139
  };
62
140
  };
63
141
  };
64
142
  get globalTypeConfig(): {
65
- readonly serializers: readonly ["UserSerializer", "UserSummarySerializer"];
143
+ readonly serializers: readonly ["BalloonSerializer", "BalloonSummarySerializer", "UserSerializer", "UserSummarySerializer"];
66
144
  };
67
145
  }
@@ -0,0 +1,13 @@
1
+ import { DreamColumn, DreamSerializers } from '@rvoh/dream';
2
+ import ApplicationModel from './ApplicationModel.js';
3
+ import User from './User.js';
4
+ export default class Balloon extends ApplicationModel {
5
+ get table(): "balloons";
6
+ get serializers(): DreamSerializers<Balloon>;
7
+ id: DreamColumn<Balloon, 'id'>;
8
+ color: DreamColumn<Balloon, 'color'>;
9
+ createdAt: DreamColumn<Balloon, 'createdAt'>;
10
+ updatedAt: DreamColumn<Balloon, 'updatedAt'>;
11
+ user: User;
12
+ userId: DreamColumn<Balloon, 'userId'>;
13
+ }
@@ -1,5 +1,6 @@
1
1
  import { DreamColumn, DreamSerializers } from '@rvoh/dream';
2
2
  import ApplicationModel from './ApplicationModel.js';
3
+ import Balloon from './Balloon.js';
3
4
  export default class User extends ApplicationModel {
4
5
  get table(): "users";
5
6
  get serializers(): DreamSerializers<User>;
@@ -7,4 +8,5 @@ export default class User extends ApplicationModel {
7
8
  email: DreamColumn<User, 'email'>;
8
9
  createdAt: DreamColumn<User, 'createdAt'>;
9
10
  updatedAt: DreamColumn<User, 'updatedAt'>;
11
+ balloons: Balloon;
10
12
  }
@@ -0,0 +1,3 @@
1
+ import Balloon from '../models/Balloon.js';
2
+ export declare const BalloonSummarySerializer: (balloon: Balloon) => import("@rvoh/dream").DreamSerializerBuilder<typeof Balloon, Balloon, undefined, Balloon>;
3
+ export declare const BalloonSerializer: (balloon: Balloon) => import("@rvoh/dream").DreamSerializerBuilder<typeof Balloon, Balloon, undefined, Balloon>;
@@ -0,0 +1,3 @@
1
+ import { Kysely } from 'kysely';
2
+ export declare function up(db: Kysely<any>): Promise<void>;
3
+ export declare function down(db: Kysely<any>): Promise<void>;
@@ -4,9 +4,18 @@ import { type CalendarDate, type DateTime } from '@rvoh/dream';
4
4
  * Please do not edit it manually.
5
5
  */
6
6
  import type { ColumnType } from "kysely";
7
+ export type BalloonColorsEnum = "blue" | "green" | "red";
8
+ export declare const BalloonColorsEnumValues: readonly ["blue", "green", "red"];
7
9
  export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
8
10
  export type Int8 = ColumnType<string, bigint | number | string, bigint | number | string>;
9
11
  export type Timestamp = ColumnType<DateTime | CalendarDate>;
12
+ export interface Balloons {
13
+ color: BalloonColorsEnum;
14
+ createdAt: Timestamp;
15
+ id: Generated<Int8>;
16
+ updatedAt: Timestamp;
17
+ userId: Int8;
18
+ }
10
19
  export interface Users {
11
20
  createdAt: Timestamp;
12
21
  email: string | null;
@@ -14,8 +23,10 @@ export interface Users {
14
23
  updatedAt: Timestamp;
15
24
  }
16
25
  export interface DB {
26
+ balloons: Balloons;
17
27
  users: Users;
18
28
  }
19
29
  export declare class DBClass {
30
+ balloons: Balloons;
20
31
  users: Users;
21
32
  }
@@ -1,5 +1,73 @@
1
1
  import { type DateTime } from '@rvoh/dream';
2
+ import { BalloonColorsEnum } from './db.js';
2
3
  export declare const schema: {
4
+ readonly balloons: {
5
+ readonly serializerKeys: readonly ["default", "summary"];
6
+ readonly scopes: {
7
+ readonly default: readonly [];
8
+ readonly named: readonly [];
9
+ };
10
+ readonly nonJsonColumnNames: readonly ["color", "createdAt", "id", "updatedAt", "userId"];
11
+ readonly columns: {
12
+ readonly color: {
13
+ readonly coercedType: BalloonColorsEnum;
14
+ readonly enumType: BalloonColorsEnum;
15
+ readonly enumArrayType: BalloonColorsEnum[];
16
+ readonly enumValues: readonly ["blue", "green", "red"];
17
+ readonly dbType: "balloon_colors_enum";
18
+ readonly allowNull: false;
19
+ readonly isArray: false;
20
+ };
21
+ readonly createdAt: {
22
+ readonly coercedType: DateTime;
23
+ readonly enumType: null;
24
+ readonly enumArrayType: null;
25
+ readonly enumValues: null;
26
+ readonly dbType: "timestamp without time zone";
27
+ readonly allowNull: false;
28
+ readonly isArray: false;
29
+ };
30
+ readonly id: {
31
+ readonly coercedType: string;
32
+ readonly enumType: null;
33
+ readonly enumArrayType: null;
34
+ readonly enumValues: null;
35
+ readonly dbType: "bigint";
36
+ readonly allowNull: false;
37
+ readonly isArray: false;
38
+ };
39
+ readonly updatedAt: {
40
+ readonly coercedType: DateTime;
41
+ readonly enumType: null;
42
+ readonly enumArrayType: null;
43
+ readonly enumValues: null;
44
+ readonly dbType: "timestamp without time zone";
45
+ readonly allowNull: false;
46
+ readonly isArray: false;
47
+ };
48
+ readonly userId: {
49
+ readonly coercedType: string;
50
+ readonly enumType: null;
51
+ readonly enumArrayType: null;
52
+ readonly enumValues: null;
53
+ readonly dbType: "bigint";
54
+ readonly allowNull: false;
55
+ readonly isArray: false;
56
+ };
57
+ };
58
+ readonly virtualColumns: readonly [];
59
+ readonly associations: {
60
+ readonly user: {
61
+ readonly type: "BelongsTo";
62
+ readonly foreignKey: "userId";
63
+ readonly foreignKeyTypeColumn: null;
64
+ readonly tables: readonly ["users"];
65
+ readonly optional: false;
66
+ readonly requiredAndClauses: null;
67
+ readonly passthroughAndClauses: null;
68
+ };
69
+ };
70
+ };
3
71
  readonly users: {
4
72
  readonly serializerKeys: readonly ["default", "summary"];
5
73
  readonly scopes: {
@@ -46,7 +114,17 @@ export declare const schema: {
46
114
  };
47
115
  };
48
116
  readonly virtualColumns: readonly [];
49
- readonly associations: {};
117
+ readonly associations: {
118
+ readonly balloons: {
119
+ readonly type: "HasMany";
120
+ readonly foreignKey: "userId";
121
+ readonly foreignKeyTypeColumn: null;
122
+ readonly tables: readonly ["balloons"];
123
+ readonly optional: null;
124
+ readonly requiredAndClauses: null;
125
+ readonly passthroughAndClauses: null;
126
+ };
127
+ };
50
128
  };
51
129
  };
52
130
  export declare const connectionTypeConfig: {
@@ -54,6 +132,7 @@ export declare const connectionTypeConfig: {
54
132
  readonly allDefaultScopeNames: readonly [];
55
133
  readonly globalNames: {
56
134
  readonly models: {
135
+ readonly Balloon: "balloons";
57
136
  readonly User: "users";
58
137
  };
59
138
  };
@@ -1,3 +1,3 @@
1
1
  export declare const globalTypeConfig: {
2
- readonly serializers: readonly ["UserSerializer", "UserSummarySerializer"];
2
+ readonly serializers: readonly ["BalloonSerializer", "BalloonSummarySerializer", "UserSerializer", "UserSummarySerializer"];
3
3
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@rvoh/psychic-spec-helpers",
4
- "version": "1.1.5",
4
+ "version": "1.1.6",
5
5
  "description": "psychic framework spec helpers",
6
6
  "author": "RVO Health",
7
7
  "repository": {
@@ -30,6 +30,7 @@
30
30
  "uspec": "vitest --config ./spec/unit/vite.config.ts",
31
31
  "fspec": "vitest --config ./spec/features/vite.config.ts",
32
32
  "build": "echo \"building psychic-spec-helpers...\" && rm -rf dist && npx tsc -p ./tsconfig.json",
33
+ "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",
33
34
  "lint": "yarn run eslint --no-warn-ignored \"src/**/*.ts\" \"spec/**/*.ts\" && yarn run prettier . --check",
34
35
  "format": "yarn run prettier . --write",
35
36
  "prepack": "yarn build"
@@ -46,9 +47,9 @@
46
47
  },
47
48
  "devDependencies": {
48
49
  "@eslint/js": "=9.0.0",
49
- "@rvoh/dream": "^1.5.0",
50
- "@rvoh/dream-spec-helpers": "^1.1.1",
51
- "@rvoh/psychic": "^1.5.2",
50
+ "@rvoh/dream": "^1.11.1",
51
+ "@rvoh/dream-spec-helpers": "^1.2.1",
52
+ "@rvoh/psychic": "^1.12.2",
52
53
  "@types/cookiejar": "^2",
53
54
  "@types/express": "^4",
54
55
  "@types/node": "^22.5.1",
@@ -56,8 +57,8 @@
56
57
  "@types/supertest": "^6.0.3",
57
58
  "eslint": "^9.9.1",
58
59
  "express": "^4.21.2",
59
- "kysely": "^0.27.5",
60
- "kysely-codegen": "^0.17.0",
60
+ "kysely": "^0.28.5",
61
+ "kysely-codegen": "~0.17.0",
61
62
  "luxon-jest-matchers": "^0.1.14",
62
63
  "openapi-typescript": "^7.8.0",
63
64
  "pg": "^8.13.1",
@@ -73,4 +74,4 @@
73
74
  "dependencies": {
74
75
  "cookiejar": "^2.1.4"
75
76
  }
76
- }
77
+ }
@@ -178,7 +178,12 @@ export class OpenapiSpecSession<OpenapiPaths> {
178
178
  ? OpenapiSpecRequestOptsPost<RequestBodyJsonContent>
179
179
  : OpenapiSpecRequestOptsPost<RequestBodyJsonContent> & { [K in Params[number]]: string }
180
180
  ): Promise<OpenapiSpecResponse<JsonContent>> {
181
- return await this.makeRequest('post', uri, expectedStatus, opts as SpecRequestOptsAll)
181
+ return await this.makeRequest(
182
+ 'post',
183
+ fillOpenapiParams(uri, opts || {}),
184
+ expectedStatus,
185
+ opts as SpecRequestOptsAll
186
+ )
182
187
  }
183
188
 
184
189
  public async put<
package/CHANGELOG.md DELETED
@@ -1,15 +0,0 @@
1
- ## 1.1.5
2
-
3
- Add "Openapi" prefix to all newly-exported type helpers, so that comparitive helpers can be defined within a user's application to take over the more succinct namespaces
4
-
5
- ## 1.1.4
6
-
7
- export RequestBody and RequestQuery, ResponseBody and ResponseCodeForUri types, so that they can be used within psychic application unit tests to be used as type guards
8
-
9
- ## 1.1.1
10
-
11
- - bump supertest to close [dependabot issue](https://github.com/rvohealth/psychic-spec-helpers/security/dependabot/20)
12
-
13
- ## 1.1.0
14
-
15
- - update for Dream 1.4.0
@@ -1,7 +0,0 @@
1
- {
2
- "files": [],
3
- "references": [
4
- { "path": "./tsconfig.app.json" },
5
- { "path": "./tsconfig.node.json" }
6
- ]
7
- }