spine-framework 0.3.14 → 0.3.16
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/.framework/cli/commands/install-app.ts +14 -6
- package/.framework/functions/_shared/index.ts +7 -7
- package/.framework/functions/_shared/webhook-registry.ts +0 -42
- package/.framework/functions/handler-registry.ts +22 -0
- package/.framework/functions/integration-routes.ts +7 -3
- package/CHANGELOG.md +9 -0
- package/dist/cli/commands/install-app.d.ts.map +1 -1
- package/dist/functions/_shared/index.d.ts +7 -7
- package/dist/functions/_shared/index.d.ts.map +1 -1
- package/dist/functions/_shared/webhook-registry.d.ts +0 -16
- package/dist/functions/_shared/webhook-registry.d.ts.map +1 -1
- package/dist/functions/handler-registry.d.ts +22 -0
- package/dist/functions/handler-registry.d.ts.map +1 -0
- package/dist/functions/integration-routes.d.ts.map +1 -1
- package/package.json +1 -1
- package/scripts/assemble-functions.sh +32 -0
- package/scripts/boundary-check.sh +7 -5
|
@@ -356,18 +356,26 @@ async function upsertIntegrations(appId: string, records: any[], dryRun: boolean
|
|
|
356
356
|
continue
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
+
// Only include fields that exist in the database schema
|
|
360
|
+
const cleanRecord = {
|
|
361
|
+
name: record.name,
|
|
362
|
+
slug: record.slug,
|
|
363
|
+
provider: record.provider,
|
|
364
|
+
status: record.status,
|
|
365
|
+
is_active: record.is_active,
|
|
366
|
+
config: record.config,
|
|
367
|
+
app_id: appId,
|
|
368
|
+
}
|
|
369
|
+
|
|
359
370
|
const { error } = await adminDb
|
|
360
371
|
.from('integrations')
|
|
361
|
-
.upsert({
|
|
362
|
-
|
|
363
|
-
app_id: appId,
|
|
364
|
-
}, {
|
|
365
|
-
onConflict: 'app_id,name',
|
|
372
|
+
.upsert(cleanRecord, {
|
|
373
|
+
onConflict: 'slug',
|
|
366
374
|
ignoreDuplicates: false
|
|
367
375
|
})
|
|
368
376
|
|
|
369
377
|
if (error) {
|
|
370
|
-
result.errors.push(`${record.
|
|
378
|
+
result.errors.push(`${record.slug}: ${error.message}`)
|
|
371
379
|
} else {
|
|
372
380
|
result.inserted++
|
|
373
381
|
}
|
|
@@ -285,21 +285,21 @@ export { emitAudit } from './audit'
|
|
|
285
285
|
// ============================================
|
|
286
286
|
|
|
287
287
|
/**
|
|
288
|
-
*
|
|
288
|
+
* lookupHandler — look up webhook handler metadata by name.
|
|
289
289
|
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
290
|
+
* Queries the webhook_handlers table for handler registration info.
|
|
291
|
+
* Actual handler loading is done via HANDLER_REGISTRY static imports.
|
|
292
292
|
*
|
|
293
293
|
* @param handlerName — The handler identifier from webhook_handlers table
|
|
294
|
-
* @returns Handler
|
|
294
|
+
* @returns Handler metadata or null if not found
|
|
295
295
|
*
|
|
296
296
|
* @example
|
|
297
297
|
* ```ts
|
|
298
|
-
* const
|
|
299
|
-
* if (
|
|
298
|
+
* const meta = await lookupHandler('cortex-webhook')
|
|
299
|
+
* if (meta) console.log(meta.functionName)
|
|
300
300
|
* ```
|
|
301
301
|
*/
|
|
302
|
-
export {
|
|
302
|
+
export { lookupHandler } from './webhook-registry'
|
|
303
303
|
|
|
304
304
|
/**
|
|
305
305
|
* registerWebhookHandler — self-register a custom webhook handler.
|
|
@@ -62,48 +62,6 @@ export async function lookupHandler(handlerName: string): Promise<{ functionName
|
|
|
62
62
|
return { functionName: data.function_name }
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
/**
|
|
66
|
-
* Loads a webhook handler function dynamically.
|
|
67
|
-
* Uses dynamic import to avoid static dependencies.
|
|
68
|
-
*
|
|
69
|
-
* @param functionName - The Netlify function name (e.g., "custom_cortex-handler")
|
|
70
|
-
* @returns The handler function or null if not found
|
|
71
|
-
*/
|
|
72
|
-
export async function loadHandler(functionName: string): Promise<Function | null> {
|
|
73
|
-
try {
|
|
74
|
-
// Dynamic import of the handler function
|
|
75
|
-
// Functions are in the same directory after assembly
|
|
76
|
-
const module = await import(`../${functionName}`)
|
|
77
|
-
|
|
78
|
-
// Handler should be exported as 'handler' or default
|
|
79
|
-
const handler = module.handler || module.default
|
|
80
|
-
|
|
81
|
-
if (typeof handler !== 'function') {
|
|
82
|
-
console.error(`[webhook-registry] Export 'handler' not found in ${functionName}`)
|
|
83
|
-
return null
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return handler
|
|
87
|
-
} catch (err) {
|
|
88
|
-
console.error(`[webhook-registry] Failed to load ${functionName}:`, err)
|
|
89
|
-
return null
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Resolves a webhook handler by name.
|
|
95
|
-
* Combines lookup + load for convenience.
|
|
96
|
-
*
|
|
97
|
-
* @param handlerName - The handler identifier
|
|
98
|
-
* @returns The handler function or null
|
|
99
|
-
*/
|
|
100
|
-
export async function resolveHandler(handlerName: string): Promise<Function | null> {
|
|
101
|
-
const metadata = await lookupHandler(handlerName)
|
|
102
|
-
if (!metadata) return null
|
|
103
|
-
|
|
104
|
-
return loadHandler(metadata.functionName)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
65
|
/**
|
|
108
66
|
* Clears the handler cache. Useful for testing or after deployments.
|
|
109
67
|
*/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module handler-registry
|
|
3
|
+
* @audience core-contributor
|
|
4
|
+
* @layer shared-service
|
|
5
|
+
* @stability stable
|
|
6
|
+
*
|
|
7
|
+
* Static handler registry for esbuild-compatible dynamic dispatch.
|
|
8
|
+
*
|
|
9
|
+
* **THIS FILE IS OVERWRITTEN AT ASSEMBLY TIME.**
|
|
10
|
+
* The stub here (empty registry) is replaced by `assemble-functions.sh`
|
|
11
|
+
* with static imports of every `custom_*.ts` handler found in the assembled
|
|
12
|
+
* functions directory. esbuild can then bundle all handlers into the
|
|
13
|
+
* `integration-routes` function at build time — no runtime dynamic imports.
|
|
14
|
+
*
|
|
15
|
+
* Keys are the handler path (e.g. "funnel-signal") AND the full file name
|
|
16
|
+
* (e.g. "custom_funnel-signal") so lookups work either way.
|
|
17
|
+
*
|
|
18
|
+
* @seeAlso scripts/assemble-functions.sh (generates this file)
|
|
19
|
+
* @seeAlso integration-routes.ts (consumes HANDLER_REGISTRY)
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export const HANDLER_REGISTRY: Record<string, any> = {}
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
|
|
38
38
|
import { adminDb } from './_shared/db'
|
|
39
39
|
import { resolvePrincipal } from './_shared/principal'
|
|
40
|
-
import {
|
|
40
|
+
import { listRegisteredHandlers } from './_shared/webhook-registry'
|
|
41
|
+
import { HANDLER_REGISTRY } from './handler-registry'
|
|
41
42
|
|
|
42
43
|
// ─── TYPES ────────────────────────────────────────────────────────────────
|
|
43
44
|
|
|
@@ -128,7 +129,7 @@ function validateSchema(data: any, schema: any, requestId: string): ValidationRe
|
|
|
128
129
|
// Validate data type
|
|
129
130
|
if (config.type) {
|
|
130
131
|
const typeValid = validateType(value, config.type, fieldName)
|
|
131
|
-
if (!typeValid.valid) {
|
|
132
|
+
if (!typeValid.valid && typeValid.error) {
|
|
132
133
|
errors.push(typeValid.error)
|
|
133
134
|
}
|
|
134
135
|
}
|
|
@@ -255,7 +256,10 @@ function sanitizeData(data: any, rules: string = 'strict'): any {
|
|
|
255
256
|
* @param handlerName - The handler key from integration config (e.g. "webhook-handler")
|
|
256
257
|
*/
|
|
257
258
|
async function loadCustomScript(handlerName: string): Promise<Function | null> {
|
|
258
|
-
|
|
259
|
+
const mod = HANDLER_REGISTRY[handlerName]
|
|
260
|
+
if (!mod) return null
|
|
261
|
+
const fn = mod.handler || mod.default
|
|
262
|
+
return typeof fn === 'function' ? fn : null
|
|
259
263
|
}
|
|
260
264
|
|
|
261
265
|
// ─── DIAGNOSTIC HANDLER (temporary — full trace in response) ──────────────
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.3.16] — 2026-06-09
|
|
8
|
+
- Added `handler-registry.ts` — static handler import registry generated at assembly time
|
|
9
|
+
- Updated `assemble-functions.sh` — generates `handler-registry.ts` with static imports of all `custom_*.ts` handlers so esbuild bundles them into `integration-routes`
|
|
10
|
+
- Updated `integration-routes.ts` — replaced dynamic `resolveHandler` import with static `HANDLER_REGISTRY` lookup for esbuild-compatible handler loading
|
|
11
|
+
- Removed `loadHandler` and `resolveHandler` from `webhook-registry.ts` — no longer needed with static registry pattern
|
|
12
|
+
|
|
13
|
+
## [0.3.15] — 2026-06-09
|
|
14
|
+
- Fixed `upsertIntegrations` in install-app.ts — now explicitly picks only valid DB columns (name, slug, provider, status, is_active, config) instead of spreading entire record, preventing "description column not found" errors
|
|
15
|
+
|
|
7
16
|
## [0.3.14] — 2026-06-09
|
|
8
17
|
- Fixed `integrations.json` handler config format — changed `"handler": "funnel-signal"` to `"handler": { "path": "funnel-signal" }` to match `integration-routes.ts` step 8 lookup at `config.handler?.path`
|
|
9
18
|
- Removed orphaned `on_funnel_signal_created` trigger from `triggers.json` — the trigger engine routes exclusively through `runPipeline(trigger.pipeline_id, ...)` and has no path to directly invoke a custom function; scoring now happens inline in `custom_funnel-signal.ts`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-app.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/install-app.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"install-app.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/install-app.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA+nBxC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,QAgB1D"}
|
|
@@ -221,21 +221,21 @@ export type { ValidationSchema } from './schema-utils';
|
|
|
221
221
|
*/
|
|
222
222
|
export { emitAudit } from './audit';
|
|
223
223
|
/**
|
|
224
|
-
*
|
|
224
|
+
* lookupHandler — look up webhook handler metadata by name.
|
|
225
225
|
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
226
|
+
* Queries the webhook_handlers table for handler registration info.
|
|
227
|
+
* Actual handler loading is done via HANDLER_REGISTRY static imports.
|
|
228
228
|
*
|
|
229
229
|
* @param handlerName — The handler identifier from webhook_handlers table
|
|
230
|
-
* @returns Handler
|
|
230
|
+
* @returns Handler metadata or null if not found
|
|
231
231
|
*
|
|
232
232
|
* @example
|
|
233
233
|
* ```ts
|
|
234
|
-
* const
|
|
235
|
-
* if (
|
|
234
|
+
* const meta = await lookupHandler('cortex-webhook')
|
|
235
|
+
* if (meta) console.log(meta.functionName)
|
|
236
236
|
* ```
|
|
237
237
|
*/
|
|
238
|
-
export {
|
|
238
|
+
export { lookupHandler } from './webhook-registry';
|
|
239
239
|
/**
|
|
240
240
|
* registerWebhookHandler — self-register a custom webhook handler.
|
|
241
241
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAMH;;;;;;;;;;;;;GAaG;AACH,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C;;;GAGG;AACH,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAElF;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,IAAI,EAAE,KAAK,IAAI,aAAa,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAMnI;;GAEG;AACH,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C;;;GAGG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3D;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C;;GAEG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD;;GAEG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEjD;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAM9C;;;GAGG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE9B;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAEhC;;;GAGG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAA;AAE5B,YAAY,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAMpC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAMrE;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnH,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMjD;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAC7D,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAMxF;;;;;;;;GAQG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAGrD,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAM9F;;;GAGG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAMtD;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMnC;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAMH;;;;;;;;;;;;;GAaG;AACH,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C;;;GAGG;AACH,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAElF;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,IAAI,EAAE,KAAK,IAAI,aAAa,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAMnI;;GAEG;AACH,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C;;;GAGG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3D;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C;;GAEG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD;;GAEG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEjD;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAM9C;;;GAGG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE9B;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAEhC;;;GAGG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAA;AAE5B,YAAY,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAMpC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAMrE;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnH,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMjD;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAC7D,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAMxF;;;;;;;;GAQG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAGrD,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAM9F;;;GAGG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAMtD;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMnC;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC9G,YAAY,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAA;AAMxE;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACvG,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAM1D;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,eAAe,EACf,aAAa,EACb,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,OAAO,EACP,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEvE,OAAO,EACL,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACtB,MAAM,eAAe,CAAA"}
|
|
@@ -30,22 +30,6 @@
|
|
|
30
30
|
export declare function lookupHandler(handlerName: string): Promise<{
|
|
31
31
|
functionName: string;
|
|
32
32
|
} | null>;
|
|
33
|
-
/**
|
|
34
|
-
* Loads a webhook handler function dynamically.
|
|
35
|
-
* Uses dynamic import to avoid static dependencies.
|
|
36
|
-
*
|
|
37
|
-
* @param functionName - The Netlify function name (e.g., "custom_cortex-handler")
|
|
38
|
-
* @returns The handler function or null if not found
|
|
39
|
-
*/
|
|
40
|
-
export declare function loadHandler(functionName: string): Promise<Function | null>;
|
|
41
|
-
/**
|
|
42
|
-
* Resolves a webhook handler by name.
|
|
43
|
-
* Combines lookup + load for convenience.
|
|
44
|
-
*
|
|
45
|
-
* @param handlerName - The handler identifier
|
|
46
|
-
* @returns The handler function or null
|
|
47
|
-
*/
|
|
48
|
-
export declare function resolveHandler(handlerName: string): Promise<Function | null>;
|
|
49
33
|
/**
|
|
50
34
|
* Clears the handler cache. Useful for testing or after deployments.
|
|
51
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-registry.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/webhook-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BjG;AAED
|
|
1
|
+
{"version":3,"file":"webhook-registry.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/webhook-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BjG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAYhE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module handler-registry
|
|
3
|
+
* @audience core-contributor
|
|
4
|
+
* @layer shared-service
|
|
5
|
+
* @stability stable
|
|
6
|
+
*
|
|
7
|
+
* Static handler registry for esbuild-compatible dynamic dispatch.
|
|
8
|
+
*
|
|
9
|
+
* **THIS FILE IS OVERWRITTEN AT ASSEMBLY TIME.**
|
|
10
|
+
* The stub here (empty registry) is replaced by `assemble-functions.sh`
|
|
11
|
+
* with static imports of every `custom_*.ts` handler found in the assembled
|
|
12
|
+
* functions directory. esbuild can then bundle all handlers into the
|
|
13
|
+
* `integration-routes` function at build time — no runtime dynamic imports.
|
|
14
|
+
*
|
|
15
|
+
* Keys are the handler path (e.g. "funnel-signal") AND the full file name
|
|
16
|
+
* (e.g. "custom_funnel-signal") so lookups work either way.
|
|
17
|
+
*
|
|
18
|
+
* @seeAlso scripts/assemble-functions.sh (generates this file)
|
|
19
|
+
* @seeAlso integration-routes.ts (consumes HANDLER_REGISTRY)
|
|
20
|
+
*/
|
|
21
|
+
export declare const HANDLER_REGISTRY: Record<string, any>;
|
|
22
|
+
//# sourceMappingURL=handler-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-registry.d.ts","sourceRoot":"","sources":["../../.framework/functions/handler-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-routes.d.ts","sourceRoot":"","sources":["../../.framework/functions/integration-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;
|
|
1
|
+
{"version":3,"file":"integration-routes.d.ts","sourceRoot":"","sources":["../../.framework/functions/integration-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AA0eH,QAAA,MAAM,OAAO,UA9P4B,GAAG,YAAY,GAAG;;;;;;EA8PzB,CAAA;AAClC,OAAO,EAAE,OAAO,EAAE,CAAA"}
|
package/package.json
CHANGED
|
@@ -69,5 +69,37 @@ rm -rf "$TARGET_DIR"
|
|
|
69
69
|
mkdir -p "$(dirname "$TARGET_DIR")"
|
|
70
70
|
mv "$TMP_DIR" "$TARGET_DIR"
|
|
71
71
|
|
|
72
|
+
# 5. Generate handler-registry.ts — static imports of all custom_* handlers
|
|
73
|
+
# This replaces the stub in handler-registry.ts so esbuild can bundle all
|
|
74
|
+
# handlers into integration-routes at build time (no runtime dynamic imports).
|
|
75
|
+
REGISTRY_FILE="$TARGET_DIR/handler-registry.ts"
|
|
76
|
+
{
|
|
77
|
+
echo "// AUTO-GENERATED by assemble-functions.sh — do not edit manually"
|
|
78
|
+
echo "// Overrides the stub in .framework/functions/handler-registry.ts"
|
|
79
|
+
echo ""
|
|
80
|
+
|
|
81
|
+
# Collect all custom_*.ts handler files
|
|
82
|
+
HANDLER_NAMES=()
|
|
83
|
+
for f in "$TARGET_DIR"/custom_*.ts; do
|
|
84
|
+
[ -f "$f" ] || continue
|
|
85
|
+
name=$(basename "$f" .ts)
|
|
86
|
+
HANDLER_NAMES+=("$name")
|
|
87
|
+
var=$(echo "$name" | tr '-' '_')
|
|
88
|
+
echo "import * as ${var} from './${name}'"
|
|
89
|
+
done
|
|
90
|
+
|
|
91
|
+
echo ""
|
|
92
|
+
echo "export const HANDLER_REGISTRY: Record<string, any> = {"
|
|
93
|
+
|
|
94
|
+
for name in "${HANDLER_NAMES[@]}"; do
|
|
95
|
+
var=$(echo "$name" | tr '-' '_')
|
|
96
|
+
stripped="${name#custom_}"
|
|
97
|
+
echo " '${name}': ${var},"
|
|
98
|
+
echo " '${stripped}': ${var},"
|
|
99
|
+
done
|
|
100
|
+
|
|
101
|
+
echo "}"
|
|
102
|
+
} > "$REGISTRY_FILE"
|
|
103
|
+
|
|
72
104
|
echo " ✓ Assembled: $(find "$TARGET_DIR" -name '*.ts' ! -name '*-test.ts' ! -name '*.test.ts' | wc -l | tr -d ' ') total functions"
|
|
73
105
|
echo "✅ Done"
|
|
@@ -29,9 +29,11 @@ echo ""
|
|
|
29
29
|
|
|
30
30
|
# Check 2: Core importing custom_ prefixed modules
|
|
31
31
|
# signal.ts is excluded: it uses a guarded dynamic import to optionally load a custom handler at runtime.
|
|
32
|
+
# handler-registry.ts is excluded: it's a core stub that gets generated at assembly time.
|
|
32
33
|
echo "2. Checking for custom_ module imports in core..."
|
|
33
34
|
if grep -r "from.*custom_\|import.*custom_" .framework/ --include="*.ts" --include="*.tsx" 2>/dev/null \
|
|
34
|
-
| grep -v "signal\.ts:"
|
|
35
|
+
| grep -v "signal\.ts:" \
|
|
36
|
+
| grep -v "handler-registry\.ts:"; then
|
|
35
37
|
echo " ❌ FAIL: Core files import custom_ modules"
|
|
36
38
|
VIOLATIONS=$((VIOLATIONS + 1))
|
|
37
39
|
else
|
|
@@ -74,13 +76,13 @@ else
|
|
|
74
76
|
fi
|
|
75
77
|
echo ""
|
|
76
78
|
|
|
77
|
-
# Check 5: Verify webhook registry is used (
|
|
78
|
-
echo "5. Checking integration-routes uses
|
|
79
|
+
# Check 5: Verify webhook registry pattern is used (dynamic lookup + static HANDLER_REGISTRY)
|
|
80
|
+
echo "5. Checking integration-routes uses registry pattern..."
|
|
79
81
|
if grep -q "webhookHandlers\|custom_webhook-handlers" .framework/functions/integration-routes.ts 2>/dev/null; then
|
|
80
|
-
echo " ❌ FAIL: integration-routes
|
|
82
|
+
echo " ❌ FAIL: integration-routes uses old static imports"
|
|
81
83
|
VIOLATIONS=$((VIOLATIONS + 1))
|
|
82
84
|
else
|
|
83
|
-
echo " ✅ PASS: integration-routes uses
|
|
85
|
+
echo " ✅ PASS: integration-routes uses registry pattern"
|
|
84
86
|
fi
|
|
85
87
|
echo ""
|
|
86
88
|
|