Quality Pass 3: Code Templates TS/JS + HTTP TLS/mTLS + channel-script tests - #40
Merged
Conversation
Code Templates were hard-locked to JavaScript in the editor. Added a persisted `language` field threaded schema→DB(migration 0011, defaults JAVASCRIPT)→service →client→TemplateEditor→ScriptEditor (new onLanguageChange callback surfaces the JS/TS toggle). No engine change — the compiler already transpiles TS. Tests: schema (default/valid/invalid), service (language threaded into insert). Also adds engine channel-script tests (12): preprocessor happy/mutate/return-true regression/throw, postprocessor reads-response/throw-surfaces. (Deploy/undeploy execution lives server-side in engine.ts — documented.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F1ad6jb5mCYxzFVXHbksqi
The HTTP dispatcher sent via global fetch with no way to trust a custom/internal CA, present a client cert (mTLS), or control verification. Added TLS support following the existing connector tls.ts pattern (TlsClientOptions + readTlsClientOptions, same as TCP/MLLP): an https URL carrying TLS material now routes through node:https.request (undici isn't a dep, so fetch can't apply per-request TLS), applying ca/cert/key/rejectUnauthorized; plain HTTP and HTTPS-without-custom-TLS keep the fetch path unchanged. rejectUnauthorized defaults true; TLS/verification errors surface as a failed Result (never a false SENT). Web HTTP-destination form gains a TLS/Certificates section (CA/client cert/key PEM + reject-unauthorized toggle). 5 new dispatcher tests against a real node:https server (trusted-CA, rejectUnauthorized:false, self-signed rejected, mTLS verification failure, body over HTTPS). Note: inline PEM (consistent with TCP/MLLP); referencing the Certificate store is a follow-up (no connector cert-resolution wiring exists yet). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F1ad6jb5mCYxzFVXHbksqi
There was a problem hiding this comment.
Pull request overview
This PR completes a “Quality Pass 3” by (1) persisting per-template JS/TS authoring language, (2) adding per-destination TLS/mTLS capabilities to the HTTP dispatcher + web form, and (3) expanding engine coverage for channel-level pre/postprocessor scripts.
Changes:
- Code templates: add a persisted
languagefield end-to-end (schema → migration → service → client → editors) with default backfill toJAVASCRIPT. - HTTP destination: add TLS options (custom CA, client cert/key, rejectUnauthorized) with a fetch-vs-
node:httpssplit and new HTTPS-focused tests. - Engine: add channel preprocessor/postprocessor tests covering return-value behavior and error surfacing.
Reviewed changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/web/src/pages/CodeTemplatePage.tsx | Includes language when creating/updating templates from the UI. |
| packages/web/src/pages/tests/GlobalScriptsPage.test.tsx | Adjusts a mock-call assertion indexing style. |
| packages/web/src/components/editors/ScriptEditor.tsx | Exposes ScriptLanguage and adds onLanguageChange callback wiring. |
| packages/web/src/components/code-templates/TemplateEditor.tsx | Persists JS/TS toggle selection into template edits and dirty-checking. |
| packages/web/src/components/channels/destinations/HttpDestinationForm.tsx | Adds TLS/Certificates UI fields and nested tls updates. |
| packages/web/src/components/channels/destinations/connector-defaults.ts | Adds HTTP destination default tls shape (ca/cert/key/rejectUnauthorized). |
| packages/web/src/api/client.ts | Extends CodeTemplateDetail with language. |
| packages/server/src/services/code-template.service.ts | Threads language through template CRUD responses/inserts/updates. |
| packages/server/src/services/tests/code-template.service.test.ts | Adds service test coverage for persisting language on insert. |
| packages/server/src/db/schema/code-templates.ts | Adds language column with default JAVASCRIPT. |
| packages/server/src/db/migrations/meta/0011_snapshot.json | Drizzle migration snapshot capturing the new column. |
| packages/server/src/db/migrations/meta/_journal.json | Registers migration 0011 in the migration journal. |
| packages/server/src/db/migrations/0011_workable_cannonball.sql | Adds language column to code_templates. |
| packages/engine/src/pipeline/tests/channel-scripts.test.ts | Adds focused tests for channel pre/postprocessor behavior and error handling. |
| packages/core-models/src/schemas/code-template.schema.ts | Adds language enum + defaults/validation to create/update schemas. |
| packages/core-models/src/schemas/tests/code-template.schema.test.ts | Adds schema tests for language defaulting and validation. |
| packages/connectors/src/registry.ts | Threads tls options into the HTTP destination runtime config. |
| packages/connectors/src/http/http-dispatcher.ts | Adds TLS-aware HTTPS send path via node:https.request. |
| packages/connectors/src/http/tests/http-dispatcher.test.ts | Adds HTTPS/TLS tests using a real node:https server and fixture PEMs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+151
to
+155
| res.on('end', () => { | ||
| const responseBody = Buffer.concat(chunks).toString('utf-8'); | ||
| const status = res.statusCode ?? 0; | ||
| if (status >= 200 && status < 300) { | ||
| resolve({ status: 'SENT', content: responseBody }); |
Comment on lines
+335
to
+339
| it('surfaces a TLS verification failure over node:https as a failed Result', async () => { | ||
| await startHttpsServer(); | ||
|
|
||
| // Client cert activates the node:https path; with verification ON and the | ||
| // server's self-signed cert NOT in the trust store, verification must fail. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Quality Pass 3 — features + channel-script coverage
Final P1 pass, completing the P0+P1 program from the testing-gaps audit.
Code Templates: per-template TypeScript/JavaScript
Templates were hard-locked to JS in the editor. Added a persisted
languagefield threaded schema → DB (migration 0011, defaultsJAVASCRIPTso existing rows backfill) → service → client type → TemplateEditor → ScriptEditor (newonLanguageChangecallback surfaces the JS/TS toggle that was previously display-only). No engine change — the sandbox already transpiles every script as TypeScript. Tests: schema (default/valid/invalid), service (language threaded into insert).HTTP destination: TLS / mTLS / custom CA
The HTTP dispatcher sent via global
fetchwith no way to trust an internal CA, present a client cert (mTLS), or control verification — you couldn't securely reach an internal HTTPS endpoint. Added TLS following the existingtls.tsconnector pattern (sameTlsClientOptionsas TCP/MLLP): an https URL carrying TLS material routes throughnode:https.request(undici isn't a dependency, sofetchcan't apply per-request TLS); plain HTTP and HTTPS-without-custom-TLS keep thefetchpath unchanged.rejectUnauthorizeddefaults true; TLS/verification errors surface as a failed Result, never a false SENT. Web HTTP-destination form gains a TLS/Certificates section. 5 new dispatcher tests against a realnode:httpsserver (trusted-CA, rejectUnauthorized:false, self-signed rejected, mTLS failure, body over HTTPS). Inline PEM (consistent with TCP/MLLP); referencing the Certificate store is a noted follow-up.Channel-level script tests
12 engine tests for the message-flow channel scripts: preprocessor (string replaces msg;
return true/false/undefined leave it intact — regression for the boolean-return corruption bug; throw → ERROR) and postprocessor (reads the routed response; throw surfaces as ERROR, not silently swallowed). Found + documented that deploy/undeploy scripts execute server-side (engine.ts, log-and-continue), not in the engine package.Verification
Server 998, engine 372, connectors 491, web 99, core-models 256; integration 25. Full lint clean; per-package typechecks pass. Migration 0011 applied to dev + test DBs.
Program status
P0+P1 complete across Passes 1–3. Deferred (plan-only): P2 items (Alerts JS/TS filtering — design locked, fail-loud, IO-bridge context; Traffic "Search" tab finish; docs cleanup; missing connector checklists; grids filter/sort polish) and RBAC Round 2 (admin role CRUD → roles-as-data, then sub-resource ACLs).
🤖 Generated with Claude Code
https://claude.ai/code/session_01F1ad6jb5mCYxzFVXHbksqi