@inkeep/agents-core 0.41.2 → 0.43.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/dist/api-client/base-client.d.ts +87 -8
- package/dist/api-client/base-client.js +174 -1
- package/dist/api-client/eval-api-client.d.ts +47 -0
- package/dist/api-client/eval-api-client.js +65 -0
- package/dist/api-client/index.d.ts +4 -0
- package/dist/api-client/index.js +5 -0
- package/dist/api-client/manage-api-client.d.ts +34 -0
- package/dist/api-client/manage-api-client.js +104 -0
- package/dist/auth/auth.d.ts +86 -20
- package/dist/auth/auth.js +60 -2
- package/dist/auth/authz/client.d.ts +87 -0
- package/dist/auth/authz/client.js +196 -0
- package/dist/auth/authz/config.d.ts +103 -0
- package/dist/auth/authz/config.js +93 -0
- package/dist/auth/authz/index.d.ts +5 -0
- package/dist/auth/authz/index.js +6 -0
- package/dist/auth/authz/permissions.d.ts +53 -0
- package/dist/auth/authz/permissions.js +83 -0
- package/dist/auth/authz/sync.d.ts +106 -0
- package/dist/auth/authz/sync.js +321 -0
- package/dist/auth/permissions.d.ts +13 -13
- package/dist/auth/permissions.js +2 -181
- package/dist/client-exports.d.ts +9 -3
- package/dist/client-exports.js +4 -2
- package/dist/constants/context-breakdown.d.ts +61 -0
- package/dist/constants/context-breakdown.js +124 -0
- package/dist/constants/execution-limits-shared/defaults.d.ts +1 -1
- package/dist/constants/execution-limits-shared/defaults.js +1 -1
- package/dist/constants/execution-limits-shared/index.d.ts +1 -1
- package/dist/constants/otel-attributes.d.ts +4 -0
- package/dist/constants/otel-attributes.js +4 -0
- package/dist/context/ContextConfig.d.ts +2 -2
- package/dist/context/ContextConfig.js +3 -3
- package/dist/context/TemplateEngine.d.ts +0 -6
- package/dist/context/TemplateEngine.js +4 -19
- package/dist/context/index.d.ts +1 -5
- package/dist/context/index.js +1 -5
- package/dist/credential-stores/keychain-store.d.ts +20 -8
- package/dist/credential-stores/keychain-store.js +107 -43
- package/dist/credential-stuffer/CredentialStuffer.d.ts +1 -1
- package/dist/data-access/index.d.ts +34 -26
- package/dist/data-access/index.js +34 -26
- package/dist/data-access/manage/agentFull.d.ts +36 -0
- package/dist/data-access/{agentFull.js → manage/agentFull.js} +209 -7
- package/dist/data-access/{agents.d.ts → manage/agents.d.ts} +64 -63
- package/dist/data-access/{agents.js → manage/agents.js} +80 -27
- package/dist/data-access/{artifactComponents.d.ts → manage/artifactComponents.d.ts} +33 -33
- package/dist/data-access/{artifactComponents.js → manage/artifactComponents.js} +5 -5
- package/dist/data-access/{contextConfigs.d.ts → manage/contextConfigs.d.ts} +26 -26
- package/dist/data-access/{contextConfigs.js → manage/contextConfigs.js} +3 -3
- package/dist/data-access/{credentialReferences.d.ts → manage/credentialReferences.d.ts} +17 -17
- package/dist/data-access/{credentialReferences.js → manage/credentialReferences.js} +2 -2
- package/dist/data-access/{dataComponents.d.ts → manage/dataComponents.d.ts} +26 -26
- package/dist/data-access/{dataComponents.js → manage/dataComponents.js} +7 -7
- package/dist/data-access/manage/evalConfig.d.ts +221 -0
- package/dist/data-access/manage/evalConfig.js +275 -0
- package/dist/data-access/{externalAgents.d.ts → manage/externalAgents.d.ts} +16 -16
- package/dist/data-access/{externalAgents.js → manage/externalAgents.js} +2 -2
- package/dist/data-access/manage/functionTools.d.ts +242 -0
- package/dist/data-access/{functionTools.js → manage/functionTools.js} +124 -30
- package/dist/data-access/{functions.d.ts → manage/functions.d.ts} +9 -9
- package/dist/data-access/{functions.js → manage/functions.js} +3 -3
- package/dist/data-access/manage/projectFull.d.ts +38 -0
- package/dist/data-access/{projectFull.js → manage/projectFull.js} +64 -65
- package/dist/data-access/manage/projectLifecycle.d.ts +119 -0
- package/dist/data-access/manage/projectLifecycle.js +234 -0
- package/dist/data-access/manage/projects.d.ts +75 -0
- package/dist/data-access/{projects.js → manage/projects.js} +15 -16
- package/dist/data-access/{subAgentExternalAgentRelations.d.ts → manage/subAgentExternalAgentRelations.d.ts} +43 -43
- package/dist/data-access/{subAgentExternalAgentRelations.js → manage/subAgentExternalAgentRelations.js} +2 -2
- package/dist/data-access/{subAgentRelations.d.ts → manage/subAgentRelations.d.ts} +65 -65
- package/dist/data-access/{subAgentRelations.js → manage/subAgentRelations.js} +3 -3
- package/dist/data-access/{subAgentTeamAgentRelations.d.ts → manage/subAgentTeamAgentRelations.d.ts} +43 -43
- package/dist/data-access/{subAgentTeamAgentRelations.js → manage/subAgentTeamAgentRelations.js} +2 -2
- package/dist/data-access/{subAgents.d.ts → manage/subAgents.d.ts} +28 -28
- package/dist/data-access/{subAgents.js → manage/subAgents.js} +4 -4
- package/dist/data-access/{tools.d.ts → manage/tools.d.ts} +65 -52
- package/dist/data-access/{tools.js → manage/tools.js} +109 -64
- package/dist/data-access/manage/triggers.d.ts +106 -0
- package/dist/data-access/manage/triggers.js +81 -0
- package/dist/data-access/{apiKeys.d.ts → runtime/apiKeys.d.ts} +37 -37
- package/dist/data-access/{apiKeys.js → runtime/apiKeys.js} +3 -3
- package/dist/data-access/runtime/cascade-delete.d.ts +77 -0
- package/dist/data-access/runtime/cascade-delete.js +111 -0
- package/dist/data-access/{contextCache.d.ts → runtime/contextCache.d.ts} +13 -13
- package/dist/data-access/{contextCache.js → runtime/contextCache.js} +5 -5
- package/dist/data-access/{conversations.d.ts → runtime/conversations.d.ts} +80 -31
- package/dist/data-access/{conversations.js → runtime/conversations.js} +13 -7
- package/dist/data-access/runtime/evalRuns.d.ts +120 -0
- package/dist/data-access/runtime/evalRuns.js +168 -0
- package/dist/data-access/{ledgerArtifacts.d.ts → runtime/ledgerArtifacts.d.ts} +13 -13
- package/dist/data-access/{ledgerArtifacts.js → runtime/ledgerArtifacts.js} +3 -3
- package/dist/data-access/{messages.d.ts → runtime/messages.d.ts} +24 -24
- package/dist/data-access/{messages.js → runtime/messages.js} +2 -2
- package/dist/data-access/{organizations.d.ts → runtime/organizations.d.ts} +16 -7
- package/dist/data-access/{organizations.js → runtime/organizations.js} +16 -4
- package/dist/data-access/runtime/projects.d.ts +62 -0
- package/dist/data-access/runtime/projects.js +90 -0
- package/dist/data-access/runtime/tasks.d.ts +55 -0
- package/dist/data-access/{tasks.js → runtime/tasks.js} +2 -2
- package/dist/data-access/runtime/triggerInvocations.d.ts +62 -0
- package/dist/data-access/runtime/triggerInvocations.js +54 -0
- package/dist/data-access/runtime/users.d.ts +19 -0
- package/dist/data-access/{users.js → runtime/users.js} +2 -2
- package/dist/data-access/validation.d.ts +4 -4
- package/dist/data-access/validation.js +1 -1
- package/dist/db/clean.d.ts +8 -4
- package/dist/db/clean.js +14 -105
- package/dist/db/delete.d.ts +1 -1
- package/dist/db/delete.js +7 -10
- package/dist/db/manage/dolt-cleanup.d.ts +51 -0
- package/dist/db/manage/dolt-cleanup.js +132 -0
- package/dist/db/manage/manage-client.d.ts +26 -0
- package/dist/db/manage/manage-client.js +68 -0
- package/dist/db/{schema.d.ts → manage/manage-schema.d.ts} +1257 -969
- package/dist/db/{schema.js → manage/manage-schema.js} +436 -334
- package/dist/db/manage/test-manage-client.d.ts +27 -0
- package/dist/db/manage/test-manage-client.js +68 -0
- package/dist/db/runtime/runtime-client.d.ts +20 -0
- package/dist/db/runtime/runtime-client.js +30 -0
- package/dist/db/runtime/runtime-schema.d.ts +2834 -0
- package/dist/db/runtime/runtime-schema.js +483 -0
- package/dist/db/runtime/test-runtime-client.d.ts +27 -0
- package/dist/db/{test-client.js → runtime/test-runtime-client.js} +11 -25
- package/dist/db/utils.d.ts +6 -0
- package/dist/db/utils.js +42 -0
- package/dist/dolt/branch.d.ts +62 -0
- package/dist/dolt/branch.js +82 -0
- package/dist/dolt/branches-api.d.ts +108 -0
- package/dist/dolt/branches-api.js +162 -0
- package/dist/dolt/commit.d.ts +94 -0
- package/dist/dolt/commit.js +103 -0
- package/dist/dolt/diff.d.ts +27 -0
- package/dist/dolt/diff.js +21 -0
- package/dist/dolt/index.d.ts +10 -0
- package/dist/dolt/index.js +11 -0
- package/dist/dolt/merge.d.ts +63 -0
- package/dist/dolt/merge.js +81 -0
- package/dist/dolt/migrate-all-branches.d.ts +4 -0
- package/dist/dolt/migrate-all-branches.js +83 -0
- package/dist/dolt/migrate-dolt.d.ts +1 -0
- package/dist/dolt/migrate-dolt.js +25 -0
- package/dist/dolt/ref-helpers.d.ts +19 -0
- package/dist/dolt/ref-helpers.js +65 -0
- package/dist/dolt/ref-middleware.d.ts +82 -0
- package/dist/dolt/ref-middleware.js +217 -0
- package/dist/dolt/ref-scope.d.ts +101 -0
- package/dist/dolt/ref-scope.js +231 -0
- package/dist/dolt/schema-sync.d.ts +135 -0
- package/dist/dolt/schema-sync.js +255 -0
- package/dist/env.d.ts +6 -4
- package/dist/env.js +3 -2
- package/dist/index.d.ts +73 -46
- package/dist/index.js +76 -49
- package/dist/types/@napi-rs__keyring/index.d.ts +14 -0
- package/dist/types/entities.d.ts +81 -2
- package/dist/types/index.d.ts +3 -3
- package/dist/types/utility.d.ts +46 -5
- package/dist/types/utility.js +2 -1
- package/dist/utils/JsonTransformer.d.ts +42 -0
- package/dist/utils/JsonTransformer.js +103 -0
- package/dist/utils/apiKeys.d.ts +5 -1
- package/dist/utils/apiKeys.js +11 -1
- package/dist/utils/colors.d.ts +34 -0
- package/dist/utils/colors.js +49 -0
- package/dist/utils/credential-store-utils.d.ts +1 -1
- package/dist/utils/format-messages.d.ts +1 -1
- package/dist/utils/index.d.ts +8 -4
- package/dist/utils/index.js +8 -4
- package/dist/utils/internal-service-auth.d.ts +79 -0
- package/dist/utils/internal-service-auth.js +140 -0
- package/dist/utils/jmespath-utils.d.ts +152 -0
- package/dist/utils/jmespath-utils.js +213 -0
- package/dist/utils/jwt-helpers.d.ts +56 -0
- package/dist/utils/jwt-helpers.js +90 -0
- package/dist/utils/mcp-client.d.ts +1 -1
- package/dist/utils/mcp-client.js +1 -1
- package/dist/utils/service-token-auth.d.ts +9 -27
- package/dist/utils/service-token-auth.js +48 -96
- package/dist/utils/signature-validation.d.ts +2 -0
- package/dist/utils/signature-validation.js +3 -0
- package/dist/utils/template-interpolation.d.ts +22 -0
- package/dist/utils/template-interpolation.js +62 -0
- package/dist/utils/third-party-mcp-servers/composio-client.d.ts +13 -1
- package/dist/utils/third-party-mcp-servers/composio-client.js +47 -29
- package/dist/utils/third-party-mcp-servers/index.d.ts +2 -2
- package/dist/utils/third-party-mcp-servers/index.js +2 -2
- package/dist/utils/trigger-auth.d.ts +85 -0
- package/dist/utils/trigger-auth.js +233 -0
- package/dist/validation/agentFull.js +2 -4
- package/dist/validation/dolt-schemas.d.ts +49 -0
- package/dist/validation/dolt-schemas.js +44 -0
- package/dist/validation/drizzle-schema-helpers.d.ts +4 -26
- package/dist/validation/drizzle-schema-helpers.js +5 -151
- package/dist/validation/index.d.ts +5 -4
- package/dist/validation/index.js +4 -3
- package/dist/validation/render-validation.js +19 -0
- package/dist/validation/schemas.d.ts +18223 -5148
- package/dist/validation/schemas.js +559 -12
- package/dist/validation/stream-event-schemas.d.ts +96 -1
- package/dist/validation/stream-event-schemas.js +67 -2
- package/drizzle/manage/0000_tearful_rhodey.sql +414 -0
- package/drizzle/manage/0001_broken_wendell_vaughn.sql +19 -0
- package/drizzle/manage/0002_bent_sunfire.sql +1 -0
- package/drizzle/manage/0003_tiny_captain_universe.sql +8 -0
- package/drizzle/manage/0004_curious_phil_sheldon.sql +2 -0
- package/drizzle/manage/0005_silent_shatterstar.sql +53 -0
- package/drizzle/manage/meta/0000_snapshot.json +2987 -0
- package/drizzle/manage/meta/0001_snapshot.json +3115 -0
- package/drizzle/manage/meta/0002_snapshot.json +3115 -0
- package/drizzle/manage/meta/0003_snapshot.json +3134 -0
- package/drizzle/manage/meta/0004_snapshot.json +3141 -0
- package/drizzle/manage/meta/0005_snapshot.json +3141 -0
- package/drizzle/manage/meta/_journal.json +48 -0
- package/drizzle/runtime/0008_silly_preak.sql +127 -0
- package/drizzle/runtime/0009_freezing_leo.sql +17 -0
- package/drizzle/runtime/meta/0008_snapshot.json +2263 -0
- package/drizzle/runtime/meta/0009_snapshot.json +2397 -0
- package/drizzle/{meta → runtime/meta}/_journal.json +14 -0
- package/package.json +56 -18
- package/spicedb/schema.zed +114 -0
- package/dist/context/ContextFetcher.d.ts +0 -73
- package/dist/context/ContextFetcher.js +0 -291
- package/dist/context/ContextResolver.d.ts +0 -60
- package/dist/context/ContextResolver.js +0 -278
- package/dist/context/context.d.ts +0 -27
- package/dist/context/context.js +0 -128
- package/dist/context/contextCache.d.ts +0 -58
- package/dist/context/contextCache.js +0 -177
- package/dist/data-access/agentFull.d.ts +0 -33
- package/dist/data-access/functionTools.d.ts +0 -169
- package/dist/data-access/projectFull.d.ts +0 -32
- package/dist/data-access/projects.d.ts +0 -71
- package/dist/data-access/tasks.d.ts +0 -45
- package/dist/data-access/users.d.ts +0 -19
- package/dist/db/client.d.ts +0 -20
- package/dist/db/client.js +0 -28
- package/dist/db/test-client.d.ts +0 -31
- package/dist/middleware/contextValidation.d.ts +0 -46
- package/dist/middleware/contextValidation.js +0 -280
- package/dist/middleware/index.d.ts +0 -2
- package/dist/middleware/index.js +0 -3
- package/dist/utils/execution.d.ts +0 -22
- package/dist/utils/execution.js +0 -25
- /package/drizzle/{0000_exotic_mysterio.sql → runtime/0000_exotic_mysterio.sql} +0 -0
- /package/drizzle/{0001_calm_sheva_callister.sql → runtime/0001_calm_sheva_callister.sql} +0 -0
- /package/drizzle/{0002_puzzling_goblin_queen.sql → runtime/0002_puzzling_goblin_queen.sql} +0 -0
- /package/drizzle/{0003_sweet_human_robot.sql → runtime/0003_sweet_human_robot.sql} +0 -0
- /package/drizzle/{0004_cuddly_shooting_star.sql → runtime/0004_cuddly_shooting_star.sql} +0 -0
- /package/drizzle/{0005_reflective_starfox.sql → runtime/0005_reflective_starfox.sql} +0 -0
- /package/drizzle/{0006_stale_thaddeus_ross.sql → runtime/0006_stale_thaddeus_ross.sql} +0 -0
- /package/drizzle/{0007_slim_karma.sql → runtime/0007_slim_karma.sql} +0 -0
- /package/drizzle/{meta → runtime/meta}/0000_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0001_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0003_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0005_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0006_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0007_snapshot.json +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { SignatureVerificationConfig, TriggerAuthHeaderInputSchema, TriggerAuthHeaderStoredSchema, TriggerAuthenticationStoredSchema } from "../validation/schemas.js";
|
|
2
|
+
import { Context } from "hono";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/trigger-auth.d.ts
|
|
6
|
+
type TriggerAuthHeaderInput = z.infer<typeof TriggerAuthHeaderInputSchema>;
|
|
7
|
+
type TriggerAuthHeaderStored = z.infer<typeof TriggerAuthHeaderStoredSchema>;
|
|
8
|
+
type TriggerAuthenticationStored = z.infer<typeof TriggerAuthenticationStoredSchema>;
|
|
9
|
+
interface TriggerAuthResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
status?: number;
|
|
12
|
+
message?: string;
|
|
13
|
+
}
|
|
14
|
+
interface HashedHeaderValue {
|
|
15
|
+
valueHash: string;
|
|
16
|
+
valuePrefix: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Hash a header value using scrypt for secure storage.
|
|
20
|
+
* Returns the hash and a prefix for display purposes.
|
|
21
|
+
*
|
|
22
|
+
* @param value - The plaintext header value to hash
|
|
23
|
+
* @returns Object containing valueHash (for storage) and valuePrefix (for display)
|
|
24
|
+
*/
|
|
25
|
+
declare function hashTriggerHeaderValue(value: string): Promise<HashedHeaderValue>;
|
|
26
|
+
/**
|
|
27
|
+
* Validate a header value against its stored hash using timing-safe comparison.
|
|
28
|
+
*
|
|
29
|
+
* @param value - The plaintext header value from the incoming request
|
|
30
|
+
* @param storedHash - The hash stored in the database
|
|
31
|
+
* @returns True if the value matches the hash
|
|
32
|
+
*/
|
|
33
|
+
declare function validateTriggerHeaderValue(value: string, storedHash: string): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Transform authentication input (plaintext values) to stored format (hashed values).
|
|
36
|
+
* Used when creating or updating triggers.
|
|
37
|
+
*
|
|
38
|
+
* @param headers - Array of header inputs with plaintext values
|
|
39
|
+
* @returns Array of headers with hashed values for storage
|
|
40
|
+
*/
|
|
41
|
+
declare function hashAuthenticationHeaders(headers: TriggerAuthHeaderInput[]): Promise<TriggerAuthHeaderStored[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Verifies incoming webhook requests using the configured authentication headers.
|
|
44
|
+
* Each configured header must be present and match its expected value (via hash comparison).
|
|
45
|
+
*
|
|
46
|
+
* @param c - Hono context containing the request headers
|
|
47
|
+
* @param authentication - Trigger authentication configuration with hashed header values
|
|
48
|
+
* @returns TriggerAuthResult indicating success/failure with appropriate HTTP status
|
|
49
|
+
*/
|
|
50
|
+
declare function verifyTriggerAuth(c: Context, authentication?: TriggerAuthenticationStored | null): Promise<TriggerAuthResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Error codes for signature verification failures.
|
|
53
|
+
*/
|
|
54
|
+
type SignatureVerificationErrorCode = 'MISSING_SIGNATURE' | 'MISSING_COMPONENT' | 'INVALID_SIGNATURE_FORMAT' | 'SIGNATURE_MISMATCH';
|
|
55
|
+
interface SignatureVerificationResult {
|
|
56
|
+
success: boolean;
|
|
57
|
+
errorCode?: SignatureVerificationErrorCode;
|
|
58
|
+
status?: number;
|
|
59
|
+
message?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Verifies webhook signature using flexible, provider-agnostic configuration.
|
|
63
|
+
* Supports GitHub, Slack, Zendesk, Stripe and other webhook signature schemes.
|
|
64
|
+
*
|
|
65
|
+
* SECURITY: Uses crypto.timingSafeEqual() for all signature comparisons to prevent timing attacks.
|
|
66
|
+
*
|
|
67
|
+
* @param c - Hono context containing request headers, query, and body
|
|
68
|
+
* @param config - Signature verification configuration
|
|
69
|
+
* @param signingSecret - HMAC signing secret
|
|
70
|
+
* @param body - Raw request body as string
|
|
71
|
+
* @returns SignatureVerificationResult with success status and error details
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // GitHub webhook verification
|
|
75
|
+
* const result = verifySignatureWithConfig(c, {
|
|
76
|
+
* algorithm: 'sha256',
|
|
77
|
+
* encoding: 'hex',
|
|
78
|
+
* signature: { source: 'header', key: 'x-hub-signature-256', prefix: 'sha256=' },
|
|
79
|
+
* signedComponents: [{ source: 'body', key: '@' }],
|
|
80
|
+
* componentJoin: { strategy: 'concatenate', separator: '' }
|
|
81
|
+
* }, secret, body);
|
|
82
|
+
*/
|
|
83
|
+
declare function verifySignatureWithConfig(c: Context, config: SignatureVerificationConfig, signingSecret: string, body: string): SignatureVerificationResult;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { HashedHeaderValue, SignatureVerificationErrorCode, SignatureVerificationResult, TriggerAuthResult, hashAuthenticationHeaders, hashTriggerHeaderValue, validateTriggerHeaderValue, verifySignatureWithConfig, verifyTriggerAuth };
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { searchJMESPath } from "./jmespath-utils.js";
|
|
2
|
+
import { createHmac, randomBytes, scrypt, timingSafeEqual } from "node:crypto";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/trigger-auth.ts
|
|
6
|
+
const scryptAsync = promisify(scrypt);
|
|
7
|
+
const SALT_LENGTH = 32;
|
|
8
|
+
const KEY_LENGTH = 64;
|
|
9
|
+
const VALUE_PREFIX_LENGTH = 8;
|
|
10
|
+
/**
|
|
11
|
+
* Hash a header value using scrypt for secure storage.
|
|
12
|
+
* Returns the hash and a prefix for display purposes.
|
|
13
|
+
*
|
|
14
|
+
* @param value - The plaintext header value to hash
|
|
15
|
+
* @returns Object containing valueHash (for storage) and valuePrefix (for display)
|
|
16
|
+
*/
|
|
17
|
+
async function hashTriggerHeaderValue(value) {
|
|
18
|
+
const salt = randomBytes(SALT_LENGTH);
|
|
19
|
+
const hashedBuffer = await scryptAsync(value, salt, KEY_LENGTH);
|
|
20
|
+
return {
|
|
21
|
+
valueHash: Buffer.concat([salt, hashedBuffer]).toString("base64"),
|
|
22
|
+
valuePrefix: value.substring(0, VALUE_PREFIX_LENGTH)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validate a header value against its stored hash using timing-safe comparison.
|
|
27
|
+
*
|
|
28
|
+
* @param value - The plaintext header value from the incoming request
|
|
29
|
+
* @param storedHash - The hash stored in the database
|
|
30
|
+
* @returns True if the value matches the hash
|
|
31
|
+
*/
|
|
32
|
+
async function validateTriggerHeaderValue(value, storedHash) {
|
|
33
|
+
try {
|
|
34
|
+
const combined = Buffer.from(storedHash, "base64");
|
|
35
|
+
const salt = combined.subarray(0, SALT_LENGTH);
|
|
36
|
+
return timingSafeEqual(combined.subarray(SALT_LENGTH), await scryptAsync(value, salt, KEY_LENGTH));
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Transform authentication input (plaintext values) to stored format (hashed values).
|
|
43
|
+
* Used when creating or updating triggers.
|
|
44
|
+
*
|
|
45
|
+
* @param headers - Array of header inputs with plaintext values
|
|
46
|
+
* @returns Array of headers with hashed values for storage
|
|
47
|
+
*/
|
|
48
|
+
async function hashAuthenticationHeaders(headers) {
|
|
49
|
+
return Promise.all(headers.map(async (header) => {
|
|
50
|
+
const { valueHash, valuePrefix } = await hashTriggerHeaderValue(header.value);
|
|
51
|
+
return {
|
|
52
|
+
name: header.name,
|
|
53
|
+
valueHash,
|
|
54
|
+
valuePrefix
|
|
55
|
+
};
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Verifies incoming webhook requests using the configured authentication headers.
|
|
60
|
+
* Each configured header must be present and match its expected value (via hash comparison).
|
|
61
|
+
*
|
|
62
|
+
* @param c - Hono context containing the request headers
|
|
63
|
+
* @param authentication - Trigger authentication configuration with hashed header values
|
|
64
|
+
* @returns TriggerAuthResult indicating success/failure with appropriate HTTP status
|
|
65
|
+
*/
|
|
66
|
+
async function verifyTriggerAuth(c, authentication) {
|
|
67
|
+
if (!authentication || !authentication.headers || authentication.headers.length === 0) return { success: true };
|
|
68
|
+
for (const header of authentication.headers) {
|
|
69
|
+
const headerName = header.name.toLowerCase();
|
|
70
|
+
const actualValue = c.req.header(headerName);
|
|
71
|
+
if (!actualValue) return {
|
|
72
|
+
success: false,
|
|
73
|
+
status: 401,
|
|
74
|
+
message: `Missing authentication header: ${header.name}`
|
|
75
|
+
};
|
|
76
|
+
if (!await validateTriggerHeaderValue(actualValue, header.valueHash)) return {
|
|
77
|
+
success: false,
|
|
78
|
+
status: 403,
|
|
79
|
+
message: `Invalid value for header: ${header.name}`
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return { success: true };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Extracts the signature from the request based on configuration.
|
|
86
|
+
* Supports extraction from headers, query parameters, or body via JMESPath.
|
|
87
|
+
* Optionally strips prefix and applies regex extraction.
|
|
88
|
+
*
|
|
89
|
+
* @param c - Hono context
|
|
90
|
+
* @param config - Signature verification configuration
|
|
91
|
+
* @param body - Raw request body as string
|
|
92
|
+
* @returns Extracted signature string or null if not found
|
|
93
|
+
*/
|
|
94
|
+
function extractSignature(c, config, body) {
|
|
95
|
+
const { signature } = config;
|
|
96
|
+
const caseSensitive = config.validation?.headerCaseSensitive ?? false;
|
|
97
|
+
let value;
|
|
98
|
+
if (signature.source === "header") {
|
|
99
|
+
const headerKey = caseSensitive ? signature.key : signature.key.toLowerCase();
|
|
100
|
+
value = c.req.header(headerKey);
|
|
101
|
+
} else if (signature.source === "query") value = c.req.query(signature.key);
|
|
102
|
+
else if (signature.source === "body") try {
|
|
103
|
+
value = searchJMESPath(JSON.parse(body), signature.key);
|
|
104
|
+
} catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
if (!value) return null;
|
|
108
|
+
if (signature.prefix && value.startsWith(signature.prefix)) value = value.slice(signature.prefix.length);
|
|
109
|
+
if (signature.regex) try {
|
|
110
|
+
const match = value.match(new RegExp(signature.regex));
|
|
111
|
+
if (match?.[1]) value = match[1];
|
|
112
|
+
else return null;
|
|
113
|
+
} catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Extracts a single signed component from the request.
|
|
120
|
+
*
|
|
121
|
+
* @param c - Hono context
|
|
122
|
+
* @param component - Component configuration
|
|
123
|
+
* @param body - Raw request body as string
|
|
124
|
+
* @param caseSensitive - Whether header names should be case-sensitive
|
|
125
|
+
* @returns Extracted component value or null if required and not found
|
|
126
|
+
*/
|
|
127
|
+
function extractComponent(c, component, body, caseSensitive) {
|
|
128
|
+
let value;
|
|
129
|
+
if (component.source === "literal") value = component.value ?? "";
|
|
130
|
+
else if (component.source === "header") {
|
|
131
|
+
if (!component.key) return component.required ? null : "";
|
|
132
|
+
const headerKey = caseSensitive ? component.key : component.key.toLowerCase();
|
|
133
|
+
value = c.req.header(headerKey);
|
|
134
|
+
} else if (component.source === "body") if (!component.key) value = body;
|
|
135
|
+
else try {
|
|
136
|
+
value = searchJMESPath(JSON.parse(body), component.key);
|
|
137
|
+
} catch {
|
|
138
|
+
return component.required ? null : "";
|
|
139
|
+
}
|
|
140
|
+
if (value === void 0 || value === null) return component.required ? null : "";
|
|
141
|
+
value = String(value);
|
|
142
|
+
if (component.regex) try {
|
|
143
|
+
const match = value.match(new RegExp(component.regex));
|
|
144
|
+
if (match?.[1]) value = match[1];
|
|
145
|
+
else return component.required ? null : "";
|
|
146
|
+
} catch {
|
|
147
|
+
return component.required ? null : "";
|
|
148
|
+
}
|
|
149
|
+
return value;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Verifies webhook signature using flexible, provider-agnostic configuration.
|
|
153
|
+
* Supports GitHub, Slack, Zendesk, Stripe and other webhook signature schemes.
|
|
154
|
+
*
|
|
155
|
+
* SECURITY: Uses crypto.timingSafeEqual() for all signature comparisons to prevent timing attacks.
|
|
156
|
+
*
|
|
157
|
+
* @param c - Hono context containing request headers, query, and body
|
|
158
|
+
* @param config - Signature verification configuration
|
|
159
|
+
* @param signingSecret - HMAC signing secret
|
|
160
|
+
* @param body - Raw request body as string
|
|
161
|
+
* @returns SignatureVerificationResult with success status and error details
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* // GitHub webhook verification
|
|
165
|
+
* const result = verifySignatureWithConfig(c, {
|
|
166
|
+
* algorithm: 'sha256',
|
|
167
|
+
* encoding: 'hex',
|
|
168
|
+
* signature: { source: 'header', key: 'x-hub-signature-256', prefix: 'sha256=' },
|
|
169
|
+
* signedComponents: [{ source: 'body', key: '@' }],
|
|
170
|
+
* componentJoin: { strategy: 'concatenate', separator: '' }
|
|
171
|
+
* }, secret, body);
|
|
172
|
+
*/
|
|
173
|
+
function verifySignatureWithConfig(c, config, signingSecret, body) {
|
|
174
|
+
const caseSensitive = config.validation?.headerCaseSensitive ?? false;
|
|
175
|
+
const allowEmptyBody = config.validation?.allowEmptyBody ?? true;
|
|
176
|
+
const normalizeUnicode = config.validation?.normalizeUnicode ?? false;
|
|
177
|
+
const signature = extractSignature(c, config, body);
|
|
178
|
+
if (!signature) return {
|
|
179
|
+
success: false,
|
|
180
|
+
errorCode: "MISSING_SIGNATURE",
|
|
181
|
+
status: 401,
|
|
182
|
+
message: "Missing or invalid signature"
|
|
183
|
+
};
|
|
184
|
+
const components = [];
|
|
185
|
+
for (const componentConfig of config.signedComponents) {
|
|
186
|
+
const componentValue = extractComponent(c, componentConfig, body, caseSensitive);
|
|
187
|
+
if (componentValue === null) return {
|
|
188
|
+
success: false,
|
|
189
|
+
errorCode: "MISSING_COMPONENT",
|
|
190
|
+
status: 400,
|
|
191
|
+
message: "Missing required signed component"
|
|
192
|
+
};
|
|
193
|
+
components.push(componentValue);
|
|
194
|
+
}
|
|
195
|
+
let signedData = components.join(config.componentJoin.separator);
|
|
196
|
+
if (normalizeUnicode) signedData = signedData.normalize("NFC");
|
|
197
|
+
if (!allowEmptyBody && signedData === "") return {
|
|
198
|
+
success: false,
|
|
199
|
+
errorCode: "MISSING_COMPONENT",
|
|
200
|
+
status: 400,
|
|
201
|
+
message: "Empty body not allowed"
|
|
202
|
+
};
|
|
203
|
+
const hmac = createHmac(config.algorithm, signingSecret);
|
|
204
|
+
hmac.update(signedData);
|
|
205
|
+
const expectedSignature = hmac.digest(config.encoding);
|
|
206
|
+
try {
|
|
207
|
+
const signatureBuffer = Buffer.from(signature, config.encoding);
|
|
208
|
+
const expectedBuffer = Buffer.from(expectedSignature, config.encoding);
|
|
209
|
+
if (signatureBuffer.length !== expectedBuffer.length) return {
|
|
210
|
+
success: false,
|
|
211
|
+
errorCode: "SIGNATURE_MISMATCH",
|
|
212
|
+
status: 403,
|
|
213
|
+
message: "Invalid signature"
|
|
214
|
+
};
|
|
215
|
+
if (!timingSafeEqual(signatureBuffer, expectedBuffer)) return {
|
|
216
|
+
success: false,
|
|
217
|
+
errorCode: "SIGNATURE_MISMATCH",
|
|
218
|
+
status: 403,
|
|
219
|
+
message: "Invalid signature"
|
|
220
|
+
};
|
|
221
|
+
return { success: true };
|
|
222
|
+
} catch {
|
|
223
|
+
return {
|
|
224
|
+
success: false,
|
|
225
|
+
errorCode: "INVALID_SIGNATURE_FORMAT",
|
|
226
|
+
status: 403,
|
|
227
|
+
message: "Invalid signature format"
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
//#endregion
|
|
233
|
+
export { hashAuthenticationHeaders, hashTriggerHeaderValue, validateTriggerHeaderValue, verifySignatureWithConfig, verifyTriggerAuth };
|
|
@@ -53,10 +53,8 @@ function validateAgentRelationships(agentData) {
|
|
|
53
53
|
if (subAgent.canTransferTo && Array.isArray(subAgent.canTransferTo)) {
|
|
54
54
|
for (const targetId of subAgent.canTransferTo) if (!availableAgentIds.has(targetId)) errors.push(`Agent '${subAgentId}' has transfer target '${targetId}' that doesn't exist in agent`);
|
|
55
55
|
}
|
|
56
|
-
if (subAgent.canDelegateTo && Array.isArray(subAgent.canDelegateTo))
|
|
57
|
-
|
|
58
|
-
if (typeof targetItem === "string") {
|
|
59
|
-
console.log("targetItem is string", targetItem);
|
|
56
|
+
if (subAgent.canDelegateTo && Array.isArray(subAgent.canDelegateTo)) {
|
|
57
|
+
for (const targetItem of subAgent.canDelegateTo) if (typeof targetItem === "string") {
|
|
60
58
|
if (!availableAgentIds.has(targetItem) && !availableExternalAgentIds.has(targetItem)) errors.push(`Agent '${subAgentId}' has delegation target '${targetItem}' that doesn't exist in agent`);
|
|
61
59
|
}
|
|
62
60
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
|
|
3
|
+
//#region src/validation/dolt-schemas.d.ts
|
|
4
|
+
declare const BranchNameSchema: z.ZodString;
|
|
5
|
+
declare const CreateBranchRequestSchema: z.ZodObject<{
|
|
6
|
+
name: z.ZodString;
|
|
7
|
+
from: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
declare const BranchInfoSchema: z.ZodObject<{
|
|
10
|
+
baseName: z.ZodString;
|
|
11
|
+
fullName: z.ZodString;
|
|
12
|
+
hash: z.ZodString;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
declare const BranchResponseSchema: z.ZodObject<{
|
|
15
|
+
data: z.ZodObject<{
|
|
16
|
+
baseName: z.ZodString;
|
|
17
|
+
fullName: z.ZodString;
|
|
18
|
+
hash: z.ZodString;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
declare const BranchListResponseSchema: z.ZodObject<{
|
|
22
|
+
data: z.ZodArray<z.ZodObject<{
|
|
23
|
+
baseName: z.ZodString;
|
|
24
|
+
fullName: z.ZodString;
|
|
25
|
+
hash: z.ZodString;
|
|
26
|
+
}, z.core.$strip>>;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
declare const BranchNameParamsSchema: z.ZodObject<{
|
|
29
|
+
tenantId: z.ZodString;
|
|
30
|
+
projectId: z.ZodString;
|
|
31
|
+
branchName: z.ZodString;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
declare const ResolvedRefSchema: z.ZodObject<{
|
|
34
|
+
type: z.ZodEnum<{
|
|
35
|
+
commit: "commit";
|
|
36
|
+
tag: "tag";
|
|
37
|
+
branch: "branch";
|
|
38
|
+
}>;
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
hash: z.ZodString;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
type ResolvedRef = z.infer<typeof ResolvedRefSchema>;
|
|
43
|
+
type CreateBranchRequest = z.infer<typeof CreateBranchRequestSchema>;
|
|
44
|
+
type BranchInfo = z.infer<typeof BranchInfoSchema>;
|
|
45
|
+
type BranchResponse = z.infer<typeof BranchResponseSchema>;
|
|
46
|
+
type BranchListResponse = z.infer<typeof BranchListResponseSchema>;
|
|
47
|
+
type BranchNameParams = z.infer<typeof BranchNameParamsSchema>;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { BranchInfo, BranchInfoSchema, BranchListResponse, BranchListResponseSchema, BranchNameParams, BranchNameParamsSchema, BranchNameSchema, BranchResponse, BranchResponseSchema, CreateBranchRequest, CreateBranchRequestSchema, ResolvedRef, ResolvedRefSchema };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
|
|
3
|
+
//#region src/validation/dolt-schemas.ts
|
|
4
|
+
const BranchNameSchema = z.string().min(1, "Branch name cannot be empty").max(255, "Branch name too long").regex(/^[a-zA-Z0-9\-_./]+$/, { message: "Branch name can only contain letters, numbers, hyphens, underscores, dots, and slashes" }).openapi({
|
|
5
|
+
example: "feature-x",
|
|
6
|
+
description: "Name of the branch"
|
|
7
|
+
});
|
|
8
|
+
const CreateBranchRequestSchema = z.object({
|
|
9
|
+
name: BranchNameSchema,
|
|
10
|
+
from: z.string().optional().describe("Branch or commit to create from. Defaults to tenant main branch.")
|
|
11
|
+
}).openapi("CreateBranchRequest");
|
|
12
|
+
const BranchInfoSchema = z.object({
|
|
13
|
+
baseName: z.string().describe("User-provided branch name"),
|
|
14
|
+
fullName: z.string().describe("Full namespaced branch name"),
|
|
15
|
+
hash: z.string().describe("Current commit hash of the branch")
|
|
16
|
+
}).openapi("BranchInfo");
|
|
17
|
+
const BranchResponseSchema = z.object({ data: BranchInfoSchema }).openapi("BranchResponse");
|
|
18
|
+
const BranchListResponseSchema = z.object({ data: z.array(BranchInfoSchema) }).openapi("BranchListResponse");
|
|
19
|
+
const BranchNameParamsSchema = z.object({
|
|
20
|
+
tenantId: z.string().openapi({ param: {
|
|
21
|
+
name: "tenantId",
|
|
22
|
+
in: "path"
|
|
23
|
+
} }),
|
|
24
|
+
projectId: z.string().openapi({ param: {
|
|
25
|
+
name: "projectId",
|
|
26
|
+
in: "path"
|
|
27
|
+
} }),
|
|
28
|
+
branchName: z.string().openapi({ param: {
|
|
29
|
+
name: "branchName",
|
|
30
|
+
in: "path"
|
|
31
|
+
} })
|
|
32
|
+
}).openapi("BranchNameParams");
|
|
33
|
+
const ResolvedRefSchema = z.object({
|
|
34
|
+
type: z.enum([
|
|
35
|
+
"commit",
|
|
36
|
+
"tag",
|
|
37
|
+
"branch"
|
|
38
|
+
]).describe("The type of ref"),
|
|
39
|
+
name: z.string().describe("The name of the ref (branch name, tag name, or commit hash)"),
|
|
40
|
+
hash: z.string().describe("The commit hash this ref resolves to")
|
|
41
|
+
}).openapi("ResolvedRef");
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { BranchInfoSchema, BranchListResponseSchema, BranchNameParamsSchema, BranchNameSchema, BranchResponseSchema, CreateBranchRequestSchema, ResolvedRefSchema };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "@hono/zod-openapi";
|
|
2
|
-
import * as
|
|
2
|
+
import * as drizzle_zod15 from "drizzle-zod";
|
|
3
3
|
import { AnySQLiteTable } from "drizzle-orm/sqlite-core";
|
|
4
4
|
|
|
5
5
|
//#region src/validation/drizzle-schema-helpers.d.ts
|
|
@@ -22,8 +22,8 @@ declare const resourceIdSchema: z.ZodString;
|
|
|
22
22
|
declare function createResourceIdSchema(description: string, options?: {
|
|
23
23
|
example?: string;
|
|
24
24
|
}): z.ZodString;
|
|
25
|
-
declare function createSelectSchemaWithModifiers<T extends AnySQLiteTable>(table: T, overrides?: Partial<Record<keyof T['_']['columns'], (schema: z.ZodTypeAny) => z.ZodTypeAny>>):
|
|
26
|
-
declare function createInsertSchemaWithModifiers<T extends AnySQLiteTable>(table: T, overrides?: Partial<Record<keyof T['_']['columns'], (schema: z.ZodTypeAny) => z.ZodTypeAny>>):
|
|
25
|
+
declare function createSelectSchemaWithModifiers<T extends AnySQLiteTable>(table: T, overrides?: Partial<Record<keyof T['_']['columns'], (schema: z.ZodTypeAny) => z.ZodTypeAny>>): drizzle_zod15.BuildSchema<"select", T["_"]["columns"], drizzle_zod15.BuildRefine<T["_"]["columns"], undefined>, undefined>;
|
|
26
|
+
declare function createInsertSchemaWithModifiers<T extends AnySQLiteTable>(table: T, overrides?: Partial<Record<keyof T['_']['columns'], (schema: z.ZodTypeAny) => z.ZodTypeAny>>): drizzle_zod15.BuildSchema<"insert", T["_"]["columns"], drizzle_zod15.BuildRefine<Pick<T["_"]["columns"], keyof T["$inferInsert"]>, undefined>, undefined>;
|
|
27
27
|
declare const createSelectSchema: typeof createSelectSchemaWithModifiers;
|
|
28
28
|
declare const createInsertSchema: typeof createInsertSchemaWithModifiers;
|
|
29
29
|
/**
|
|
@@ -38,27 +38,5 @@ declare const createInsertSchema: typeof createInsertSchemaWithModifiers;
|
|
|
38
38
|
* The schema shape itself is not modified, but the field schemas are registered.
|
|
39
39
|
*/
|
|
40
40
|
declare function registerFieldSchemas<T extends z.ZodObject<any>>(schema: T): T;
|
|
41
|
-
/**
|
|
42
|
-
* Wrapper for .partial() that registers the resulting schema and its fields in the global registry.
|
|
43
|
-
* This function ensures that field schemas are properly registered and configured with OpenAPI metadata.
|
|
44
|
-
*/
|
|
45
|
-
declare function partialWithRegistry<T extends z.ZodObject<any>>(schema: T, metadata?: {
|
|
46
|
-
description?: string;
|
|
47
|
-
[key: string]: unknown;
|
|
48
|
-
}): T;
|
|
49
|
-
/**
|
|
50
|
-
* Wrapper for .omit() that registers the resulting schema and its fields in the global registry
|
|
51
|
-
*/
|
|
52
|
-
declare function omitWithRegistry<T extends z.ZodObject<any>>(schema: T, keys: z.ZodObject<any>['shape'], metadata?: {
|
|
53
|
-
description?: string;
|
|
54
|
-
[key: string]: unknown;
|
|
55
|
-
}): T;
|
|
56
|
-
/**
|
|
57
|
-
* Wrapper for .extend() that registers the resulting schema and its fields in the global registry
|
|
58
|
-
*/
|
|
59
|
-
declare function extendWithRegistry<T extends z.ZodObject<any>>(schema: T, shape: z.ZodRawShape, metadata?: {
|
|
60
|
-
description?: string;
|
|
61
|
-
[key: string]: unknown;
|
|
62
|
-
}): T;
|
|
63
41
|
//#endregion
|
|
64
|
-
export { MAX_ID_LENGTH, MIN_ID_LENGTH, URL_SAFE_ID_PATTERN, createInsertSchema, createResourceIdSchema, createSelectSchema,
|
|
42
|
+
export { MAX_ID_LENGTH, MIN_ID_LENGTH, URL_SAFE_ID_PATTERN, createInsertSchema, createResourceIdSchema, createSelectSchema, registerFieldSchemas, resourceIdSchema };
|
|
@@ -31,95 +31,17 @@ function createResourceIdSchema(description, options) {
|
|
|
31
31
|
modified.meta({ description });
|
|
32
32
|
return modified;
|
|
33
33
|
}
|
|
34
|
-
const FIELD_MODIFIERS = {
|
|
35
|
-
id: (schema) => {
|
|
36
|
-
const modified = schema.min(MIN_ID_LENGTH).max(MAX_ID_LENGTH).describe("Resource identifier").regex(URL_SAFE_ID_PATTERN, { message: "ID must contain only letters, numbers, hyphens, underscores, and dots" }).openapi({
|
|
37
|
-
description: "Resource identifier",
|
|
38
|
-
example: "resource_789"
|
|
39
|
-
});
|
|
40
|
-
modified.meta({ description: "Resource identifier" });
|
|
41
|
-
return modified;
|
|
42
|
-
},
|
|
43
|
-
name: (_schema) => {
|
|
44
|
-
const modified = z.string().describe("Name");
|
|
45
|
-
modified.meta({ description: "Name" });
|
|
46
|
-
return modified;
|
|
47
|
-
},
|
|
48
|
-
description: (_schema) => {
|
|
49
|
-
const modified = z.string().describe("Description");
|
|
50
|
-
modified.meta({ description: "Description" });
|
|
51
|
-
return modified;
|
|
52
|
-
},
|
|
53
|
-
tenantId: (schema) => {
|
|
54
|
-
const modified = schema.describe("Tenant identifier");
|
|
55
|
-
modified.meta({ description: "Tenant identifier" });
|
|
56
|
-
return modified;
|
|
57
|
-
},
|
|
58
|
-
projectId: (schema) => {
|
|
59
|
-
const modified = schema.describe("Project identifier");
|
|
60
|
-
modified.meta({ description: "Project identifier" });
|
|
61
|
-
return modified;
|
|
62
|
-
},
|
|
63
|
-
agentId: (schema) => {
|
|
64
|
-
const modified = schema.describe("Agent identifier");
|
|
65
|
-
modified.meta({ description: "Agent identifier" });
|
|
66
|
-
return modified;
|
|
67
|
-
},
|
|
68
|
-
subAgentId: (schema) => {
|
|
69
|
-
const modified = schema.describe("Sub-agent identifier");
|
|
70
|
-
modified.meta({ description: "Sub-agent identifier" });
|
|
71
|
-
return modified;
|
|
72
|
-
},
|
|
73
|
-
createdAt: (schema) => {
|
|
74
|
-
const modified = schema.describe("Creation timestamp");
|
|
75
|
-
modified.meta({ description: "Creation timestamp" });
|
|
76
|
-
return modified;
|
|
77
|
-
},
|
|
78
|
-
updatedAt: (schema) => {
|
|
79
|
-
const modified = schema.describe("Last update timestamp");
|
|
80
|
-
modified.meta({ description: "Last update timestamp" });
|
|
81
|
-
return modified;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
34
|
function createSelectSchemaWithModifiers(table, overrides) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const tableFieldNames = Object.keys(tableColumns);
|
|
88
|
-
const modifiers = {};
|
|
89
|
-
for (const fieldName of tableFieldNames) {
|
|
90
|
-
const fieldNameStr = String(fieldName);
|
|
91
|
-
if (fieldNameStr in FIELD_MODIFIERS) modifiers[fieldNameStr] = FIELD_MODIFIERS[fieldNameStr];
|
|
92
|
-
}
|
|
93
|
-
return createSelectSchema$1(table, {
|
|
94
|
-
...modifiers,
|
|
95
|
-
...overrides
|
|
96
|
-
});
|
|
35
|
+
if (!table._?.columns) return createSelectSchema$1(table, overrides);
|
|
36
|
+
throw new Error("Unexpected \"tableColumns\" is defined");
|
|
97
37
|
}
|
|
98
38
|
function createInsertSchemaWithModifiers(table, overrides) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const tableFieldNames = Object.keys(tableColumns);
|
|
102
|
-
const modifiers = {};
|
|
103
|
-
for (const fieldName of tableFieldNames) {
|
|
104
|
-
const fieldNameStr = String(fieldName);
|
|
105
|
-
if (fieldNameStr in FIELD_MODIFIERS) modifiers[fieldNameStr] = FIELD_MODIFIERS[fieldNameStr];
|
|
106
|
-
}
|
|
107
|
-
return createInsertSchema$1(table, {
|
|
108
|
-
...modifiers,
|
|
109
|
-
...overrides
|
|
110
|
-
});
|
|
39
|
+
if (!table._?.columns) return createInsertSchema$1(table, overrides);
|
|
40
|
+
throw new Error("Unexpected \"tableColumns\" is defined");
|
|
111
41
|
}
|
|
112
42
|
const createSelectSchema = createSelectSchemaWithModifiers;
|
|
113
43
|
const createInsertSchema = createInsertSchemaWithModifiers;
|
|
114
44
|
/**
|
|
115
|
-
* Helper function to register a schema in the global registry using .meta() and return it.
|
|
116
|
-
* This ensures metadata persists through transformations.
|
|
117
|
-
*/
|
|
118
|
-
function registerSchema(schema, metadata) {
|
|
119
|
-
schema.meta(metadata);
|
|
120
|
-
return schema;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
45
|
* Registers all field schemas in an object schema that match known field names.
|
|
124
46
|
* This ensures metadata persists through transformations like .partial() and .omit().
|
|
125
47
|
* For the 'id' field, also applies full validation constraints via .openapi().
|
|
@@ -164,74 +86,6 @@ function registerFieldSchemas(schema) {
|
|
|
164
86
|
}
|
|
165
87
|
return schema;
|
|
166
88
|
}
|
|
167
|
-
/**
|
|
168
|
-
* Wrapper for .partial() that registers the resulting schema and its fields in the global registry.
|
|
169
|
-
* This function ensures that field schemas are properly registered and configured with OpenAPI metadata.
|
|
170
|
-
*/
|
|
171
|
-
function partialWithRegistry(schema, metadata) {
|
|
172
|
-
const partialSchema = schema.partial();
|
|
173
|
-
registerFieldSchemas(partialSchema);
|
|
174
|
-
const shape = partialSchema.shape;
|
|
175
|
-
const newShape = {};
|
|
176
|
-
const fieldMetadata = {
|
|
177
|
-
id: { description: "Resource identifier" },
|
|
178
|
-
name: { description: "Name" },
|
|
179
|
-
description: { description: "Description" },
|
|
180
|
-
tenantId: { description: "Tenant identifier" },
|
|
181
|
-
projectId: { description: "Project identifier" },
|
|
182
|
-
agentId: { description: "Agent identifier" },
|
|
183
|
-
subAgentId: { description: "Sub-agent identifier" },
|
|
184
|
-
createdAt: { description: "Creation timestamp" },
|
|
185
|
-
updatedAt: { description: "Last update timestamp" }
|
|
186
|
-
};
|
|
187
|
-
for (const [fieldName, fieldSchema] of Object.entries(shape)) {
|
|
188
|
-
let configuredSchema = fieldSchema;
|
|
189
|
-
if (fieldName in fieldMetadata) {
|
|
190
|
-
let innerSchema;
|
|
191
|
-
const isOptional = configuredSchema instanceof z.ZodOptional;
|
|
192
|
-
if (isOptional) innerSchema = configuredSchema._def.innerType;
|
|
193
|
-
else innerSchema = configuredSchema;
|
|
194
|
-
if (fieldName === "id" && innerSchema instanceof z.ZodString) {
|
|
195
|
-
const configuredId = innerSchema.min(MIN_ID_LENGTH).max(MAX_ID_LENGTH).describe("Resource identifier").regex(URL_SAFE_ID_PATTERN, { message: "ID must contain only letters, numbers, hyphens, underscores, and dots" }).openapi({
|
|
196
|
-
description: "Resource identifier",
|
|
197
|
-
minLength: MIN_ID_LENGTH,
|
|
198
|
-
maxLength: MAX_ID_LENGTH,
|
|
199
|
-
pattern: URL_SAFE_ID_PATTERN.source,
|
|
200
|
-
example: "resource_789"
|
|
201
|
-
});
|
|
202
|
-
configuredId.meta({ description: "Resource identifier" });
|
|
203
|
-
configuredSchema = isOptional ? configuredId.optional() : configuredId;
|
|
204
|
-
} else if (innerSchema instanceof z.ZodString) {
|
|
205
|
-
const configuredField = innerSchema.describe(fieldMetadata[fieldName].description).openapi({ description: fieldMetadata[fieldName].description });
|
|
206
|
-
configuredField.meta(fieldMetadata[fieldName]);
|
|
207
|
-
configuredSchema = isOptional ? configuredField.optional() : configuredField;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
newShape[fieldName] = configuredSchema;
|
|
211
|
-
}
|
|
212
|
-
const reconstructedSchema = partialSchema.extend(newShape).partial();
|
|
213
|
-
registerFieldSchemas(reconstructedSchema);
|
|
214
|
-
if (metadata) registerSchema(reconstructedSchema, metadata);
|
|
215
|
-
return reconstructedSchema;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Wrapper for .omit() that registers the resulting schema and its fields in the global registry
|
|
219
|
-
*/
|
|
220
|
-
function omitWithRegistry(schema, keys, metadata) {
|
|
221
|
-
const omittedSchema = schema.omit(keys);
|
|
222
|
-
registerFieldSchemas(omittedSchema);
|
|
223
|
-
if (metadata) registerSchema(omittedSchema, metadata);
|
|
224
|
-
return omittedSchema;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Wrapper for .extend() that registers the resulting schema and its fields in the global registry
|
|
228
|
-
*/
|
|
229
|
-
function extendWithRegistry(schema, shape, metadata) {
|
|
230
|
-
const extendedSchema = schema.extend(shape);
|
|
231
|
-
registerFieldSchemas(extendedSchema);
|
|
232
|
-
if (metadata) registerSchema(extendedSchema, metadata);
|
|
233
|
-
return extendedSchema;
|
|
234
|
-
}
|
|
235
89
|
|
|
236
90
|
//#endregion
|
|
237
|
-
export { MAX_ID_LENGTH, MIN_ID_LENGTH, URL_SAFE_ID_PATTERN, createInsertSchema, createResourceIdSchema, createSelectSchema,
|
|
91
|
+
export { MAX_ID_LENGTH, MIN_ID_LENGTH, URL_SAFE_ID_PATTERN, createInsertSchema, createResourceIdSchema, createSelectSchema, registerFieldSchemas, resourceIdSchema };
|