@contractkit/plugin-typescript 0.25.3 → 0.26.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractkit/plugin-typescript",
3
- "version": "0.25.3",
3
+ "version": "0.26.0",
4
4
  "description": "ContractKit built-in plugin: TypeScript codegen (SDK clients, Koa routers, Zod schemas, plain types)",
5
5
  "author": {
6
6
  "name": "Marooned Software",
@@ -26,7 +26,7 @@
26
26
  ".": "./dist/index.js"
27
27
  },
28
28
  "dependencies": {
29
- "@contractkit/core": "0.20.0"
29
+ "@contractkit/core": "0.21.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@repo/config-typescript": "0.1.0",
@@ -160,6 +160,10 @@ export function generateOp(root: OpRootNode, options: OpCodegenOptions = {}): st
160
160
  body.push(`import { parseAndValidate } from '@maroonedsoftware/zod';`);
161
161
  }
162
162
 
163
+ if (fileUsesMultipart(root)) {
164
+ body.push(`import { MultipartBody } from '@maroonedsoftware/multipart';`);
165
+ }
166
+
163
167
  const helpers: string[] = [];
164
168
  if (opNeedsScalar(root, 'binary')) {
165
169
  helpers.push(`const _ZodBinary = z.custom<Buffer>((val) => Buffer.isBuffer(val), { error: 'Must be binary data' });`);
@@ -256,7 +260,10 @@ function generateHandler(route: OpRouteNode, op: OpOperationNode, root: OpRootNo
256
260
  middlewares.push(`bodyParserMiddleware([${tokensExpr}])`);
257
261
  }
258
262
  if (op.signature) {
259
- middlewares.push(`requireSignature('${op.signature}')`);
263
+ const sigArgs = op.signaturePolicy
264
+ ? `'${op.signature}', { policy: '${op.signaturePolicy}' }`
265
+ : `'${op.signature}'`;
266
+ middlewares.push(`requireSignature(${sigArgs})`);
260
267
  }
261
268
  const middlewareStr = middlewares.length > 0 ? `, ${middlewares.join(', ')},` : ',';
262
269
 
@@ -773,6 +780,12 @@ function fileNeedsSignature(root: OpRootNode): boolean {
773
780
  return root.routes.some(route => route.operations.some(op => !!op.signature));
774
781
  }
775
782
 
783
+ function fileUsesMultipart(root: OpRootNode): boolean {
784
+ return root.routes.some(route =>
785
+ route.operations.some(op => (op.request?.bodies ?? []).some(b => b.contentType === 'multipart/form-data')),
786
+ );
787
+ }
788
+
776
789
  function isValidIdentifier(name: string): boolean {
777
790
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
778
791
  }
@@ -193,6 +193,7 @@ describe('generateOperation', () => {
193
193
  expect(output).toContain("case 'multipart/form-data':");
194
194
  expect(output).toContain('body = ctx.body as MultipartBody;');
195
195
  expect(output).toContain('body = await parseAndValidate(ctx.body, UploadMeta)');
196
+ expect(output).toContain("import { MultipartBody } from '@maroonedsoftware/multipart';");
196
197
  });
197
198
  });
198
199
 
@@ -471,6 +472,7 @@ describe('generateOperation', () => {
471
472
  const output = generateOp(root);
472
473
  expect(output).toContain("bodyParserMiddleware(['multipart'])");
473
474
  expect(output).toContain('ctx.body as MultipartBody');
475
+ expect(output).toContain("import { MultipartBody } from '@maroonedsoftware/multipart';");
474
476
  });
475
477
  });
476
478
 
@@ -849,6 +851,17 @@ describe('generateOp — route modifiers JSDoc', () => {
849
851
  expect(out).toContain(`requireSignature('MODERN_TREASURY_WEBHOOK')`);
850
852
  });
851
853
 
854
+ it('passes the signature policy to requireSignature when set', () => {
855
+ const op = opOperation('post', {
856
+ signature: 'SLACK_WEBHOOK',
857
+ signaturePolicy: 'slackSignatureValid',
858
+ request: opRequest('Payload'),
859
+ });
860
+ const root = opRoot([opRoute('/webhooks', [op])]);
861
+ const out = generateOp(root);
862
+ expect(out).toContain(`requireSignature('SLACK_WEBHOOK', { policy: 'slackSignatureValid' })`);
863
+ });
864
+
852
865
  it('places requireSignature after bodyParserMiddleware in the route line', () => {
853
866
  const op = opOperation('post', {
854
867
  signature: 'MY_KEY',