@gencow/core 0.1.27 → 0.1.29

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 (130) hide show
  1. package/dist/auth-config.d.ts +92 -5
  2. package/dist/config.d.ts +107 -0
  3. package/dist/config.js +12 -0
  4. package/dist/context.d.ts +139 -0
  5. package/dist/context.js +3 -0
  6. package/dist/crud.d.ts +5 -5
  7. package/dist/crud.js +19 -35
  8. package/dist/document-types.d.ts +65 -0
  9. package/dist/document-types.js +15 -0
  10. package/dist/grounded-answer-types.d.ts +62 -0
  11. package/dist/grounded-answer-types.js +6 -0
  12. package/dist/http-action.d.ts +77 -0
  13. package/dist/http-action.js +41 -0
  14. package/dist/index.d.ts +30 -5
  15. package/dist/index.js +15 -2
  16. package/dist/platform-capacity-profile.d.ts +19 -0
  17. package/dist/platform-capacity-profile.js +94 -0
  18. package/dist/procedure.d.ts +58 -0
  19. package/dist/procedure.js +115 -0
  20. package/dist/rag-ingest-types.d.ts +39 -0
  21. package/dist/rag-ingest-types.js +1 -0
  22. package/dist/rag-operations-types.d.ts +81 -0
  23. package/dist/rag-operations-types.js +1 -0
  24. package/dist/rag-schema.d.ts +1466 -0
  25. package/dist/rag-schema.js +87 -0
  26. package/dist/reactive-mutation-types.d.ts +11 -0
  27. package/dist/reactive-mutation-types.js +1 -0
  28. package/dist/reactive-mutation.d.ts +51 -0
  29. package/dist/reactive-mutation.js +75 -0
  30. package/dist/reactive-query-types.d.ts +12 -0
  31. package/dist/reactive-query-types.js +1 -0
  32. package/dist/reactive-query.d.ts +14 -0
  33. package/dist/reactive-query.js +28 -0
  34. package/dist/reactive-realtime.d.ts +48 -0
  35. package/dist/reactive-realtime.js +236 -0
  36. package/dist/reactive.d.ts +29 -5
  37. package/dist/reactive.js +65 -0
  38. package/dist/rls-db.d.ts +9 -2
  39. package/dist/runtime-env-policy.d.ts +5 -0
  40. package/dist/runtime-env-policy.js +56 -0
  41. package/dist/search-types.d.ts +83 -0
  42. package/dist/search-types.js +1 -0
  43. package/dist/server.d.ts +1 -2
  44. package/dist/server.js +0 -1
  45. package/dist/storage-metering.d.ts +13 -0
  46. package/dist/storage-metering.js +18 -0
  47. package/dist/storage-shared.d.ts +36 -0
  48. package/dist/storage-shared.js +39 -0
  49. package/dist/storage.d.ts +5 -27
  50. package/dist/storage.js +30 -22
  51. package/dist/wake-app-result.d.ts +22 -0
  52. package/dist/wake-app-result.js +11 -0
  53. package/dist/workflow-types.d.ts +16 -2
  54. package/dist/workflow.d.ts +1 -1
  55. package/dist/workflow.js +136 -11
  56. package/dist/workflows-api.js +71 -3
  57. package/package.json +11 -7
  58. package/src/auth-config.ts +104 -3
  59. package/src/config.ts +119 -0
  60. package/src/context.ts +152 -0
  61. package/src/crud.ts +18 -35
  62. package/src/document-types.ts +102 -0
  63. package/src/grounded-answer-types.ts +78 -0
  64. package/src/http-action.ts +101 -0
  65. package/src/index.ts +142 -19
  66. package/src/platform-capacity-profile.ts +114 -0
  67. package/src/procedure.ts +283 -0
  68. package/src/rag-ingest-types.ts +52 -0
  69. package/src/rag-operations-types.ts +90 -0
  70. package/src/rag-schema.ts +94 -0
  71. package/src/reactive-mutation-types.ts +13 -0
  72. package/src/reactive-mutation.ts +115 -0
  73. package/src/reactive-query-types.ts +14 -0
  74. package/src/reactive-query.ts +48 -0
  75. package/src/reactive-realtime.ts +267 -0
  76. package/src/rls-db.ts +9 -4
  77. package/src/runtime-env-policy.ts +66 -0
  78. package/src/search-types.ts +91 -0
  79. package/src/server.ts +6 -2
  80. package/src/storage-metering.ts +35 -0
  81. package/src/storage-shared.ts +74 -0
  82. package/src/storage.ts +44 -53
  83. package/src/wake-app-result.ts +37 -0
  84. package/src/workflow-types.ts +16 -2
  85. package/src/workflow.ts +166 -12
  86. package/src/workflows-api.ts +82 -3
  87. package/src/__tests__/auth.test.ts +0 -118
  88. package/src/__tests__/crons.test.ts +0 -83
  89. package/src/__tests__/crud-codegen-integration.test.ts +0 -246
  90. package/src/__tests__/crud-owner-rls.test.ts +0 -387
  91. package/src/__tests__/crud.test.ts +0 -930
  92. package/src/__tests__/dist-exports.test.ts +0 -176
  93. package/src/__tests__/fixtures/basic/auth.ts +0 -32
  94. package/src/__tests__/fixtures/basic/drizzle.config.ts +0 -12
  95. package/src/__tests__/fixtures/basic/index.ts +0 -6
  96. package/src/__tests__/fixtures/basic/migrations/0000_last_warstar.sql +0 -75
  97. package/src/__tests__/fixtures/basic/migrations/meta/0000_snapshot.json +0 -497
  98. package/src/__tests__/fixtures/basic/migrations/meta/_journal.json +0 -13
  99. package/src/__tests__/fixtures/basic/schema.ts +0 -51
  100. package/src/__tests__/fixtures/basic/tasks.ts +0 -15
  101. package/src/__tests__/fixtures/common/auth-schema.ts +0 -67
  102. package/src/__tests__/helpers/basic-rls-fixture.ts +0 -135
  103. package/src/__tests__/helpers/pglite-migrations.ts +0 -32
  104. package/src/__tests__/helpers/pglite-rls-session.ts +0 -51
  105. package/src/__tests__/helpers/seed-like-fill.ts +0 -202
  106. package/src/__tests__/helpers/test-gencow-ctx-rls.ts +0 -50
  107. package/src/__tests__/httpaction.test.ts +0 -122
  108. package/src/__tests__/image-optimization.test.ts +0 -648
  109. package/src/__tests__/load.test.ts +0 -389
  110. package/src/__tests__/network-sim.test.ts +0 -319
  111. package/src/__tests__/reactive.test.ts +0 -479
  112. package/src/__tests__/retry.test.ts +0 -113
  113. package/src/__tests__/rls-crud-basic.test.ts +0 -317
  114. package/src/__tests__/rls-crud-no-owner-rls-pglite.test.ts +0 -117
  115. package/src/__tests__/rls-custom-mutation-handlers.test.ts +0 -142
  116. package/src/__tests__/rls-custom-query-handlers.test.ts +0 -128
  117. package/src/__tests__/rls-db-leased-connection.test.ts +0 -118
  118. package/src/__tests__/rls-session-and-policies.test.ts +0 -228
  119. package/src/__tests__/scheduler-durable-v2.test.ts +0 -288
  120. package/src/__tests__/scheduler-durable.test.ts +0 -173
  121. package/src/__tests__/scheduler-exec.test.ts +0 -328
  122. package/src/__tests__/scheduler.test.ts +0 -187
  123. package/src/__tests__/storage.test.ts +0 -334
  124. package/src/__tests__/tsconfig.json +0 -8
  125. package/src/__tests__/validator.test.ts +0 -323
  126. package/src/__tests__/workflow.test.ts +0 -606
  127. package/src/__tests__/ws-integration.test.ts +0 -309
  128. package/src/__tests__/ws-scale.test.ts +0 -241
  129. package/src/auth.ts +0 -155
  130. package/src/reactive.ts +0 -580
package/src/index.ts CHANGED
@@ -9,34 +9,134 @@ export type {
9
9
  GencowCtx,
10
10
  AuthCtx,
11
11
  UserIdentity,
12
- QueryDef,
13
- MutationDef,
14
12
  RealtimeCtx,
13
+ RealtimeNotifyEvent,
14
+ AIContext,
15
+ AIMessage,
16
+ AIResult,
17
+ } from "./context.js";
18
+ export { defineApi } from "./context.js";
19
+ export type { QueryDef } from "./reactive-query-types.js";
20
+ export type { MutationDef } from "./reactive-mutation-types.js";
21
+ export type {
15
22
  HttpActionDef,
16
23
  HttpActionRequest,
17
24
  HttpActionResponse,
18
25
  HttpActionHandler,
19
- AIContext,
20
- AIMessage,
21
- AIResult,
22
- } from "./reactive.js";
26
+ } from "./http-action.js";
27
+ export type {
28
+ SearchPrimitive,
29
+ SearchScope,
30
+ SearchFilter,
31
+ SearchOptions,
32
+ VectorSearchOptions,
33
+ HybridSearchOptions,
34
+ SearchHit,
35
+ SearchResponse,
36
+ SearchTierConfig,
37
+ } from "./search-types.js";
38
+ export type {
39
+ DocumentVisibility,
40
+ DocumentConvertMode,
41
+ DocumentConvertProvider,
42
+ DocumentResolvedProvider,
43
+ DocumentConvertInput,
44
+ DocumentPage,
45
+ DocumentSection,
46
+ DocumentProviderTrace,
47
+ DocumentConvertResult,
48
+ DocumentCacheArtifact,
49
+ DocumentCacheKeyInput,
50
+ GencowServicesCtx,
51
+ WorkflowDocumentServicesCtx,
52
+ } from "./document-types.js";
53
+ export { buildDocumentCacheKey } from "./document-types.js";
54
+ export type {
55
+ WakeAppBootFailedResult,
56
+ WakeAppDeferredResult,
57
+ WakeAppDeferredStatus,
58
+ WakeAppResult,
59
+ WakeAppSuccessResult,
60
+ WakeAppSuccessStatus,
61
+ } from "./wake-app-result.js";
62
+ export {
63
+ DEFAULT_WAKE_RETRY_AFTER_SEC,
64
+ buildWakeAppBootFailedResult,
65
+ buildWakeAppSuccessResult,
66
+ isWakeAppDeferredResult,
67
+ } from "./wake-app-result.js";
68
+ export type { PlatformCapacityPreset, PlatformCapacityProfileName } from "./platform-capacity-profile.js";
69
+ export {
70
+ PLATFORM_CAPACITY_ENV_KEYS,
71
+ PLATFORM_CAPACITY_PRESETS,
72
+ PLATFORM_CAPACITY_PROFILE_ENV,
73
+ detectPlatformCapacityProfile,
74
+ resolvePlatformCapacityPreset,
75
+ } from "./platform-capacity-profile.js";
76
+ export type {
77
+ RagIngestReindexMode,
78
+ RagIngestInput,
79
+ RagIngestWorkflowArgs,
80
+ RagIngestStartResult,
81
+ RagIngestJobStatus,
82
+ RagIngestJobRecord,
83
+ } from "./rag-ingest-types.js";
84
+ export type {
85
+ CitationCoverage,
86
+ ClaimSupportStatus,
87
+ GroundedAnswerMode,
88
+ Citation,
89
+ ClaimEvidenceMap,
90
+ GroundedAnswer,
91
+ GroundingBudget,
92
+ GroundedClaimInput,
93
+ GroundedCompareInput,
94
+ GroundedTopicInput,
95
+ GroundedAnswerInput,
96
+ GroundingRuntime,
97
+ } from "./grounded-answer-types.js";
98
+ export { DEFAULT_GROUNDING_BUDGET } from "./grounded-answer-types.js";
99
+ export type {
100
+ RagOperationKind,
101
+ RagOperationMetricUnit,
102
+ RagIndexHealth,
103
+ RagOperationMetric,
104
+ RagOperationsSummary,
105
+ RagEvaluationExpectedClaim,
106
+ RagEvaluationFixture,
107
+ RagEvaluationFixtureResult,
108
+ RagEvaluationRunResult,
109
+ RagReindexMode,
110
+ RagReindexPlan,
111
+ } from "./rag-operations-types.js";
112
+ export {
113
+ ragCorpora,
114
+ ragSources,
115
+ ragSections,
116
+ ragChunks,
117
+ ragIngestJobs,
118
+ ragOperationMetrics,
119
+ } from "./rag-schema.js";
120
+ export { buildQuerySubscriptionKey, subscriptionKeyMatchesQueryKey } from "./reactive-realtime.js";
121
+ export { query, getQueryHandler, getQueryDef, getRegisteredQueries } from "./reactive-query.js";
122
+ export { mutation, getRegisteredMutations } from "./reactive-mutation.js";
123
+ export { procQuery, procMutation } from "./procedure.js";
124
+ export type {
125
+ GencowProcedureBuilder,
126
+ GencowProcedureDef,
127
+ GencowProcedureMiddleware,
128
+ GencowProcedureHandler,
129
+ } from "./procedure.js";
130
+ export { httpAction, getRegisteredHttpActions } from "./http-action.js";
23
131
  export {
24
- query,
25
- mutation,
26
- httpAction,
27
- buildRealtimeCtx,
28
132
  subscribe,
29
133
  unsubscribe,
30
134
  registerClient,
31
135
  deregisterClient,
136
+ buildRealtimeCtx,
32
137
  handleWsMessage,
33
- getQueryHandler,
34
- getQueryDef,
35
- getRegisteredQueries,
36
- getRegisteredMutations,
37
- getRegisteredHttpActions,
38
- } from "./reactive.js";
39
- export type { Storage } from "./storage.js";
138
+ } from "./reactive-realtime.js";
139
+ export type { Storage, StoredFile } from "./storage.js";
40
140
  export { createScheduler, getSchedulerInfo } from "./scheduler.js";
41
141
  export type {
42
142
  Scheduler,
@@ -82,17 +182,40 @@ export { v, parseArgs, GencowValidationError } from "./v.js";
82
182
  export type { Validator, Infer, InferArgs } from "./v.js";
83
183
  export { withRetry } from "./retry.js";
84
184
  export type { RetryOptions } from "./retry.js";
185
+ export { filterTenantRuntimeEnvVars, isReservedTenantRuntimeEnvKey } from "./runtime-env-policy.js";
85
186
  export { cronJobs } from "./crons.js";
86
187
  export type { CronJobsBuilder, CronJobDef, IntervalOptions, DailyOptions, WeeklyOptions } from "./crons.js";
87
188
  export { defineAuth } from "./auth-config.js";
88
- export type { GencowAuthConfig, AuthEmailVerification } from "./auth-config.js";
189
+ export type {
190
+ GencowAuthConfig,
191
+ AuthEmailVerification,
192
+ AuthPasswordReset,
193
+ AuthEvents,
194
+ AuthHookContext,
195
+ AuthUserLike,
196
+ AuthOAuthConfig,
197
+ SocialProviderConfig,
198
+ SocialProvidersConfig,
199
+ KakaoConfig,
200
+ NaverConfig,
201
+ CustomOAuthProvider,
202
+ OAuthUserInfo,
203
+ } from "./auth-config.js";
204
+ export { defineConfig } from "./config.js";
205
+ export type { GencowConfig, GencowDbConfig, GencowDeployConfig } from "./config.js";
89
206
 
90
207
  // ─── RLS + CRUD Factory ───────────
91
208
  export { ownerRls, getOwnerRlsMeta, registerOwnerRls } from "./rls.js";
92
209
  export type { OwnerRlsMeta } from "./rls.js";
93
210
  export { createRlsDb } from "./rls-db.js";
94
211
  export type { RlsSessionContext } from "./rls-db.js";
95
- export { crud, parseFilterNode, applyFilterOp, getOwnerRlsTables, getRegisteredCrudCodegenMeta } from "./crud.js";
212
+ export {
213
+ crud,
214
+ parseFilterNode,
215
+ applyFilterOp,
216
+ getOwnerRlsTables,
217
+ getRegisteredCrudCodegenMeta,
218
+ } from "./crud.js";
96
219
  export type { CrudCodegenMeta } from "./crud.js";
97
220
 
98
221
  // Deprecated alias — 하위호환용, 향후 메이저 버전에서 제거 예정
@@ -0,0 +1,114 @@
1
+ export type PlatformCapacityProfileName = "prod" | "dev" | "local";
2
+
3
+ export interface PlatformCapacityPreset {
4
+ profile: PlatformCapacityProfileName;
5
+ maxConcurrentRunning: number | null;
6
+ maxConcurrentWake: number | null;
7
+ maxWakeQueueMs: number;
8
+ minAvailableRamMB: number | null;
9
+ evictionThresholdMB: number | null;
10
+ sleepTimeoutMinutes: number;
11
+ sleepMaxPerCycle: number;
12
+ warmPoolMinIdle: number;
13
+ warmPoolMax: number;
14
+ deployCandidateReserve: number;
15
+ }
16
+
17
+ export const PLATFORM_CAPACITY_PROFILE_ENV = "GENCOW_CAPACITY_PROFILE";
18
+
19
+ export const PLATFORM_CAPACITY_ENV_KEYS = [
20
+ PLATFORM_CAPACITY_PROFILE_ENV,
21
+ "MAX_CONCURRENT_RUNNING",
22
+ "MAX_CONCURRENT_WAKE",
23
+ "MAX_WAKE_QUEUE_MS",
24
+ "MIN_AVAILABLE_RAM_MB",
25
+ "WAKE_RETRY_AFTER_SEC",
26
+ "EVICTION_THRESHOLD_MB",
27
+ "GENCOW_SLEEP_TIMEOUT_MINUTES",
28
+ "GENCOW_SLEEP_MAX_PER_CYCLE",
29
+ "WARM_POOL_MIN_IDLE",
30
+ "WARM_POOL_MAX",
31
+ "DEPLOY_CANDIDATE_RESERVE",
32
+ "GENCOW_APP_PORT_RANGE",
33
+ "COWBOX_WARM_POOL_PORT_RANGE",
34
+ ] as const;
35
+
36
+ export const PLATFORM_CAPACITY_PRESETS: Record<PlatformCapacityProfileName, PlatformCapacityPreset> = Object.freeze({
37
+ prod: Object.freeze({
38
+ profile: "prod",
39
+ maxConcurrentRunning: 600,
40
+ maxConcurrentWake: 20,
41
+ maxWakeQueueMs: 5000,
42
+ minAvailableRamMB: 8192,
43
+ evictionThresholdMB: 16384,
44
+ sleepTimeoutMinutes: 15,
45
+ sleepMaxPerCycle: 50,
46
+ warmPoolMinIdle: 10,
47
+ warmPoolMax: 650,
48
+ deployCandidateReserve: 40,
49
+ }),
50
+ dev: Object.freeze({
51
+ profile: "dev",
52
+ maxConcurrentRunning: 60,
53
+ maxConcurrentWake: 5,
54
+ maxWakeQueueMs: 3000,
55
+ minAvailableRamMB: 2048,
56
+ evictionThresholdMB: 4096,
57
+ sleepTimeoutMinutes: 10,
58
+ sleepMaxPerCycle: 20,
59
+ warmPoolMinIdle: 3,
60
+ warmPoolMax: 70,
61
+ deployCandidateReserve: 5,
62
+ }),
63
+ local: Object.freeze({
64
+ profile: "local",
65
+ maxConcurrentRunning: null,
66
+ maxConcurrentWake: null,
67
+ maxWakeQueueMs: 5000,
68
+ minAvailableRamMB: null,
69
+ evictionThresholdMB: null,
70
+ sleepTimeoutMinutes: 30,
71
+ sleepMaxPerCycle: 10,
72
+ warmPoolMinIdle: 3,
73
+ warmPoolMax: 10,
74
+ deployCandidateReserve: 0,
75
+ }),
76
+ });
77
+
78
+ function normalizeDomain(value: string | undefined): string {
79
+ return (value || "")
80
+ .trim()
81
+ .toLowerCase()
82
+ .replace(/^https?:\/\//, "")
83
+ .replace(/\/.*$/, "");
84
+ }
85
+
86
+ export function detectPlatformCapacityProfile(
87
+ env: Record<string, string | undefined> = process.env,
88
+ ): PlatformCapacityProfileName {
89
+ const explicit = env[PLATFORM_CAPACITY_PROFILE_ENV]?.trim().toLowerCase();
90
+ if (explicit) {
91
+ if (["prod", "production", "128gb"].includes(explicit)) return "prod";
92
+ if (["dev", "development", "16gb"].includes(explicit)) return "dev";
93
+ if (["local", "test", "disabled"].includes(explicit)) return "local";
94
+ throw new Error(`Invalid ${PLATFORM_CAPACITY_PROFILE_ENV}: ${explicit}. Expected prod, dev, or local.`);
95
+ }
96
+
97
+ const baseDomain = normalizeDomain(env.BASE_DOMAIN);
98
+ if (baseDomain === "gencow.dev") return "dev";
99
+ if (baseDomain === "gencow.app") return "prod";
100
+
101
+ const platformUrl = normalizeDomain(env.GENCOW_PLATFORM_URL);
102
+ if (platformUrl === "gencow.dev") return "dev";
103
+ if (platformUrl === "gencow.app") return "prod";
104
+
105
+ if (env.NODE_ENV === "production" && env.IS_PLATFORM === "true") return "prod";
106
+ return "local";
107
+ }
108
+
109
+ export function resolvePlatformCapacityPreset(
110
+ env: Record<string, string | undefined> = process.env,
111
+ ): PlatformCapacityPreset {
112
+ const profile = detectPlatformCapacityProfile(env);
113
+ return { ...PLATFORM_CAPACITY_PRESETS[profile] };
114
+ }
@@ -0,0 +1,283 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ import type { GencowCtx } from "./context.js";
3
+
4
+ type InferInputSchema<TSchema> = TSchema extends { "~standard": { types: { input: infer TInput } } }
5
+ ? TInput
6
+ : TSchema extends StandardSchemaV1
7
+ ? StandardSchemaV1.InferInput<TSchema>
8
+ : unknown;
9
+
10
+ type InferOutputSchema<TSchema> = TSchema extends { "~standard": { types: { output: infer TOutput } } }
11
+ ? TOutput
12
+ : TSchema extends { _output: infer TOutput }
13
+ ? TOutput
14
+ : TSchema extends StandardSchemaV1
15
+ ? StandardSchemaV1.InferOutput<TSchema>
16
+ : unknown;
17
+
18
+ type NextFn<TContext, TInput, TOutput> = (overrides?: {
19
+ context?: TContext;
20
+ input?: TInput;
21
+ }) => Promise<TOutput>;
22
+
23
+ export type GencowProcedureMiddleware<TContext, TInput, TOutput> = (options: {
24
+ context: TContext;
25
+ input: TInput;
26
+ next: NextFn<TContext, TInput, TOutput>;
27
+ }) => Promise<TOutput> | TOutput;
28
+
29
+ export type GencowProcedureHandler<TContext, TInput, TOutput> = (options: {
30
+ context: TContext;
31
+ input: TInput;
32
+ }) => Promise<TOutput> | TOutput;
33
+
34
+ export interface GencowProcedureDef<
35
+ TKind extends "query" | "mutation" = "query" | "mutation",
36
+ TContext = any,
37
+ TInput = unknown,
38
+ TOutput = unknown,
39
+ > {
40
+ kind: TKind;
41
+ name: string;
42
+ /** When false (default), RPC requires an authenticated user. */
43
+ isPublic: boolean;
44
+ middlewares: readonly GencowProcedureMiddleware<TContext, TInput, TOutput>[];
45
+ inputSchema?: StandardSchemaV1;
46
+ outputSchema?: StandardSchemaV1;
47
+ inputValidationIndex: number;
48
+ outputValidationIndex: number;
49
+ handler: (context: TContext, input: TInput) => Promise<TOutput>;
50
+ }
51
+
52
+ export interface GencowProcedureBuilder<
53
+ TKind extends "query" | "mutation" = "query" | "mutation",
54
+ TContext = any,
55
+ TInput = unknown,
56
+ TOutput = unknown,
57
+ > {
58
+ name(name: string): GencowProcedureBuilder<TKind, TContext, TInput, TOutput>;
59
+ /**
60
+ * Allow calling this procedure without authentication (like `query("x", { public: true, ... })`).
61
+ * Default is authenticated-only.
62
+ */
63
+ allowPublic(): GencowProcedureBuilder<TKind, TContext, TInput, TOutput>;
64
+ use(
65
+ middleware: GencowProcedureMiddleware<TContext, TInput, TOutput>,
66
+ ): GencowProcedureBuilder<TKind, TContext, TInput, TOutput>;
67
+ input<TNextSchema extends StandardSchemaV1>(
68
+ schema: TNextSchema,
69
+ ): GencowProcedureBuilder<TKind, TContext, InferInputSchema<TNextSchema>, TOutput>;
70
+ output<TNextSchema extends StandardSchemaV1>(
71
+ schema: TNextSchema,
72
+ ): GencowProcedureBuilder<TKind, TContext, TInput, InferOutputSchema<TNextSchema>>;
73
+ handler(
74
+ handler: GencowProcedureHandler<TContext, TInput, TOutput>,
75
+ ): GencowProcedureDef<TKind, TContext, TInput, TOutput>;
76
+ }
77
+
78
+ function hasStandardSchema(schema: unknown): schema is StandardSchemaV1 {
79
+ return (
80
+ !!schema &&
81
+ typeof schema === "object" &&
82
+ "~standard" in schema &&
83
+ !!(schema as any)["~standard"] &&
84
+ typeof (schema as any)["~standard"].validate === "function"
85
+ );
86
+ }
87
+
88
+ async function validateWithSchema<TOutput>(schema: unknown, value: unknown): Promise<TOutput> {
89
+ if (!schema) return value as TOutput;
90
+
91
+ if (hasStandardSchema(schema)) {
92
+ const result = (await schema["~standard"].validate(value)) as
93
+ | { value: TOutput }
94
+ | { issues: readonly { message: string }[] };
95
+ if ("issues" in result && result.issues.length > 0) {
96
+ throw new Error(result.issues[0]?.message ?? "Validation failed");
97
+ }
98
+ if ("value" in result) {
99
+ return result.value as TOutput;
100
+ }
101
+ throw new Error("Validation failed");
102
+ }
103
+
104
+ throw new Error("procQuery/procMutation only supports Standard Schema v1 validators");
105
+ }
106
+
107
+ function composeMiddlewares<TContext, TInput, TOutput>(
108
+ middlewares: Array<GencowProcedureMiddleware<TContext, TInput, TOutput>>,
109
+ handler: GencowProcedureHandler<TContext, TInput, TOutput>,
110
+ inputSchema: StandardSchemaV1 | undefined,
111
+ outputSchema: StandardSchemaV1 | undefined,
112
+ inputValidationIndex: number,
113
+ outputValidationIndex: number,
114
+ ): (context: TContext, input: TInput) => Promise<TOutput> {
115
+ return async (initialContext, initialInput) => {
116
+ let idx = -1;
117
+ const boundedInputValidationIndex = Math.min(Math.max(0, inputValidationIndex), middlewares.length);
118
+ const boundedOutputValidationIndex = Math.min(Math.max(0, outputValidationIndex), middlewares.length);
119
+
120
+ const run = async (currentIdx: number, context: TContext, input: TInput): Promise<TOutput> => {
121
+ if (currentIdx <= idx) {
122
+ throw new Error("next() called multiple times in the same middleware");
123
+ }
124
+ idx = currentIdx;
125
+ let currentInput = input;
126
+
127
+ if (currentIdx === boundedInputValidationIndex) {
128
+ currentInput = (await validateWithSchema(inputSchema, currentInput)) as TInput;
129
+ }
130
+
131
+ if (currentIdx === middlewares.length) {
132
+ const output = await handler({ context, input: currentInput });
133
+ if (currentIdx === boundedOutputValidationIndex) {
134
+ return await validateWithSchema<TOutput>(outputSchema, output);
135
+ }
136
+ return output;
137
+ }
138
+
139
+ const middleware = middlewares[currentIdx];
140
+ const output = await middleware({
141
+ context,
142
+ input: currentInput,
143
+ next: async (overrides) => {
144
+ return await run(
145
+ currentIdx + 1,
146
+ (overrides?.context ?? context) as TContext,
147
+ (overrides?.input ?? currentInput) as TInput,
148
+ );
149
+ },
150
+ });
151
+
152
+ if (currentIdx === boundedOutputValidationIndex) {
153
+ return await validateWithSchema<TOutput>(outputSchema, output);
154
+ }
155
+
156
+ return output;
157
+ };
158
+
159
+ return await run(0, initialContext, initialInput);
160
+ };
161
+ }
162
+
163
+ class GencowProcedureBuilderImpl<
164
+ TKind extends "query" | "mutation",
165
+ TContext = any,
166
+ TInput = unknown,
167
+ TOutput = unknown,
168
+ > implements GencowProcedureBuilder<TKind, TContext, TInput, TOutput> {
169
+ constructor(
170
+ private readonly kind: TKind,
171
+ private readonly procedureName?: string,
172
+ private readonly middlewares: Array<GencowProcedureMiddleware<TContext, TInput, TOutput>> = [],
173
+ private readonly inputSchema?: StandardSchemaV1,
174
+ private readonly outputSchema?: StandardSchemaV1,
175
+ private readonly inputValidationIndex = -1,
176
+ private readonly outputValidationIndex = -1,
177
+ private readonly isPublic = false,
178
+ ) {}
179
+
180
+ name(name: string) {
181
+ return new GencowProcedureBuilderImpl<TKind, TContext, TInput, TOutput>(
182
+ this.kind,
183
+ name,
184
+ this.middlewares,
185
+ this.inputSchema,
186
+ this.outputSchema,
187
+ this.inputValidationIndex,
188
+ this.outputValidationIndex,
189
+ this.isPublic,
190
+ );
191
+ }
192
+
193
+ allowPublic() {
194
+ return new GencowProcedureBuilderImpl<TKind, TContext, TInput, TOutput>(
195
+ this.kind,
196
+ this.procedureName,
197
+ this.middlewares,
198
+ this.inputSchema,
199
+ this.outputSchema,
200
+ this.inputValidationIndex,
201
+ this.outputValidationIndex,
202
+ true,
203
+ );
204
+ }
205
+
206
+ use(middleware: GencowProcedureMiddleware<TContext, TInput, TOutput>) {
207
+ return new GencowProcedureBuilderImpl<TKind, TContext, TInput, TOutput>(
208
+ this.kind,
209
+ this.procedureName,
210
+ [...this.middlewares, middleware],
211
+ this.inputSchema,
212
+ this.outputSchema,
213
+ this.inputValidationIndex,
214
+ this.outputValidationIndex,
215
+ this.isPublic,
216
+ );
217
+ }
218
+
219
+ input<TNextSchema extends StandardSchemaV1>(schema: TNextSchema) {
220
+ const nextInputValidationIndex = this.middlewares.length < 0 ? 0 : this.middlewares.length;
221
+
222
+ return new GencowProcedureBuilderImpl<TKind, TContext, InferInputSchema<TNextSchema>, TOutput>(
223
+ this.kind,
224
+ this.procedureName,
225
+ this.middlewares as Array<GencowProcedureMiddleware<TContext, InferInputSchema<TNextSchema>, TOutput>>,
226
+ schema,
227
+ this.outputSchema,
228
+ nextInputValidationIndex,
229
+ this.outputValidationIndex,
230
+ this.isPublic,
231
+ );
232
+ }
233
+
234
+ output<TNextSchema extends StandardSchemaV1>(schema: TNextSchema) {
235
+ const nextOutputValidationIndex = this.middlewares.length < 0 ? 0 : this.middlewares.length;
236
+
237
+ return new GencowProcedureBuilderImpl<TKind, TContext, TInput, InferOutputSchema<TNextSchema>>(
238
+ this.kind,
239
+ this.procedureName,
240
+ this.middlewares as Array<GencowProcedureMiddleware<TContext, TInput, InferOutputSchema<TNextSchema>>>,
241
+ this.inputSchema,
242
+ schema,
243
+ this.inputValidationIndex,
244
+ nextOutputValidationIndex,
245
+ this.isPublic,
246
+ );
247
+ }
248
+
249
+ handler(
250
+ handler: GencowProcedureHandler<TContext, TInput, TOutput>,
251
+ ): GencowProcedureDef<TKind, TContext, TInput, TOutput> {
252
+ if (!this.procedureName) {
253
+ throw new Error("Procedure name is required. Call .name(...) before .handler(...)");
254
+ }
255
+
256
+ const run = composeMiddlewares(
257
+ this.middlewares,
258
+ handler,
259
+ this.inputSchema,
260
+ this.outputSchema,
261
+ this.inputValidationIndex,
262
+ this.outputValidationIndex,
263
+ );
264
+
265
+ return {
266
+ kind: this.kind,
267
+ name: this.procedureName,
268
+ isPublic: this.isPublic,
269
+ middlewares: [...this.middlewares],
270
+ inputSchema: this.inputSchema,
271
+ outputSchema: this.outputSchema,
272
+ inputValidationIndex: this.inputValidationIndex,
273
+ outputValidationIndex: this.outputValidationIndex,
274
+ handler: run,
275
+ };
276
+ }
277
+ }
278
+
279
+ export const procQuery: GencowProcedureBuilder<"query", GencowCtx> =
280
+ new GencowProcedureBuilderImpl<"query", GencowCtx>("query");
281
+
282
+ export const procMutation: GencowProcedureBuilder<"mutation", GencowCtx> =
283
+ new GencowProcedureBuilderImpl<"mutation", GencowCtx>("mutation");
@@ -0,0 +1,52 @@
1
+ import type { DocumentConvertProvider, DocumentConvertMode, DocumentProviderTrace, DocumentVisibility } from "./document-types.js";
2
+
3
+ export type RagIngestReindexMode = "if_changed" | "force";
4
+ export type RagIngestJobStatus =
5
+ | "queued"
6
+ | "converting"
7
+ | "chunking"
8
+ | "embedding"
9
+ | "upserting"
10
+ | "completed"
11
+ | "failed"
12
+ | "canceled";
13
+
14
+ export type RagIngestInput = {
15
+ storageId: string;
16
+ corpus: string;
17
+ visibility: DocumentVisibility;
18
+ ownerUserId?: string;
19
+ sourceKey?: string;
20
+ metadata?: Record<string, unknown>;
21
+ reindexMode?: RagIngestReindexMode;
22
+ mode?: DocumentConvertMode;
23
+ provider?: DocumentConvertProvider;
24
+ };
25
+
26
+ export type RagIngestWorkflowArgs = RagIngestInput & {
27
+ jobId: string;
28
+ sourceId: string;
29
+ };
30
+
31
+ export type RagIngestStartResult = {
32
+ workflowId: string;
33
+ jobId: string;
34
+ sourceId: string;
35
+ status: "queued";
36
+ };
37
+
38
+ export type RagIngestJobRecord = {
39
+ id: string;
40
+ workflowId: string;
41
+ sourceId: string;
42
+ corpus: string;
43
+ visibility: DocumentVisibility;
44
+ ownerUserId: string | null;
45
+ status: RagIngestJobStatus;
46
+ stage: string;
47
+ providerTrace: Partial<DocumentProviderTrace> | Record<string, never>;
48
+ metrics: Record<string, unknown>;
49
+ error: string | null;
50
+ startedAt: string;
51
+ completedAt: string | null;
52
+ };