@hookflo/tern 1.0.6 → 2.0.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.
Files changed (37) hide show
  1. package/README.md +70 -10
  2. package/dist/normalization/index.d.ts +20 -0
  3. package/dist/normalization/index.js +78 -0
  4. package/dist/normalization/providers/payment/paypal.d.ts +2 -0
  5. package/dist/normalization/providers/payment/paypal.js +12 -0
  6. package/dist/normalization/providers/payment/razorpay.d.ts +2 -0
  7. package/dist/normalization/providers/payment/razorpay.js +13 -0
  8. package/dist/normalization/providers/payment/stripe.d.ts +2 -0
  9. package/dist/normalization/providers/payment/stripe.js +13 -0
  10. package/dist/normalization/providers/registry.d.ts +5 -0
  11. package/dist/normalization/providers/registry.js +23 -0
  12. package/dist/normalization/storage/interface.d.ts +13 -0
  13. package/dist/normalization/storage/interface.js +2 -0
  14. package/dist/normalization/storage/memory.d.ts +12 -0
  15. package/dist/normalization/storage/memory.js +39 -0
  16. package/dist/normalization/templates/base/auth.d.ts +2 -0
  17. package/dist/normalization/templates/base/auth.js +22 -0
  18. package/dist/normalization/templates/base/ecommerce.d.ts +2 -0
  19. package/dist/normalization/templates/base/ecommerce.js +25 -0
  20. package/dist/normalization/templates/base/payment.d.ts +2 -0
  21. package/dist/normalization/templates/base/payment.js +25 -0
  22. package/dist/normalization/templates/registry.d.ts +6 -0
  23. package/dist/normalization/templates/registry.js +22 -0
  24. package/dist/normalization/transformer/engine.d.ts +11 -0
  25. package/dist/normalization/transformer/engine.js +86 -0
  26. package/dist/normalization/transformer/validator.d.ts +12 -0
  27. package/dist/normalization/transformer/validator.js +56 -0
  28. package/dist/normalization/types.d.ts +79 -0
  29. package/dist/normalization/types.js +2 -0
  30. package/dist/platforms/algorithms.d.ts +1 -1
  31. package/dist/platforms/algorithms.js +89 -89
  32. package/dist/verifiers/algorithms.d.ts +2 -2
  33. package/dist/verifiers/algorithms.js +62 -62
  34. package/dist/verifiers/base.d.ts +1 -1
  35. package/dist/verifiers/custom-algorithms.d.ts +2 -2
  36. package/dist/verifiers/custom-algorithms.js +8 -8
  37. package/package.json +1 -1
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchemaValidator = void 0;
4
+ class SchemaValidator {
5
+ validateSchema(userSchema, baseTemplate) {
6
+ const errors = [];
7
+ // Ensure required base fields exist and are enabled or have defaults
8
+ for (const baseField of baseTemplate.fields) {
9
+ if (!baseField.required)
10
+ continue;
11
+ const userField = userSchema.fields.find((f) => f.id === baseField.id);
12
+ if (!userField) {
13
+ errors.push(`Missing required field in schema: ${baseField.id}`);
14
+ continue;
15
+ }
16
+ if (!userField.enabled && baseField.defaultValue === undefined) {
17
+ errors.push(`Required field disabled without default: ${baseField.id}`);
18
+ }
19
+ if (userField.type !== baseField.type) {
20
+ errors.push(`Type mismatch for field ${baseField.id}: expected ${baseField.type}, got ${userField.type}`);
21
+ }
22
+ }
23
+ return { valid: errors.length === 0, errors };
24
+ }
25
+ validateOutput(output, userSchema, baseTemplate) {
26
+ const errors = [];
27
+ for (const field of userSchema.fields) {
28
+ if (!field.enabled)
29
+ continue;
30
+ const value = output[field.name];
31
+ if (value === undefined) {
32
+ if (field.required)
33
+ errors.push(`Missing required field in output: ${field.name}`);
34
+ continue;
35
+ }
36
+ if (!this.matchesType(value, field.type)) {
37
+ errors.push(`Type mismatch for output field ${field.name}`);
38
+ }
39
+ }
40
+ return { valid: errors.length === 0, errors };
41
+ }
42
+ matchesType(value, type) {
43
+ if (type === 'number')
44
+ return typeof value === 'number' && !Number.isNaN(value);
45
+ if (type === 'string')
46
+ return typeof value === 'string';
47
+ if (type === 'boolean')
48
+ return typeof value === 'boolean';
49
+ if (type === 'object')
50
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
51
+ if (type === 'array')
52
+ return Array.isArray(value);
53
+ return true;
54
+ }
55
+ }
56
+ exports.SchemaValidator = SchemaValidator;
@@ -0,0 +1,79 @@
1
+ export type TemplateCategory = 'payment' | 'auth' | 'ecommerce';
2
+ export interface TemplateField {
3
+ id: string;
4
+ name: string;
5
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array';
6
+ required: boolean;
7
+ description?: string;
8
+ defaultValue?: unknown;
9
+ }
10
+ export interface BaseTemplate {
11
+ id: string;
12
+ category: TemplateCategory;
13
+ version: string;
14
+ fields: TemplateField[];
15
+ }
16
+ export interface UserSchemaField {
17
+ id: string;
18
+ name: string;
19
+ type: TemplateField['type'];
20
+ required: boolean;
21
+ enabled: boolean;
22
+ defaultValue?: unknown;
23
+ }
24
+ export interface FieldMapping {
25
+ schemaFieldId: string;
26
+ providerPath: string;
27
+ transform?: string;
28
+ }
29
+ export interface ProviderMapping {
30
+ provider: string;
31
+ fieldMappings: FieldMapping[];
32
+ }
33
+ export interface UserSchema {
34
+ id: string;
35
+ userId: string;
36
+ baseTemplateId: string;
37
+ category: TemplateCategory;
38
+ fields: UserSchemaField[];
39
+ providerMappings: ProviderMapping[];
40
+ createdAt: Date;
41
+ updatedAt: Date;
42
+ }
43
+ export interface NormalizedPayloadMeta {
44
+ provider: string;
45
+ schemaId: string;
46
+ schemaVersion: string;
47
+ transformedAt: Date;
48
+ }
49
+ export interface NormalizedResult {
50
+ normalized: Record<string, unknown>;
51
+ meta: NormalizedPayloadMeta;
52
+ }
53
+ export interface CreateSchemaInput {
54
+ userId: string;
55
+ baseTemplateId: string;
56
+ category: TemplateCategory;
57
+ fields: UserSchemaField[];
58
+ providerMappings: ProviderMapping[];
59
+ }
60
+ export interface UpdateSchemaInput {
61
+ fields?: UserSchemaField[];
62
+ providerMappings?: ProviderMapping[];
63
+ }
64
+ export interface ProviderInfoField {
65
+ path: string;
66
+ type?: TemplateField['type'];
67
+ description?: string;
68
+ }
69
+ export interface ProviderInfo {
70
+ id: string;
71
+ name: string;
72
+ category: TemplateCategory;
73
+ samplePaths?: ProviderInfoField[];
74
+ }
75
+ export interface TransformParams {
76
+ rawPayload: unknown;
77
+ provider: string;
78
+ schemaId: string;
79
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,4 @@
1
- import { PlatformAlgorithmConfig, WebhookPlatform, SignatureConfig } from "../types";
1
+ import { PlatformAlgorithmConfig, WebhookPlatform, SignatureConfig } from '../types';
2
2
  export declare const platformAlgorithmConfigs: Record<WebhookPlatform, PlatformAlgorithmConfig>;
3
3
  export declare function getPlatformAlgorithmConfig(platform: WebhookPlatform): PlatformAlgorithmConfig;
4
4
  export declare function platformUsesAlgorithm(platform: WebhookPlatform, algorithm: string): boolean;
@@ -7,139 +7,139 @@ exports.getPlatformsUsingAlgorithm = getPlatformsUsingAlgorithm;
7
7
  exports.validateSignatureConfig = validateSignatureConfig;
8
8
  exports.platformAlgorithmConfigs = {
9
9
  github: {
10
- platform: "github",
10
+ platform: 'github',
11
11
  signatureConfig: {
12
- algorithm: "hmac-sha256",
13
- headerName: "x-hub-signature-256",
14
- headerFormat: "prefixed",
15
- prefix: "sha256=",
12
+ algorithm: 'hmac-sha256',
13
+ headerName: 'x-hub-signature-256',
14
+ headerFormat: 'prefixed',
15
+ prefix: 'sha256=',
16
16
  timestampHeader: undefined,
17
- payloadFormat: "raw",
17
+ payloadFormat: 'raw',
18
18
  },
19
- description: "GitHub webhooks use HMAC-SHA256 with sha256= prefix",
19
+ description: 'GitHub webhooks use HMAC-SHA256 with sha256= prefix',
20
20
  },
21
21
  stripe: {
22
- platform: "stripe",
22
+ platform: 'stripe',
23
23
  signatureConfig: {
24
- algorithm: "hmac-sha256",
25
- headerName: "stripe-signature",
26
- headerFormat: "comma-separated",
24
+ algorithm: 'hmac-sha256',
25
+ headerName: 'stripe-signature',
26
+ headerFormat: 'comma-separated',
27
27
  timestampHeader: undefined,
28
- payloadFormat: "timestamped",
28
+ payloadFormat: 'timestamped',
29
29
  customConfig: {
30
- signatureFormat: "t={timestamp},v1={signature}",
30
+ signatureFormat: 't={timestamp},v1={signature}',
31
31
  },
32
32
  },
33
- description: "Stripe webhooks use HMAC-SHA256 with comma-separated format",
33
+ description: 'Stripe webhooks use HMAC-SHA256 with comma-separated format',
34
34
  },
35
35
  clerk: {
36
- platform: "clerk",
36
+ platform: 'clerk',
37
37
  signatureConfig: {
38
- algorithm: "hmac-sha256",
39
- headerName: "svix-signature",
40
- headerFormat: "raw",
41
- timestampHeader: "svix-timestamp",
42
- timestampFormat: "unix",
43
- payloadFormat: "custom",
38
+ algorithm: 'hmac-sha256',
39
+ headerName: 'svix-signature',
40
+ headerFormat: 'raw',
41
+ timestampHeader: 'svix-timestamp',
42
+ timestampFormat: 'unix',
43
+ payloadFormat: 'custom',
44
44
  customConfig: {
45
- signatureFormat: "v1={signature}",
46
- payloadFormat: "{id}.{timestamp}.{body}",
47
- encoding: "base64",
48
- idHeader: "svix-id",
45
+ signatureFormat: 'v1={signature}',
46
+ payloadFormat: '{id}.{timestamp}.{body}',
47
+ encoding: 'base64',
48
+ idHeader: 'svix-id',
49
49
  },
50
50
  },
51
- description: "Clerk webhooks use HMAC-SHA256 with base64 encoding",
51
+ description: 'Clerk webhooks use HMAC-SHA256 with base64 encoding',
52
52
  },
53
53
  dodopayments: {
54
- platform: "dodopayments",
54
+ platform: 'dodopayments',
55
55
  signatureConfig: {
56
- algorithm: "hmac-sha256",
57
- headerName: "webhook-signature",
58
- headerFormat: "raw",
59
- timestampHeader: "webhook-timestamp",
60
- timestampFormat: "unix",
61
- payloadFormat: "custom",
56
+ algorithm: 'hmac-sha256',
57
+ headerName: 'webhook-signature',
58
+ headerFormat: 'raw',
59
+ timestampHeader: 'webhook-timestamp',
60
+ timestampFormat: 'unix',
61
+ payloadFormat: 'custom',
62
62
  customConfig: {
63
- signatureFormat: "v1={signature}",
64
- payloadFormat: "{id}.{timestamp}.{body}",
65
- encoding: "base64",
66
- idHeader: "webhook-id",
63
+ signatureFormat: 'v1={signature}',
64
+ payloadFormat: '{id}.{timestamp}.{body}',
65
+ encoding: 'base64',
66
+ idHeader: 'webhook-id',
67
67
  },
68
68
  },
69
- description: "Dodo Payments webhooks use HMAC-SHA256 with svix-style format (Standard Webhooks)",
69
+ description: 'Dodo Payments webhooks use HMAC-SHA256 with svix-style format (Standard Webhooks)',
70
70
  },
71
71
  shopify: {
72
- platform: "shopify",
72
+ platform: 'shopify',
73
73
  signatureConfig: {
74
- algorithm: "hmac-sha256",
75
- headerName: "x-shopify-hmac-sha256",
76
- headerFormat: "raw",
77
- timestampHeader: "x-shopify-shop-domain",
78
- payloadFormat: "raw",
74
+ algorithm: 'hmac-sha256',
75
+ headerName: 'x-shopify-hmac-sha256',
76
+ headerFormat: 'raw',
77
+ timestampHeader: 'x-shopify-shop-domain',
78
+ payloadFormat: 'raw',
79
79
  },
80
- description: "Shopify webhooks use HMAC-SHA256",
80
+ description: 'Shopify webhooks use HMAC-SHA256',
81
81
  },
82
82
  vercel: {
83
- platform: "vercel",
83
+ platform: 'vercel',
84
84
  signatureConfig: {
85
- algorithm: "hmac-sha256",
86
- headerName: "x-vercel-signature",
87
- headerFormat: "raw",
88
- timestampHeader: "x-vercel-timestamp",
89
- timestampFormat: "unix",
90
- payloadFormat: "raw",
85
+ algorithm: 'hmac-sha256',
86
+ headerName: 'x-vercel-signature',
87
+ headerFormat: 'raw',
88
+ timestampHeader: 'x-vercel-timestamp',
89
+ timestampFormat: 'unix',
90
+ payloadFormat: 'raw',
91
91
  },
92
- description: "Vercel webhooks use HMAC-SHA256",
92
+ description: 'Vercel webhooks use HMAC-SHA256',
93
93
  },
94
94
  polar: {
95
- platform: "polar",
95
+ platform: 'polar',
96
96
  signatureConfig: {
97
- algorithm: "hmac-sha256",
98
- headerName: "x-polar-signature",
99
- headerFormat: "raw",
100
- timestampHeader: "x-polar-timestamp",
101
- timestampFormat: "unix",
102
- payloadFormat: "raw",
97
+ algorithm: 'hmac-sha256',
98
+ headerName: 'x-polar-signature',
99
+ headerFormat: 'raw',
100
+ timestampHeader: 'x-polar-timestamp',
101
+ timestampFormat: 'unix',
102
+ payloadFormat: 'raw',
103
103
  },
104
- description: "Polar webhooks use HMAC-SHA256",
104
+ description: 'Polar webhooks use HMAC-SHA256',
105
105
  },
106
106
  supabase: {
107
- platform: "supabase",
107
+ platform: 'supabase',
108
108
  signatureConfig: {
109
- algorithm: "custom",
110
- headerName: "x-webhook-token",
111
- headerFormat: "raw",
112
- payloadFormat: "raw",
109
+ algorithm: 'custom',
110
+ headerName: 'x-webhook-token',
111
+ headerFormat: 'raw',
112
+ payloadFormat: 'raw',
113
113
  customConfig: {
114
- type: "token-based",
115
- idHeader: "x-webhook-id",
114
+ type: 'token-based',
115
+ idHeader: 'x-webhook-id',
116
116
  },
117
117
  },
118
- description: "Supabase webhooks use token-based authentication",
118
+ description: 'Supabase webhooks use token-based authentication',
119
119
  },
120
120
  custom: {
121
- platform: "custom",
121
+ platform: 'custom',
122
122
  signatureConfig: {
123
- algorithm: "hmac-sha256",
124
- headerName: "x-webhook-token",
125
- headerFormat: "raw",
126
- payloadFormat: "raw",
123
+ algorithm: 'hmac-sha256',
124
+ headerName: 'x-webhook-token',
125
+ headerFormat: 'raw',
126
+ payloadFormat: 'raw',
127
127
  customConfig: {
128
- type: "token-based",
129
- idHeader: "x-webhook-id",
128
+ type: 'token-based',
129
+ idHeader: 'x-webhook-id',
130
130
  },
131
131
  },
132
- description: "Custom webhook configuration",
132
+ description: 'Custom webhook configuration',
133
133
  },
134
134
  unknown: {
135
- platform: "unknown",
135
+ platform: 'unknown',
136
136
  signatureConfig: {
137
- algorithm: "hmac-sha256",
138
- headerName: "x-webhook-signature",
139
- headerFormat: "raw",
140
- payloadFormat: "raw",
137
+ algorithm: 'hmac-sha256',
138
+ headerName: 'x-webhook-signature',
139
+ headerFormat: 'raw',
140
+ payloadFormat: 'raw',
141
141
  },
142
- description: "Unknown platform - using default HMAC-SHA256",
142
+ description: 'Unknown platform - using default HMAC-SHA256',
143
143
  },
144
144
  };
145
145
  function getPlatformAlgorithmConfig(platform) {
@@ -159,14 +159,14 @@ function validateSignatureConfig(config) {
159
159
  return false;
160
160
  }
161
161
  switch (config.algorithm) {
162
- case "hmac-sha256":
163
- case "hmac-sha1":
164
- case "hmac-sha512":
162
+ case 'hmac-sha256':
163
+ case 'hmac-sha1':
164
+ case 'hmac-sha512':
165
165
  return true;
166
- case "rsa-sha256":
167
- case "ed25519":
166
+ case 'rsa-sha256':
167
+ case 'ed25519':
168
168
  return !!config.customConfig?.publicKey;
169
- case "custom":
169
+ case 'custom':
170
170
  return !!config.customConfig;
171
171
  default:
172
172
  return false;
@@ -1,5 +1,5 @@
1
- import { WebhookVerifier } from "./base";
2
- import { WebhookVerificationResult, SignatureConfig, WebhookPlatform } from "../types";
1
+ import { WebhookVerifier } from './base';
2
+ import { WebhookVerificationResult, SignatureConfig, WebhookPlatform } from '../types';
3
3
  export declare abstract class AlgorithmBasedVerifier extends WebhookVerifier {
4
4
  protected config: SignatureConfig;
5
5
  protected platform: WebhookPlatform;