cfw-graphql-bootstrap 1.0.1 → 1.0.3

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/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { BaseContext as BaseContext$1, ApolloServerOptions, ApolloServerPlugin } from '@apollo/server';
2
2
  import { ExecutionContext } from '@cloudflare/workers-types';
3
3
  import { CloudflareContextFunctionArgument } from '@as-integrations/cloudflare-workers';
4
- import { KeyValueCache, KeyValueCacheSetOptions } from '@apollo/utils.keyvaluecache';
5
4
  import { GraphQLSchema, GraphQLError, DocumentNode } from 'graphql';
6
5
  import { Hono, MiddlewareHandler } from 'hono';
7
6
  import { ApolloServerErrorCode } from '@apollo/server/errors';
8
7
  import DataLoader, { BatchLoadFn, Options } from 'dataloader';
8
+ import { KeyValueCache, KeyValueCacheSetOptions } from '@apollo/utils.keyvaluecache';
9
9
  export { gql } from 'graphql-tag';
10
10
 
11
11
  declare const logger: any;
@@ -330,6 +330,7 @@ interface BaseContext extends JaegerContext, BaseContext$1 {
330
330
  logger: typeof logger;
331
331
  executionCtx: ExecutionContext;
332
332
  cache?: KVCache;
333
+ db?: D1Database;
333
334
  env: EnvConfig;
334
335
  /** @deprecated should not be used directly */
335
336
  authorization: string;
@@ -342,15 +343,20 @@ type Runner = {
342
343
  fetch: typeof Hono.prototype.fetch;
343
344
  port?: number;
344
345
  };
346
+
345
347
  type ServerConfig<TDatasource, TContext extends BaseContext> = {
346
348
  path?: string;
347
349
  apollo: Partial<ApolloServerOptions<BaseContext>>;
348
- datasources?: (cache: KeyValueCache<string>, context: TContext) => TDatasource;
350
+ datasources: (cache: KVCache, context: TContext) => TDatasource;
349
351
  extendContext?: ContextExtendFunction<TContext>;
350
352
  };
351
353
  declare class ServerBuilder<TDatasource, TContext extends BaseContext> {
352
354
  readonly config: ServerConfig<TDatasource, TContext>;
353
- readonly app: Hono;
355
+ readonly app: Hono<{
356
+ Variables: {
357
+ env: any;
358
+ };
359
+ }>;
354
360
  readonly schema: GraphQLSchema;
355
361
  readonly plugins: ApolloServerPlugin<BaseContext>[];
356
362
  constructor(config: ServerConfig<TDatasource, TContext>);
@@ -412,7 +418,11 @@ interface HealthCheckOptions {
412
418
  [key: string]: () => Promise<boolean>;
413
419
  };
414
420
  }
415
- declare function configureHealthChecks(app: Hono, options?: HealthCheckOptions): void;
421
+ declare function configureHealthChecks(app: Hono<{
422
+ Variables: {
423
+ env: any;
424
+ };
425
+ }>, options?: HealthCheckOptions): void;
416
426
 
417
427
  declare enum ErrorCode {
418
428
  UNAUTHENTICATED = "UNAUTHENTICATED",
@@ -436,7 +446,7 @@ type SchemaModule = ReturnType<typeof createSchemaModule>;
436
446
  declare const getNonUserInputErrors: (errors: readonly GraphQLError[]) => GraphQLError[];
437
447
 
438
448
  type DataSources = Record<string, any>;
439
- type DataSourcesFn = <TContext extends BaseContext = BaseContext>(cache: KeyValueCache<string>, contextValue: TContext) => DataSources;
449
+ type DataSourcesFn = <TContext extends BaseContext = BaseContext>(cache: KVCache, contextValue: TContext) => DataSources;
440
450
  type ComputedContext<TDatasource, TContext extends BaseContext> = TContext & {
441
451
  datasources: ReturnType<NonNullable<ServerConfig<TDatasource, TContext>['datasources']>>;
442
452
  };
@@ -444,4 +454,165 @@ declare const ApolloDataSources: <TDatasource, TContext extends BaseContext>(opt
444
454
  datasources: DataSourcesFn;
445
455
  }) => ApolloServerPlugin<ComputedContext<TDatasource, TContext>>;
446
456
 
447
- export { ApolloDataSources, ApolloKVAdapter, AppError, type BaseContext, type BaseServerOptions, BatchingDataSource, type CacheOptions, CachedDataLoader, type ComputedContext, type ContextExtendFunction, type ContextUser, type EnvConfig, ErrorCode, InMemoryCache, KVCache, type Runner, type SchemaModule, ServerBuilder, type ServerConfig, type ServerOptions, cached, configureHealthChecks, createApolloCache, createApolloLoggingPlugin, createBatchingDataSource, createCache, createContextFunction, createGraphQLServer, createRateLimitMiddleware, createSchemaModule, createTracingMiddleware, createValidationMiddleware, ensureBatchOrder, ensureBatchOrderNullable, envLoader, getNonUserInputErrors, logger };
457
+ interface BaseDatasource<TContext extends BaseContext = BaseContext> {
458
+ readonly name: string;
459
+ context?: TContext;
460
+ init?(): Promise<void> | void;
461
+ connect?(): Promise<void> | void;
462
+ disconnect?(): Promise<void> | void;
463
+ healthCheck?(): Promise<boolean> | boolean;
464
+ clear?(): Promise<void> | void;
465
+ }
466
+ /**
467
+ * Abstract base class for all datasources in the GraphQL bootstrap
468
+ * Provides common functionality like caching, logging, and lifecycle management
469
+ */
470
+ declare abstract class AbstractDatasource<TContext extends BaseContext = BaseContext> implements BaseDatasource<TContext> {
471
+ abstract readonly name: string;
472
+ context: TContext;
473
+ protected cache: KVCache;
474
+ protected logger: TContext['logger'];
475
+ constructor(cache: KVCache, context: TContext);
476
+ /**
477
+ * Initialize datasource-specific configuration
478
+ * Override this method to add custom initialization logic
479
+ */
480
+ protected initialize(): void;
481
+ init(): Promise<void>;
482
+ connect(): Promise<void>;
483
+ disconnect(): Promise<void>;
484
+ healthCheck(): Promise<boolean>;
485
+ clear(): Promise<void>;
486
+ /**
487
+ * Helper method to get a cached result or fetch fresh data
488
+ * Uses the enhanced KVCache memoize function
489
+ */
490
+ protected cached<T>(key: string, fetchFn: () => Promise<T>, ttl?: number): Promise<T>;
491
+ /**
492
+ * Helper method to invalidate cache entries by pattern
493
+ */
494
+ protected invalidateCache(pattern: string): Promise<number>;
495
+ }
496
+
497
+ interface RestClientOptions {
498
+ baseURL: string;
499
+ timeout?: number;
500
+ headers?: Record<string, string>;
501
+ retries?: number;
502
+ }
503
+ /**
504
+ * REST datasource for making HTTP API calls with caching and error handling
505
+ * Optimized for Cloudflare Workers environment
506
+ */
507
+ declare class RestDatasource<TContext extends BaseContext = BaseContext> extends AbstractDatasource<TContext> {
508
+ readonly name = "rest";
509
+ private baseURL;
510
+ private timeout;
511
+ private headers;
512
+ private retries;
513
+ constructor(cache: KVCache, context: TContext, options: RestClientOptions);
514
+ healthCheck(): Promise<boolean>;
515
+ /**
516
+ * GET request with caching
517
+ */
518
+ get<T = any>(path: string, options?: {
519
+ cache?: boolean;
520
+ ttl?: number;
521
+ params?: Record<string, string>;
522
+ }): Promise<T>;
523
+ /**
524
+ * POST request (no caching)
525
+ */
526
+ post<T = any>(path: string, data?: any, options?: {
527
+ invalidatePattern?: string;
528
+ }): Promise<T>;
529
+ /**
530
+ * PUT request (no caching)
531
+ */
532
+ put<T = any>(path: string, data?: any, options?: {
533
+ invalidatePattern?: string;
534
+ }): Promise<T>;
535
+ /**
536
+ * DELETE request (no caching)
537
+ */
538
+ delete<T = any>(path: string, options?: {
539
+ invalidatePattern?: string;
540
+ }): Promise<T>;
541
+ private buildURL;
542
+ private fetchWithRetry;
543
+ private shouldRetry;
544
+ private delay;
545
+ }
546
+
547
+ interface PrismaClientLike {
548
+ $connect(): Promise<void>;
549
+ $disconnect(): Promise<void>;
550
+ $queryRaw: any;
551
+ $queryRawUnsafe(sql: string, ...values: any[]): Promise<any>;
552
+ $executeRawUnsafe(sql: string, ...values: any[]): Promise<number>;
553
+ }
554
+ interface PrismaD1 {
555
+ }
556
+ declare global {
557
+ var __prismaD1Clients: Map<string, any> | undefined;
558
+ }
559
+ /**
560
+ * Abstract Prisma datasource optimized for Cloudflare D1
561
+ * Automatically creates PrismaD1 adapter and requires user to implement createClient()
562
+ *
563
+ * @example
564
+ * ```typescript
565
+ * import { PrismaClient } from '@prisma/client';
566
+ * import { PrismaD1 } from '@prisma/adapter-d1';
567
+ *
568
+ * class UserDatasource extends PrismaD1Datasource<BaseContext, PrismaClient> {
569
+ * createClient(adapter: PrismaD1): PrismaClient {
570
+ * // Called only ONCE per datasource class, then cached globally
571
+ * console.log('Creating UserDatasource client'); // Will only log once
572
+ * return new PrismaClient({ adapter });
573
+ * }
574
+ *
575
+ * async getUser(id: string) {
576
+ * return this.client.user.findUnique({ where: { id } });
577
+ * }
578
+ * }
579
+ *
580
+ * // Multiple instances share the same client efficiently:
581
+ * datasources: (cache: KVCache, context: TContext) => ({
582
+ * user: new UserDatasource(cache, context), // Client cached by class name
583
+ * admin: new UserDatasource(cache, context), // Reuses same client!
584
+ * })
585
+ * ```
586
+ */
587
+ declare abstract class PrismaD1Datasource<TContext extends BaseContext = BaseContext, TPrismaClient extends PrismaClientLike = PrismaClientLike> extends AbstractDatasource<TContext> {
588
+ readonly name = "prisma-d1";
589
+ private _client;
590
+ constructor(cache: KVCache, context: TContext);
591
+ /**
592
+ * Abstract method to create Prisma client with D1 adapter
593
+ * Called only once per datasource class, then cached globally
594
+ */
595
+ abstract createClient(adapter: PrismaD1): TPrismaClient;
596
+ get client(): TPrismaClient;
597
+ connect(): Promise<void>;
598
+ disconnectWithContext(ctx?: {
599
+ waitUntil: (promise: Promise<any>) => void;
600
+ }): Promise<void>;
601
+ disconnect(): Promise<void>;
602
+ healthCheck(): Promise<boolean>;
603
+ /**
604
+ * Execute a cached query using raw SQL
605
+ */
606
+ queryRaw<T = any>(sql: string, values?: any[], options?: {
607
+ cache?: boolean;
608
+ ttl?: number;
609
+ }): Promise<T>;
610
+ /**
611
+ * Execute a mutation and invalidate cache
612
+ */
613
+ executeRaw(sql: string, values?: any[], options?: {
614
+ invalidatePattern?: string;
615
+ }): Promise<number>;
616
+ }
617
+
618
+ export { AbstractDatasource, ApolloDataSources, ApolloKVAdapter, AppError, type BaseContext, type BaseDatasource, type BaseServerOptions, BatchingDataSource, type CacheOptions, CachedDataLoader, type ComputedContext, type ContextExtendFunction, type ContextUser, type EnvConfig, ErrorCode, InMemoryCache, KVCache, type PrismaClientLike, type PrismaD1, PrismaD1Datasource, type RestClientOptions, RestDatasource, type Runner, type SchemaModule, ServerBuilder, type ServerConfig, type ServerOptions, cached, configureHealthChecks, createApolloCache, createApolloLoggingPlugin, createBatchingDataSource, createCache, createContextFunction, createGraphQLServer, createRateLimitMiddleware, createSchemaModule, createTracingMiddleware, createValidationMiddleware, ensureBatchOrder, ensureBatchOrderNullable, envLoader, getNonUserInputErrors, logger };
package/dist/index.js CHANGED
@@ -95,55 +95,6 @@ function createLogger(context) {
95
95
  return logger.child(context);
96
96
  }
97
97
 
98
- // src/context/constants.ts
99
- var Headers = {
100
- GATEWAY_USER: "x-gateway-user",
101
- GATEWAY_USER_SIGNATURE: "x-gateway-user-signature",
102
- AUTH: "authorization",
103
- CLIENT_ID: "x-client-id"
104
- };
105
-
106
- // src/context/auth.ts
107
- async function verifyAndParseUser(encodedUser, signature, secret) {
108
- if (!encodedUser || !signature) {
109
- return void 0;
110
- }
111
- try {
112
- const encoder = new TextEncoder();
113
- const key = await crypto.subtle.importKey(
114
- "raw",
115
- encoder.encode(secret),
116
- { name: "HMAC", hash: "SHA-256" },
117
- false,
118
- ["verify"]
119
- );
120
- const signatureBuffer = hexToBuffer(signature);
121
- const dataBuffer = encoder.encode(encodedUser);
122
- const isValid = await crypto.subtle.verify(
123
- "HMAC",
124
- key,
125
- signatureBuffer,
126
- dataBuffer
127
- );
128
- if (!isValid) {
129
- console.error("Invalid user signature");
130
- return void 0;
131
- }
132
- const user = JSON.parse(atob(encodedUser));
133
- return user;
134
- } catch (error) {
135
- console.error("Error verifying user:", error);
136
- return void 0;
137
- }
138
- }
139
- function hexToBuffer(hex) {
140
- const bytes = new Uint8Array(hex.length / 2);
141
- for (let i = 0; i < hex.length; i += 2) {
142
- bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
143
- }
144
- return bytes.buffer;
145
- }
146
-
147
98
  // src/cache/kv-cache.ts
148
99
  var KVCache = class {
149
100
  constructor(kv, defaultNamespace) {
@@ -544,6 +495,55 @@ var CachedDataLoader = class {
544
495
  }
545
496
  };
546
497
 
498
+ // src/context/constants.ts
499
+ var Headers = {
500
+ GATEWAY_USER: "x-gateway-user",
501
+ GATEWAY_USER_SIGNATURE: "x-gateway-user-signature",
502
+ AUTH: "authorization",
503
+ CLIENT_ID: "x-client-id"
504
+ };
505
+
506
+ // src/context/auth.ts
507
+ async function verifyAndParseUser(encodedUser, signature, secret) {
508
+ if (!encodedUser || !signature) {
509
+ return void 0;
510
+ }
511
+ try {
512
+ const encoder = new TextEncoder();
513
+ const key = await crypto.subtle.importKey(
514
+ "raw",
515
+ encoder.encode(secret),
516
+ { name: "HMAC", hash: "SHA-256" },
517
+ false,
518
+ ["verify"]
519
+ );
520
+ const signatureBuffer = hexToBuffer(signature);
521
+ const dataBuffer = encoder.encode(encodedUser);
522
+ const isValid = await crypto.subtle.verify(
523
+ "HMAC",
524
+ key,
525
+ signatureBuffer,
526
+ dataBuffer
527
+ );
528
+ if (!isValid) {
529
+ console.error("Invalid user signature");
530
+ return void 0;
531
+ }
532
+ const user = JSON.parse(atob(encodedUser));
533
+ return user;
534
+ } catch (error) {
535
+ console.error("Error verifying user:", error);
536
+ return void 0;
537
+ }
538
+ }
539
+ function hexToBuffer(hex) {
540
+ const bytes = new Uint8Array(hex.length / 2);
541
+ for (let i = 0; i < hex.length; i += 2) {
542
+ bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
543
+ }
544
+ return bytes.buffer;
545
+ }
546
+
547
547
  // src/env/config.ts
548
548
  var EnvParser = class {
549
549
  constructor(env) {
@@ -669,10 +669,13 @@ async function createBaseContext(honoContext) {
669
669
  "KV cache not found in context - this should not happen if using ServerBuilder"
670
670
  );
671
671
  }
672
+ const db = rawEnv?.DB;
672
673
  return {
673
674
  user,
674
675
  logger,
675
676
  cache,
677
+ db,
678
+ // Raw D1 binding for datasources
676
679
  env,
677
680
  // Pass validated env config
678
681
  executionCtx: honoContext.ctx,
@@ -702,6 +705,31 @@ function assertDefined(t, msg) {
702
705
  import { ApolloServer } from "@apollo/server";
703
706
  import { startServerAndCreateCloudflareWorkersHandler } from "@as-integrations/cloudflare-workers";
704
707
 
708
+ // src/datasources/apollo-plugin.datasource.ts
709
+ var ApolloDataSources = (options) => ({
710
+ requestDidStart: async (requestContext) => {
711
+ const kvCache = requestContext.contextValue.cache;
712
+ if (!kvCache) {
713
+ throw new Error(
714
+ "KVCache not found in context. This should not happen if using ServerBuilder."
715
+ );
716
+ }
717
+ const dataSources = options.datasources(
718
+ kvCache,
719
+ requestContext.contextValue
720
+ );
721
+ const connectPromises = Object.values(dataSources).map(
722
+ async (dataSource) => {
723
+ if (dataSource && typeof dataSource.connect === "function") {
724
+ await dataSource.connect();
725
+ }
726
+ }
727
+ );
728
+ await Promise.all(connectPromises);
729
+ requestContext.contextValue.datasources = dataSources;
730
+ }
731
+ });
732
+
705
733
  // src/server/hono.configure.ts
706
734
  import { Hono } from "hono";
707
735
  import { cors } from "hono/cors";
@@ -914,7 +942,7 @@ function configureHono(builder) {
914
942
  const app = new Hono();
915
943
  app.use("*", async (c, next) => {
916
944
  const rawEnv = c.env || {};
917
- const env = typeof rawEnv.NODE_ENV !== "undefined" ? rawEnv : {};
945
+ const env = rawEnv;
918
946
  c.set("env", env);
919
947
  await next();
920
948
  });
@@ -932,8 +960,8 @@ function configureHono(builder) {
932
960
  "/*",
933
961
  cors({
934
962
  origin: (origin, c) => {
935
- const env = c.env;
936
- const isProd = env.NODE_ENV === "production";
963
+ const env = c.get("env");
964
+ const isProd = env?.NODE_ENV === "production";
937
965
  const allowedOrigins = env.ALLOWED_ORIGINS ? typeof env.ALLOWED_ORIGINS === "string" ? env.ALLOWED_ORIGINS.split(",").map((s) => s.trim()) : env.ALLOWED_ORIGINS : ["http://localhost:3000"];
938
966
  if (!isProd) {
939
967
  return origin || "*";
@@ -1072,17 +1100,6 @@ function configurePlugins(builder) {
1072
1100
  builder.plugins.push(createApolloLoggingPlugin());
1073
1101
  }
1074
1102
 
1075
- // src/datasources/apollo-plugin.datasource.ts
1076
- var ApolloDataSources = (options) => ({
1077
- requestDidStart: async (requestContext) => {
1078
- const dataSources = options.datasources(
1079
- requestContext.cache,
1080
- requestContext.contextValue
1081
- );
1082
- requestContext.contextValue.datasources = dataSources;
1083
- }
1084
- });
1085
-
1086
1103
  // src/server/server.builder.ts
1087
1104
  var ServerBuilder = class {
1088
1105
  constructor(config) {
@@ -1096,13 +1113,11 @@ var ServerBuilder = class {
1096
1113
  const honoApp = this.app;
1097
1114
  configurePlugins(this);
1098
1115
  const plugins = [...this.plugins];
1099
- if (this.config.datasources) {
1100
- plugins.push(
1101
- ApolloDataSources({
1102
- datasources: this.config.datasources
1103
- })
1104
- );
1105
- }
1116
+ plugins.push(
1117
+ ApolloDataSources({
1118
+ datasources: this.config.datasources
1119
+ })
1120
+ );
1106
1121
  const createHandler = (env) => {
1107
1122
  if (!env?.KV) {
1108
1123
  throw new Error(
@@ -1200,7 +1215,286 @@ var createSchemaModule = (typeDefs, resolvers) => ({
1200
1215
  typeDefs,
1201
1216
  resolvers
1202
1217
  });
1218
+
1219
+ // src/datasources/base.datasource.ts
1220
+ var AbstractDatasource = class {
1221
+ constructor(cache, context) {
1222
+ this.cache = cache;
1223
+ this.context = context;
1224
+ this.logger = context.logger;
1225
+ this.initialize();
1226
+ }
1227
+ /**
1228
+ * Initialize datasource-specific configuration
1229
+ * Override this method to add custom initialization logic
1230
+ */
1231
+ initialize() {
1232
+ this.logger?.info(`Initializing datasource: ${this.name}`);
1233
+ }
1234
+ async init() {
1235
+ this.logger?.info(`Initializing datasource: ${this.name}`);
1236
+ }
1237
+ async connect() {
1238
+ this.logger?.info(`Connecting datasource: ${this.name}`);
1239
+ }
1240
+ async disconnect() {
1241
+ this.logger?.info(`Disconnecting datasource: ${this.name}`);
1242
+ }
1243
+ async healthCheck() {
1244
+ this.logger?.debug(`Health check for datasource: ${this.name}`);
1245
+ return true;
1246
+ }
1247
+ async clear() {
1248
+ this.logger?.info(`Clearing datasource: ${this.name}`);
1249
+ }
1250
+ /**
1251
+ * Helper method to get a cached result or fetch fresh data
1252
+ * Uses the enhanced KVCache memoize function
1253
+ */
1254
+ async cached(key, fetchFn, ttl) {
1255
+ return this.cache.memoize(key, {}, fetchFn, { ttl });
1256
+ }
1257
+ /**
1258
+ * Helper method to invalidate cache entries by pattern
1259
+ */
1260
+ async invalidateCache(pattern) {
1261
+ return this.cache.invalidate(pattern);
1262
+ }
1263
+ };
1264
+
1265
+ // src/datasources/rest.datasource.ts
1266
+ var RestDatasource = class extends AbstractDatasource {
1267
+ constructor(cache, context, options) {
1268
+ super(cache, context);
1269
+ this.name = "rest";
1270
+ this.baseURL = options.baseURL.replace(/\/$/, "");
1271
+ this.timeout = options.timeout ?? 1e4;
1272
+ this.headers = {
1273
+ "Content-Type": "application/json",
1274
+ "User-Agent": "cfw-graphql-bootstrap/1.0",
1275
+ ...options.headers
1276
+ };
1277
+ this.retries = options.retries ?? 3;
1278
+ }
1279
+ async healthCheck() {
1280
+ try {
1281
+ this.logger?.debug(`Health check for REST datasource: ${this.baseURL}`);
1282
+ const response = await this.get("/health");
1283
+ const isHealthy = response.status < 400;
1284
+ this.logger?.info(
1285
+ `REST datasource health check: ${isHealthy ? "OK" : "FAILED"}`
1286
+ );
1287
+ return isHealthy;
1288
+ } catch (error) {
1289
+ this.logger?.error("REST datasource health check failed:", error);
1290
+ return false;
1291
+ }
1292
+ }
1293
+ /**
1294
+ * GET request with caching
1295
+ */
1296
+ async get(path, options) {
1297
+ const url = this.buildURL(path, options?.params);
1298
+ const cacheKey = `rest:get:${url}`;
1299
+ if (options?.cache !== false) {
1300
+ return this.cached(
1301
+ cacheKey,
1302
+ () => this.fetchWithRetry(url, { method: "GET" }),
1303
+ options?.ttl
1304
+ );
1305
+ }
1306
+ return this.fetchWithRetry(url, { method: "GET" });
1307
+ }
1308
+ /**
1309
+ * POST request (no caching)
1310
+ */
1311
+ async post(path, data, options) {
1312
+ const url = this.buildURL(path);
1313
+ const result = await this.fetchWithRetry(url, {
1314
+ method: "POST",
1315
+ body: data ? JSON.stringify(data) : void 0
1316
+ });
1317
+ if (options?.invalidatePattern) {
1318
+ await this.invalidateCache(options.invalidatePattern);
1319
+ }
1320
+ return result;
1321
+ }
1322
+ /**
1323
+ * PUT request (no caching)
1324
+ */
1325
+ async put(path, data, options) {
1326
+ const url = this.buildURL(path);
1327
+ const result = await this.fetchWithRetry(url, {
1328
+ method: "PUT",
1329
+ body: data ? JSON.stringify(data) : void 0
1330
+ });
1331
+ if (options?.invalidatePattern) {
1332
+ await this.invalidateCache(options.invalidatePattern);
1333
+ }
1334
+ return result;
1335
+ }
1336
+ /**
1337
+ * DELETE request (no caching)
1338
+ */
1339
+ async delete(path, options) {
1340
+ const url = this.buildURL(path);
1341
+ const result = await this.fetchWithRetry(url, { method: "DELETE" });
1342
+ if (options?.invalidatePattern) {
1343
+ await this.invalidateCache(options.invalidatePattern);
1344
+ }
1345
+ return result;
1346
+ }
1347
+ buildURL(path, params) {
1348
+ const url = `${this.baseURL}${path.startsWith("/") ? path : `/${path}`}`;
1349
+ if (params) {
1350
+ const searchParams = new URLSearchParams(params);
1351
+ return `${url}?${searchParams.toString()}`;
1352
+ }
1353
+ return url;
1354
+ }
1355
+ async fetchWithRetry(url, options, attempt = 1) {
1356
+ try {
1357
+ this.logger?.debug(
1358
+ `[${attempt}/${this.retries}] ${options.method || "GET"} ${url}`
1359
+ );
1360
+ const controller = new AbortController();
1361
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1362
+ const response = await fetch(url, {
1363
+ ...options,
1364
+ headers: {
1365
+ ...this.headers,
1366
+ ...options.headers
1367
+ },
1368
+ signal: controller.signal
1369
+ });
1370
+ clearTimeout(timeoutId);
1371
+ if (!response.ok) {
1372
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1373
+ }
1374
+ this.logger?.debug(
1375
+ `\u2713 ${options.method || "GET"} ${url} - ${response.status}`
1376
+ );
1377
+ return await response.json();
1378
+ } catch (error) {
1379
+ this.logger?.warn(
1380
+ `\u2717 ${options.method || "GET"} ${url} - Attempt ${attempt} failed:`,
1381
+ error
1382
+ );
1383
+ if (attempt < this.retries && this.shouldRetry(error)) {
1384
+ const delay = Math.pow(2, attempt) * 1e3;
1385
+ this.logger?.info(`Retrying in ${delay}ms...`);
1386
+ await this.delay(delay);
1387
+ return this.fetchWithRetry(url, options, attempt + 1);
1388
+ }
1389
+ this.logger?.error(`Failed after ${attempt} attempts:`, error);
1390
+ throw error;
1391
+ }
1392
+ }
1393
+ shouldRetry(error) {
1394
+ return error.name === "AbortError" || error.message?.includes("fetch") || (error.message?.includes("HTTP 5") ?? false);
1395
+ }
1396
+ delay(ms) {
1397
+ return new Promise((resolve) => setTimeout(resolve, ms));
1398
+ }
1399
+ };
1400
+
1401
+ // src/datasources/prisma.datasource.ts
1402
+ var PrismaD1Datasource = class extends AbstractDatasource {
1403
+ constructor(cache, context) {
1404
+ super(cache, context);
1405
+ this.name = "prisma-d1";
1406
+ this._client = null;
1407
+ }
1408
+ get client() {
1409
+ if (!this._client) {
1410
+ throw new Error("Prisma client not initialized. Call connect() first.");
1411
+ }
1412
+ return this._client;
1413
+ }
1414
+ async connect() {
1415
+ this.logger.info("Connecting Prisma D1 datasource...");
1416
+ if (!this.context.db) {
1417
+ const error = 'D1 database binding not found. Add to wrangler.toml:\n[[d1_databases]]\nbinding = "DB"\ndatabase_name = "your-database-name"\ndatabase_id = "your-database-id"';
1418
+ this.logger.error(error);
1419
+ throw new Error(error);
1420
+ }
1421
+ const clientKey = this.constructor.name;
1422
+ if (!global.__prismaD1Clients) {
1423
+ global.__prismaD1Clients = /* @__PURE__ */ new Map();
1424
+ }
1425
+ if (global.__prismaD1Clients.has(clientKey)) {
1426
+ this._client = global.__prismaD1Clients.get(clientKey);
1427
+ this.logger.debug(`Using cached Prisma client for ${clientKey}`);
1428
+ } else {
1429
+ this.logger.debug("Creating new PrismaD1 adapter and client...");
1430
+ const d1Module = await import("@prisma/adapter-d1");
1431
+ const PrismaD1 = d1Module.PrismaD1 ?? d1Module.default;
1432
+ const adapter = new PrismaD1(this.context.db);
1433
+ this._client = this.createClient(adapter);
1434
+ global.__prismaD1Clients.set(clientKey, this._client);
1435
+ this.logger.debug(`Cached new Prisma client for ${clientKey}`);
1436
+ }
1437
+ await this._client.$connect();
1438
+ this.logger.info("\u2713 Prisma D1 datasource connected");
1439
+ }
1440
+ // Helper method for proper resource cleanup in Workers context
1441
+ async disconnectWithContext(ctx) {
1442
+ if (!this._client) return;
1443
+ const disconnectPromise = this._client.$disconnect();
1444
+ if (ctx?.waitUntil) {
1445
+ ctx.waitUntil(disconnectPromise);
1446
+ } else {
1447
+ await disconnectPromise;
1448
+ }
1449
+ }
1450
+ async disconnect() {
1451
+ if (this._client) {
1452
+ await this._client.$disconnect();
1453
+ }
1454
+ }
1455
+ async healthCheck() {
1456
+ try {
1457
+ this.logger.debug("Prisma D1 datasource health check...");
1458
+ if (this._client) {
1459
+ await this._client.$queryRaw`SELECT 1`;
1460
+ }
1461
+ this.logger.info("Prisma D1 datasource health check: OK");
1462
+ return true;
1463
+ } catch (error) {
1464
+ this.logger.error("Prisma D1 datasource health check failed:", error);
1465
+ return false;
1466
+ }
1467
+ }
1468
+ /**
1469
+ * Execute a cached query using raw SQL
1470
+ */
1471
+ async queryRaw(sql, values, options) {
1472
+ const cacheKey = `prisma-d1:raw:${sql}:${JSON.stringify(values || [])}`;
1473
+ if (options?.cache !== false) {
1474
+ return this.cached(
1475
+ cacheKey,
1476
+ () => this._client.$queryRawUnsafe(sql, ...values || []),
1477
+ options?.ttl
1478
+ );
1479
+ }
1480
+ return this._client.$queryRawUnsafe(sql, ...values || []);
1481
+ }
1482
+ /**
1483
+ * Execute a mutation and invalidate cache
1484
+ */
1485
+ async executeRaw(sql, values, options) {
1486
+ if (!this._client) {
1487
+ throw new Error("Prisma client not initialized. Call connect() first.");
1488
+ }
1489
+ const result = await this._client.$executeRawUnsafe(sql, ...values || []);
1490
+ if (options?.invalidatePattern) {
1491
+ await this.invalidateCache(options.invalidatePattern);
1492
+ }
1493
+ return result;
1494
+ }
1495
+ };
1203
1496
  export {
1497
+ AbstractDatasource,
1204
1498
  ApolloDataSources,
1205
1499
  ApolloKVAdapter,
1206
1500
  AppError,
@@ -1209,6 +1503,8 @@ export {
1209
1503
  ErrorCode,
1210
1504
  InMemoryCache,
1211
1505
  KVCache,
1506
+ PrismaD1Datasource,
1507
+ RestDatasource,
1212
1508
  ServerBuilder,
1213
1509
  cached,
1214
1510
  configureHealthChecks,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/logger/index.ts","../src/context/constants.ts","../src/context/auth.ts","../src/cache/kv-cache.ts","../src/cache/batching-datasource.ts","../src/cache/apollo-cache-adapter.ts","../src/cache/index.ts","../src/env/config.ts","../src/context/index.ts","../src/utils/builder.util.ts","../src/server/server.builder.ts","../src/server/hono.configure.ts","../src/middleware/validation.ts","../src/middleware/rate-limit.ts","../src/middleware/tracing.ts","../src/middleware/health.ts","../src/utils/graphql.util.ts","../src/utils/tracing.util.ts","../src/logger/apollo.logger.ts","../src/server/plugin.configure.ts","../src/datasources/apollo-plugin.datasource.ts","../src/server/index.ts","../src/utils/error.util.ts","../src/utils/schema.util.ts"],"sourcesContent":["import pino from 'pino/browser';\n\n// Configuration for Cloudflare Workers environment\nconst isDev = process.env.NODE_ENV !== 'production';\nconst logLevel = process.env.LOG_LEVEL || (isDev ? 'debug' : 'info');\n\n// Custom serializers for Cloudflare Workers\nconst serializers = {\n err: (err: any) => {\n if (!err) return err;\n return {\n type: err.constructor?.name || err.name,\n message: err.message,\n stack: err.stack,\n code: err.code,\n statusCode: err.statusCode,\n };\n },\n req: (req: Request) => {\n if (!req) return req;\n return {\n method: req.method,\n url: req.url,\n headers: Object.fromEntries(req.headers.entries()),\n };\n },\n res: (res: Response) => {\n if (!res) return res;\n return {\n statusCode: res.status,\n headers: Object.fromEntries(res.headers.entries()),\n };\n },\n};\n\n// Create pino logger optimized for Cloudflare Workers\nexport const logger = pino({\n browser: {\n asObject: true,\n write: {\n info: (o: any) => {\n // In production, send to external logging service\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.log(JSON.stringify(o));\n },\n error: (o: any) => {\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.error(JSON.stringify(o));\n },\n debug: (o: any) => {\n if (isDev) {\n console.debug(JSON.stringify(o));\n }\n },\n warn: (o: any) => {\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.warn(JSON.stringify(o));\n },\n fatal: (o: any) => {\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.error(JSON.stringify(o));\n },\n trace: (o: any) => {\n if (isDev) {\n console.trace(JSON.stringify(o));\n }\n },\n },\n },\n level: logLevel,\n base: {\n env: process.env.NODE_ENV,\n service: 'graphql-subgraph',\n runtime: 'cloudflare-workers',\n },\n serializers,\n timestamp: () => `,\"timestamp\":\"${new Date().toISOString()}\"`,\n formatters: {\n level: (label: string) => {\n return {level: label.toUpperCase()};\n },\n log: (object: any) => {\n // Add request context if available\n if (globalThis.requestContext) {\n object.traceId = globalThis.requestContext.traceId;\n object.spanId = globalThis.requestContext.spanId;\n object.userId = globalThis.requestContext.userId;\n }\n return object;\n },\n },\n});\n\n// Helper for creating child loggers with context\nexport function createLogger(context: Record<string, any>) {\n return logger.child(context);\n}\n\n// Export pino types for TypeScript\nexport type Logger = typeof logger;\n\n// Declare global types for Cloudflare Workers\ndeclare global {\n var logshipper: {\n log: (data: any) => void;\n };\n var requestContext: {\n traceId?: string;\n spanId?: string;\n userId?: string;\n };\n}\n","export const Headers = {\n GATEWAY_USER: 'x-gateway-user',\n GATEWAY_USER_SIGNATURE: 'x-gateway-user-signature',\n AUTH: 'authorization',\n CLIENT_ID: 'x-client-id',\n} as const;\n","import type {ContextUser} from './types';\n\n/**\n * Verifies and parses user context from gateway headers\n * For Cloudflare Workers deployment, we use HMAC signature verification\n * to ensure the user data hasn't been tampered with\n */\nexport async function verifyAndParseUser(\n encodedUser: string | null,\n signature: string | null,\n secret: string\n): Promise<ContextUser | undefined> {\n if (!encodedUser || !signature) {\n return undefined;\n }\n\n try {\n // Verify HMAC signature\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n ['verify']\n );\n\n const signatureBuffer = hexToBuffer(signature);\n const dataBuffer = encoder.encode(encodedUser);\n\n const isValid = await crypto.subtle.verify(\n 'HMAC',\n key,\n signatureBuffer,\n dataBuffer\n );\n\n if (!isValid) {\n console.error('Invalid user signature');\n return undefined;\n }\n\n // Parse the verified user data\n const user = JSON.parse(atob(encodedUser));\n return user;\n } catch (error) {\n console.error('Error verifying user:', error);\n return undefined;\n }\n}\n\nfunction hexToBuffer(hex: string): ArrayBuffer {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n // Return the ArrayBuffer directly, not SharedArrayBuffer\n return bytes.buffer as ArrayBuffer;\n}\n","/**\n * KV Cache implementation for Cloudflare Workers\n * Provides caching capabilities for GraphQL resolvers using Cloudflare KV\n */\n\nexport interface CacheOptions {\n ttl?: number; // Time to live in seconds\n namespace?: string; // Cache namespace prefix\n cacheKey?: string; // Custom cache key\n}\n\nexport class KVCache {\n private defaultTTL: number = 300; // 5 minutes default\n private defaultNamespace: string = 'cache';\n\n constructor(\n private kv: KVNamespace,\n defaultNamespace?: string\n ) {\n if (defaultNamespace) {\n this.defaultNamespace = defaultNamespace;\n }\n }\n\n /**\n * Get a value from cache\n */\n async get<T = any>(key: string): Promise<T | null> {\n try {\n const value = await this.kv.get(key);\n if (!value) return null;\n\n // Try to parse JSON, fallback to raw value\n try {\n return JSON.parse(value);\n } catch {\n return value as T;\n }\n } catch (error) {\n console.error(`Cache get error for key ${key}:`, error);\n return null;\n }\n }\n\n /**\n * Set a value in cache with metadata\n */\n async set(\n key: string,\n value: any,\n options: CacheOptions = {}\n ): Promise<void> {\n try {\n const serialized =\n typeof value === 'string' ? value : JSON.stringify(value);\n\n const ttl = options.ttl || this.defaultTTL;\n const kvOptions: KVNamespacePutOptions = {\n expirationTtl: ttl,\n metadata: {\n createdAt: new Date().toISOString(),\n ttl: ttl,\n namespace: options.namespace || this.defaultNamespace,\n },\n };\n\n await this.kv.put(key, serialized, kvOptions);\n } catch (error) {\n console.error(`Cache set error for key ${key}:`, error);\n }\n }\n\n /**\n * Delete a value from cache\n */\n async delete(key: string): Promise<void> {\n try {\n await this.kv.delete(key);\n } catch (error) {\n console.error(`Cache delete error for key ${key}:`, error);\n }\n }\n\n /**\n * Check if a key exists in cache\n */\n async has(key: string): Promise<boolean> {\n try {\n const value = await this.kv.get(key);\n return value !== null;\n } catch (error) {\n console.error(`Cache has error for key ${key}:`, error);\n return false;\n }\n }\n\n /**\n * Clear multiple keys matching a prefix\n */\n async clearPrefix(prefix: string): Promise<number> {\n try {\n const list = await this.kv.list({prefix});\n const promises = list.keys.map((key) => this.kv.delete(key.name));\n await Promise.all(promises);\n return list.keys.length;\n } catch (error) {\n console.error(`Cache clear prefix error for ${prefix}:`, error);\n return 0;\n }\n }\n\n /**\n * Invalidate cache by pattern\n */\n async invalidate(pattern: string): Promise<number> {\n return this.clearPrefix(pattern);\n }\n\n /**\n * Clear all cache in a namespace\n */\n async clearNamespace(namespace?: string): Promise<number> {\n const prefix = namespace ? `${namespace}:` : `${this.defaultNamespace}:`;\n return this.invalidate(prefix);\n }\n\n /**\n * Get or set a value with a factory function\n * Useful for cache-aside pattern\n */\n async getOrSet<T>(\n key: string,\n factory: () => Promise<T>,\n options: CacheOptions = {}\n ): Promise<T> {\n // Try to get from cache first\n const cached = await this.get<T>(key);\n if (cached !== null) {\n return cached;\n }\n\n // Fetch fresh value\n const fresh = await factory();\n\n // Cache the fresh value (non-blocking)\n this.set(key, fresh, options).catch((error) => {\n console.error(`Background cache write error for ${key}:`, error);\n });\n\n return fresh;\n }\n\n /**\n * Memoize function with automatic key generation\n */\n async memoize<T>(\n cacheKey: string,\n params: any,\n fetchFn: () => Promise<T>,\n options: CacheOptions = {}\n ): Promise<T> {\n const namespace = options.namespace || this.defaultNamespace;\n const key = this.generateKey(`${namespace}:${cacheKey}`, params);\n\n try {\n // Try to get from cache\n const cached = await this.get<T>(key);\n if (cached !== null) {\n return cached;\n }\n } catch (error) {\n console.warn(`Cache read error for ${key}:`, error);\n }\n\n // Cache miss - fetch data\n const data = await fetchFn();\n\n // Store in cache (non-blocking)\n this.set(key, data, options).catch((error) => {\n console.warn(`Cache write error for ${key}:`, error);\n });\n\n return data;\n }\n\n /**\n * Generate cache key with namespace and params\n */\n private generateKey(namespace: string, params: any): string {\n const sortedParams = Object.keys(params)\n .sort()\n .reduce((obj: any, key) => {\n if (params[key] !== undefined && params[key] !== null) {\n obj[key] = params[key];\n }\n return obj;\n }, {});\n\n const paramString = JSON.stringify(sortedParams);\n const hash = this.simpleHash(paramString);\n return `${namespace}:${hash}`;\n }\n\n /**\n * Simple hash function for generating cache keys\n */\n private simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(36);\n }\n}\n\n/**\n * Create a cache key from multiple parts\n */\nexport function createCacheKey(\n ...parts: (string | number | undefined)[]\n): string {\n return parts\n .filter((part) => part !== undefined)\n .map((part) => String(part))\n .join(':');\n}\n\n/**\n * Cache key patterns for different data types\n */\nexport const CacheKeys = {\n user: (id: string) => createCacheKey('user', id),\n query: (name: string, variables?: string) =>\n createCacheKey('query', name, variables),\n list: (type: string, page?: number) => createCacheKey('list', type, page),\n permission: (userId: string, resource: string) =>\n createCacheKey('perm', userId, resource),\n} as const;\n","import DataLoader, {type BatchLoadFn, type Options} from 'dataloader';\nimport type {BaseContext} from '@/context';\nimport {KVCache} from './kv-cache';\n\n/**\n * Ensures that output items has the same order as input keys (dataloader requirement).\n * Returns error objects for non-existent ids.\n *\n * @param keys list of input keys\n * @param items list of output items\n * @param primaryKey name of the key-holding property\n */\nexport function ensureBatchOrder<\n K extends string | number,\n T extends Record<string, any>,\n>(keys: readonly K[], items: T[], primaryKey = 'id'): Array<T | Error> {\n const itemsMap = new Map<K, T>();\n\n // Build a map for O(1) lookups\n for (const item of items) {\n const key = item[primaryKey] as K;\n if (key !== undefined) {\n itemsMap.set(key, item);\n }\n }\n\n // Return items in the same order as keys\n return keys.map(\n (key) =>\n itemsMap.get(key) || new Error(`Missing value for ${primaryKey} ${key}`)\n );\n}\n\n/**\n * Ensures that output items has the same order as input keys (dataloader requirement).\n * Returns null for non-existent ids.\n *\n * @param keys list of input keys\n * @param items list of output items\n * @param primaryKey name of the key-holding property\n */\nexport function ensureBatchOrderNullable<\n K extends string | number,\n T extends Record<string, any>,\n>(keys: readonly K[], items: T[], primaryKey = 'id'): Array<T | null> {\n const itemsMap = new Map<K, T>();\n\n // Build a map for O(1) lookups\n for (const item of items) {\n const key = item[primaryKey] as K;\n if (key !== undefined) {\n itemsMap.set(key, item);\n }\n }\n\n // Return items in the same order as keys, with nulls for missing\n return keys.map((key) => itemsMap.get(key) || null);\n}\n\n/**\n * Base class for batching data sources with caching support.\n * Uses DataLoader for request batching and deduplication.\n *\n * @typeParam TContext - Apollo context type\n * @typeParam K - Primary key type\n * @typeParam V - Output item type\n * @typeParam CK - Cache key type (same as K by default)\n *\n * @example\n * ```typescript\n * export class UserBatchingDataSource extends BatchingDataSource<BaseContext, string, User> {\n * constructor() {\n * super(async (ids: readonly string[]) => {\n * const users = await fetchUsersFromDB(ids);\n * return ensureBatchOrder(ids, users);\n * });\n * }\n * }\n * ```\n */\nexport class BatchingDataSource<TContext extends BaseContext, K, V, CK = K> {\n protected context!: TContext;\n protected loader: DataLoader<K, V, CK>;\n protected cache?: KVCache;\n\n /**\n * Creates a new batching data source\n *\n * @param resolveBatch - Batch resolving function\n * @param options - DataLoader options\n * @param cacheNamespace - Optional namespace for KV caching\n */\n constructor(\n resolveBatch: BatchLoadFn<K, V>,\n options: Options<K, V, CK> = {},\n protected cacheNamespace?: string\n ) {\n // Bind context to the batch function\n const boundResolveBatch: BatchLoadFn<K, V> = async (keys) => {\n // If we have cache, try to load from cache first\n if (this.cache && this.cacheNamespace) {\n const results: Array<V | undefined> = [];\n const uncachedKeys: K[] = [];\n const uncachedIndexes: number[] = [];\n\n // Check cache for each key\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const cacheKey = `${this.cacheNamespace}:${String(key)}`;\n const cached = await this.cache.get<V>(cacheKey);\n\n if (cached !== null) {\n results[i] = cached;\n } else {\n uncachedKeys.push(key);\n uncachedIndexes.push(i);\n }\n }\n\n // If all items were cached, return them\n if (uncachedKeys.length === 0) {\n return results as V[];\n }\n\n // Fetch uncached items\n const freshItems = await resolveBatch.call(this, uncachedKeys);\n\n // Merge fresh items back and cache them\n for (let i = 0; i < uncachedIndexes.length; i++) {\n const index = uncachedIndexes[i];\n const item = freshItems[i] as V;\n const key = uncachedKeys[i];\n\n results[index] = item;\n\n // Cache the fresh item (non-blocking)\n if (!(item instanceof Error) && item !== null && item !== undefined) {\n const cacheKey = `${this.cacheNamespace}:${String(key)}`;\n this.cache.set(cacheKey, item, {ttl: 300}).catch((err) => {\n console.warn(`Failed to cache item ${cacheKey}:`, err);\n });\n }\n }\n\n return results as V[];\n }\n\n // No cache, just resolve normally\n return resolveBatch.call(this, keys);\n };\n\n this.loader = new DataLoader(boundResolveBatch, {\n ...options,\n // Default to caching within the request\n cache: options.cache !== false,\n });\n }\n\n /**\n * Initialize with Apollo context\n */\n initialize(config: {contextValue: TContext}) {\n this.context = config.contextValue;\n this.cache = config.contextValue.cache;\n }\n\n /**\n * Load a single item by key\n */\n async load(id: K): Promise<V> {\n return this.loader.load(id);\n }\n\n /**\n * Load multiple items by keys\n */\n async loadMany(ids: readonly K[]): Promise<Array<V | Error>> {\n return this.loader.loadMany(ids);\n }\n\n /**\n * Clear a single item from the DataLoader cache\n */\n clear(id: K): this {\n this.loader.clear(id);\n return this;\n }\n\n /**\n * Clear all items from the DataLoader cache\n */\n clearAll(): this {\n this.loader.clearAll();\n return this;\n }\n\n /**\n * Prime the cache with a specific value\n */\n prime(key: K, value: V): this {\n this.loader.prime(key, value);\n return this;\n }\n}\n\n/**\n * Factory function for creating batching data sources\n *\n * @example\n * ```typescript\n * const userDataSource = createBatchingDataSource<BaseContext, string, User>(\n * async (ids) => {\n * const users = await fetchUsersFromDB(ids);\n * return ensureBatchOrder(ids, users);\n * },\n * { cache: true },\n * 'users'\n * );\n * ```\n */\nexport function createBatchingDataSource<\n TContext extends BaseContext,\n K,\n V,\n CK = K,\n>(\n resolveBatch: BatchLoadFn<K, V>,\n options?: Options<K, V, CK>,\n cacheNamespace?: string\n): BatchingDataSource<TContext, K, V, CK> {\n return new BatchingDataSource(resolveBatch, options, cacheNamespace);\n}\n","/**\n * Apollo KeyValueCache adapter for Cloudflare KV\n *\n * Implements the Apollo Server KeyValueCache interface to work with\n * Cloudflare Workers KV storage.\n */\n\nimport type {\n KeyValueCache,\n KeyValueCacheSetOptions,\n} from '@apollo/utils.keyvaluecache';\nimport {KVCache} from './kv-cache';\n\n/**\n * Adapter that makes our KVCache compatible with Apollo's KeyValueCache interface\n *\n * Apollo Server uses this for:\n * - Response caching\n * - APQ (Automatic Persisted Queries)\n * - DataSource caching\n *\n * @example\n * ```typescript\n * const apolloCache = new ApolloKVAdapter(new KVCache(env.KV));\n *\n * const server = new ApolloServer({\n * cache: apolloCache,\n * // ... other options\n * });\n * ```\n */\nexport class ApolloKVAdapter implements KeyValueCache<string> {\n constructor(private kvCache: KVCache) {}\n\n /**\n * Get a value from cache\n * Apollo expects undefined for cache misses\n */\n async get(key: string): Promise<string | undefined> {\n const value = await this.kvCache.get<string>(key);\n // Apollo expects undefined, not null for cache misses\n return value === null ? undefined : value;\n }\n\n /**\n * Set a value in cache with TTL support\n * Apollo passes TTL in seconds via options\n */\n async set(\n key: string,\n value: string,\n options?: KeyValueCacheSetOptions\n ): Promise<void> {\n await this.kvCache.set(key, value, {\n ttl: options?.ttl, // Apollo's TTL is already in seconds\n });\n }\n\n /**\n * Delete a value from cache\n * Apollo expects boolean or void return\n */\n async delete(key: string): Promise<boolean | void> {\n await this.kvCache.delete(key);\n return true;\n }\n}\n\n/**\n * Factory function to create an Apollo-compatible cache from KV namespace\n *\n * @param kv - Cloudflare KV namespace binding\n * @returns Apollo-compatible KeyValueCache\n */\nexport function createApolloCache(kv: KVNamespace): KeyValueCache<string> {\n return new ApolloKVAdapter(new KVCache(kv));\n}\n\n/**\n * In-memory LRU cache for development/testing\n * Falls back to simple Map-based implementation\n */\nexport class InMemoryCache implements KeyValueCache<string> {\n private cache = new Map<string, {value: string; expires?: number}>();\n\n async get(key: string): Promise<string | undefined> {\n const item = this.cache.get(key);\n if (!item) return undefined;\n\n // Check expiration\n if (item.expires && Date.now() > item.expires) {\n this.cache.delete(key);\n return undefined;\n }\n\n return item.value;\n }\n\n async set(\n key: string,\n value: string,\n options?: KeyValueCacheSetOptions\n ): Promise<void> {\n const expires = options?.ttl\n ? Date.now() + options.ttl * 1000 // Convert seconds to milliseconds\n : undefined;\n\n this.cache.set(key, {value, expires});\n }\n\n async delete(key: string): Promise<boolean> {\n return this.cache.delete(key);\n }\n\n /**\n * Clear all cache entries\n */\n clear(): void {\n this.cache.clear();\n }\n}\n","/**\n * Cache module for GraphQL resolvers\n * Provides caching interface for Cloudflare Workers KV\n */\n\nimport {KVCache, createCacheKey, CacheKeys} from './kv-cache';\nimport type {CacheOptions} from './kv-cache';\nimport {\n BatchingDataSource,\n createBatchingDataSource,\n ensureBatchOrder,\n ensureBatchOrderNullable,\n} from './batching-datasource';\nimport {\n ApolloKVAdapter,\n createApolloCache,\n InMemoryCache,\n} from './apollo-cache-adapter';\n\nexport {KVCache, createCacheKey, CacheKeys};\nexport type {CacheOptions};\nexport {\n BatchingDataSource,\n createBatchingDataSource,\n ensureBatchOrder,\n ensureBatchOrderNullable,\n};\nexport {ApolloKVAdapter, createApolloCache, InMemoryCache};\n\n/**\n * Cache factory - creates KV cache if available\n */\nexport function createCache(env: Env): KVCache | null {\n // Check for KV namespace (Cloudflare Workers KV)\n if (env.KV) {\n return new KVCache(env.KV);\n }\n\n // No cache available\n return null;\n}\n\n/**\n * Decorator for caching resolver results\n */\nexport function cached(\n options: CacheOptions & {keyGenerator?: (...args: any[]) => string} = {}\n) {\n return function (\n target: any,\n propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]) {\n const context = args[2]; // GraphQL context is third argument\n const cache = context?.cache;\n\n if (!cache) {\n // No cache available, run original method\n return originalMethod.apply(this, args);\n }\n\n // Generate cache key\n const key = options.keyGenerator\n ? options.keyGenerator(...args)\n : createCacheKey(propertyKey, JSON.stringify(args[1])); // Use field name and arguments\n\n // Try cache-aside pattern\n return cache.getOrSet(\n key,\n () => originalMethod.apply(this, args),\n options\n );\n };\n\n return descriptor;\n };\n}\n\n/**\n * GraphQL DataLoader integration for batching and caching\n */\nexport class CachedDataLoader<K, V> {\n private loader: any; // DataLoader instance\n private cache: KVCache;\n\n constructor(\n batchFn: (keys: K[]) => Promise<V[]>,\n cache: KVCache,\n private options: CacheOptions = {}\n ) {\n this.cache = cache;\n\n // Initialize DataLoader with cache\n // Note: DataLoader is not included by default, install if needed\n // this.loader = new DataLoader(batchFn, { cache: this.createCacheMap() });\n }\n\n async load(key: K): Promise<V> {\n const cacheKey = createCacheKey('loader', String(key));\n\n return this.cache.getOrSet(\n cacheKey,\n async () => {\n // Fallback to batch function for single key\n // In production, use actual DataLoader\n return this.loader ? this.loader.load(key) : null;\n },\n this.options\n );\n }\n\n async loadMany(keys: K[]): Promise<V[]> {\n return Promise.all(keys.map((key) => this.load(key)));\n }\n\n async clear(key: K): Promise<void> {\n const cacheKey = createCacheKey('loader', String(key));\n await this.cache.delete(cacheKey);\n }\n\n async clearAll(): Promise<void> {\n await this.cache.clearPrefix('loader:');\n }\n}\n","/**\n * Environment configuration type\n */\nexport interface EnvConfig {\n // Core\n NODE_ENV: 'development' | 'test' | 'production';\n PORT: number;\n\n // Security\n GATEWAY_SECRET?: string;\n ALLOWED_ORIGINS: string[];\n\n // Logging\n LOG_LEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n\n // Rate limiting\n RATE_LIMIT_WINDOW_MS: number;\n RATE_LIMIT_MAX: number;\n\n // Monitoring\n ENABLE_METRICS: boolean;\n ENABLE_TRACING: boolean;\n\n // GraphQL\n MAX_QUERY_DEPTH: number;\n MAX_QUERY_COMPLEXITY: number;\n INTROSPECTION_ENABLED: boolean;\n\n // External services (optional)\n LOG_SERVICE_URL?: string;\n LOG_SERVICE_TOKEN?: string;\n}\n\n/**\n * Lightweight environment parser inspired by @ltv/env\n */\nclass EnvParser {\n constructor(private env: Record<string, any>) {}\n\n string(key: string): string | undefined;\n string(key: string, defaultValue: string): string;\n string(key: string, defaultValue?: string): string | undefined {\n const value = this.env[key];\n return value !== undefined && value !== '' ? String(value) : defaultValue;\n }\n\n int(key: string): number | undefined;\n int(key: string, defaultValue: number): number;\n int(key: string, defaultValue?: number): number | undefined {\n const value = this.env[key];\n if (value === undefined || value === '') return defaultValue;\n const parsed = parseInt(String(value), 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n\n bool(key: string): boolean | undefined;\n bool(key: string, defaultValue: boolean): boolean;\n bool(key: string, defaultValue?: boolean): boolean | undefined {\n const value = this.env[key];\n if (value === undefined || value === '') return defaultValue;\n const str = String(value).toLowerCase();\n return str === 'true' || str === '1';\n }\n\n array(key: string): string[] | undefined;\n array(key: string, defaultValue: string[]): string[];\n array(key: string, defaultValue?: string[]): string[] | undefined {\n const value = this.env[key];\n if (value === undefined || value === '') return defaultValue;\n if (Array.isArray(value)) return value;\n return String(value)\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n }\n\n enum<T extends string>(key: string, validValues: T[]): T | undefined;\n enum<T extends string>(key: string, validValues: T[], defaultValue: T): T;\n enum<T extends string>(\n key: string,\n validValues: T[],\n defaultValue?: T\n ): T | undefined {\n const value = this.string(key);\n if (value && validValues.includes(value as T)) {\n return value as T;\n }\n return defaultValue;\n }\n}\n\n/**\n * Environment loader for Cloudflare Workers\n */\nexport class EnvironmentLoader {\n private config: EnvConfig | null = null;\n\n /**\n * Load environment from Cloudflare Workers env object\n */\n load(env: Record<string, any>): EnvConfig {\n const parser = new EnvParser(env);\n\n this.config = {\n NODE_ENV: parser.enum(\n 'NODE_ENV',\n ['development', 'test', 'production'],\n 'production'\n ),\n PORT: parser.int('PORT', 3344),\n GATEWAY_SECRET: parser.string('GATEWAY_SECRET'),\n ALLOWED_ORIGINS: parser.array('ALLOWED_ORIGINS', [\n 'http://localhost:3000',\n ]),\n LOG_LEVEL: parser.enum(\n 'LOG_LEVEL',\n ['trace', 'debug', 'info', 'warn', 'error', 'fatal'],\n 'info'\n ),\n RATE_LIMIT_WINDOW_MS: parser.int('RATE_LIMIT_WINDOW_MS', 60000),\n RATE_LIMIT_MAX: parser.int('RATE_LIMIT_MAX', 100),\n ENABLE_METRICS: parser.bool('ENABLE_METRICS', true),\n ENABLE_TRACING: parser.bool('ENABLE_TRACING', true),\n MAX_QUERY_DEPTH: parser.int('MAX_QUERY_DEPTH', 10),\n MAX_QUERY_COMPLEXITY: parser.int('MAX_QUERY_COMPLEXITY', 1000),\n INTROSPECTION_ENABLED: parser.bool('INTROSPECTION_ENABLED', false),\n LOG_SERVICE_URL: parser.string('LOG_SERVICE_URL'),\n LOG_SERVICE_TOKEN: parser.string('LOG_SERVICE_TOKEN'),\n };\n\n return this.config;\n }\n\n /**\n * Get current configuration\n */\n getConfig(): EnvConfig {\n if (!this.config) {\n throw new Error('Environment not loaded. Call load() first.');\n }\n return this.config;\n }\n\n /**\n * Helper getters for common checks\n */\n get isDev(): boolean {\n return this.config?.NODE_ENV === 'development';\n }\n\n get isTest(): boolean {\n return this.config?.NODE_ENV === 'test';\n }\n\n get isProd(): boolean {\n return this.config?.NODE_ENV === 'production';\n }\n}\n\n// Singleton instance\nexport const envLoader = new EnvironmentLoader();\n","import type {BaseContext as ApolloBaseContext} from '@apollo/server';\nimport type {ExecutionContext} from '@cloudflare/workers-types';\nimport type {CloudflareContextFunctionArgument} from '@as-integrations/cloudflare-workers';\nimport {logger} from '../logger';\nimport {Headers} from './constants';\nimport {verifyAndParseUser} from './auth';\nimport type {ContextUser} from './types';\nimport {createCache} from '@/cache';\nimport type {KVCache} from '@/cache';\nimport {envLoader, type EnvConfig} from '@/env';\n\nexport type {ContextUser} from './types';\n\n// TODO: Replace with actual jaeger types when available\nexport interface JaegerContext {\n rootSpan?: {\n getBaggageItem: (key: string) => string | undefined;\n };\n}\n\nexport interface BaseContext extends JaegerContext, ApolloBaseContext {\n user?: ContextUser;\n logger: typeof logger;\n executionCtx: ExecutionContext;\n cache?: KVCache; // KV cache for resolvers\n env: EnvConfig; // Validated environment configuration\n\n /** @deprecated should not be used directly */\n authorization: string;\n clientId: string;\n}\n\nexport type ContextExtendFunction<T extends BaseContext> = (\n ctx: BaseContext,\n honoContext: CloudflareContextFunctionArgument<unknown>\n) => T | Promise<T>;\n\nasync function createBaseContext(\n honoContext: CloudflareContextFunctionArgument<any>\n): Promise<BaseContext> {\n const request = honoContext.request;\n const rawEnv = honoContext.env;\n\n // Load and validate environment configuration\n const env = envLoader.load(rawEnv);\n\n // Parse user from gateway headers with signature verification\n let user: ContextUser | undefined;\n\n // Check if this is a subgraph request from gateway\n const encodedUser = request.headers.get(Headers.GATEWAY_USER);\n if (encodedUser) {\n // In production, verify signature. In dev, allow without signature\n if (env.GATEWAY_SECRET) {\n const signature = request.headers.get(Headers.GATEWAY_USER_SIGNATURE);\n user = await verifyAndParseUser(\n encodedUser,\n signature,\n env.GATEWAY_SECRET\n );\n } else if (env.NODE_ENV !== 'production') {\n // Development mode: parse without verification\n try {\n user = JSON.parse(atob(encodedUser));\n } catch (e) {\n console.error('Failed to parse user in dev mode:', e);\n }\n }\n }\n\n // Create cache instance - KV is now required\n // Pass raw env for KV bindings, not the parsed config\n const cache = createCache(rawEnv) as KVCache | undefined;\n if (!cache) {\n // This should not happen as ServerBuilder validates KV exists\n logger.warn(\n 'KV cache not found in context - this should not happen if using ServerBuilder'\n );\n }\n\n return {\n user,\n logger,\n cache,\n env, // Pass validated env config\n executionCtx: honoContext.ctx,\n authorization: request.headers.get(Headers.AUTH) || '',\n clientId: request.headers.get(Headers.CLIENT_ID) || '',\n };\n}\n\nexport function createContextFunction<T extends BaseContext>(\n extendContext?: ContextExtendFunction<T>\n) {\n if (!extendContext) {\n return (honoContext: CloudflareContextFunctionArgument<unknown>) =>\n createBaseContext(honoContext);\n }\n\n return async (honoContext: CloudflareContextFunctionArgument<unknown>) => {\n const baseContext = await createBaseContext(honoContext);\n return extendContext(baseContext, honoContext);\n };\n}\n","export function assertDefined<T>(t: T | undefined, msg: string): t is T {\n if (t === undefined) {\n throw new Error('Assertion failed when configuring server: ' + msg);\n }\n return true;\n}\n","import {\n createContextFunction,\n type BaseContext,\n type ContextExtendFunction,\n} from '@/context';\nimport {createApolloCache} from '@/cache';\nimport {assertDefined} from '@/utils/builder.util';\nimport type {ApolloServerOptions, ApolloServerPlugin} from '@apollo/server';\nimport {ApolloServer} from '@apollo/server';\nimport type {KeyValueCache} from '@apollo/utils.keyvaluecache';\nimport {startServerAndCreateCloudflareWorkersHandler} from '@as-integrations/cloudflare-workers';\nimport type {GraphQLSchema} from 'graphql';\nimport type {Hono} from 'hono';\nimport {configureHono} from './hono.configure';\nimport {configurePlugins} from './plugin.configure';\nimport {ApolloDataSources} from '../datasources/apollo-plugin.datasource';\n\nexport type Runner = {\n fetch: typeof Hono.prototype.fetch;\n port?: number;\n};\n\nexport type ServerConfig<TDatasource, TContext extends BaseContext> = {\n path?: string;\n apollo: Partial<ApolloServerOptions<BaseContext>>;\n datasources?: (\n cache: KeyValueCache<string>,\n context: TContext\n ) => TDatasource;\n extendContext?: ContextExtendFunction<TContext>;\n};\n\nexport class ServerBuilder<TDatasource, TContext extends BaseContext> {\n readonly app: Hono;\n\n readonly schema: GraphQLSchema;\n readonly plugins: ApolloServerPlugin<BaseContext>[] = [];\n\n constructor(readonly config: ServerConfig<TDatasource, TContext>) {\n this.assert();\n\n // TODO: Configure metrics\n this.app = configureHono(this);\n this.schema = this.config.apollo.schema as GraphQLSchema;\n }\n\n configure(): Runner {\n const honoApp = this.app;\n configurePlugins(this);\n\n // Build plugins array with datasources if defined\n const plugins: ApolloServerPlugin<TContext>[] = [...this.plugins];\n\n // Add datasources plugin if datasources function is provided\n if (this.config.datasources) {\n plugins.push(\n ApolloDataSources({\n datasources: this.config.datasources as any,\n }) as any\n );\n }\n\n // We need to create the Apollo server for each request to pass the correct cache\n const createHandler = (env: any) => {\n // Validate KV binding exists\n if (!env?.KV) {\n throw new Error(\n 'Missing required KV namespace binding. ' +\n 'Please add KV namespace binding in your wrangler.toml:\\n' +\n '[[kv_namespaces]]\\n' +\n 'binding = \"KV\"\\n' +\n 'id = \"your-kv-namespace-id\"'\n );\n }\n\n // Create Apollo cache from KV\n const apolloCache = createApolloCache(env.KV);\n\n // Create Apollo server with cache\n // We need to ensure we don't include gateway if schema is provided\n const {gateway, ...apolloConfigWithoutGateway} = this.config.apollo || {};\n\n const server = new ApolloServer<TContext>({\n ...apolloConfigWithoutGateway, // User config without gateway\n schema: this.schema, // Our schema\n plugins, // Our plugins\n cache: apolloCache, // Apollo cache for APQ and response caching (override any user cache)\n } as ApolloServerOptions<TContext>);\n\n return startServerAndCreateCloudflareWorkersHandler<any, any>(server, {\n context: async (c) =>\n createContextFunction(this.config.extendContext)(c),\n });\n };\n\n // Cache handlers per environment (for efficiency)\n const handlerCache = new WeakMap();\n\n const getOrCreateHandler = (env: any) => {\n if (!handlerCache.has(env)) {\n handlerCache.set(env, createHandler(env));\n }\n return handlerCache.get(env);\n };\n\n honoApp.all(this.config.path ?? '/', async (c) => {\n // Get or create handler for this environment\n const cfHandler = getOrCreateHandler(c.env);\n\n // In local development, executionCtx doesn't exist\n // In Cloudflare Workers, it's provided\n let executionCtx;\n try {\n executionCtx = c.executionCtx;\n } catch (e) {\n // Create a mock executionCtx for local development\n executionCtx = {\n waitUntil: (promise: Promise<any>) => promise,\n passThroughOnException: () => {},\n };\n }\n return cfHandler(c.req.raw, c.env, executionCtx);\n });\n\n return {\n async fetch(request, env, ctx) {\n return honoApp.fetch(request, env, ctx);\n },\n };\n }\n\n assert() {\n assertDefined(\n this.config.apollo.schema,\n 'Apollo server config must have a schema'\n );\n }\n}\n","import {BaseContext} from '@/context';\nimport {Hono} from 'hono';\nimport {cors} from 'hono/cors';\nimport {compress} from 'hono/compress';\nimport {ServerBuilder} from './server.builder';\nimport {createValidationMiddleware} from '@/middleware/validation';\nimport {createRateLimitMiddleware} from '@/middleware/rate-limit';\nimport {createTracingMiddleware} from '@/middleware/tracing';\nimport {configureHealthChecks} from '@/middleware/health';\n\nexport function configureHono<TContext extends BaseContext>(\n builder: ServerBuilder<unknown, TContext>\n) {\n const app = new Hono();\n\n // Add environment to context for all middleware\n app.use('*', async (c, next) => {\n // Get environment from Cloudflare or set default\n const rawEnv = c.env || {};\n const env =\n typeof rawEnv.NODE_ENV !== 'undefined'\n ? rawEnv // Cloudflare Workers env\n : {}; // Local development fallback\n c.set('env', env);\n await next();\n });\n\n // Add request tracing first for all requests\n app.use('*', createTracingMiddleware());\n\n // Add compression for responses\n app.use('*', compress());\n\n // Add validation middleware\n app.use('*', createValidationMiddleware());\n\n // Add rate limiting\n app.use('*', createRateLimitMiddleware());\n\n // Configure health checks\n configureHealthChecks(app, {\n checks: {\n graphql: async () => true, // Check GraphQL schema is loaded\n },\n });\n\n // Configure CORS for development and production\n app.use(\n '/*',\n cors({\n origin: (origin, c) => {\n // Get environment from context\n const env = c.env;\n const isProd = env.NODE_ENV === 'production';\n const allowedOrigins = env.ALLOWED_ORIGINS\n ? typeof env.ALLOWED_ORIGINS === 'string'\n ? env.ALLOWED_ORIGINS.split(',').map((s) => s.trim())\n : env.ALLOWED_ORIGINS\n : ['http://localhost:3000'];\n\n // Allow all origins in development\n if (!isProd) {\n return origin || '*';\n }\n // In production, configure allowed origins\n return allowedOrigins.includes(origin) ? origin : allowedOrigins[0];\n },\n allowHeaders: [\n 'Content-Type',\n 'Authorization',\n 'x-apollo-operation-name',\n 'apollo-require-preflight',\n ],\n allowMethods: ['POST', 'GET', 'OPTIONS'],\n credentials: true,\n maxAge: 86400,\n })\n );\n\n // Add security headers\n app.use('*', async (c, next) => {\n await next();\n\n const env = c.get('env');\n const isProd = env?.NODE_ENV === 'production';\n\n // Security headers for GraphQL endpoints\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('X-Frame-Options', 'DENY');\n c.header('X-XSS-Protection', '1; mode=block');\n c.header('Referrer-Policy', 'strict-origin-when-cross-origin');\n\n // Remove server identification\n c.header('Server', 'GraphQL');\n\n // Content Security Policy for GraphQL\n if (isProd) {\n c.header(\n 'Content-Security-Policy',\n \"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';\"\n );\n // HSTS for production\n c.header(\n 'Strict-Transport-Security',\n 'max-age=31536000; includeSubDomains; preload'\n );\n }\n });\n\n return app;\n}\n","import type {MiddlewareHandler} from 'hono';\nimport {AppError, ErrorCode} from '@/utils/error.util';\n\ninterface ValidationOptions {\n maxQueryDepth?: number;\n maxQueryComplexity?: number;\n maxAliasCount?: number;\n}\n\nexport function createValidationMiddleware(\n options: ValidationOptions = {}\n): MiddlewareHandler {\n return async (c, next) => {\n try {\n // Get environment from context\n const env = c.get('env');\n const maxQueryDepth = options.maxQueryDepth || env?.MAX_QUERY_DEPTH || 10;\n const maxQueryComplexity =\n options.maxQueryComplexity || env?.MAX_QUERY_COMPLEXITY || 1000;\n const maxAliasCount = options.maxAliasCount || 15;\n // Validate content type for GraphQL\n const contentType = c.req.header('content-type');\n if (\n c.req.method === 'POST' &&\n !contentType?.includes('application/json')\n ) {\n return c.json(\n {\n errors: [\n {\n message: 'Content-Type must be application/json',\n extensions: {code: 'BAD_REQUEST'},\n },\n ],\n },\n 400\n );\n }\n\n // Rate limiting headers check\n const clientId = c.req.header('x-client-id');\n if (!clientId && env?.NODE_ENV === 'production') {\n return c.json(\n {\n errors: [\n {\n message: 'Client identification required',\n extensions: {code: 'BAD_REQUEST'},\n },\n ],\n },\n 400\n );\n }\n\n await next();\n } catch (error) {\n console.error('Validation middleware error:', error);\n return c.json(\n {\n errors: [\n {\n message: 'Request validation failed',\n extensions: {code: 'INTERNAL_SERVER_ERROR'},\n },\n ],\n },\n 500\n );\n }\n };\n}\n","import type {MiddlewareHandler} from 'hono';\n\ninterface RateLimitOptions {\n windowMs?: number;\n max?: number;\n keyGenerator?: (c: any) => string;\n}\n\nexport function createRateLimitMiddleware(\n options: RateLimitOptions = {}\n): MiddlewareHandler {\n const {\n keyGenerator = (c) =>\n c.req.header('x-client-id') ||\n c.req.header('cf-connecting-ip') ||\n 'anonymous',\n } = options;\n\n return async (c, next) => {\n // Get environment from context\n const env = c.get('env');\n const windowMs = options.windowMs || env?.RATE_LIMIT_WINDOW_MS || 60 * 1000;\n const max = options.max || env?.RATE_LIMIT_MAX || 100;\n\n const key = keyGenerator(c);\n const rateLimitKey = `rate_limit:${key}`;\n\n // In Cloudflare Workers, use KV or Durable Objects for rate limiting\n // This is a simplified example\n if (c.env?.RATE_LIMIT_KV) {\n const current = await c.env.RATE_LIMIT_KV.get(rateLimitKey);\n const count = current ? parseInt(current, 10) : 0;\n\n if (count >= max) {\n return c.json(\n {\n errors: [\n {\n message: 'Too many requests',\n extensions: {\n code: 'RATE_LIMITED',\n retryAfter: windowMs / 1000,\n },\n },\n ],\n },\n 429,\n {\n 'Retry-After': String(windowMs / 1000),\n 'X-RateLimit-Limit': String(max),\n 'X-RateLimit-Remaining': '0',\n 'X-RateLimit-Reset': String(Date.now() + windowMs),\n }\n );\n }\n\n // Increment counter\n await c.env.RATE_LIMIT_KV.put(rateLimitKey, String(count + 1), {\n expirationTtl: windowMs / 1000,\n });\n\n // Add rate limit headers\n c.header('X-RateLimit-Limit', String(max));\n c.header('X-RateLimit-Remaining', String(max - count - 1));\n c.header('X-RateLimit-Reset', String(Date.now() + windowMs));\n }\n\n await next();\n };\n}\n","import type {MiddlewareHandler} from 'hono';\nimport {logger} from '@/logger';\n\nexport function createTracingMiddleware(): MiddlewareHandler {\n return async (c, next) => {\n // Get environment from context\n const env = c.get('env');\n // Extract or generate trace ID\n const traceId = c.req.header('x-trace-id') || generateTraceId();\n const spanId = generateSpanId();\n const parentSpanId = c.req.header('x-parent-span-id');\n const userId = c.get('userId');\n\n // Set global request context for pino logger\n globalThis.requestContext = {\n traceId,\n spanId,\n userId,\n };\n\n // Store in Hono context for other middleware\n c.set('traceId', traceId);\n c.set('spanId', spanId);\n\n // Add to response headers for correlation\n c.header('x-trace-id', traceId);\n c.header('x-span-id', spanId);\n\n const startTime = Date.now();\n\n try {\n await next();\n } finally {\n const duration = Date.now() - startTime;\n\n // Log request metrics using pino\n logger.info(\n {\n type: 'request',\n traceId,\n spanId,\n parentSpanId,\n method: c.req.method,\n path: c.req.path,\n status: c.res.status,\n duration,\n userAgent: c.req.header('user-agent'),\n ip:\n c.req.header('cf-connecting-ip') || c.req.header('x-forwarded-for'),\n },\n `${c.req.method} ${c.req.path} - ${c.res.status} (${duration}ms)`\n );\n\n // Add Server-Timing header for performance monitoring\n c.header('Server-Timing', `total;dur=${duration}`);\n\n // Clear global request context\n delete globalThis.requestContext;\n }\n };\n}\n\nfunction generateTraceId(): string {\n // Generate a 32-character hex string (128 bits)\n return Array.from(crypto.getRandomValues(new Uint8Array(16)))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nfunction generateSpanId(): string {\n // Generate a 16-character hex string (64 bits)\n return Array.from(crypto.getRandomValues(new Uint8Array(8)))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n","import type {Hono} from 'hono';\n\ninterface HealthCheckOptions {\n checks?: {\n [key: string]: () => Promise<boolean>;\n };\n}\n\nexport function configureHealthChecks(\n app: Hono,\n options: HealthCheckOptions = {}\n) {\n // Liveness probe - is the service running?\n app.get('/health', (c) => {\n return c.json({\n status: 'ok',\n timestamp: new Date().toISOString(),\n uptime: process.uptime ? process.uptime() : 0,\n });\n });\n\n // Readiness probe - is the service ready to accept traffic?\n app.get('/ready', async (c) => {\n const checks = options.checks || {};\n const results: Record<string, boolean> = {};\n let allHealthy = true;\n\n for (const [name, check] of Object.entries(checks)) {\n try {\n results[name] = await check();\n if (!results[name]) allHealthy = false;\n } catch (error) {\n results[name] = false;\n allHealthy = false;\n }\n }\n\n const status = allHealthy ? 200 : 503;\n return c.json(\n {\n status: allHealthy ? 'ready' : 'not_ready',\n checks: results,\n timestamp: new Date().toISOString(),\n },\n status\n );\n });\n\n // Metrics endpoint (for Prometheus)\n app.get('/metrics', (c) => {\n // In production, integrate with Prometheus client\n return c.text(`# HELP graphql_requests_total Total number of GraphQL requests\n# TYPE graphql_requests_total counter\ngraphql_requests_total 0\n\n# HELP graphql_errors_total Total number of GraphQL errors\n# TYPE graphql_errors_total counter\ngraphql_errors_total 0\n\n# HELP graphql_duration_seconds GraphQL request duration\n# TYPE graphql_duration_seconds histogram\ngraphql_duration_seconds_bucket{le=\"0.1\"} 0\ngraphql_duration_seconds_bucket{le=\"0.5\"} 0\ngraphql_duration_seconds_bucket{le=\"1\"} 0\ngraphql_duration_seconds_bucket{le=\"+Inf\"} 0\ngraphql_duration_seconds_sum 0\ngraphql_duration_seconds_count 0`);\n });\n}\n","import type {GraphQLError} from 'graphql';\nimport {ApolloServerErrorCode} from '@apollo/server/errors';\n\n// Unfortunately, this string constant is not exposed separately\nconst BAD_USER_INPUT_CODE = ApolloServerErrorCode.BAD_USER_INPUT;\n\nexport const getNonUserInputErrors = (errors: readonly GraphQLError[]) =>\n errors.filter((e) => e.extensions?.code !== BAD_USER_INPUT_CODE);\n","// import {CommonBaggageItems} from '@hiliosai/jaeger-apollo-plugin';\n\nimport type {GraphQLRequestContext} from '@apollo/server';\nimport {BaseContext} from '../context';\n\nexport enum CommonBaggageItems {\n ROOT_OP_NAME = 'root_op_name',\n}\n\nexport const getOpsName = (gqlCtx: GraphQLRequestContext<BaseContext>) =>\n gqlCtx.contextValue.rootSpan?.getBaggageItem(\n CommonBaggageItems.ROOT_OP_NAME\n ) ||\n gqlCtx.request.operationName ||\n gqlCtx.operationName ||\n 'UNKNOWN';\n","import {getNonUserInputErrors} from '@/utils/graphql.util';\nimport {getOpsName} from '@/utils/tracing.util';\nimport type {ApolloServerPlugin} from '@apollo/server';\nimport type {BaseContext} from '../context';\nimport {createLogger} from './index';\n\nconst getUserId = (gqlCtx: BaseContext) => gqlCtx.user?.id ?? 'UNKNOWN';\n\nexport function createApolloLoggingPlugin(): ApolloServerPlugin<BaseContext> {\n return {\n async requestDidStart(requestContext) {\n const start = Date.now();\n const operationName = requestContext.request.operationName;\n\n // Create a logger with request context\n const requestLogger = createLogger({\n source: 'apollo',\n operationName,\n });\n\n return {\n async didResolveOperation(gqlCtx) {\n const userId = getUserId(gqlCtx.contextValue);\n const operation = getOpsName(gqlCtx);\n\n requestLogger.info(\n {\n event: 'operation_resolved',\n operation,\n userId,\n operationName: gqlCtx.operationName,\n variables: gqlCtx.request.variables,\n },\n `Operation [${operation}] resolved for user [${userId}]`\n );\n },\n\n async willSendResponse(gqlCtx) {\n const errors = getNonUserInputErrors(gqlCtx.errors || []);\n const duration = Date.now() - start;\n const userId = getUserId(gqlCtx.contextValue);\n const operation = getOpsName(gqlCtx);\n\n if (errors.length > 0) {\n // Log errors with full context\n requestLogger.error(\n {\n event: 'operation_error',\n operation,\n userId,\n duration,\n errors: errors.map((e) => ({\n message: e.message,\n path: e.path,\n extensions: e.extensions,\n stack: e.stack,\n })),\n },\n `Operation [${operation}] failed with ${errors.length} error(s)`\n );\n }\n\n // Log completion with metrics\n requestLogger.info(\n {\n event: 'operation_complete',\n operation,\n userId,\n duration,\n success: errors.length === 0,\n errorCount: errors.length,\n },\n `Operation [${operation}] completed in ${duration}ms${errors.length > 0 ? ' with errors' : ' successfully'}`\n );\n },\n\n async didEncounterErrors(gqlCtx) {\n const errors = gqlCtx.errors || [];\n const userId = getUserId(gqlCtx.contextValue);\n\n requestLogger.error(\n {\n event: 'graphql_errors',\n userId,\n errors: errors.map((e) => ({\n message: e.message,\n path: e.path,\n extensions: e.extensions,\n })),\n },\n `GraphQL execution encountered ${errors.length} error(s)`\n );\n },\n };\n },\n };\n}\n","import type {BaseContext} from '@/context';\nimport {createApolloLoggingPlugin} from '@/logger/apollo.logger';\nimport {ApolloServerPluginLandingPageDisabled} from '@apollo/server/plugin/disabled';\nimport {ServerBuilder} from './server.builder';\n\nexport function configurePlugins<TContext extends BaseContext>(\n builder: ServerBuilder<unknown, TContext>\n) {\n // disable landing page\n builder.plugins.push(ApolloServerPluginLandingPageDisabled());\n\n // logger\n builder.plugins.push(createApolloLoggingPlugin());\n}\n","import type {KeyValueCache} from '@apollo/utils.keyvaluecache';\nimport type {ApolloServerPlugin} from '@apollo/server';\nimport type {BaseContext} from '../context';\nimport type {ServerConfig} from '../server/server.builder';\n\ntype DataSources = Record<string, any>;\ntype DataSourcesFn = <TContext extends BaseContext = BaseContext>(\n cache: KeyValueCache<string>,\n contextValue: TContext\n) => DataSources;\n\nexport type ComputedContext<\n TDatasource,\n TContext extends BaseContext,\n> = TContext & {\n datasources: ReturnType<\n NonNullable<ServerConfig<TDatasource, TContext>['datasources']>\n >;\n};\n\nexport const ApolloDataSources = <\n TDatasource,\n TContext extends BaseContext,\n>(options: {\n datasources: DataSourcesFn;\n}): ApolloServerPlugin<ComputedContext<TDatasource, TContext>> => ({\n requestDidStart: async (requestContext) => {\n const dataSources = options.datasources(\n requestContext.cache,\n requestContext.contextValue\n );\n requestContext.contextValue.datasources =\n dataSources as unknown as TDatasource;\n },\n});\n","import {BaseContext} from '@/context';\nimport {logger} from '@/logger';\nimport {ServerBuilder, ServerConfig} from './server.builder';\n\nexport type BaseServerOptions = {\n /**\n * The version of the server\n *\n * @type {string}\n */\n version: string;\n /**\n * The name of the server\n *\n * @type {string}\n */\n name: string;\n\n /**\n * The port to listen on\n *\n * @type {number}\n */\n port?: number;\n\n /**\n * The hostname to listen on\n *\n * @type {string}\n */\n hostname?: string;\n};\n\nexport type ServerOptions<\n TDatasource,\n TContext extends BaseContext,\n> = BaseServerOptions & {\n config: ServerConfig<TDatasource, TContext>;\n};\n\nconst SERVICE_NAME_REGEX = /^[a-z0-9\\-_]+$/i;\n\nexport function createGraphQLServer<TDatasource, TContext extends BaseContext>(\n options: ServerOptions<TDatasource, TContext>\n) {\n if (!SERVICE_NAME_REGEX.test(options.name)) {\n throw new Error('Service name must be alphanumeric, hyphen, or underscore');\n }\n logger.info(`Creating GraphQL server ${options.name} v${options.version}`);\n return new ServerBuilder<TDatasource, TContext>(options.config);\n}\n","import {GraphQLError} from 'graphql';\nimport {ApolloServerErrorCode} from '@apollo/server/errors';\n\nexport enum ErrorCode {\n // Authentication & Authorization\n UNAUTHENTICATED = 'UNAUTHENTICATED',\n FORBIDDEN = 'FORBIDDEN',\n\n // Validation\n VALIDATION_FAILED = 'VALIDATION_FAILED',\n\n // Rate Limiting\n RATE_LIMITED = 'RATE_LIMITED',\n\n // External Service\n EXTERNAL_SERVICE_ERROR = 'EXTERNAL_SERVICE_ERROR',\n\n // Data\n NOT_FOUND = 'NOT_FOUND',\n CONFLICT = 'CONFLICT',\n}\n\nexport class AppError extends GraphQLError {\n constructor(\n message: string,\n code: ErrorCode | ApolloServerErrorCode,\n extensions?: Record<string, any>\n ) {\n super(message, {\n extensions: {\n code,\n ...extensions,\n },\n });\n }\n}\n\nexport function createErrorHandler(logger: any) {\n return (error: Error, context: any) => {\n const errorId = generateErrorId();\n\n logger.error({\n errorId,\n message: error.message,\n stack: error.stack,\n context: {\n user: context.user?.id,\n operation: context.operation?.name,\n },\n });\n\n if (error instanceof GraphQLError) {\n return error;\n }\n\n // Don't expose internal errors in production\n if (process.env.NODE_ENV === 'production') {\n return new AppError(\n 'Internal server error',\n ApolloServerErrorCode.INTERNAL_SERVER_ERROR,\n {errorId}\n );\n }\n\n return error;\n };\n}\n\nfunction generateErrorId(): string {\n return `err_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n}\n","import type {DocumentNode} from 'graphql';\n\nexport const createSchemaModule = (\n typeDefs: DocumentNode,\n resolvers?: any\n) => ({\n typeDefs,\n resolvers,\n});\n\nexport type SchemaModule = ReturnType<typeof createSchemaModule>;\nexport {gql} from 'graphql-tag';\n"],"mappings":"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","names":["cached","cached","ApolloServerErrorCode","ErrorCode"]}
1
+ {"version":3,"sources":["../src/logger/index.ts","../src/cache/kv-cache.ts","../src/cache/batching-datasource.ts","../src/cache/apollo-cache-adapter.ts","../src/cache/index.ts","../src/context/constants.ts","../src/context/auth.ts","../src/env/config.ts","../src/context/index.ts","../src/utils/builder.util.ts","../src/server/server.builder.ts","../src/datasources/apollo-plugin.datasource.ts","../src/server/hono.configure.ts","../src/middleware/validation.ts","../src/middleware/rate-limit.ts","../src/middleware/tracing.ts","../src/middleware/health.ts","../src/utils/graphql.util.ts","../src/utils/tracing.util.ts","../src/logger/apollo.logger.ts","../src/server/plugin.configure.ts","../src/server/index.ts","../src/utils/error.util.ts","../src/utils/schema.util.ts","../src/datasources/base.datasource.ts","../src/datasources/rest.datasource.ts","../src/datasources/prisma.datasource.ts"],"sourcesContent":["import pino from 'pino/browser';\n\n// Configuration for Cloudflare Workers environment\nconst isDev = process.env.NODE_ENV !== 'production';\nconst logLevel = process.env.LOG_LEVEL || (isDev ? 'debug' : 'info');\n\n// Custom serializers for Cloudflare Workers\nconst serializers = {\n err: (err: any) => {\n if (!err) return err;\n return {\n type: err.constructor?.name || err.name,\n message: err.message,\n stack: err.stack,\n code: err.code,\n statusCode: err.statusCode,\n };\n },\n req: (req: Request) => {\n if (!req) return req;\n return {\n method: req.method,\n url: req.url,\n headers: Object.fromEntries(req.headers.entries()),\n };\n },\n res: (res: Response) => {\n if (!res) return res;\n return {\n statusCode: res.status,\n headers: Object.fromEntries(res.headers.entries()),\n };\n },\n};\n\n// Create pino logger optimized for Cloudflare Workers\nexport const logger = pino({\n browser: {\n asObject: true,\n write: {\n info: (o: any) => {\n // In production, send to external logging service\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.log(JSON.stringify(o));\n },\n error: (o: any) => {\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.error(JSON.stringify(o));\n },\n debug: (o: any) => {\n if (isDev) {\n console.debug(JSON.stringify(o));\n }\n },\n warn: (o: any) => {\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.warn(JSON.stringify(o));\n },\n fatal: (o: any) => {\n if (!isDev && globalThis.logshipper) {\n globalThis.logshipper.log(o);\n }\n console.error(JSON.stringify(o));\n },\n trace: (o: any) => {\n if (isDev) {\n console.trace(JSON.stringify(o));\n }\n },\n },\n },\n level: logLevel,\n base: {\n env: process.env.NODE_ENV,\n service: 'graphql-subgraph',\n runtime: 'cloudflare-workers',\n },\n serializers,\n timestamp: () => `,\"timestamp\":\"${new Date().toISOString()}\"`,\n formatters: {\n level: (label: string) => {\n return {level: label.toUpperCase()};\n },\n log: (object: any) => {\n // Add request context if available\n if (globalThis.requestContext) {\n object.traceId = globalThis.requestContext.traceId;\n object.spanId = globalThis.requestContext.spanId;\n object.userId = globalThis.requestContext.userId;\n }\n return object;\n },\n },\n});\n\n// Helper for creating child loggers with context\nexport function createLogger(context: Record<string, any>) {\n return logger.child(context);\n}\n\n// Export pino types for TypeScript\nexport type Logger = typeof logger;\n\n// Declare global types for Cloudflare Workers\ndeclare global {\n var logshipper: {\n log: (data: any) => void;\n };\n var requestContext: {\n traceId?: string;\n spanId?: string;\n userId?: string;\n };\n}\n","/**\n * KV Cache implementation for Cloudflare Workers\n * Provides caching capabilities for GraphQL resolvers using Cloudflare KV\n */\n\nexport interface CacheOptions {\n ttl?: number; // Time to live in seconds\n namespace?: string; // Cache namespace prefix\n cacheKey?: string; // Custom cache key\n}\n\nexport class KVCache {\n private defaultTTL: number = 300; // 5 minutes default\n private defaultNamespace: string = 'cache';\n\n constructor(\n private kv: KVNamespace,\n defaultNamespace?: string\n ) {\n if (defaultNamespace) {\n this.defaultNamespace = defaultNamespace;\n }\n }\n\n /**\n * Get a value from cache\n */\n async get<T = any>(key: string): Promise<T | null> {\n try {\n const value = await this.kv.get(key);\n if (!value) return null;\n\n // Try to parse JSON, fallback to raw value\n try {\n return JSON.parse(value);\n } catch {\n return value as T;\n }\n } catch (error) {\n console.error(`Cache get error for key ${key}:`, error);\n return null;\n }\n }\n\n /**\n * Set a value in cache with metadata\n */\n async set(\n key: string,\n value: any,\n options: CacheOptions = {}\n ): Promise<void> {\n try {\n const serialized =\n typeof value === 'string' ? value : JSON.stringify(value);\n\n const ttl = options.ttl || this.defaultTTL;\n const kvOptions: KVNamespacePutOptions = {\n expirationTtl: ttl,\n metadata: {\n createdAt: new Date().toISOString(),\n ttl: ttl,\n namespace: options.namespace || this.defaultNamespace,\n },\n };\n\n await this.kv.put(key, serialized, kvOptions);\n } catch (error) {\n console.error(`Cache set error for key ${key}:`, error);\n }\n }\n\n /**\n * Delete a value from cache\n */\n async delete(key: string): Promise<void> {\n try {\n await this.kv.delete(key);\n } catch (error) {\n console.error(`Cache delete error for key ${key}:`, error);\n }\n }\n\n /**\n * Check if a key exists in cache\n */\n async has(key: string): Promise<boolean> {\n try {\n const value = await this.kv.get(key);\n return value !== null;\n } catch (error) {\n console.error(`Cache has error for key ${key}:`, error);\n return false;\n }\n }\n\n /**\n * Clear multiple keys matching a prefix\n */\n async clearPrefix(prefix: string): Promise<number> {\n try {\n const list = await this.kv.list({prefix});\n const promises = list.keys.map((key) => this.kv.delete(key.name));\n await Promise.all(promises);\n return list.keys.length;\n } catch (error) {\n console.error(`Cache clear prefix error for ${prefix}:`, error);\n return 0;\n }\n }\n\n /**\n * Invalidate cache by pattern\n */\n async invalidate(pattern: string): Promise<number> {\n return this.clearPrefix(pattern);\n }\n\n /**\n * Clear all cache in a namespace\n */\n async clearNamespace(namespace?: string): Promise<number> {\n const prefix = namespace ? `${namespace}:` : `${this.defaultNamespace}:`;\n return this.invalidate(prefix);\n }\n\n /**\n * Get or set a value with a factory function\n * Useful for cache-aside pattern\n */\n async getOrSet<T>(\n key: string,\n factory: () => Promise<T>,\n options: CacheOptions = {}\n ): Promise<T> {\n // Try to get from cache first\n const cached = await this.get<T>(key);\n if (cached !== null) {\n return cached;\n }\n\n // Fetch fresh value\n const fresh = await factory();\n\n // Cache the fresh value (non-blocking)\n this.set(key, fresh, options).catch((error) => {\n console.error(`Background cache write error for ${key}:`, error);\n });\n\n return fresh;\n }\n\n /**\n * Memoize function with automatic key generation\n */\n async memoize<T>(\n cacheKey: string,\n params: any,\n fetchFn: () => Promise<T>,\n options: CacheOptions = {}\n ): Promise<T> {\n const namespace = options.namespace || this.defaultNamespace;\n const key = this.generateKey(`${namespace}:${cacheKey}`, params);\n\n try {\n // Try to get from cache\n const cached = await this.get<T>(key);\n if (cached !== null) {\n return cached;\n }\n } catch (error) {\n console.warn(`Cache read error for ${key}:`, error);\n }\n\n // Cache miss - fetch data\n const data = await fetchFn();\n\n // Store in cache (non-blocking)\n this.set(key, data, options).catch((error) => {\n console.warn(`Cache write error for ${key}:`, error);\n });\n\n return data;\n }\n\n /**\n * Generate cache key with namespace and params\n */\n private generateKey(namespace: string, params: any): string {\n const sortedParams = Object.keys(params)\n .sort()\n .reduce((obj: any, key) => {\n if (params[key] !== undefined && params[key] !== null) {\n obj[key] = params[key];\n }\n return obj;\n }, {});\n\n const paramString = JSON.stringify(sortedParams);\n const hash = this.simpleHash(paramString);\n return `${namespace}:${hash}`;\n }\n\n /**\n * Simple hash function for generating cache keys\n */\n private simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(36);\n }\n}\n\n/**\n * Create a cache key from multiple parts\n */\nexport function createCacheKey(\n ...parts: (string | number | undefined)[]\n): string {\n return parts\n .filter((part) => part !== undefined)\n .map((part) => String(part))\n .join(':');\n}\n\n/**\n * Cache key patterns for different data types\n */\nexport const CacheKeys = {\n user: (id: string) => createCacheKey('user', id),\n query: (name: string, variables?: string) =>\n createCacheKey('query', name, variables),\n list: (type: string, page?: number) => createCacheKey('list', type, page),\n permission: (userId: string, resource: string) =>\n createCacheKey('perm', userId, resource),\n} as const;\n","import DataLoader, {type BatchLoadFn, type Options} from 'dataloader';\nimport type {BaseContext} from '@/context';\nimport {KVCache} from './kv-cache';\n\n/**\n * Ensures that output items has the same order as input keys (dataloader requirement).\n * Returns error objects for non-existent ids.\n *\n * @param keys list of input keys\n * @param items list of output items\n * @param primaryKey name of the key-holding property\n */\nexport function ensureBatchOrder<\n K extends string | number,\n T extends Record<string, any>,\n>(keys: readonly K[], items: T[], primaryKey = 'id'): Array<T | Error> {\n const itemsMap = new Map<K, T>();\n\n // Build a map for O(1) lookups\n for (const item of items) {\n const key = item[primaryKey] as K;\n if (key !== undefined) {\n itemsMap.set(key, item);\n }\n }\n\n // Return items in the same order as keys\n return keys.map(\n (key) =>\n itemsMap.get(key) || new Error(`Missing value for ${primaryKey} ${key}`)\n );\n}\n\n/**\n * Ensures that output items has the same order as input keys (dataloader requirement).\n * Returns null for non-existent ids.\n *\n * @param keys list of input keys\n * @param items list of output items\n * @param primaryKey name of the key-holding property\n */\nexport function ensureBatchOrderNullable<\n K extends string | number,\n T extends Record<string, any>,\n>(keys: readonly K[], items: T[], primaryKey = 'id'): Array<T | null> {\n const itemsMap = new Map<K, T>();\n\n // Build a map for O(1) lookups\n for (const item of items) {\n const key = item[primaryKey] as K;\n if (key !== undefined) {\n itemsMap.set(key, item);\n }\n }\n\n // Return items in the same order as keys, with nulls for missing\n return keys.map((key) => itemsMap.get(key) || null);\n}\n\n/**\n * Base class for batching data sources with caching support.\n * Uses DataLoader for request batching and deduplication.\n *\n * @typeParam TContext - Apollo context type\n * @typeParam K - Primary key type\n * @typeParam V - Output item type\n * @typeParam CK - Cache key type (same as K by default)\n *\n * @example\n * ```typescript\n * export class UserBatchingDataSource extends BatchingDataSource<BaseContext, string, User> {\n * constructor() {\n * super(async (ids: readonly string[]) => {\n * const users = await fetchUsersFromDB(ids);\n * return ensureBatchOrder(ids, users);\n * });\n * }\n * }\n * ```\n */\nexport class BatchingDataSource<TContext extends BaseContext, K, V, CK = K> {\n protected context!: TContext;\n protected loader: DataLoader<K, V, CK>;\n protected cache?: KVCache;\n\n /**\n * Creates a new batching data source\n *\n * @param resolveBatch - Batch resolving function\n * @param options - DataLoader options\n * @param cacheNamespace - Optional namespace for KV caching\n */\n constructor(\n resolveBatch: BatchLoadFn<K, V>,\n options: Options<K, V, CK> = {},\n protected cacheNamespace?: string\n ) {\n // Bind context to the batch function\n const boundResolveBatch: BatchLoadFn<K, V> = async (keys) => {\n // If we have cache, try to load from cache first\n if (this.cache && this.cacheNamespace) {\n const results: Array<V | undefined> = [];\n const uncachedKeys: K[] = [];\n const uncachedIndexes: number[] = [];\n\n // Check cache for each key\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const cacheKey = `${this.cacheNamespace}:${String(key)}`;\n const cached = await this.cache.get<V>(cacheKey);\n\n if (cached !== null) {\n results[i] = cached;\n } else {\n uncachedKeys.push(key);\n uncachedIndexes.push(i);\n }\n }\n\n // If all items were cached, return them\n if (uncachedKeys.length === 0) {\n return results as V[];\n }\n\n // Fetch uncached items\n const freshItems = await resolveBatch.call(this, uncachedKeys);\n\n // Merge fresh items back and cache them\n for (let i = 0; i < uncachedIndexes.length; i++) {\n const index = uncachedIndexes[i];\n const item = freshItems[i] as V;\n const key = uncachedKeys[i];\n\n results[index] = item;\n\n // Cache the fresh item (non-blocking)\n if (!(item instanceof Error) && item !== null && item !== undefined) {\n const cacheKey = `${this.cacheNamespace}:${String(key)}`;\n this.cache.set(cacheKey, item, {ttl: 300}).catch((err) => {\n console.warn(`Failed to cache item ${cacheKey}:`, err);\n });\n }\n }\n\n return results as V[];\n }\n\n // No cache, just resolve normally\n return resolveBatch.call(this, keys);\n };\n\n this.loader = new DataLoader(boundResolveBatch, {\n ...options,\n // Default to caching within the request\n cache: options.cache !== false,\n });\n }\n\n /**\n * Initialize with Apollo context\n */\n initialize(config: {contextValue: TContext}) {\n this.context = config.contextValue;\n this.cache = config.contextValue.cache;\n }\n\n /**\n * Load a single item by key\n */\n async load(id: K): Promise<V> {\n return this.loader.load(id);\n }\n\n /**\n * Load multiple items by keys\n */\n async loadMany(ids: readonly K[]): Promise<Array<V | Error>> {\n return this.loader.loadMany(ids);\n }\n\n /**\n * Clear a single item from the DataLoader cache\n */\n clear(id: K): this {\n this.loader.clear(id);\n return this;\n }\n\n /**\n * Clear all items from the DataLoader cache\n */\n clearAll(): this {\n this.loader.clearAll();\n return this;\n }\n\n /**\n * Prime the cache with a specific value\n */\n prime(key: K, value: V): this {\n this.loader.prime(key, value);\n return this;\n }\n}\n\n/**\n * Factory function for creating batching data sources\n *\n * @example\n * ```typescript\n * const userDataSource = createBatchingDataSource<BaseContext, string, User>(\n * async (ids) => {\n * const users = await fetchUsersFromDB(ids);\n * return ensureBatchOrder(ids, users);\n * },\n * { cache: true },\n * 'users'\n * );\n * ```\n */\nexport function createBatchingDataSource<\n TContext extends BaseContext,\n K,\n V,\n CK = K,\n>(\n resolveBatch: BatchLoadFn<K, V>,\n options?: Options<K, V, CK>,\n cacheNamespace?: string\n): BatchingDataSource<TContext, K, V, CK> {\n return new BatchingDataSource(resolveBatch, options, cacheNamespace);\n}\n","/**\n * Apollo KeyValueCache adapter for Cloudflare KV\n *\n * Implements the Apollo Server KeyValueCache interface to work with\n * Cloudflare Workers KV storage.\n */\n\nimport type {\n KeyValueCache,\n KeyValueCacheSetOptions,\n} from '@apollo/utils.keyvaluecache';\nimport {KVCache} from './kv-cache';\n\n/**\n * Adapter that makes our KVCache compatible with Apollo's KeyValueCache interface\n *\n * Apollo Server uses this for:\n * - Response caching\n * - APQ (Automatic Persisted Queries)\n * - DataSource caching\n *\n * @example\n * ```typescript\n * const apolloCache = new ApolloKVAdapter(new KVCache(env.KV));\n *\n * const server = new ApolloServer({\n * cache: apolloCache,\n * // ... other options\n * });\n * ```\n */\nexport class ApolloKVAdapter implements KeyValueCache<string> {\n constructor(private kvCache: KVCache) {}\n\n /**\n * Get a value from cache\n * Apollo expects undefined for cache misses\n */\n async get(key: string): Promise<string | undefined> {\n const value = await this.kvCache.get<string>(key);\n // Apollo expects undefined, not null for cache misses\n return value === null ? undefined : value;\n }\n\n /**\n * Set a value in cache with TTL support\n * Apollo passes TTL in seconds via options\n */\n async set(\n key: string,\n value: string,\n options?: KeyValueCacheSetOptions\n ): Promise<void> {\n await this.kvCache.set(key, value, {\n ttl: options?.ttl, // Apollo's TTL is already in seconds\n });\n }\n\n /**\n * Delete a value from cache\n * Apollo expects boolean or void return\n */\n async delete(key: string): Promise<boolean | void> {\n await this.kvCache.delete(key);\n return true;\n }\n}\n\n/**\n * Factory function to create an Apollo-compatible cache from KV namespace\n *\n * @param kv - Cloudflare KV namespace binding\n * @returns Apollo-compatible KeyValueCache\n */\nexport function createApolloCache(kv: KVNamespace): KeyValueCache<string> {\n return new ApolloKVAdapter(new KVCache(kv));\n}\n\n/**\n * In-memory LRU cache for development/testing\n * Falls back to simple Map-based implementation\n */\nexport class InMemoryCache implements KeyValueCache<string> {\n private cache = new Map<string, {value: string; expires?: number}>();\n\n async get(key: string): Promise<string | undefined> {\n const item = this.cache.get(key);\n if (!item) return undefined;\n\n // Check expiration\n if (item.expires && Date.now() > item.expires) {\n this.cache.delete(key);\n return undefined;\n }\n\n return item.value;\n }\n\n async set(\n key: string,\n value: string,\n options?: KeyValueCacheSetOptions\n ): Promise<void> {\n const expires = options?.ttl\n ? Date.now() + options.ttl * 1000 // Convert seconds to milliseconds\n : undefined;\n\n this.cache.set(key, {value, expires});\n }\n\n async delete(key: string): Promise<boolean> {\n return this.cache.delete(key);\n }\n\n /**\n * Clear all cache entries\n */\n clear(): void {\n this.cache.clear();\n }\n}\n","/**\n * Cache module for GraphQL resolvers\n * Provides caching interface for Cloudflare Workers KV\n */\n\nimport {KVCache, createCacheKey, CacheKeys} from './kv-cache';\nimport type {CacheOptions} from './kv-cache';\nimport {\n BatchingDataSource,\n createBatchingDataSource,\n ensureBatchOrder,\n ensureBatchOrderNullable,\n} from './batching-datasource';\nimport {\n ApolloKVAdapter,\n createApolloCache,\n InMemoryCache,\n} from './apollo-cache-adapter';\n\nexport {KVCache, createCacheKey, CacheKeys};\nexport type {CacheOptions};\nexport {\n BatchingDataSource,\n createBatchingDataSource,\n ensureBatchOrder,\n ensureBatchOrderNullable,\n};\nexport {ApolloKVAdapter, createApolloCache, InMemoryCache};\n\n/**\n * Cache factory - creates KV cache if available\n */\nexport function createCache(env: Env): KVCache | null {\n // Check for KV namespace (Cloudflare Workers KV)\n if (env.KV) {\n return new KVCache(env.KV);\n }\n\n // No cache available\n return null;\n}\n\n/**\n * Decorator for caching resolver results\n */\nexport function cached(\n options: CacheOptions & {keyGenerator?: (...args: any[]) => string} = {}\n) {\n return function (\n target: any,\n propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]) {\n const context = args[2]; // GraphQL context is third argument\n const cache = context?.cache;\n\n if (!cache) {\n // No cache available, run original method\n return originalMethod.apply(this, args);\n }\n\n // Generate cache key\n const key = options.keyGenerator\n ? options.keyGenerator(...args)\n : createCacheKey(propertyKey, JSON.stringify(args[1])); // Use field name and arguments\n\n // Try cache-aside pattern\n return cache.getOrSet(\n key,\n () => originalMethod.apply(this, args),\n options\n );\n };\n\n return descriptor;\n };\n}\n\n/**\n * GraphQL DataLoader integration for batching and caching\n */\nexport class CachedDataLoader<K, V> {\n private loader: any; // DataLoader instance\n private cache: KVCache;\n\n constructor(\n batchFn: (keys: K[]) => Promise<V[]>,\n cache: KVCache,\n private options: CacheOptions = {}\n ) {\n this.cache = cache;\n\n // Initialize DataLoader with cache\n // Note: DataLoader is not included by default, install if needed\n // this.loader = new DataLoader(batchFn, { cache: this.createCacheMap() });\n }\n\n async load(key: K): Promise<V> {\n const cacheKey = createCacheKey('loader', String(key));\n\n return this.cache.getOrSet(\n cacheKey,\n async () => {\n // Fallback to batch function for single key\n // In production, use actual DataLoader\n return this.loader ? this.loader.load(key) : null;\n },\n this.options\n );\n }\n\n async loadMany(keys: K[]): Promise<V[]> {\n return Promise.all(keys.map((key) => this.load(key)));\n }\n\n async clear(key: K): Promise<void> {\n const cacheKey = createCacheKey('loader', String(key));\n await this.cache.delete(cacheKey);\n }\n\n async clearAll(): Promise<void> {\n await this.cache.clearPrefix('loader:');\n }\n}\n","export const Headers = {\n GATEWAY_USER: 'x-gateway-user',\n GATEWAY_USER_SIGNATURE: 'x-gateway-user-signature',\n AUTH: 'authorization',\n CLIENT_ID: 'x-client-id',\n} as const;\n","import type {ContextUser} from './types';\n\n/**\n * Verifies and parses user context from gateway headers\n * For Cloudflare Workers deployment, we use HMAC signature verification\n * to ensure the user data hasn't been tampered with\n */\nexport async function verifyAndParseUser(\n encodedUser: string | null,\n signature: string | null,\n secret: string\n): Promise<ContextUser | undefined> {\n if (!encodedUser || !signature) {\n return undefined;\n }\n\n try {\n // Verify HMAC signature\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n ['verify']\n );\n\n const signatureBuffer = hexToBuffer(signature);\n const dataBuffer = encoder.encode(encodedUser);\n\n const isValid = await crypto.subtle.verify(\n 'HMAC',\n key,\n signatureBuffer,\n dataBuffer\n );\n\n if (!isValid) {\n console.error('Invalid user signature');\n return undefined;\n }\n\n // Parse the verified user data\n const user = JSON.parse(atob(encodedUser));\n return user;\n } catch (error) {\n console.error('Error verifying user:', error);\n return undefined;\n }\n}\n\nfunction hexToBuffer(hex: string): ArrayBuffer {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n }\n // Return the ArrayBuffer directly, not SharedArrayBuffer\n return bytes.buffer as ArrayBuffer;\n}\n","/**\n * Environment configuration type\n */\nexport interface EnvConfig {\n // Core\n NODE_ENV: 'development' | 'test' | 'production';\n PORT: number;\n\n // Security\n GATEWAY_SECRET?: string;\n ALLOWED_ORIGINS: string[];\n\n // Logging\n LOG_LEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n\n // Rate limiting\n RATE_LIMIT_WINDOW_MS: number;\n RATE_LIMIT_MAX: number;\n\n // Monitoring\n ENABLE_METRICS: boolean;\n ENABLE_TRACING: boolean;\n\n // GraphQL\n MAX_QUERY_DEPTH: number;\n MAX_QUERY_COMPLEXITY: number;\n INTROSPECTION_ENABLED: boolean;\n\n // External services (optional)\n LOG_SERVICE_URL?: string;\n LOG_SERVICE_TOKEN?: string;\n}\n\n/**\n * Lightweight environment parser inspired by @ltv/env\n */\nclass EnvParser {\n constructor(private env: Record<string, any>) {}\n\n string(key: string): string | undefined;\n string(key: string, defaultValue: string): string;\n string(key: string, defaultValue?: string): string | undefined {\n const value = this.env[key];\n return value !== undefined && value !== '' ? String(value) : defaultValue;\n }\n\n int(key: string): number | undefined;\n int(key: string, defaultValue: number): number;\n int(key: string, defaultValue?: number): number | undefined {\n const value = this.env[key];\n if (value === undefined || value === '') return defaultValue;\n const parsed = parseInt(String(value), 10);\n return isNaN(parsed) ? defaultValue : parsed;\n }\n\n bool(key: string): boolean | undefined;\n bool(key: string, defaultValue: boolean): boolean;\n bool(key: string, defaultValue?: boolean): boolean | undefined {\n const value = this.env[key];\n if (value === undefined || value === '') return defaultValue;\n const str = String(value).toLowerCase();\n return str === 'true' || str === '1';\n }\n\n array(key: string): string[] | undefined;\n array(key: string, defaultValue: string[]): string[];\n array(key: string, defaultValue?: string[]): string[] | undefined {\n const value = this.env[key];\n if (value === undefined || value === '') return defaultValue;\n if (Array.isArray(value)) return value;\n return String(value)\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n }\n\n enum<T extends string>(key: string, validValues: T[]): T | undefined;\n enum<T extends string>(key: string, validValues: T[], defaultValue: T): T;\n enum<T extends string>(\n key: string,\n validValues: T[],\n defaultValue?: T\n ): T | undefined {\n const value = this.string(key);\n if (value && validValues.includes(value as T)) {\n return value as T;\n }\n return defaultValue;\n }\n}\n\n/**\n * Environment loader for Cloudflare Workers\n */\nexport class EnvironmentLoader {\n private config: EnvConfig | null = null;\n\n /**\n * Load environment from Cloudflare Workers env object\n */\n load(env: Record<string, any>): EnvConfig {\n const parser = new EnvParser(env);\n\n this.config = {\n NODE_ENV: parser.enum(\n 'NODE_ENV',\n ['development', 'test', 'production'],\n 'production'\n ),\n PORT: parser.int('PORT', 3344),\n GATEWAY_SECRET: parser.string('GATEWAY_SECRET'),\n ALLOWED_ORIGINS: parser.array('ALLOWED_ORIGINS', [\n 'http://localhost:3000',\n ]),\n LOG_LEVEL: parser.enum(\n 'LOG_LEVEL',\n ['trace', 'debug', 'info', 'warn', 'error', 'fatal'],\n 'info'\n ),\n RATE_LIMIT_WINDOW_MS: parser.int('RATE_LIMIT_WINDOW_MS', 60000),\n RATE_LIMIT_MAX: parser.int('RATE_LIMIT_MAX', 100),\n ENABLE_METRICS: parser.bool('ENABLE_METRICS', true),\n ENABLE_TRACING: parser.bool('ENABLE_TRACING', true),\n MAX_QUERY_DEPTH: parser.int('MAX_QUERY_DEPTH', 10),\n MAX_QUERY_COMPLEXITY: parser.int('MAX_QUERY_COMPLEXITY', 1000),\n INTROSPECTION_ENABLED: parser.bool('INTROSPECTION_ENABLED', false),\n LOG_SERVICE_URL: parser.string('LOG_SERVICE_URL'),\n LOG_SERVICE_TOKEN: parser.string('LOG_SERVICE_TOKEN'),\n };\n\n return this.config;\n }\n\n /**\n * Get current configuration\n */\n getConfig(): EnvConfig {\n if (!this.config) {\n throw new Error('Environment not loaded. Call load() first.');\n }\n return this.config;\n }\n\n /**\n * Helper getters for common checks\n */\n get isDev(): boolean {\n return this.config?.NODE_ENV === 'development';\n }\n\n get isTest(): boolean {\n return this.config?.NODE_ENV === 'test';\n }\n\n get isProd(): boolean {\n return this.config?.NODE_ENV === 'production';\n }\n}\n\n// Singleton instance\nexport const envLoader = new EnvironmentLoader();\n","import type {BaseContext as ApolloBaseContext} from '@apollo/server';\nimport type {ExecutionContext} from '@cloudflare/workers-types';\nimport type {CloudflareContextFunctionArgument} from '@as-integrations/cloudflare-workers';\nimport {logger} from '../logger';\nimport {Headers} from './constants';\nimport {verifyAndParseUser} from './auth';\nimport type {ContextUser} from './types';\nimport {createCache} from '@/cache';\nimport type {KVCache} from '@/cache';\nimport {envLoader, type EnvConfig} from '@/env';\n\nexport type {ContextUser} from './types';\n\n// TODO: Replace with actual jaeger types when available\nexport interface JaegerContext {\n rootSpan?: {\n getBaggageItem: (key: string) => string | undefined;\n };\n}\n\nexport interface BaseContext extends JaegerContext, ApolloBaseContext {\n user?: ContextUser;\n logger: typeof logger;\n executionCtx: ExecutionContext;\n cache?: KVCache; // KV cache for resolvers\n db?: D1Database; // D1 database binding for datasources\n env: EnvConfig; // Validated environment configuration\n\n /** @deprecated should not be used directly */\n authorization: string;\n clientId: string;\n}\n\nexport type ContextExtendFunction<T extends BaseContext> = (\n ctx: BaseContext,\n honoContext: CloudflareContextFunctionArgument<unknown>\n) => T | Promise<T>;\n\nasync function createBaseContext(\n honoContext: CloudflareContextFunctionArgument<any>\n): Promise<BaseContext> {\n const request = honoContext.request;\n const rawEnv = honoContext.env;\n\n // Load and validate environment configuration\n const env = envLoader.load(rawEnv);\n\n // Parse user from gateway headers with signature verification\n let user: ContextUser | undefined;\n\n // Check if this is a subgraph request from gateway\n const encodedUser = request.headers.get(Headers.GATEWAY_USER);\n if (encodedUser) {\n // In production, verify signature. In dev, allow without signature\n if (env.GATEWAY_SECRET) {\n const signature = request.headers.get(Headers.GATEWAY_USER_SIGNATURE);\n user = await verifyAndParseUser(\n encodedUser,\n signature,\n env.GATEWAY_SECRET\n );\n } else if (env.NODE_ENV !== 'production') {\n // Development mode: parse without verification\n try {\n user = JSON.parse(atob(encodedUser));\n } catch (e) {\n console.error('Failed to parse user in dev mode:', e);\n }\n }\n }\n\n // Create cache instance - KV is now required\n // Pass raw env for KV bindings, not the parsed config\n const cache = createCache(rawEnv) as KVCache | undefined;\n if (!cache) {\n // This should not happen as ServerBuilder validates KV exists\n logger.warn(\n 'KV cache not found in context - this should not happen if using ServerBuilder'\n );\n }\n\n // Get D1 database binding (optional - datasources will validate if needed)\n const db = rawEnv?.DB as D1Database | undefined;\n\n return {\n user,\n logger,\n cache,\n db, // Raw D1 binding for datasources\n env, // Pass validated env config\n executionCtx: honoContext.ctx,\n authorization: request.headers.get(Headers.AUTH) || '',\n clientId: request.headers.get(Headers.CLIENT_ID) || '',\n };\n}\n\nexport function createContextFunction<T extends BaseContext>(\n extendContext?: ContextExtendFunction<T>\n) {\n if (!extendContext) {\n return (honoContext: CloudflareContextFunctionArgument<unknown>) =>\n createBaseContext(honoContext);\n }\n\n return async (honoContext: CloudflareContextFunctionArgument<unknown>) => {\n const baseContext = await createBaseContext(honoContext);\n return extendContext(baseContext, honoContext);\n };\n}\n","export function assertDefined<T>(t: T | undefined, msg: string): t is T {\n if (t === undefined) {\n throw new Error('Assertion failed when configuring server: ' + msg);\n }\n return true;\n}\n","import {createApolloCache} from '@/cache';\nimport {\n createContextFunction,\n type BaseContext,\n type ContextExtendFunction,\n} from '@/context';\nimport {assertDefined} from '@/utils/builder.util';\nimport type {ApolloServerOptions, ApolloServerPlugin} from '@apollo/server';\nimport {ApolloServer} from '@apollo/server';\nimport {startServerAndCreateCloudflareWorkersHandler} from '@as-integrations/cloudflare-workers';\nimport type {GraphQLSchema} from 'graphql';\nimport type {Hono} from 'hono';\nimport {ApolloDataSources} from '../datasources/apollo-plugin.datasource';\nimport {configureHono} from './hono.configure';\nimport {configurePlugins} from './plugin.configure';\n\nexport type Runner = {\n fetch: typeof Hono.prototype.fetch;\n port?: number;\n};\n\nimport type {KVCache} from '@/cache';\n\nexport type ServerConfig<TDatasource, TContext extends BaseContext> = {\n path?: string;\n apollo: Partial<ApolloServerOptions<BaseContext>>;\n datasources: (cache: KVCache, context: TContext) => TDatasource;\n extendContext?: ContextExtendFunction<TContext>;\n};\n\nexport class ServerBuilder<TDatasource, TContext extends BaseContext> {\n readonly app: Hono<{\n Variables: {\n env: any;\n };\n }>;\n\n readonly schema: GraphQLSchema;\n readonly plugins: ApolloServerPlugin<BaseContext>[] = [];\n\n constructor(readonly config: ServerConfig<TDatasource, TContext>) {\n this.assert();\n\n // TODO: Configure metrics\n this.app = configureHono(this);\n this.schema = this.config.apollo.schema as GraphQLSchema;\n }\n\n configure(): Runner {\n const honoApp = this.app;\n configurePlugins(this);\n\n // Build plugins array with datasources\n const plugins: ApolloServerPlugin<TContext>[] = [...this.plugins];\n\n // Add datasources plugin (now required)\n plugins.push(\n ApolloDataSources({\n datasources: this.config.datasources as any,\n }) as any\n );\n\n // We need to create the Apollo server for each request to pass the correct cache\n const createHandler = (env: any) => {\n // Validate KV binding exists\n if (!env?.KV) {\n throw new Error(\n 'Missing required KV namespace binding. ' +\n 'Please add KV namespace binding in your wrangler.toml:\\n' +\n '[[kv_namespaces]]\\n' +\n 'binding = \"KV\"\\n' +\n 'id = \"your-kv-namespace-id\"'\n );\n }\n\n // Create Apollo cache from KV\n const apolloCache = createApolloCache(env.KV);\n\n // Create Apollo server with cache\n // We need to ensure we don't include gateway if schema is provided\n const {gateway, ...apolloConfigWithoutGateway} = this.config.apollo || {};\n\n const server = new ApolloServer<TContext>({\n ...apolloConfigWithoutGateway, // User config without gateway\n schema: this.schema, // Our schema\n plugins, // Our plugins\n cache: apolloCache, // Apollo cache for APQ and response caching (override any user cache)\n } as ApolloServerOptions<TContext>);\n\n return startServerAndCreateCloudflareWorkersHandler<any, any>(server, {\n context: async (c) =>\n createContextFunction(this.config.extendContext)(c),\n });\n };\n\n // Cache handlers per environment (for efficiency)\n const handlerCache = new WeakMap();\n\n const getOrCreateHandler = (env: any) => {\n if (!handlerCache.has(env)) {\n handlerCache.set(env, createHandler(env));\n }\n return handlerCache.get(env);\n };\n\n honoApp.all(this.config.path ?? '/', async (c) => {\n // Get or create handler for this environment\n const cfHandler = getOrCreateHandler(c.env);\n\n // In local development, executionCtx doesn't exist\n // In Cloudflare Workers, it's provided\n let executionCtx;\n try {\n executionCtx = c.executionCtx;\n } catch (e) {\n // Create a mock executionCtx for local development\n executionCtx = {\n waitUntil: (promise: Promise<any>) => promise,\n passThroughOnException: () => {},\n };\n }\n return cfHandler(c.req.raw, c.env, executionCtx);\n });\n\n return {\n async fetch(request, env, ctx) {\n return honoApp.fetch(request, env, ctx);\n },\n };\n }\n\n assert() {\n assertDefined(\n this.config.apollo.schema,\n 'Apollo server config must have a schema'\n );\n }\n}\n","import type {ApolloServerPlugin} from '@apollo/server';\nimport type {BaseContext} from '../context';\nimport type {ServerConfig} from '../server/server.builder';\nimport type {KVCache} from '../cache';\n\ntype DataSources = Record<string, any>;\ntype DataSourcesFn = <TContext extends BaseContext = BaseContext>(\n cache: KVCache,\n contextValue: TContext\n) => DataSources;\n\nexport type ComputedContext<\n TDatasource,\n TContext extends BaseContext,\n> = TContext & {\n datasources: ReturnType<\n NonNullable<ServerConfig<TDatasource, TContext>['datasources']>\n >;\n};\n\nexport const ApolloDataSources = <\n TDatasource,\n TContext extends BaseContext,\n>(options: {\n datasources: DataSourcesFn;\n}): ApolloServerPlugin<ComputedContext<TDatasource, TContext>> => ({\n requestDidStart: async (requestContext) => {\n // Get KVCache from context instead of Apollo's cache\n const kvCache = requestContext.contextValue.cache;\n if (!kvCache) {\n throw new Error(\n 'KVCache not found in context. This should not happen if using ServerBuilder.'\n );\n }\n\n const dataSources = options.datasources(\n kvCache,\n requestContext.contextValue\n );\n\n // Auto-connect datasources that have connect method\n const connectPromises = Object.values(dataSources).map(\n async (dataSource) => {\n if (dataSource && typeof dataSource.connect === 'function') {\n await dataSource.connect();\n }\n }\n );\n\n await Promise.all(connectPromises);\n\n requestContext.contextValue.datasources =\n dataSources as unknown as TDatasource;\n },\n});\n","import {BaseContext} from '@/context';\nimport {Hono} from 'hono';\nimport {cors} from 'hono/cors';\nimport {compress} from 'hono/compress';\nimport {ServerBuilder} from './server.builder';\nimport {createValidationMiddleware} from '@/middleware/validation';\nimport {createRateLimitMiddleware} from '@/middleware/rate-limit';\nimport {createTracingMiddleware} from '@/middleware/tracing';\nimport {configureHealthChecks} from '@/middleware/health';\n\nexport function configureHono<TContext extends BaseContext>(\n builder: ServerBuilder<unknown, TContext>\n) {\n const app = new Hono<{\n Variables: {\n env: any;\n };\n }>();\n\n // Add environment to context for all middleware\n app.use('*', async (c, next) => {\n // Get environment from Cloudflare or set default\n const rawEnv = c.env || {};\n const env = rawEnv as any; // Type assertion for environment variables\n c.set('env', env);\n await next();\n });\n\n // Add request tracing first for all requests\n app.use('*', createTracingMiddleware());\n\n // Add compression for responses\n app.use('*', compress());\n\n // Add validation middleware\n app.use('*', createValidationMiddleware());\n\n // Add rate limiting\n app.use('*', createRateLimitMiddleware());\n\n // Configure health checks\n configureHealthChecks(app, {\n checks: {\n graphql: async () => true, // Check GraphQL schema is loaded\n },\n });\n\n // Configure CORS for development and production\n app.use(\n '/*',\n cors({\n origin: (origin, c) => {\n // Get environment from context\n const env = c.get('env') as any;\n const isProd = env?.NODE_ENV === 'production';\n const allowedOrigins = env.ALLOWED_ORIGINS\n ? typeof env.ALLOWED_ORIGINS === 'string'\n ? env.ALLOWED_ORIGINS.split(',').map((s) => s.trim())\n : env.ALLOWED_ORIGINS\n : ['http://localhost:3000'];\n\n // Allow all origins in development\n if (!isProd) {\n return origin || '*';\n }\n // In production, configure allowed origins\n return allowedOrigins.includes(origin) ? origin : allowedOrigins[0];\n },\n allowHeaders: [\n 'Content-Type',\n 'Authorization',\n 'x-apollo-operation-name',\n 'apollo-require-preflight',\n ],\n allowMethods: ['POST', 'GET', 'OPTIONS'],\n credentials: true,\n maxAge: 86400,\n })\n );\n\n // Add security headers\n app.use('*', async (c, next) => {\n await next();\n\n const env = c.get('env') as any;\n const isProd = env?.NODE_ENV === 'production';\n\n // Security headers for GraphQL endpoints\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('X-Frame-Options', 'DENY');\n c.header('X-XSS-Protection', '1; mode=block');\n c.header('Referrer-Policy', 'strict-origin-when-cross-origin');\n\n // Remove server identification\n c.header('Server', 'GraphQL');\n\n // Content Security Policy for GraphQL\n if (isProd) {\n c.header(\n 'Content-Security-Policy',\n \"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';\"\n );\n // HSTS for production\n c.header(\n 'Strict-Transport-Security',\n 'max-age=31536000; includeSubDomains; preload'\n );\n }\n });\n\n return app;\n}\n","import type {MiddlewareHandler} from 'hono';\nimport {AppError, ErrorCode} from '@/utils/error.util';\n\ninterface ValidationOptions {\n maxQueryDepth?: number;\n maxQueryComplexity?: number;\n maxAliasCount?: number;\n}\n\nexport function createValidationMiddleware(\n options: ValidationOptions = {}\n): MiddlewareHandler {\n return async (c, next) => {\n try {\n // Get environment from context\n const env = c.get('env');\n const maxQueryDepth = options.maxQueryDepth || env?.MAX_QUERY_DEPTH || 10;\n const maxQueryComplexity =\n options.maxQueryComplexity || env?.MAX_QUERY_COMPLEXITY || 1000;\n const maxAliasCount = options.maxAliasCount || 15;\n // Validate content type for GraphQL\n const contentType = c.req.header('content-type');\n if (\n c.req.method === 'POST' &&\n !contentType?.includes('application/json')\n ) {\n return c.json(\n {\n errors: [\n {\n message: 'Content-Type must be application/json',\n extensions: {code: 'BAD_REQUEST'},\n },\n ],\n },\n 400\n );\n }\n\n // Rate limiting headers check\n const clientId = c.req.header('x-client-id');\n if (!clientId && env?.NODE_ENV === 'production') {\n return c.json(\n {\n errors: [\n {\n message: 'Client identification required',\n extensions: {code: 'BAD_REQUEST'},\n },\n ],\n },\n 400\n );\n }\n\n await next();\n } catch (error) {\n console.error('Validation middleware error:', error);\n return c.json(\n {\n errors: [\n {\n message: 'Request validation failed',\n extensions: {code: 'INTERNAL_SERVER_ERROR'},\n },\n ],\n },\n 500\n );\n }\n };\n}\n","import type {MiddlewareHandler} from 'hono';\n\ninterface RateLimitOptions {\n windowMs?: number;\n max?: number;\n keyGenerator?: (c: any) => string;\n}\n\nexport function createRateLimitMiddleware(\n options: RateLimitOptions = {}\n): MiddlewareHandler {\n const {\n keyGenerator = (c) =>\n c.req.header('x-client-id') ||\n c.req.header('cf-connecting-ip') ||\n 'anonymous',\n } = options;\n\n return async (c, next) => {\n // Get environment from context\n const env = c.get('env');\n const windowMs = options.windowMs || env?.RATE_LIMIT_WINDOW_MS || 60 * 1000;\n const max = options.max || env?.RATE_LIMIT_MAX || 100;\n\n const key = keyGenerator(c);\n const rateLimitKey = `rate_limit:${key}`;\n\n // In Cloudflare Workers, use KV or Durable Objects for rate limiting\n // This is a simplified example\n if (c.env?.RATE_LIMIT_KV) {\n const current = await c.env.RATE_LIMIT_KV.get(rateLimitKey);\n const count = current ? parseInt(current, 10) : 0;\n\n if (count >= max) {\n return c.json(\n {\n errors: [\n {\n message: 'Too many requests',\n extensions: {\n code: 'RATE_LIMITED',\n retryAfter: windowMs / 1000,\n },\n },\n ],\n },\n 429,\n {\n 'Retry-After': String(windowMs / 1000),\n 'X-RateLimit-Limit': String(max),\n 'X-RateLimit-Remaining': '0',\n 'X-RateLimit-Reset': String(Date.now() + windowMs),\n }\n );\n }\n\n // Increment counter\n await c.env.RATE_LIMIT_KV.put(rateLimitKey, String(count + 1), {\n expirationTtl: windowMs / 1000,\n });\n\n // Add rate limit headers\n c.header('X-RateLimit-Limit', String(max));\n c.header('X-RateLimit-Remaining', String(max - count - 1));\n c.header('X-RateLimit-Reset', String(Date.now() + windowMs));\n }\n\n await next();\n };\n}\n","import type {MiddlewareHandler} from 'hono';\nimport {logger} from '@/logger';\n\nexport function createTracingMiddleware(): MiddlewareHandler {\n return async (c, next) => {\n // Get environment from context\n const env = c.get('env');\n // Extract or generate trace ID\n const traceId = c.req.header('x-trace-id') || generateTraceId();\n const spanId = generateSpanId();\n const parentSpanId = c.req.header('x-parent-span-id');\n const userId = c.get('userId');\n\n // Set global request context for pino logger\n globalThis.requestContext = {\n traceId,\n spanId,\n userId,\n };\n\n // Store in Hono context for other middleware\n c.set('traceId', traceId);\n c.set('spanId', spanId);\n\n // Add to response headers for correlation\n c.header('x-trace-id', traceId);\n c.header('x-span-id', spanId);\n\n const startTime = Date.now();\n\n try {\n await next();\n } finally {\n const duration = Date.now() - startTime;\n\n // Log request metrics using pino\n logger.info(\n {\n type: 'request',\n traceId,\n spanId,\n parentSpanId,\n method: c.req.method,\n path: c.req.path,\n status: c.res.status,\n duration,\n userAgent: c.req.header('user-agent'),\n ip:\n c.req.header('cf-connecting-ip') || c.req.header('x-forwarded-for'),\n },\n `${c.req.method} ${c.req.path} - ${c.res.status} (${duration}ms)`\n );\n\n // Add Server-Timing header for performance monitoring\n c.header('Server-Timing', `total;dur=${duration}`);\n\n // Clear global request context\n delete globalThis.requestContext;\n }\n };\n}\n\nfunction generateTraceId(): string {\n // Generate a 32-character hex string (128 bits)\n return Array.from(crypto.getRandomValues(new Uint8Array(16)))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nfunction generateSpanId(): string {\n // Generate a 16-character hex string (64 bits)\n return Array.from(crypto.getRandomValues(new Uint8Array(8)))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n","import type {Hono} from 'hono';\n\ninterface HealthCheckOptions {\n checks?: {\n [key: string]: () => Promise<boolean>;\n };\n}\n\nexport function configureHealthChecks(\n app: Hono<{\n Variables: {\n env: any;\n };\n }>,\n options: HealthCheckOptions = {}\n) {\n // Liveness probe - is the service running?\n app.get('/health', (c) => {\n return c.json({\n status: 'ok',\n timestamp: new Date().toISOString(),\n uptime: process.uptime ? process.uptime() : 0,\n });\n });\n\n // Readiness probe - is the service ready to accept traffic?\n app.get('/ready', async (c) => {\n const checks = options.checks || {};\n const results: Record<string, boolean> = {};\n let allHealthy = true;\n\n for (const [name, check] of Object.entries(checks)) {\n try {\n results[name] = await check();\n if (!results[name]) allHealthy = false;\n } catch (error) {\n results[name] = false;\n allHealthy = false;\n }\n }\n\n const status = allHealthy ? 200 : 503;\n return c.json(\n {\n status: allHealthy ? 'ready' : 'not_ready',\n checks: results,\n timestamp: new Date().toISOString(),\n },\n status\n );\n });\n\n // Metrics endpoint (for Prometheus)\n app.get('/metrics', (c) => {\n // In production, integrate with Prometheus client\n return c.text(`# HELP graphql_requests_total Total number of GraphQL requests\n# TYPE graphql_requests_total counter\ngraphql_requests_total 0\n\n# HELP graphql_errors_total Total number of GraphQL errors\n# TYPE graphql_errors_total counter\ngraphql_errors_total 0\n\n# HELP graphql_duration_seconds GraphQL request duration\n# TYPE graphql_duration_seconds histogram\ngraphql_duration_seconds_bucket{le=\"0.1\"} 0\ngraphql_duration_seconds_bucket{le=\"0.5\"} 0\ngraphql_duration_seconds_bucket{le=\"1\"} 0\ngraphql_duration_seconds_bucket{le=\"+Inf\"} 0\ngraphql_duration_seconds_sum 0\ngraphql_duration_seconds_count 0`);\n });\n}\n","import type {GraphQLError} from 'graphql';\nimport {ApolloServerErrorCode} from '@apollo/server/errors';\n\n// Unfortunately, this string constant is not exposed separately\nconst BAD_USER_INPUT_CODE = ApolloServerErrorCode.BAD_USER_INPUT;\n\nexport const getNonUserInputErrors = (errors: readonly GraphQLError[]) =>\n errors.filter((e) => e.extensions?.code !== BAD_USER_INPUT_CODE);\n","// import {CommonBaggageItems} from '@hiliosai/jaeger-apollo-plugin';\n\nimport type {GraphQLRequestContext} from '@apollo/server';\nimport {BaseContext} from '../context';\n\nexport enum CommonBaggageItems {\n ROOT_OP_NAME = 'root_op_name',\n}\n\nexport const getOpsName = (gqlCtx: GraphQLRequestContext<BaseContext>) =>\n gqlCtx.contextValue.rootSpan?.getBaggageItem(\n CommonBaggageItems.ROOT_OP_NAME\n ) ||\n gqlCtx.request.operationName ||\n gqlCtx.operationName ||\n 'UNKNOWN';\n","import {getNonUserInputErrors} from '@/utils/graphql.util';\nimport {getOpsName} from '@/utils/tracing.util';\nimport type {ApolloServerPlugin} from '@apollo/server';\nimport type {BaseContext} from '../context';\nimport {createLogger} from './index';\n\nconst getUserId = (gqlCtx: BaseContext) => gqlCtx.user?.id ?? 'UNKNOWN';\n\nexport function createApolloLoggingPlugin(): ApolloServerPlugin<BaseContext> {\n return {\n async requestDidStart(requestContext) {\n const start = Date.now();\n const operationName = requestContext.request.operationName;\n\n // Create a logger with request context\n const requestLogger = createLogger({\n source: 'apollo',\n operationName,\n });\n\n return {\n async didResolveOperation(gqlCtx) {\n const userId = getUserId(gqlCtx.contextValue);\n const operation = getOpsName(gqlCtx);\n\n requestLogger.info(\n {\n event: 'operation_resolved',\n operation,\n userId,\n operationName: gqlCtx.operationName,\n variables: gqlCtx.request.variables,\n },\n `Operation [${operation}] resolved for user [${userId}]`\n );\n },\n\n async willSendResponse(gqlCtx) {\n const errors = getNonUserInputErrors(gqlCtx.errors || []);\n const duration = Date.now() - start;\n const userId = getUserId(gqlCtx.contextValue);\n const operation = getOpsName(gqlCtx);\n\n if (errors.length > 0) {\n // Log errors with full context\n requestLogger.error(\n {\n event: 'operation_error',\n operation,\n userId,\n duration,\n errors: errors.map((e) => ({\n message: e.message,\n path: e.path,\n extensions: e.extensions,\n stack: e.stack,\n })),\n },\n `Operation [${operation}] failed with ${errors.length} error(s)`\n );\n }\n\n // Log completion with metrics\n requestLogger.info(\n {\n event: 'operation_complete',\n operation,\n userId,\n duration,\n success: errors.length === 0,\n errorCount: errors.length,\n },\n `Operation [${operation}] completed in ${duration}ms${errors.length > 0 ? ' with errors' : ' successfully'}`\n );\n },\n\n async didEncounterErrors(gqlCtx) {\n const errors = gqlCtx.errors || [];\n const userId = getUserId(gqlCtx.contextValue);\n\n requestLogger.error(\n {\n event: 'graphql_errors',\n userId,\n errors: errors.map((e) => ({\n message: e.message,\n path: e.path,\n extensions: e.extensions,\n })),\n },\n `GraphQL execution encountered ${errors.length} error(s)`\n );\n },\n };\n },\n };\n}\n","import type {BaseContext} from '@/context';\nimport {createApolloLoggingPlugin} from '@/logger/apollo.logger';\nimport {ApolloServerPluginLandingPageDisabled} from '@apollo/server/plugin/disabled';\nimport {ServerBuilder} from './server.builder';\n\nexport function configurePlugins<TContext extends BaseContext>(\n builder: ServerBuilder<unknown, TContext>\n) {\n // disable landing page\n builder.plugins.push(ApolloServerPluginLandingPageDisabled());\n\n // logger\n builder.plugins.push(createApolloLoggingPlugin());\n}\n","import {BaseContext} from '@/context';\nimport {logger} from '@/logger';\nimport {ServerBuilder, ServerConfig} from './server.builder';\n\nexport type BaseServerOptions = {\n /**\n * The version of the server\n *\n * @type {string}\n */\n version: string;\n /**\n * The name of the server\n *\n * @type {string}\n */\n name: string;\n\n /**\n * The port to listen on\n *\n * @type {number}\n */\n port?: number;\n\n /**\n * The hostname to listen on\n *\n * @type {string}\n */\n hostname?: string;\n};\n\nexport type ServerOptions<\n TDatasource,\n TContext extends BaseContext,\n> = BaseServerOptions & {\n config: ServerConfig<TDatasource, TContext>;\n};\n\nconst SERVICE_NAME_REGEX = /^[a-z0-9\\-_]+$/i;\n\nexport function createGraphQLServer<TDatasource, TContext extends BaseContext>(\n options: ServerOptions<TDatasource, TContext>\n) {\n if (!SERVICE_NAME_REGEX.test(options.name)) {\n throw new Error('Service name must be alphanumeric, hyphen, or underscore');\n }\n logger.info(`Creating GraphQL server ${options.name} v${options.version}`);\n return new ServerBuilder<TDatasource, TContext>(options.config);\n}\n","import {GraphQLError} from 'graphql';\nimport {ApolloServerErrorCode} from '@apollo/server/errors';\n\nexport enum ErrorCode {\n // Authentication & Authorization\n UNAUTHENTICATED = 'UNAUTHENTICATED',\n FORBIDDEN = 'FORBIDDEN',\n\n // Validation\n VALIDATION_FAILED = 'VALIDATION_FAILED',\n\n // Rate Limiting\n RATE_LIMITED = 'RATE_LIMITED',\n\n // External Service\n EXTERNAL_SERVICE_ERROR = 'EXTERNAL_SERVICE_ERROR',\n\n // Data\n NOT_FOUND = 'NOT_FOUND',\n CONFLICT = 'CONFLICT',\n}\n\nexport class AppError extends GraphQLError {\n constructor(\n message: string,\n code: ErrorCode | ApolloServerErrorCode,\n extensions?: Record<string, any>\n ) {\n super(message, {\n extensions: {\n code,\n ...extensions,\n },\n });\n }\n}\n\nexport function createErrorHandler(logger: any) {\n return (error: Error, context: any) => {\n const errorId = generateErrorId();\n\n logger.error({\n errorId,\n message: error.message,\n stack: error.stack,\n context: {\n user: context.user?.id,\n operation: context.operation?.name,\n },\n });\n\n if (error instanceof GraphQLError) {\n return error;\n }\n\n // Don't expose internal errors in production\n if (process.env.NODE_ENV === 'production') {\n return new AppError(\n 'Internal server error',\n ApolloServerErrorCode.INTERNAL_SERVER_ERROR,\n {errorId}\n );\n }\n\n return error;\n };\n}\n\nfunction generateErrorId(): string {\n return `err_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n}\n","import type {DocumentNode} from 'graphql';\n\nexport const createSchemaModule = (\n typeDefs: DocumentNode,\n resolvers?: any\n) => ({\n typeDefs,\n resolvers,\n});\n\nexport type SchemaModule = ReturnType<typeof createSchemaModule>;\nexport {gql} from 'graphql-tag';\n","import type {BaseContext} from '@/context';\nimport type {KVCache} from '@/cache';\n\nexport interface BaseDatasource<TContext extends BaseContext = BaseContext> {\n readonly name: string;\n context?: TContext;\n\n init?(): Promise<void> | void;\n connect?(): Promise<void> | void;\n disconnect?(): Promise<void> | void;\n healthCheck?(): Promise<boolean> | boolean;\n clear?(): Promise<void> | void;\n}\n\n/**\n * Abstract base class for all datasources in the GraphQL bootstrap\n * Provides common functionality like caching, logging, and lifecycle management\n */\nexport abstract class AbstractDatasource<\n TContext extends BaseContext = BaseContext,\n> implements BaseDatasource<TContext> {\n abstract readonly name: string;\n context: TContext;\n protected cache: KVCache;\n protected logger: TContext['logger'];\n\n constructor(cache: KVCache, context: TContext) {\n this.cache = cache;\n this.context = context;\n this.logger = context.logger;\n\n // Call initialize after construction\n this.initialize();\n }\n\n /**\n * Initialize datasource-specific configuration\n * Override this method to add custom initialization logic\n */\n protected initialize(): void {\n // Default implementation - override in subclasses\n this.logger?.info(`Initializing datasource: ${this.name}`);\n }\n\n async init(): Promise<void> {\n // Default implementation - override in subclasses\n this.logger?.info(`Initializing datasource: ${this.name}`);\n }\n\n async connect(): Promise<void> {\n // Default implementation - override in subclasses\n this.logger?.info(`Connecting datasource: ${this.name}`);\n }\n\n async disconnect(): Promise<void> {\n // Default implementation - override in subclasses\n this.logger?.info(`Disconnecting datasource: ${this.name}`);\n }\n\n async healthCheck(): Promise<boolean> {\n this.logger?.debug(`Health check for datasource: ${this.name}`);\n return true;\n }\n\n async clear(): Promise<void> {\n // Default implementation - override in subclasses\n this.logger?.info(`Clearing datasource: ${this.name}`);\n }\n\n /**\n * Helper method to get a cached result or fetch fresh data\n * Uses the enhanced KVCache memoize function\n */\n protected async cached<T>(\n key: string,\n fetchFn: () => Promise<T>,\n ttl?: number\n ): Promise<T> {\n return this.cache.memoize(key, {}, fetchFn, {ttl});\n }\n\n /**\n * Helper method to invalidate cache entries by pattern\n */\n protected async invalidateCache(pattern: string): Promise<number> {\n return this.cache.invalidate(pattern);\n }\n}\n","import type {BaseContext} from '@/context';\nimport type {KVCache} from '@/cache';\nimport {AbstractDatasource} from './base.datasource';\n\nexport interface RestClientOptions {\n baseURL: string;\n timeout?: number;\n headers?: Record<string, string>;\n retries?: number;\n}\n\n/**\n * REST datasource for making HTTP API calls with caching and error handling\n * Optimized for Cloudflare Workers environment\n */\nexport class RestDatasource<\n TContext extends BaseContext = BaseContext,\n> extends AbstractDatasource<TContext> {\n readonly name = 'rest';\n private baseURL: string;\n private timeout: number;\n private headers: Record<string, string>;\n private retries: number;\n\n constructor(cache: KVCache, context: TContext, options: RestClientOptions) {\n super(cache, context);\n this.baseURL = options.baseURL.replace(/\\/$/, ''); // Remove trailing slash\n this.timeout = options.timeout ?? 10000;\n this.headers = {\n 'Content-Type': 'application/json',\n 'User-Agent': 'cfw-graphql-bootstrap/1.0',\n ...options.headers,\n };\n this.retries = options.retries ?? 3;\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n this.logger?.debug(`Health check for REST datasource: ${this.baseURL}`);\n const response = await this.get('/health');\n const isHealthy = response.status < 400;\n this.logger?.info(\n `REST datasource health check: ${isHealthy ? 'OK' : 'FAILED'}`\n );\n return isHealthy;\n } catch (error) {\n this.logger?.error('REST datasource health check failed:', error);\n return false;\n }\n }\n\n /**\n * GET request with caching\n */\n async get<T = any>(\n path: string,\n options?: {\n cache?: boolean;\n ttl?: number;\n params?: Record<string, string>;\n }\n ): Promise<T> {\n const url = this.buildURL(path, options?.params);\n const cacheKey = `rest:get:${url}`;\n\n if (options?.cache !== false) {\n return this.cached(\n cacheKey,\n () => this.fetchWithRetry(url, {method: 'GET'}),\n options?.ttl\n );\n }\n\n return this.fetchWithRetry(url, {method: 'GET'});\n }\n\n /**\n * POST request (no caching)\n */\n async post<T = any>(\n path: string,\n data?: any,\n options?: {\n invalidatePattern?: string;\n }\n ): Promise<T> {\n const url = this.buildURL(path);\n const result = await this.fetchWithRetry(url, {\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n });\n\n // Invalidate cache if pattern provided\n if (options?.invalidatePattern) {\n await this.invalidateCache(options.invalidatePattern);\n }\n\n return result;\n }\n\n /**\n * PUT request (no caching)\n */\n async put<T = any>(\n path: string,\n data?: any,\n options?: {\n invalidatePattern?: string;\n }\n ): Promise<T> {\n const url = this.buildURL(path);\n const result = await this.fetchWithRetry(url, {\n method: 'PUT',\n body: data ? JSON.stringify(data) : undefined,\n });\n\n // Invalidate cache if pattern provided\n if (options?.invalidatePattern) {\n await this.invalidateCache(options.invalidatePattern);\n }\n\n return result;\n }\n\n /**\n * DELETE request (no caching)\n */\n async delete<T = any>(\n path: string,\n options?: {\n invalidatePattern?: string;\n }\n ): Promise<T> {\n const url = this.buildURL(path);\n const result = await this.fetchWithRetry(url, {method: 'DELETE'});\n\n // Invalidate cache if pattern provided\n if (options?.invalidatePattern) {\n await this.invalidateCache(options.invalidatePattern);\n }\n\n return result;\n }\n\n private buildURL(path: string, params?: Record<string, string>): string {\n const url = `${this.baseURL}${path.startsWith('/') ? path : `/${path}`}`;\n\n if (params) {\n const searchParams = new URLSearchParams(params);\n return `${url}?${searchParams.toString()}`;\n }\n\n return url;\n }\n\n private async fetchWithRetry<T = any>(\n url: string,\n options: RequestInit,\n attempt = 1\n ): Promise<T> {\n try {\n this.logger?.debug(\n `[${attempt}/${this.retries}] ${options.method || 'GET'} ${url}`\n );\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n ...options,\n headers: {\n ...this.headers,\n ...options.headers,\n },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n this.logger?.debug(\n `✓ ${options.method || 'GET'} ${url} - ${response.status}`\n );\n return await response.json();\n } catch (error) {\n this.logger?.warn(\n `✗ ${options.method || 'GET'} ${url} - Attempt ${attempt} failed:`,\n error\n );\n\n if (attempt < this.retries && this.shouldRetry(error)) {\n const delay = Math.pow(2, attempt) * 1000;\n this.logger?.info(`Retrying in ${delay}ms...`);\n await this.delay(delay); // Exponential backoff\n return this.fetchWithRetry(url, options, attempt + 1);\n }\n\n this.logger?.error(`Failed after ${attempt} attempts:`, error);\n throw error;\n }\n }\n\n private shouldRetry(error: any): boolean {\n // Retry on network errors and 5xx status codes\n return (\n error.name === 'AbortError' ||\n error.message?.includes('fetch') ||\n (error.message?.includes('HTTP 5') ?? false)\n );\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import type {KVCache} from '@/cache';\nimport type {BaseContext} from '@/context';\nimport {AbstractDatasource} from './base.datasource';\n\n// Minimal Prisma Client interface for type safety\nexport interface PrismaClientLike {\n $connect(): Promise<void>;\n $disconnect(): Promise<void>;\n $queryRaw: any;\n $queryRawUnsafe(sql: string, ...values: any[]): Promise<any>;\n $executeRawUnsafe(sql: string, ...values: any[]): Promise<number>;\n}\n\n// PrismaD1 adapter type (imported dynamically)\nexport interface PrismaD1 {\n // We don't need to define the full interface since it's used opaquely\n // The actual implementation comes from '@prisma/adapter-d1'\n}\n\n// Global Prisma client cache for reuse\ndeclare global {\n var __prismaD1Clients: Map<string, any> | undefined;\n}\n\n/**\n * Abstract Prisma datasource optimized for Cloudflare D1\n * Automatically creates PrismaD1 adapter and requires user to implement createClient()\n *\n * @example\n * ```typescript\n * import { PrismaClient } from '@prisma/client';\n * import { PrismaD1 } from '@prisma/adapter-d1';\n *\n * class UserDatasource extends PrismaD1Datasource<BaseContext, PrismaClient> {\n * createClient(adapter: PrismaD1): PrismaClient {\n * // Called only ONCE per datasource class, then cached globally\n * console.log('Creating UserDatasource client'); // Will only log once\n * return new PrismaClient({ adapter });\n * }\n *\n * async getUser(id: string) {\n * return this.client.user.findUnique({ where: { id } });\n * }\n * }\n *\n * // Multiple instances share the same client efficiently:\n * datasources: (cache: KVCache, context: TContext) => ({\n * user: new UserDatasource(cache, context), // Client cached by class name\n * admin: new UserDatasource(cache, context), // Reuses same client!\n * })\n * ```\n */\nexport abstract class PrismaD1Datasource<\n TContext extends BaseContext = BaseContext,\n TPrismaClient extends PrismaClientLike = PrismaClientLike,\n> extends AbstractDatasource<TContext> {\n readonly name = 'prisma-d1';\n private _client: TPrismaClient | null = null;\n\n constructor(cache: KVCache, context: TContext) {\n super(cache, context);\n }\n\n /**\n * Abstract method to create Prisma client with D1 adapter\n * Called only once per datasource class, then cached globally\n */\n abstract createClient(adapter: PrismaD1): TPrismaClient;\n\n get client(): TPrismaClient {\n if (!this._client) {\n throw new Error('Prisma client not initialized. Call connect() first.');\n }\n return this._client;\n }\n\n async connect(): Promise<void> {\n this.logger.info('Connecting Prisma D1 datasource...');\n\n // Get D1 database binding from context\n if (!this.context.db) {\n const error =\n 'D1 database binding not found. Add to wrangler.toml:\\n' +\n '[[d1_databases]]\\n' +\n 'binding = \"DB\"\\n' +\n 'database_name = \"your-database-name\"\\n' +\n 'database_id = \"your-database-id\"';\n this.logger.error(error);\n throw new Error(error);\n }\n\n // Create cache key based on datasource constructor name\n const clientKey = this.constructor.name;\n\n // Initialize global client cache if needed\n if (!global.__prismaD1Clients) {\n global.__prismaD1Clients = new Map();\n }\n\n // Check if we have a cached client for this datasource class\n if (global.__prismaD1Clients.has(clientKey)) {\n this._client = global.__prismaD1Clients.get(clientKey);\n this.logger.debug(`Using cached Prisma client for ${clientKey}`);\n } else {\n this.logger.debug('Creating new PrismaD1 adapter and client...');\n\n // Create PrismaD1 adapter\n const d1Module = await import('@prisma/adapter-d1');\n const PrismaD1 = (d1Module as any).PrismaD1 ?? d1Module.default;\n const adapter = new PrismaD1(this.context.db);\n\n // Create client only once per datasource class\n this._client = this.createClient(adapter);\n\n // Cache the client globally\n global.__prismaD1Clients.set(clientKey, this._client);\n this.logger.debug(`Cached new Prisma client for ${clientKey}`);\n }\n\n await this._client.$connect();\n this.logger.info('✓ Prisma D1 datasource connected');\n }\n\n // Helper method for proper resource cleanup in Workers context\n async disconnectWithContext(ctx?: {\n waitUntil: (promise: Promise<any>) => void;\n }): Promise<void> {\n if (!this._client) return;\n\n const disconnectPromise = this._client.$disconnect();\n\n // Use ctx.waitUntil() if available to ensure cleanup completes\n if (ctx?.waitUntil) {\n ctx.waitUntil(disconnectPromise);\n } else {\n await disconnectPromise;\n }\n }\n\n async disconnect(): Promise<void> {\n if (this._client) {\n await this._client.$disconnect();\n }\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n this.logger.debug('Prisma D1 datasource health check...');\n if (this._client) {\n await this._client.$queryRaw`SELECT 1`;\n }\n this.logger.info('Prisma D1 datasource health check: OK');\n return true;\n } catch (error) {\n this.logger.error('Prisma D1 datasource health check failed:', error);\n return false;\n }\n }\n\n /**\n * Execute a cached query using raw SQL\n */\n async queryRaw<T = any>(\n sql: string,\n values?: any[],\n options?: {\n cache?: boolean;\n ttl?: number;\n }\n ): Promise<T> {\n const cacheKey = `prisma-d1:raw:${sql}:${JSON.stringify(values || [])}`;\n\n if (options?.cache !== false) {\n return this.cached(\n cacheKey,\n () => this._client!.$queryRawUnsafe(sql, ...(values || [])),\n options?.ttl\n );\n }\n\n return this._client!.$queryRawUnsafe(sql, ...(values || []));\n }\n\n /**\n * Execute a mutation and invalidate cache\n */\n async executeRaw(\n sql: string,\n values?: any[],\n options?: {\n invalidatePattern?: string;\n }\n ): Promise<number> {\n if (!this._client) {\n throw new Error('Prisma client not initialized. Call connect() first.');\n }\n\n const result = await this._client.$executeRawUnsafe(sql, ...(values || []));\n\n // Invalidate cache if pattern provided\n if (options?.invalidatePattern) {\n await this.invalidateCache(options.invalidatePattern);\n }\n\n return result;\n }\n}\n"],"mappings":"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","names":["cached","cached","ApolloServerErrorCode","ErrorCode"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cfw-graphql-bootstrap",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Enterprise-grade GraphQL server for Cloudflare Workers",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -22,13 +22,14 @@
22
22
  "prepublishOnly": "bun run build",
23
23
  "test-server": "bun run --watch src/test-server.ts",
24
24
  "format": "prettier --write .",
25
- "cf-typegen": "wrangler types"
25
+ "cf-typegen": "wrangler types",
26
+ "typecheck": "tsc --noEmit"
26
27
  },
27
28
  "dependencies": {
28
29
  "@apollo/subgraph": "2.12.2",
29
- "@apollo/utils.keyvaluecache": "^2.1.1",
30
+ "@apollo/utils.keyvaluecache": "4.0.0",
30
31
  "@as-integrations/cloudflare-workers": "1.1.1",
31
- "dataloader": "^2.2.2",
32
+ "dataloader": "2.2.3",
32
33
  "graphql": "16.12.0",
33
34
  "graphql-tag": "2.12.6",
34
35
  "pino": "10.2.0"
@@ -37,16 +38,28 @@
37
38
  "@apollo/server": "^5.0.0",
38
39
  "@cloudflare/workers-types": "^4.0.0",
39
40
  "hono": "^4.0.0",
40
- "typescript": "^5.0.0"
41
+ "typescript": "5.9.3",
42
+ "@prisma/client": "^7.0.0",
43
+ "@prisma/adapter-d1": "^7.0.0"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "@prisma/client": {
47
+ "optional": true
48
+ },
49
+ "@prisma/adapter-d1": {
50
+ "optional": true
51
+ }
41
52
  },
42
53
  "devDependencies": {
43
54
  "@apollo/server": "5.2.0",
44
- "@cloudflare/workers-types": "4.20260116.0",
55
+ "@cloudflare/workers-types": "4.20260117.0",
45
56
  "@hiliosai/prettier": "1.0.2",
46
57
  "@hiliosai/typescript": "1.0.1",
47
- "@types/bun": "latest",
58
+ "@prisma/adapter-d1": "7.2.0",
59
+ "@prisma/client": "7.2.0",
60
+ "@types/bun": "1.3.6",
48
61
  "hono": "4.11.4",
49
- "tsup": "^8.0.2",
62
+ "tsup": "8.5.1",
50
63
  "wrangler": "4.59.2"
51
64
  },
52
65
  "prettier": "@hiliosai/prettier"