@shipfox/api-integration-core-dto 8.0.0 → 9.0.1

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 (58) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +19 -0
  3. package/dist/event-catalog.d.ts +15 -0
  4. package/dist/event-catalog.d.ts.map +1 -0
  5. package/dist/event-catalog.js +3 -0
  6. package/dist/event-catalog.js.map +1 -0
  7. package/dist/index.d.ts +1 -4
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -4
  10. package/dist/index.js.map +1 -1
  11. package/dist/schemas/index.d.ts +1 -1
  12. package/dist/schemas/index.d.ts.map +1 -1
  13. package/dist/schemas/index.js +1 -1
  14. package/dist/schemas/index.js.map +1 -1
  15. package/dist/schemas/integrations.d.ts +2 -2
  16. package/dist/schemas/integrations.d.ts.map +1 -1
  17. package/dist/schemas/integrations.js +2 -2
  18. package/dist/schemas/integrations.js.map +1 -1
  19. package/dist/tsconfig.test.tsbuildinfo +1 -1
  20. package/dist/webhooks.d.ts +0 -5
  21. package/dist/webhooks.d.ts.map +1 -1
  22. package/dist/webhooks.js +0 -17
  23. package/dist/webhooks.js.map +1 -1
  24. package/package.json +5 -6
  25. package/src/event-catalog.ts +16 -0
  26. package/src/index.ts +1 -4
  27. package/src/schemas/index.ts +1 -0
  28. package/src/schemas/integrations.ts +7 -2
  29. package/src/webhooks.test.ts +20 -1
  30. package/src/webhooks.ts +0 -24
  31. package/tsconfig.build.tsbuildinfo +1 -1
  32. package/dist/contracts/index.d.ts +0 -4
  33. package/dist/contracts/index.d.ts.map +0 -1
  34. package/dist/contracts/index.js +0 -3
  35. package/dist/contracts/index.js.map +0 -1
  36. package/dist/contracts/integrations.d.ts +0 -206
  37. package/dist/contracts/integrations.d.ts.map +0 -1
  38. package/dist/contracts/integrations.js +0 -44
  39. package/dist/contracts/integrations.js.map +0 -1
  40. package/dist/errors.d.ts +0 -4
  41. package/dist/errors.d.ts.map +0 -1
  42. package/dist/errors.js +0 -10
  43. package/dist/errors.js.map +0 -1
  44. package/dist/ports.d.ts +0 -66
  45. package/dist/ports.d.ts.map +0 -1
  46. package/dist/ports.js +0 -3
  47. package/dist/ports.js.map +0 -1
  48. package/dist/slug.d.ts +0 -7
  49. package/dist/slug.d.ts.map +0 -1
  50. package/dist/slug.js +0 -14
  51. package/dist/slug.js.map +0 -1
  52. package/src/contracts/index.ts +0 -48
  53. package/src/contracts/integrations.test.ts +0 -64
  54. package/src/contracts/integrations.ts +0 -325
  55. package/src/errors.ts +0 -6
  56. package/src/ports.ts +0 -79
  57. package/src/slug.test.ts +0 -32
  58. package/src/slug.ts +0 -26
@@ -76,10 +76,6 @@ export declare const webhookProcessingResultSchema: z.ZodDiscriminatedUnion<[z.Z
76
76
  deliveryId: z.ZodOptional<z.ZodString>;
77
77
  }, z.core.$strict>], "outcome">;
78
78
  export type WebhookProcessingResult = z.infer<typeof webhookProcessingResultSchema>;
79
- /** Processes one provider-neutral inbound webhook request. */
80
- export interface WebhookRequestProcessor {
81
- process(request: StoredWebhookRequest): Promise<WebhookProcessingResult>;
82
- }
83
79
  export interface CreateStoredWebhookRequestInput {
84
80
  requestId: string;
85
81
  routeId: WebhookRouteId;
@@ -92,6 +88,5 @@ export interface CreateStoredWebhookRequestInput {
92
88
  export declare function encodeWebhookBody(body: Uint8Array): string;
93
89
  export declare function decodeWebhookBody(body: z.infer<typeof webhookBodySchema>): Uint8Array;
94
90
  export declare function createStoredWebhookRequest(input: CreateStoredWebhookRequestInput): StoredWebhookRequest;
95
- export declare function createMaximumSizeStoredWebhookRequestFixture(): StoredWebhookRequest;
96
91
  export {};
97
92
  //# sourceMappingURL=webhooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,eAAO,MAAM,8BAA8B,EAAG,CAAU,CAAC;AACzD,eAAO,MAAM,0BAA0B,QAAa,CAAC;AACrD,eAAO,MAAM,oCAAoC,QAAc,CAAC;AAChE,eAAO,MAAM,wBAAwB,QAAY,CAAC;AAClD,eAAO,MAAM,mCAAmC,QAAW,CAAC;AAW5D,eAAO,MAAM,eAAe,wGAA8D,CAAC;AAE3F,eAAO,MAAM,oBAAoB;;;;;;;;EAA0B,CAAC;AAC5D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AA4BlE,QAAA,MAAM,iBAAiB;;;kBAYpB,CAAC;AA6BJ,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAGrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;+BAuBxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,8DAA8D;AAC9D,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CA0B1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,GAAG,UAAU,CAyBrF;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,+BAA+B,GACrC,oBAAoB,CAetB;AAED,wBAAgB,4CAA4C,IAAI,oBAAoB,CAiBnF"}
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,eAAO,MAAM,8BAA8B,EAAG,CAAU,CAAC;AACzD,eAAO,MAAM,0BAA0B,QAAa,CAAC;AACrD,eAAO,MAAM,oCAAoC,QAAc,CAAC;AAChE,eAAO,MAAM,wBAAwB,QAAY,CAAC;AAClD,eAAO,MAAM,mCAAmC,QAAW,CAAC;AAW5D,eAAO,MAAM,eAAe,wGAA8D,CAAC;AAE3F,eAAO,MAAM,oBAAoB;;;;;;;;EAA0B,CAAC;AAC5D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AA4BlE,QAAA,MAAM,iBAAiB;;;kBAYpB,CAAC;AA6BJ,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAGrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;+BAuBxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CA0B1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,GAAG,UAAU,CAyBrF;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,+BAA+B,GACrC,oBAAoB,CAetB"}
package/dist/webhooks.js CHANGED
@@ -130,22 +130,5 @@ export function createStoredWebhookRequest(input) {
130
130
  }
131
131
  });
132
132
  }
133
- export function createMaximumSizeStoredWebhookRequestFixture() {
134
- const headers = Object.fromEntries(Array.from({
135
- length: 8
136
- }, (_, index)=>[
137
- `x-fixture-${index}`,
138
- 'a'.repeat(index === 7 ? 8_000 : 8 * 1024)
139
- ]));
140
- return createStoredWebhookRequest({
141
- requestId: '9b11d65a-f7e7-40ea-b421-06af012a9be5',
142
- routeId: 'webhook.connection',
143
- receivedAt: '2026-07-20T10:30:00.123Z',
144
- rawQueryString: 'q='.padEnd(WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH, 'q'),
145
- headers,
146
- body: new Uint8Array(WEBHOOK_MAX_RAW_BODY_BYTES),
147
- connectionId: 'c0a8012e-0b6d-4d8f-8d5c-6d74102602b0'
148
- });
149
- }
150
133
 
151
134
  //# sourceMappingURL=webhooks.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/webhooks.ts"],"sourcesContent":["import {z} from 'zod';\n\nexport const WEBHOOK_REQUEST_SCHEMA_VERSION = 1 as const;\nexport const WEBHOOK_MAX_RAW_BODY_BYTES = 512 * 1024;\nexport const WEBHOOK_MAX_SERIALIZED_REQUEST_BYTES = 1024 * 1024;\nexport const WEBHOOK_MAX_HEADER_BYTES = 64 * 1024;\nexport const WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH = 8 * 1024;\n\nconst standardWebhookRouteIds = [\n 'github',\n 'gitea',\n 'linear',\n 'sentry',\n 'slack.event',\n 'slack.command',\n] as const;\n\nexport const webhookRouteIds = [...standardWebhookRouteIds, 'webhook.connection'] as const;\n\nexport const webhookRouteIdSchema = z.enum(webhookRouteIds);\nexport type WebhookRouteId = z.infer<typeof webhookRouteIdSchema>;\n\nconst base64Pattern = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;\n\nfunction decodedBase64Length(value: string): number {\n const paddingLength = value.endsWith('==') ? 2 : value.endsWith('=') ? 1 : 0;\n\n return (value.length / 4) * 3 - paddingLength;\n}\n\nfunction headersByteLength(headers: Record<string, string>): number {\n return new TextEncoder().encode(JSON.stringify(headers)).byteLength;\n}\n\nconst webhookHeadersSchema = z\n .record(z.string(), z.string().max(8 * 1024))\n .refine(\n (headers) =>\n Object.keys(headers).every(\n (name) => name === name.toLowerCase() && name.length > 0 && name.length <= 128,\n ),\n 'Webhook header names must be lowercase and at most 128 characters',\n )\n .refine(\n (headers) => headersByteLength(headers) <= WEBHOOK_MAX_HEADER_BYTES,\n `Webhook headers must serialize to at most ${WEBHOOK_MAX_HEADER_BYTES} bytes`,\n );\n\nconst webhookBodySchema = z\n .object({\n encoding: z.literal('base64'),\n data: z\n .string()\n .max(Math.ceil(WEBHOOK_MAX_RAW_BODY_BYTES / 3) * 4)\n .regex(base64Pattern),\n })\n .strict()\n .refine(\n (body) => decodedBase64Length(body.data) <= WEBHOOK_MAX_RAW_BODY_BYTES,\n `Webhook bodies must decode to at most ${WEBHOOK_MAX_RAW_BODY_BYTES} bytes`,\n );\n\nconst storedWebhookRequestBaseSchema = z.object({\n schema_version: z.literal(WEBHOOK_REQUEST_SCHEMA_VERSION),\n request_id: z.string().uuid(),\n received_at: z.string().datetime({offset: true}),\n method: z.literal('POST'),\n raw_query_string: z.string().max(WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH),\n headers: webhookHeadersSchema,\n body: webhookBodySchema,\n});\n\nconst emptyPathParametersSchema = z.object({}).strict();\nconst connectionPathParametersSchema = z.object({connection_id: z.string().uuid()}).strict();\n\nconst standardWebhookRouteRequestSchema = storedWebhookRequestBaseSchema\n .extend({\n route_id: z.enum(standardWebhookRouteIds),\n path_parameters: emptyPathParametersSchema,\n })\n .strict();\n\nconst genericWebhookRouteRequestSchema = storedWebhookRequestBaseSchema\n .extend({\n route_id: z.literal('webhook.connection'),\n path_parameters: connectionPathParametersSchema,\n })\n .strict();\n\nexport const storedWebhookRequestSchema = z.discriminatedUnion('route_id', [\n standardWebhookRouteRequestSchema,\n genericWebhookRouteRequestSchema,\n]);\nexport type StoredWebhookRequest = z.infer<typeof storedWebhookRequestSchema>;\n\nexport const webhookProcessingResultSchema = z.discriminatedUnion('outcome', [\n z\n .object({\n outcome: z.literal('processed'),\n deliveryId: z.string().min(1).optional(),\n challenge: z.string().min(1).optional(),\n })\n .strict(),\n z.object({outcome: z.literal('duplicate'), deliveryId: z.string().min(1)}).strict(),\n z\n .object({\n outcome: z.literal('discarded'),\n reason: z.enum([\n 'missing_required_input',\n 'invalid_signature',\n 'stale_at_receipt',\n 'malformed_payload',\n 'unsupported_event',\n 'connection_unavailable',\n ]),\n deliveryId: z.string().min(1).optional(),\n })\n .strict(),\n]);\nexport type WebhookProcessingResult = z.infer<typeof webhookProcessingResultSchema>;\n\n/** Processes one provider-neutral inbound webhook request. */\nexport interface WebhookRequestProcessor {\n process(request: StoredWebhookRequest): Promise<WebhookProcessingResult>;\n}\n\nexport interface CreateStoredWebhookRequestInput {\n requestId: string;\n routeId: WebhookRouteId;\n receivedAt: string;\n rawQueryString: string;\n headers: Record<string, string>;\n body: Uint8Array;\n connectionId?: string | undefined;\n}\n\nexport function encodeWebhookBody(body: Uint8Array): string {\n let encoded = '';\n\n for (let index = 0; index < body.length; index += 3) {\n const first = body[index] ?? 0;\n const second = body[index + 1];\n const third = body[index + 2];\n const combined = (first << 16) | ((second ?? 0) << 8) | (third ?? 0);\n\n encoded += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[\n (combined >> 18) & 63\n ];\n encoded += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[\n (combined >> 12) & 63\n ];\n encoded +=\n second === undefined\n ? '='\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[(combined >> 6) & 63];\n encoded +=\n third === undefined\n ? '='\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[combined & 63];\n }\n\n return encoded;\n}\n\nexport function decodeWebhookBody(body: z.infer<typeof webhookBodySchema>): Uint8Array {\n const output = new Uint8Array(decodedBase64Length(body.data));\n let outputIndex = 0;\n\n for (let index = 0; index < body.data.length; index += 4) {\n const chunk = body.data.slice(index, index + 4);\n const values = chunk\n .split('')\n .map((character) =>\n character === '='\n ? 0\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.indexOf(character),\n );\n const first = values[0] ?? 0;\n const second = values[1] ?? 0;\n const third = values[2] ?? 0;\n const fourth = values[3] ?? 0;\n const combined = (first << 18) | (second << 12) | (third << 6) | fourth;\n\n output[outputIndex++] = (combined >> 16) & 255;\n if (chunk[2] !== '=') output[outputIndex++] = (combined >> 8) & 255;\n if (chunk[3] !== '=') output[outputIndex++] = combined & 255;\n }\n\n return output;\n}\n\nexport function createStoredWebhookRequest(\n input: CreateStoredWebhookRequestInput,\n): StoredWebhookRequest {\n const pathParameters =\n input.routeId === 'webhook.connection' ? {connection_id: input.connectionId} : {};\n\n return storedWebhookRequestSchema.parse({\n schema_version: WEBHOOK_REQUEST_SCHEMA_VERSION,\n request_id: input.requestId,\n route_id: input.routeId,\n received_at: input.receivedAt,\n method: 'POST',\n path_parameters: pathParameters,\n raw_query_string: input.rawQueryString,\n headers: input.headers,\n body: {encoding: 'base64', data: encodeWebhookBody(input.body)},\n });\n}\n\nexport function createMaximumSizeStoredWebhookRequestFixture(): StoredWebhookRequest {\n const headers = Object.fromEntries(\n Array.from({length: 8}, (_, index) => [\n `x-fixture-${index}`,\n 'a'.repeat(index === 7 ? 8_000 : 8 * 1024),\n ]),\n );\n\n return createStoredWebhookRequest({\n requestId: '9b11d65a-f7e7-40ea-b421-06af012a9be5',\n routeId: 'webhook.connection',\n receivedAt: '2026-07-20T10:30:00.123Z',\n rawQueryString: 'q='.padEnd(WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH, 'q'),\n headers,\n body: new Uint8Array(WEBHOOK_MAX_RAW_BODY_BYTES),\n connectionId: 'c0a8012e-0b6d-4d8f-8d5c-6d74102602b0',\n });\n}\n"],"names":["z","WEBHOOK_REQUEST_SCHEMA_VERSION","WEBHOOK_MAX_RAW_BODY_BYTES","WEBHOOK_MAX_SERIALIZED_REQUEST_BYTES","WEBHOOK_MAX_HEADER_BYTES","WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH","standardWebhookRouteIds","webhookRouteIds","webhookRouteIdSchema","enum","base64Pattern","decodedBase64Length","value","paddingLength","endsWith","length","headersByteLength","headers","TextEncoder","encode","JSON","stringify","byteLength","webhookHeadersSchema","record","string","max","refine","Object","keys","every","name","toLowerCase","webhookBodySchema","object","encoding","literal","data","Math","ceil","regex","strict","body","storedWebhookRequestBaseSchema","schema_version","request_id","uuid","received_at","datetime","offset","method","raw_query_string","emptyPathParametersSchema","connectionPathParametersSchema","connection_id","standardWebhookRouteRequestSchema","extend","route_id","path_parameters","genericWebhookRouteRequestSchema","storedWebhookRequestSchema","discriminatedUnion","webhookProcessingResultSchema","outcome","deliveryId","min","optional","challenge","reason","encodeWebhookBody","encoded","index","first","second","third","combined","undefined","decodeWebhookBody","output","Uint8Array","outputIndex","chunk","slice","values","split","map","character","indexOf","fourth","createStoredWebhookRequest","input","pathParameters","routeId","connectionId","parse","requestId","receivedAt","rawQueryString","createMaximumSizeStoredWebhookRequestFixture","fromEntries","Array","from","_","repeat","padEnd"],"mappings":"AAAA,SAAQA,CAAC,QAAO,MAAM;AAEtB,OAAO,MAAMC,iCAAiC,EAAW;AACzD,OAAO,MAAMC,6BAA6B,MAAM,KAAK;AACrD,OAAO,MAAMC,uCAAuC,OAAO,KAAK;AAChE,OAAO,MAAMC,2BAA2B,KAAK,KAAK;AAClD,OAAO,MAAMC,sCAAsC,IAAI,KAAK;AAE5D,MAAMC,0BAA0B;IAC9B;IACA;IACA;IACA;IACA;IACA;CACD;AAED,OAAO,MAAMC,kBAAkB;OAAID;IAAyB;CAAqB,CAAU;AAE3F,OAAO,MAAME,uBAAuBR,EAAES,IAAI,CAACF,iBAAiB;AAG5D,MAAMG,gBAAgB;AAEtB,SAASC,oBAAoBC,KAAa;IACxC,MAAMC,gBAAgBD,MAAME,QAAQ,CAAC,QAAQ,IAAIF,MAAME,QAAQ,CAAC,OAAO,IAAI;IAE3E,OAAO,AAACF,MAAMG,MAAM,GAAG,IAAK,IAAIF;AAClC;AAEA,SAASG,kBAAkBC,OAA+B;IACxD,OAAO,IAAIC,cAAcC,MAAM,CAACC,KAAKC,SAAS,CAACJ,UAAUK,UAAU;AACrE;AAEA,MAAMC,uBAAuBvB,EAC1BwB,MAAM,CAACxB,EAAEyB,MAAM,IAAIzB,EAAEyB,MAAM,GAAGC,GAAG,CAAC,IAAI,OACtCC,MAAM,CACL,CAACV,UACCW,OAAOC,IAAI,CAACZ,SAASa,KAAK,CACxB,CAACC,OAASA,SAASA,KAAKC,WAAW,MAAMD,KAAKhB,MAAM,GAAG,KAAKgB,KAAKhB,MAAM,IAAI,MAE/E,qEAEDY,MAAM,CACL,CAACV,UAAYD,kBAAkBC,YAAYb,0BAC3C,CAAC,0CAA0C,EAAEA,yBAAyB,MAAM,CAAC;AAGjF,MAAM6B,oBAAoBjC,EACvBkC,MAAM,CAAC;IACNC,UAAUnC,EAAEoC,OAAO,CAAC;IACpBC,MAAMrC,EACHyB,MAAM,GACNC,GAAG,CAACY,KAAKC,IAAI,CAACrC,6BAA6B,KAAK,GAChDsC,KAAK,CAAC9B;AACX,GACC+B,MAAM,GACNd,MAAM,CACL,CAACe,OAAS/B,oBAAoB+B,KAAKL,IAAI,KAAKnC,4BAC5C,CAAC,sCAAsC,EAAEA,2BAA2B,MAAM,CAAC;AAG/E,MAAMyC,iCAAiC3C,EAAEkC,MAAM,CAAC;IAC9CU,gBAAgB5C,EAAEoC,OAAO,CAACnC;IAC1B4C,YAAY7C,EAAEyB,MAAM,GAAGqB,IAAI;IAC3BC,aAAa/C,EAAEyB,MAAM,GAAGuB,QAAQ,CAAC;QAACC,QAAQ;IAAI;IAC9CC,QAAQlD,EAAEoC,OAAO,CAAC;IAClBe,kBAAkBnD,EAAEyB,MAAM,GAAGC,GAAG,CAACrB;IACjCY,SAASM;IACTmB,MAAMT;AACR;AAEA,MAAMmB,4BAA4BpD,EAAEkC,MAAM,CAAC,CAAC,GAAGO,MAAM;AACrD,MAAMY,iCAAiCrD,EAAEkC,MAAM,CAAC;IAACoB,eAAetD,EAAEyB,MAAM,GAAGqB,IAAI;AAAE,GAAGL,MAAM;AAE1F,MAAMc,oCAAoCZ,+BACvCa,MAAM,CAAC;IACNC,UAAUzD,EAAES,IAAI,CAACH;IACjBoD,iBAAiBN;AACnB,GACCX,MAAM;AAET,MAAMkB,mCAAmChB,+BACtCa,MAAM,CAAC;IACNC,UAAUzD,EAAEoC,OAAO,CAAC;IACpBsB,iBAAiBL;AACnB,GACCZ,MAAM;AAET,OAAO,MAAMmB,6BAA6B5D,EAAE6D,kBAAkB,CAAC,YAAY;IACzEN;IACAI;CACD,EAAE;AAGH,OAAO,MAAMG,gCAAgC9D,EAAE6D,kBAAkB,CAAC,WAAW;IAC3E7D,EACGkC,MAAM,CAAC;QACN6B,SAAS/D,EAAEoC,OAAO,CAAC;QACnB4B,YAAYhE,EAAEyB,MAAM,GAAGwC,GAAG,CAAC,GAAGC,QAAQ;QACtCC,WAAWnE,EAAEyB,MAAM,GAAGwC,GAAG,CAAC,GAAGC,QAAQ;IACvC,GACCzB,MAAM;IACTzC,EAAEkC,MAAM,CAAC;QAAC6B,SAAS/D,EAAEoC,OAAO,CAAC;QAAc4B,YAAYhE,EAAEyB,MAAM,GAAGwC,GAAG,CAAC;IAAE,GAAGxB,MAAM;IACjFzC,EACGkC,MAAM,CAAC;QACN6B,SAAS/D,EAAEoC,OAAO,CAAC;QACnBgC,QAAQpE,EAAES,IAAI,CAAC;YACb;YACA;YACA;YACA;YACA;YACA;SACD;QACDuD,YAAYhE,EAAEyB,MAAM,GAAGwC,GAAG,CAAC,GAAGC,QAAQ;IACxC,GACCzB,MAAM;CACV,EAAE;AAkBH,OAAO,SAAS4B,kBAAkB3B,IAAgB;IAChD,IAAI4B,UAAU;IAEd,IAAK,IAAIC,QAAQ,GAAGA,QAAQ7B,KAAK3B,MAAM,EAAEwD,SAAS,EAAG;QACnD,MAAMC,QAAQ9B,IAAI,CAAC6B,MAAM,IAAI;QAC7B,MAAME,SAAS/B,IAAI,CAAC6B,QAAQ,EAAE;QAC9B,MAAMG,QAAQhC,IAAI,CAAC6B,QAAQ,EAAE;QAC7B,MAAMI,WAAW,AAACH,SAAS,KAAO,AAACC,CAAAA,UAAU,CAAA,KAAM,IAAMC,CAAAA,SAAS,CAAA;QAElEJ,WAAW,kEAAkE,CAC3E,AAACK,YAAY,KAAM,GACpB;QACDL,WAAW,kEAAkE,CAC3E,AAACK,YAAY,KAAM,GACpB;QACDL,WACEG,WAAWG,YACP,MACA,kEAAkE,CAAC,AAACD,YAAY,IAAK,GAAG;QAC9FL,WACEI,UAAUE,YACN,MACA,kEAAkE,CAACD,WAAW,GAAG;IACzF;IAEA,OAAOL;AACT;AAEA,OAAO,SAASO,kBAAkBnC,IAAuC;IACvE,MAAMoC,SAAS,IAAIC,WAAWpE,oBAAoB+B,KAAKL,IAAI;IAC3D,IAAI2C,cAAc;IAElB,IAAK,IAAIT,QAAQ,GAAGA,QAAQ7B,KAAKL,IAAI,CAACtB,MAAM,EAAEwD,SAAS,EAAG;QACxD,MAAMU,QAAQvC,KAAKL,IAAI,CAAC6C,KAAK,CAACX,OAAOA,QAAQ;QAC7C,MAAMY,SAASF,MACZG,KAAK,CAAC,IACNC,GAAG,CAAC,CAACC,YACJA,cAAc,MACV,IACA,mEAAmEC,OAAO,CAACD;QAEnF,MAAMd,QAAQW,MAAM,CAAC,EAAE,IAAI;QAC3B,MAAMV,SAASU,MAAM,CAAC,EAAE,IAAI;QAC5B,MAAMT,QAAQS,MAAM,CAAC,EAAE,IAAI;QAC3B,MAAMK,SAASL,MAAM,CAAC,EAAE,IAAI;QAC5B,MAAMR,WAAW,AAACH,SAAS,KAAOC,UAAU,KAAOC,SAAS,IAAKc;QAEjEV,MAAM,CAACE,cAAc,GAAG,AAACL,YAAY,KAAM;QAC3C,IAAIM,KAAK,CAAC,EAAE,KAAK,KAAKH,MAAM,CAACE,cAAc,GAAG,AAACL,YAAY,IAAK;QAChE,IAAIM,KAAK,CAAC,EAAE,KAAK,KAAKH,MAAM,CAACE,cAAc,GAAGL,WAAW;IAC3D;IAEA,OAAOG;AACT;AAEA,OAAO,SAASW,2BACdC,KAAsC;IAEtC,MAAMC,iBACJD,MAAME,OAAO,KAAK,uBAAuB;QAACtC,eAAeoC,MAAMG,YAAY;IAAA,IAAI,CAAC;IAElF,OAAOjC,2BAA2BkC,KAAK,CAAC;QACtClD,gBAAgB3C;QAChB4C,YAAY6C,MAAMK,SAAS;QAC3BtC,UAAUiC,MAAME,OAAO;QACvB7C,aAAa2C,MAAMM,UAAU;QAC7B9C,QAAQ;QACRQ,iBAAiBiC;QACjBxC,kBAAkBuC,MAAMO,cAAc;QACtChF,SAASyE,MAAMzE,OAAO;QACtByB,MAAM;YAACP,UAAU;YAAUE,MAAMgC,kBAAkBqB,MAAMhD,IAAI;QAAC;IAChE;AACF;AAEA,OAAO,SAASwD;IACd,MAAMjF,UAAUW,OAAOuE,WAAW,CAChCC,MAAMC,IAAI,CAAC;QAACtF,QAAQ;IAAC,GAAG,CAACuF,GAAG/B,QAAU;YACpC,CAAC,UAAU,EAAEA,OAAO;YACpB,IAAIgC,MAAM,CAAChC,UAAU,IAAI,QAAQ,IAAI;SACtC;IAGH,OAAOkB,2BAA2B;QAChCM,WAAW;QACXH,SAAS;QACTI,YAAY;QACZC,gBAAgB,KAAKO,MAAM,CAACnG,qCAAqC;QACjEY;QACAyB,MAAM,IAAIqC,WAAW7E;QACrB2F,cAAc;IAChB;AACF"}
1
+ {"version":3,"sources":["../src/webhooks.ts"],"sourcesContent":["import {z} from 'zod';\n\nexport const WEBHOOK_REQUEST_SCHEMA_VERSION = 1 as const;\nexport const WEBHOOK_MAX_RAW_BODY_BYTES = 512 * 1024;\nexport const WEBHOOK_MAX_SERIALIZED_REQUEST_BYTES = 1024 * 1024;\nexport const WEBHOOK_MAX_HEADER_BYTES = 64 * 1024;\nexport const WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH = 8 * 1024;\n\nconst standardWebhookRouteIds = [\n 'github',\n 'gitea',\n 'linear',\n 'sentry',\n 'slack.event',\n 'slack.command',\n] as const;\n\nexport const webhookRouteIds = [...standardWebhookRouteIds, 'webhook.connection'] as const;\n\nexport const webhookRouteIdSchema = z.enum(webhookRouteIds);\nexport type WebhookRouteId = z.infer<typeof webhookRouteIdSchema>;\n\nconst base64Pattern = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;\n\nfunction decodedBase64Length(value: string): number {\n const paddingLength = value.endsWith('==') ? 2 : value.endsWith('=') ? 1 : 0;\n\n return (value.length / 4) * 3 - paddingLength;\n}\n\nfunction headersByteLength(headers: Record<string, string>): number {\n return new TextEncoder().encode(JSON.stringify(headers)).byteLength;\n}\n\nconst webhookHeadersSchema = z\n .record(z.string(), z.string().max(8 * 1024))\n .refine(\n (headers) =>\n Object.keys(headers).every(\n (name) => name === name.toLowerCase() && name.length > 0 && name.length <= 128,\n ),\n 'Webhook header names must be lowercase and at most 128 characters',\n )\n .refine(\n (headers) => headersByteLength(headers) <= WEBHOOK_MAX_HEADER_BYTES,\n `Webhook headers must serialize to at most ${WEBHOOK_MAX_HEADER_BYTES} bytes`,\n );\n\nconst webhookBodySchema = z\n .object({\n encoding: z.literal('base64'),\n data: z\n .string()\n .max(Math.ceil(WEBHOOK_MAX_RAW_BODY_BYTES / 3) * 4)\n .regex(base64Pattern),\n })\n .strict()\n .refine(\n (body) => decodedBase64Length(body.data) <= WEBHOOK_MAX_RAW_BODY_BYTES,\n `Webhook bodies must decode to at most ${WEBHOOK_MAX_RAW_BODY_BYTES} bytes`,\n );\n\nconst storedWebhookRequestBaseSchema = z.object({\n schema_version: z.literal(WEBHOOK_REQUEST_SCHEMA_VERSION),\n request_id: z.string().uuid(),\n received_at: z.string().datetime({offset: true}),\n method: z.literal('POST'),\n raw_query_string: z.string().max(WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH),\n headers: webhookHeadersSchema,\n body: webhookBodySchema,\n});\n\nconst emptyPathParametersSchema = z.object({}).strict();\nconst connectionPathParametersSchema = z.object({connection_id: z.string().uuid()}).strict();\n\nconst standardWebhookRouteRequestSchema = storedWebhookRequestBaseSchema\n .extend({\n route_id: z.enum(standardWebhookRouteIds),\n path_parameters: emptyPathParametersSchema,\n })\n .strict();\n\nconst genericWebhookRouteRequestSchema = storedWebhookRequestBaseSchema\n .extend({\n route_id: z.literal('webhook.connection'),\n path_parameters: connectionPathParametersSchema,\n })\n .strict();\n\nexport const storedWebhookRequestSchema = z.discriminatedUnion('route_id', [\n standardWebhookRouteRequestSchema,\n genericWebhookRouteRequestSchema,\n]);\nexport type StoredWebhookRequest = z.infer<typeof storedWebhookRequestSchema>;\n\nexport const webhookProcessingResultSchema = z.discriminatedUnion('outcome', [\n z\n .object({\n outcome: z.literal('processed'),\n deliveryId: z.string().min(1).optional(),\n challenge: z.string().min(1).optional(),\n })\n .strict(),\n z.object({outcome: z.literal('duplicate'), deliveryId: z.string().min(1)}).strict(),\n z\n .object({\n outcome: z.literal('discarded'),\n reason: z.enum([\n 'missing_required_input',\n 'invalid_signature',\n 'stale_at_receipt',\n 'malformed_payload',\n 'unsupported_event',\n 'connection_unavailable',\n ]),\n deliveryId: z.string().min(1).optional(),\n })\n .strict(),\n]);\nexport type WebhookProcessingResult = z.infer<typeof webhookProcessingResultSchema>;\n\nexport interface CreateStoredWebhookRequestInput {\n requestId: string;\n routeId: WebhookRouteId;\n receivedAt: string;\n rawQueryString: string;\n headers: Record<string, string>;\n body: Uint8Array;\n connectionId?: string | undefined;\n}\n\nexport function encodeWebhookBody(body: Uint8Array): string {\n let encoded = '';\n\n for (let index = 0; index < body.length; index += 3) {\n const first = body[index] ?? 0;\n const second = body[index + 1];\n const third = body[index + 2];\n const combined = (first << 16) | ((second ?? 0) << 8) | (third ?? 0);\n\n encoded += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[\n (combined >> 18) & 63\n ];\n encoded += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[\n (combined >> 12) & 63\n ];\n encoded +=\n second === undefined\n ? '='\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[(combined >> 6) & 63];\n encoded +=\n third === undefined\n ? '='\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[combined & 63];\n }\n\n return encoded;\n}\n\nexport function decodeWebhookBody(body: z.infer<typeof webhookBodySchema>): Uint8Array {\n const output = new Uint8Array(decodedBase64Length(body.data));\n let outputIndex = 0;\n\n for (let index = 0; index < body.data.length; index += 4) {\n const chunk = body.data.slice(index, index + 4);\n const values = chunk\n .split('')\n .map((character) =>\n character === '='\n ? 0\n : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.indexOf(character),\n );\n const first = values[0] ?? 0;\n const second = values[1] ?? 0;\n const third = values[2] ?? 0;\n const fourth = values[3] ?? 0;\n const combined = (first << 18) | (second << 12) | (third << 6) | fourth;\n\n output[outputIndex++] = (combined >> 16) & 255;\n if (chunk[2] !== '=') output[outputIndex++] = (combined >> 8) & 255;\n if (chunk[3] !== '=') output[outputIndex++] = combined & 255;\n }\n\n return output;\n}\n\nexport function createStoredWebhookRequest(\n input: CreateStoredWebhookRequestInput,\n): StoredWebhookRequest {\n const pathParameters =\n input.routeId === 'webhook.connection' ? {connection_id: input.connectionId} : {};\n\n return storedWebhookRequestSchema.parse({\n schema_version: WEBHOOK_REQUEST_SCHEMA_VERSION,\n request_id: input.requestId,\n route_id: input.routeId,\n received_at: input.receivedAt,\n method: 'POST',\n path_parameters: pathParameters,\n raw_query_string: input.rawQueryString,\n headers: input.headers,\n body: {encoding: 'base64', data: encodeWebhookBody(input.body)},\n });\n}\n"],"names":["z","WEBHOOK_REQUEST_SCHEMA_VERSION","WEBHOOK_MAX_RAW_BODY_BYTES","WEBHOOK_MAX_SERIALIZED_REQUEST_BYTES","WEBHOOK_MAX_HEADER_BYTES","WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH","standardWebhookRouteIds","webhookRouteIds","webhookRouteIdSchema","enum","base64Pattern","decodedBase64Length","value","paddingLength","endsWith","length","headersByteLength","headers","TextEncoder","encode","JSON","stringify","byteLength","webhookHeadersSchema","record","string","max","refine","Object","keys","every","name","toLowerCase","webhookBodySchema","object","encoding","literal","data","Math","ceil","regex","strict","body","storedWebhookRequestBaseSchema","schema_version","request_id","uuid","received_at","datetime","offset","method","raw_query_string","emptyPathParametersSchema","connectionPathParametersSchema","connection_id","standardWebhookRouteRequestSchema","extend","route_id","path_parameters","genericWebhookRouteRequestSchema","storedWebhookRequestSchema","discriminatedUnion","webhookProcessingResultSchema","outcome","deliveryId","min","optional","challenge","reason","encodeWebhookBody","encoded","index","first","second","third","combined","undefined","decodeWebhookBody","output","Uint8Array","outputIndex","chunk","slice","values","split","map","character","indexOf","fourth","createStoredWebhookRequest","input","pathParameters","routeId","connectionId","parse","requestId","receivedAt","rawQueryString"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shipfox/api-integration-core-dto",
3
3
  "license": "MIT",
4
- "version": "8.0.0",
4
+ "version": "9.0.1",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/ShipfoxHQ/shipfox.git",
@@ -11,10 +11,6 @@
11
11
  "type": "module",
12
12
  "main": "dist/index.js",
13
13
  "types": "dist/index.d.ts",
14
- "imports": {
15
- "#test/*": "./test/*",
16
- "#*": "./dist/*"
17
- },
18
14
  "exports": {
19
15
  ".": {
20
16
  "types": "./dist/index.d.ts",
@@ -27,7 +23,10 @@
27
23
  },
28
24
  "dependencies": {
29
25
  "zod": "^4.4.3",
30
- "@shipfox/inter-module": "0.2.0"
26
+ "@shipfox/inter-module": "0.2.1"
27
+ },
28
+ "imports": {
29
+ "#*": "./dist/*"
31
30
  },
32
31
  "scripts": {
33
32
  "build": "shipfox-swc",
@@ -0,0 +1,16 @@
1
+ export type IntegrationEventPayloadKind = 'raw-provider' | 'shipfox-normalized';
2
+
3
+ export interface IntegrationEventDoc {
4
+ name: string;
5
+ summary: string;
6
+ emittedWhen: string;
7
+ payloadKind: IntegrationEventPayloadKind;
8
+ payloadDocUrl?: string | undefined;
9
+ }
10
+
11
+ export interface IntegrationEventCatalog {
12
+ provider: string;
13
+ passthrough?: boolean | undefined;
14
+ upstreamEventsDocUrl?: string | undefined;
15
+ events: readonly IntegrationEventDoc[];
16
+ }
package/src/index.ts CHANGED
@@ -1,7 +1,4 @@
1
- export * from '#contracts/index.js';
2
- export * from '#errors.js';
1
+ export * from '#event-catalog.js';
3
2
  export * from '#events.js';
4
- export * from '#ports.js';
5
3
  export * from '#schemas/index.js';
6
- export * from '#slug.js';
7
4
  export * from '#webhooks.js';
@@ -1,4 +1,5 @@
1
1
  export {
2
+ CONNECTION_SLUG_MAX_LENGTH,
2
3
  connectionSlugSchema,
3
4
  type IntegrationCapabilityDto,
4
5
  type IntegrationConnectionDto,
@@ -1,7 +1,12 @@
1
1
  import {z} from 'zod';
2
- import {connectionSlugSchema} from '#slug.js';
3
2
 
4
- export {connectionSlugSchema};
3
+ export const CONNECTION_SLUG_MAX_LENGTH = 100;
4
+
5
+ export const connectionSlugSchema = z
6
+ .string()
7
+ .min(1)
8
+ .max(CONNECTION_SLUG_MAX_LENGTH)
9
+ .regex(/^[a-z0-9]+(?:[_-][a-z0-9]+)*$/);
5
10
 
6
11
  export const integrationProviderKindSchema = z.string().min(1);
7
12
  export type IntegrationProviderKindDto = z.infer<typeof integrationProviderKindSchema>;
@@ -1,9 +1,9 @@
1
1
  import {
2
- createMaximumSizeStoredWebhookRequestFixture,
3
2
  createStoredWebhookRequest,
4
3
  decodeWebhookBody,
5
4
  storedWebhookRequestSchema,
6
5
  WEBHOOK_MAX_RAW_BODY_BYTES,
6
+ WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH,
7
7
  WEBHOOK_MAX_SERIALIZED_REQUEST_BYTES,
8
8
  webhookProcessingResultSchema,
9
9
  } from './webhooks.js';
@@ -11,6 +11,25 @@ import {
11
11
  const requestId = '9b11d65a-f7e7-40ea-b421-06af012a9be5';
12
12
  const receivedAt = '2026-07-20T10:30:00.123Z';
13
13
 
14
+ function createMaximumSizeStoredWebhookRequestFixture() {
15
+ const headers = Object.fromEntries(
16
+ Array.from({length: 8}, (_, index) => [
17
+ `x-fixture-${index}`,
18
+ 'a'.repeat(index === 7 ? 8_000 : 8 * 1024),
19
+ ]),
20
+ );
21
+
22
+ return createStoredWebhookRequest({
23
+ requestId,
24
+ routeId: 'webhook.connection',
25
+ receivedAt,
26
+ rawQueryString: 'q='.padEnd(WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH, 'q'),
27
+ headers,
28
+ body: new Uint8Array(WEBHOOK_MAX_RAW_BODY_BYTES),
29
+ connectionId: 'c0a8012e-0b6d-4d8f-8d5c-6d74102602b0',
30
+ });
31
+ }
32
+
14
33
  describe('storedWebhookRequestSchema', () => {
15
34
  it('round-trips exact body bytes from a direct adapter through the stored contract', () => {
16
35
  const body = new Uint8Array([0, 255, 5, 128, 42]);
package/src/webhooks.ts CHANGED
@@ -119,11 +119,6 @@ export const webhookProcessingResultSchema = z.discriminatedUnion('outcome', [
119
119
  ]);
120
120
  export type WebhookProcessingResult = z.infer<typeof webhookProcessingResultSchema>;
121
121
 
122
- /** Processes one provider-neutral inbound webhook request. */
123
- export interface WebhookRequestProcessor {
124
- process(request: StoredWebhookRequest): Promise<WebhookProcessingResult>;
125
- }
126
-
127
122
  export interface CreateStoredWebhookRequestInput {
128
123
  requestId: string;
129
124
  routeId: WebhookRouteId;
@@ -207,22 +202,3 @@ export function createStoredWebhookRequest(
207
202
  body: {encoding: 'base64', data: encodeWebhookBody(input.body)},
208
203
  });
209
204
  }
210
-
211
- export function createMaximumSizeStoredWebhookRequestFixture(): StoredWebhookRequest {
212
- const headers = Object.fromEntries(
213
- Array.from({length: 8}, (_, index) => [
214
- `x-fixture-${index}`,
215
- 'a'.repeat(index === 7 ? 8_000 : 8 * 1024),
216
- ]),
217
- );
218
-
219
- return createStoredWebhookRequest({
220
- requestId: '9b11d65a-f7e7-40ea-b421-06af012a9be5',
221
- routeId: 'webhook.connection',
222
- receivedAt: '2026-07-20T10:30:00.123Z',
223
- rawQueryString: 'q='.padEnd(WEBHOOK_MAX_RAW_QUERY_STRING_LENGTH, 'q'),
224
- headers,
225
- body: new Uint8Array(WEBHOOK_MAX_RAW_BODY_BYTES),
226
- connectionId: 'c0a8012e-0b6d-4d8f-8d5c-6d74102602b0',
227
- });
228
- }