@celerity-sdk/testing 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/test-app.ts","../src/discovery.ts","../src/blueprint.ts","../src/mocks.ts","../src/clients.ts","../src/jwt.ts","../src/http.ts","../src/wait.ts","../src/ws.ts","../src/index.ts"],"sourcesContent":["import \"reflect-metadata\";\nimport type {\n Type,\n InjectionToken,\n Provider,\n HttpRequest,\n HttpResponse,\n WebSocketMessage,\n ConsumerEventInput,\n ScheduleEventInput,\n EventResult,\n} from \"@celerity-sdk/types\";\nimport type { Container, HandlerRegistry, TestingApplication } from \"@celerity-sdk/core\";\nimport { CelerityFactory } from \"@celerity-sdk/core\";\nimport { discoverResourceTokens } from \"./discovery\";\nimport { loadBlueprintResources } from \"./blueprint\";\nimport type { MockFn } from \"./mocks\";\nimport { createMocksForTokens } from \"./mocks\";\nimport { createRealClients } from \"./clients\";\n\nexport type CreateTestAppOptions = {\n /** The module under test. Its providers, controllers, guards, and imports are bootstrapped. */\n module: Type;\n /** When true, creates real resource clients from env vars. When false (default), creates mocks. */\n integration?: boolean;\n /** Additional providers to register in the test module. */\n providers?: Array<Type | (Provider & { provide: InjectionToken })>;\n /** Additional controllers to register. */\n controllers?: Type[];\n /** Additional guards to register. */\n guards?: Type[];\n /** Explicit overrides registered last — takes precedence over auto-discovery. */\n overrides?: Record<symbol, unknown>;\n /** Path to the blueprint file. Auto-detected if omitted. */\n blueprintPath?: string;\n};\n\n/**\n * TestApp wraps TestingApplication with mock access and lifecycle management.\n */\nexport class TestApp {\n private mocks: Map<symbol, Record<string, MockFn>>;\n private closeables: Array<{ close?(): void | Promise<void> }>;\n private inner: TestingApplication;\n\n constructor(\n inner: TestingApplication,\n mocks: Map<symbol, Record<string, MockFn>>,\n closeables: Array<{ close?(): void | Promise<void> }>,\n ) {\n this.inner = inner;\n this.mocks = mocks;\n this.closeables = closeables;\n }\n\n // -- Delegate to TestingApplication --\n\n injectHttp(request: HttpRequest): Promise<HttpResponse> {\n return this.inner.injectHttp(request);\n }\n\n injectWebSocket(route: string, message: WebSocketMessage): Promise<void> {\n return this.inner.injectWebSocket(route, message);\n }\n\n injectConsumer(handlerTag: string, event: ConsumerEventInput): Promise<EventResult> {\n return this.inner.injectConsumer(handlerTag, event);\n }\n\n injectSchedule(handlerTag: string, event: ScheduleEventInput): Promise<EventResult> {\n return this.inner.injectSchedule(handlerTag, event);\n }\n\n injectCustom(name: string, payload?: unknown): Promise<unknown> {\n return this.inner.injectCustom(name, payload);\n }\n\n getContainer(): Container {\n return this.inner.getContainer();\n }\n\n getRegistry(): HandlerRegistry {\n return this.inner.getRegistry();\n }\n\n // -- Mock access (unit mode) --\n\n /** Retrieve the auto-generated mock for a resource token. */\n getMock<T>(token: symbol): T {\n const mock = this.mocks.get(token);\n if (!mock) {\n throw new Error(`No mock found for token: ${String(token)}`);\n }\n return mock as T;\n }\n\n /** Get the mock Datastore for a named resource (e.g., \"usersDatastore\"). */\n getDatastoreMock(name: string): Record<string, MockFn> {\n return this.getMock(Symbol.for(`celerity:datastore:${name}`));\n }\n\n /** Get the mock Topic for a named resource. */\n getTopicMock(name: string): Record<string, MockFn> {\n return this.getMock(Symbol.for(`celerity:topic:${name}`));\n }\n\n /** Get the mock Queue for a named resource. */\n getQueueMock(name: string): Record<string, MockFn> {\n return this.getMock(Symbol.for(`celerity:queue:${name}`));\n }\n\n /** Get the mock Cache for a named resource. */\n getCacheMock(name: string): Record<string, MockFn> {\n return this.getMock(Symbol.for(`celerity:cache:${name}`));\n }\n\n /** Get the mock Bucket for a named resource. */\n getBucketMock(name: string): Record<string, MockFn> {\n return this.getMock(Symbol.for(`celerity:bucket:${name}`));\n }\n\n /** Get the mock Config namespace for a named resource. */\n getConfigMock(name: string): Record<string, MockFn> {\n return this.getMock(Symbol.for(`celerity:config:${name}`));\n }\n\n // -- Lifecycle --\n\n /** Close all real resource clients (integration mode). No-op in unit mode. */\n async close(): Promise<void> {\n for (const client of this.closeables) {\n try {\n await client.close?.();\n } catch {\n // Best-effort cleanup\n }\n }\n }\n}\n\n/**\n * Create a test application for unit or integration testing.\n *\n * - `integration: false` (default): Auto-discovers resource dependencies from the\n * module graph and creates mock objects for each. Access mocks via `app.getDatastoreMock()`, etc.\n *\n * - `integration: true`: Creates real resource clients from env vars provided by\n * `celerity dev test`. Physical resource names are resolved from the blueprint.\n *\n * In both modes, custom providers/controllers/guards can be added, and explicit\n * overrides take precedence over auto-discovered resources.\n */\nexport async function createTestApp(options: CreateTestAppOptions): Promise<TestApp> {\n const { providers = [], controllers = [], guards = [], overrides = {} } = options;\n\n const { inner, mocks, closeables } = await setupResources(options);\n const container = inner.getContainer();\n\n for (const provider of providers) {\n if (typeof provider === \"function\") {\n container.registerClass(provider);\n } else {\n container.register(provider.provide, provider);\n }\n }\n\n for (const ctrl of controllers) {\n if (!container.has(ctrl)) container.registerClass(ctrl);\n }\n\n for (const guard of guards) {\n if (!container.has(guard)) container.registerClass(guard);\n }\n\n applyOverrides(container, overrides);\n\n return new TestApp(inner, mocks, closeables);\n}\n\nasync function setupResources(options: CreateTestAppOptions): Promise<{\n inner: TestingApplication;\n mocks: Map<symbol, Record<string, MockFn>>;\n closeables: Array<{ close?(): void | Promise<void> }>;\n}> {\n const { module: rootModule, integration = false, blueprintPath } = options;\n\n const resourceInfos = discoverResourceTokens(rootModule);\n\n let mocks = new Map<symbol, Record<string, MockFn>>();\n let closeables: Array<{ close?(): void | Promise<void> }> = [];\n let resourceHandles = new Map<symbol, unknown>();\n\n if (integration) {\n const blueprintResources = loadBlueprintResources(blueprintPath);\n const result = await createRealClients(resourceInfos, blueprintResources);\n resourceHandles = result.handles;\n closeables = result.closeables;\n } else {\n mocks = createMocksForTokens(resourceInfos);\n for (const [token, mock] of mocks) {\n resourceHandles.set(token, mock);\n }\n }\n\n const inner = await CelerityFactory.createTestingApp(rootModule, {\n systemLayers: [],\n });\n\n const container = inner.getContainer();\n for (const [token, handle] of resourceHandles) {\n container.registerValue(token, handle);\n }\n\n return { inner, mocks, closeables };\n}\n\nfunction applyOverrides(container: Container, overrides: Record<symbol, unknown>): void {\n for (const [token, value] of Object.entries(overrides)) {\n container.registerValue(token as unknown as symbol, value);\n }\n for (const sym of Object.getOwnPropertySymbols(overrides)) {\n container.registerValue(sym, (overrides as Record<symbol, unknown>)[sym]);\n }\n}\n","import \"reflect-metadata\";\nimport type { Type } from \"@celerity-sdk/types\";\nimport { isRuntimeProvidedToken } from \"@celerity-sdk/common\";\nimport { buildModuleGraph, getClassDependencyTokens } from \"@celerity-sdk/core\";\n\n/**\n * Parsed resource token info extracted from a Symbol description\n * like \"celerity:datastore:usersDatastore\".\n */\nexport type ResourceTokenInfo = {\n token: symbol;\n type: string; // \"datastore\", \"topic\", \"queue\", \"cache\", \"bucket\", \"sqlDatabase\", \"config\"\n name: string; // \"usersDatastore\", \"userEventsTopic\", etc.\n};\n\n/**\n * Walks the module graph for the given root module and extracts all resource\n * layer tokens from provider, controller, and guard constructor parameters.\n *\n * This discovers which resources the module (and its imports) depend on\n * without instantiating anything.\n */\nexport function discoverResourceTokens(rootModule: Type): ResourceTokenInfo[] {\n const graph = buildModuleGraph(rootModule);\n const seen = new Set<symbol>();\n const result: ResourceTokenInfo[] = [];\n\n for (const [, node] of graph) {\n const classes: Type[] = [\n ...node.controllers,\n ...node.guards.filter((g): g is Type => typeof g === \"function\"),\n ];\n\n for (const provider of node.providers) {\n if (typeof provider === \"function\") {\n classes.push(provider);\n } else if (\"useClass\" in provider) {\n classes.push((provider as { useClass: Type }).useClass);\n }\n }\n\n for (const cls of classes) {\n const depTokens = getClassDependencyTokens(cls);\n for (const dep of depTokens) {\n if (typeof dep !== \"symbol\") continue;\n if (!isRuntimeProvidedToken(dep)) continue;\n if (seen.has(dep)) continue;\n seen.add(dep);\n\n const parsed = parseResourceToken(dep);\n if (parsed) {\n result.push(parsed);\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Parse a resource token symbol like Symbol.for(\"celerity:datastore:usersDatastore\")\n * into its type and name components.\n */\nfunction parseResourceToken(token: symbol): ResourceTokenInfo | null {\n const desc = token.description;\n if (!desc) return null;\n\n // Format: \"celerity:<type>:<name>\"\n const parts = desc.split(\":\");\n if (parts.length < 3 || parts[0] !== \"celerity\") return null;\n\n return {\n token,\n type: parts[1],\n name: parts.slice(2).join(\":\"), // handle names with colons (unlikely but safe)\n };\n}\n","import { readFileSync, existsSync } from \"node:fs\";\nimport { resolve, join, extname } from \"node:path\";\nimport yaml from \"js-yaml\";\nimport stripJsonComments from \"strip-json-comments\";\n\n/**\n * Physical resource info extracted from the blueprint.\n */\nexport type BlueprintResource = {\n resourceId: string;\n type: string; // \"celerity/datastore\", \"celerity/topic\", etc.\n physicalName: string; // spec.name or fallback to resourceId\n};\n\ntype BlueprintSpec = {\n resources?: Record<string, { type?: string; spec?: { name?: string } }>;\n};\n\n/**\n * Parse the app blueprint and extract resource definitions with their\n * physical names (spec.name). This maps resource IDs used in decorators\n * (e.g., \"usersDatastore\") to the actual infrastructure names (e.g., \"users\").\n */\nexport function loadBlueprintResources(blueprintPath?: string): Map<string, BlueprintResource> {\n const path = blueprintPath ?? findBlueprintPath();\n if (!path) return new Map();\n\n const bp = parseBlueprint(path) as BlueprintSpec | undefined;\n\n const resources = new Map<string, BlueprintResource>();\n const bpResources = bp?.resources;\n if (!bpResources || typeof bpResources !== \"object\") return resources;\n\n for (const [id, resource] of Object.entries(bpResources)) {\n if (!resource?.type) continue;\n\n resources.set(id, {\n resourceId: id,\n type: resource.type,\n physicalName: resource.spec?.name ?? id,\n });\n }\n\n return resources;\n}\n\n/**\n * Map a resource type from the token format (\"datastore\") to the blueprint\n * format (\"celerity/datastore\").\n */\nexport function tokenTypeToBlueprintType(tokenType: string): string {\n return `celerity/${tokenType}`;\n}\n\n/**\n * WebSocket configuration extracted from the blueprint's API resource.\n */\nexport type WebSocketConfig = {\n /** The base path for WebSocket connections (e.g., \"/ws\"). */\n basePath: string;\n /** The route key used for message routing (e.g., \"action\"). */\n routeKey: string;\n /** The auth strategy: \"authMessage\" or \"connect\". */\n authStrategy: \"authMessage\" | \"connect\";\n};\n\n/**\n * Extract WebSocket configuration from the first celerity/api resource\n * in the blueprint that has WebSocket protocol configured.\n *\n * Returns null if no WebSocket configuration is found.\n */\nexport function loadWebSocketConfig(blueprintPath?: string): WebSocketConfig | null {\n const path = blueprintPath ?? findBlueprintPath();\n if (!path) return null;\n\n const bp = parseBlueprint(path) as unknown;\n if (!bp || typeof bp !== \"object\") return null;\n\n const resources = (bp as Record<string, unknown>).resources;\n if (!resources || typeof resources !== \"object\") return null;\n\n for (const resource of Object.values(resources as Record<string, unknown>)) {\n if (!resource || typeof resource !== \"object\") continue;\n const res = resource as Record<string, unknown>;\n if (res.type !== \"celerity/api\" || !res.spec) continue;\n\n const spec = res.spec as Record<string, unknown>;\n const { routeKey, authStrategy } = findWsProtocolConfig(spec.protocols);\n const basePath = findWsBasePath(spec.domain);\n\n return { basePath, routeKey, authStrategy };\n }\n\n return null;\n}\n\nfunction findWsProtocolConfig(protocols: unknown): {\n routeKey: string;\n authStrategy: \"authMessage\" | \"connect\";\n} {\n const defaults = { routeKey: \"action\", authStrategy: \"authMessage\" as const };\n if (!Array.isArray(protocols)) return defaults;\n\n for (const proto of protocols) {\n if (typeof proto !== \"object\" || !proto) continue;\n const wsCfg = (proto as Record<string, unknown>).websocketConfig;\n if (!wsCfg || typeof wsCfg !== \"object\") continue;\n\n const cfg = wsCfg as Record<string, unknown>;\n return {\n routeKey: typeof cfg.routeKey === \"string\" ? cfg.routeKey : defaults.routeKey,\n authStrategy:\n cfg.authStrategy === \"connect\" || cfg.authStrategy === \"authMessage\"\n ? cfg.authStrategy\n : defaults.authStrategy,\n };\n }\n\n return defaults;\n}\n\nfunction findWsBasePath(domain: unknown): string {\n if (!domain || typeof domain !== \"object\") return \"/ws\";\n\n const basePaths = (domain as Record<string, unknown>).basePaths;\n if (!Array.isArray(basePaths)) return \"/ws\";\n\n for (const entry of basePaths) {\n if (typeof entry !== \"object\" || !entry) continue;\n const bp = entry as Record<string, unknown>;\n if (bp.protocol !== \"websocket\") continue;\n return typeof bp.basePath === \"string\" ? bp.basePath : \"/ws\";\n }\n\n return \"/ws\";\n}\n\nfunction parseBlueprint(filePath: string): unknown {\n const content = readFileSync(filePath, \"utf-8\");\n const ext = extname(filePath);\n if (ext === \".jsonc\" || ext === \".json\") {\n return JSON.parse(stripJsonComments(content, { trailingCommas: true }));\n }\n return yaml.load(content);\n}\n\nfunction findBlueprintPath(): string | null {\n const cwd = process.cwd();\n const candidates = [\n join(cwd, \"app.blueprint.yaml\"),\n join(cwd, \"app.blueprint.yml\"),\n join(cwd, \"app.blueprint.jsonc\"),\n join(cwd, \"app.blueprint.json\"),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return resolve(candidate);\n }\n }\n return null;\n}\n","import type { ResourceTokenInfo } from \"./discovery\";\n\n// Intentionally uses `any` to remain compatible with jest.Mock and vi.fn return types.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type MockFn = (...args: any[]) => any;\nexport type MockFnCreator = () => MockFn;\n\ntype TestFrameworkGlobals = {\n jest?: { fn?: MockFnCreator };\n vi?: { fn?: MockFnCreator };\n};\n\n/**\n * Detects the test framework and returns its mock function creator.\n * Falls back to a basic no-op function if neither jest nor vitest is detected.\n */\nfunction detectMockFnCreator(): MockFnCreator {\n const g = globalThis as typeof globalThis & TestFrameworkGlobals;\n if (g.jest?.fn) {\n return g.jest.fn;\n }\n if (g.vi?.fn) {\n return g.vi.fn;\n }\n // Basic spy fallback\n return () => {\n const fn = (..._args: unknown[]) => undefined;\n return fn as MockFn;\n };\n}\n\n/**\n * Creates a mock object for a resource type with all interface methods stubbed.\n * Returns null for resource types that cannot be meaningfully mocked (e.g. sqlDatabase).\n */\nexport function createResourceMock(\n resourceType: string,\n mockFn?: MockFnCreator,\n): Record<string, MockFn> | null {\n const create = mockFn ?? detectMockFnCreator();\n\n switch (resourceType) {\n case \"datastore\":\n return createDatastoreMock(create);\n case \"topic\":\n return createTopicMock(create);\n case \"queue\":\n return createQueueMock(create);\n case \"cache\":\n return createCacheMock(create);\n case \"bucket\":\n return createBucketMock(create);\n case \"config\":\n return createConfigMock(create);\n default:\n // sqlDatabase uses Knex with a massive fluent API — mocking it isn't\n // practical. Use integration mode with a real database instead.\n return null;\n }\n}\n\nfunction createDatastoreMock(fn: MockFnCreator): Record<string, MockFn> {\n return {\n getItem: fn(),\n putItem: fn(),\n deleteItem: fn(),\n query: fn(),\n scan: fn(),\n batchGetItems: fn(),\n batchWriteItems: fn(),\n };\n}\n\nfunction createTopicMock(fn: MockFnCreator): Record<string, MockFn> {\n return {\n publish: fn(),\n publishBatch: fn(),\n };\n}\n\nfunction createQueueMock(fn: MockFnCreator): Record<string, MockFn> {\n return {\n sendMessage: fn(),\n sendMessageBatch: fn(),\n };\n}\n\nfunction createCacheMock(fn: MockFnCreator): Record<string, MockFn> {\n return {\n get: fn(),\n set: fn(),\n delete: fn(),\n incr: fn(),\n decr: fn(),\n incrFloat: fn(),\n mget: fn(),\n mset: fn(),\n mdelete: fn(),\n exists: fn(),\n expire: fn(),\n persist: fn(),\n ttl: fn(),\n rename: fn(),\n getSet: fn(),\n append: fn(),\n keyType: fn(),\n scanKeys: fn(),\n hashGet: fn(),\n hashSet: fn(),\n hashDelete: fn(),\n hashGetAll: fn(),\n hashExists: fn(),\n hashIncr: fn(),\n hashKeys: fn(),\n hashLen: fn(),\n listPush: fn(),\n listPop: fn(),\n listRange: fn(),\n listLen: fn(),\n listTrim: fn(),\n listIndex: fn(),\n setAdd: fn(),\n setRemove: fn(),\n setMembers: fn(),\n setIsMember: fn(),\n setLen: fn(),\n setUnion: fn(),\n setIntersect: fn(),\n setDiff: fn(),\n sortedSetAdd: fn(),\n sortedSetRemove: fn(),\n sortedSetScore: fn(),\n sortedSetRank: fn(),\n sortedSetRange: fn(),\n sortedSetRangeByScore: fn(),\n sortedSetIncr: fn(),\n sortedSetLen: fn(),\n transaction: fn(),\n };\n}\n\nfunction createBucketMock(fn: MockFnCreator): Record<string, MockFn> {\n return {\n get: fn(),\n put: fn(),\n delete: fn(),\n info: fn(),\n exists: fn(),\n list: fn(),\n copy: fn(),\n signUrl: fn(),\n };\n}\n\nfunction createConfigMock(fn: MockFnCreator): Record<string, MockFn> {\n return {\n get: fn(),\n getOrThrow: fn(),\n getAll: fn(),\n parse: fn(),\n };\n}\n\n/**\n * Creates mock objects for all discovered resource tokens.\n * Returns a map of token → mock object. Tokens for unmockable resource types\n * (like sqlDatabase) are omitted.\n */\nexport function createMocksForTokens(\n tokens: ResourceTokenInfo[],\n mockFn?: MockFnCreator,\n): Map<symbol, Record<string, MockFn>> {\n const mocks = new Map<symbol, Record<string, MockFn>>();\n for (const info of tokens) {\n const mock = createResourceMock(info.type, mockFn);\n if (mock) {\n mocks.set(info.token, mock);\n }\n }\n return mocks;\n}\n","import type { ResourceTokenInfo } from \"./discovery\";\nimport type { BlueprintResource } from \"./blueprint\";\n\ntype Closeable = { close?(): void | Promise<void> };\n\n/**\n * Creates real resource client handles for integration testing by dynamically\n * importing the relevant SDK package and calling its factory with local env vars.\n *\n * Each resource package is an optional peer dependency — only the packages\n * actually needed by the module under test are imported.\n *\n * Returns a map of token → real resource handle, plus a list of clients\n * that need closing when tests finish.\n */\nexport async function createRealClients(\n tokens: ResourceTokenInfo[],\n blueprintResources: Map<string, BlueprintResource>,\n): Promise<{ handles: Map<symbol, unknown>; closeables: Closeable[] }> {\n const handles = new Map<symbol, unknown>();\n const closeables: Closeable[] = [];\n\n // Group tokens by type to share a single client per resource type.\n const byType = new Map<string, ResourceTokenInfo[]>();\n for (const info of tokens) {\n const group = byType.get(info.type) ?? [];\n group.push(info);\n byType.set(info.type, group);\n }\n\n for (const [type, infos] of byType) {\n try {\n switch (type) {\n case \"datastore\":\n await createDatastoreHandles(infos, blueprintResources, handles, closeables);\n break;\n case \"topic\":\n await createTopicHandles(infos, blueprintResources, handles, closeables);\n break;\n case \"queue\":\n await createQueueHandles(infos, blueprintResources, handles, closeables);\n break;\n case \"cache\":\n await createCacheHandles(infos, handles, closeables);\n break;\n case \"bucket\":\n await createBucketHandles(infos, blueprintResources, handles, closeables);\n break;\n case \"sqlDatabase\":\n await createSqlHandles(infos, blueprintResources, handles, closeables);\n break;\n case \"config\":\n await createConfigHandles(infos, handles);\n break;\n }\n } catch (err) {\n const pkg = type === \"sqlDatabase\" ? \"sql-database\" : type;\n throw new Error(\n `Failed to create ${type} client for integration test. ` +\n `Is @celerity-sdk/${pkg} installed? Error: ${err}`,\n );\n }\n }\n\n return { handles, closeables };\n}\n\nfunction physicalName(info: ResourceTokenInfo, bp: Map<string, BlueprintResource>): string {\n return bp.get(info.name)?.physicalName ?? info.name;\n}\n\nasync function createConfigHandles(\n infos: ResourceTokenInfo[],\n handles: Map<symbol, unknown>,\n): Promise<void> {\n const { ConfigNamespaceImpl, LocalConfigBackend } = await import(\"@celerity-sdk/config\");\n const backend = new LocalConfigBackend();\n\n for (const info of infos) {\n const envKey = info.name.toUpperCase();\n const storeId = process.env[`CELERITY_CONFIG_${envKey}_STORE_ID`] ?? info.name;\n const ns = new ConfigNamespaceImpl(backend, storeId);\n handles.set(info.token, ns);\n }\n}\n\nasync function createDatastoreHandles(\n infos: ResourceTokenInfo[],\n bp: Map<string, BlueprintResource>,\n handles: Map<symbol, unknown>,\n closeables: Closeable[],\n): Promise<void> {\n const { createDatastoreClient } = await import(\"@celerity-sdk/datastore\");\n const client = await createDatastoreClient({ provider: \"local\" });\n closeables.push(client);\n for (const info of infos) {\n handles.set(info.token, client.datastore(physicalName(info, bp)));\n }\n}\n\nasync function createTopicHandles(\n infos: ResourceTokenInfo[],\n bp: Map<string, BlueprintResource>,\n handles: Map<symbol, unknown>,\n closeables: Closeable[],\n): Promise<void> {\n const { createTopicClient } = await import(\"@celerity-sdk/topic\");\n const client = await createTopicClient({ provider: \"local\" });\n closeables.push(client);\n for (const info of infos) {\n handles.set(info.token, client.topic(physicalName(info, bp)));\n }\n}\n\nasync function createQueueHandles(\n infos: ResourceTokenInfo[],\n bp: Map<string, BlueprintResource>,\n handles: Map<symbol, unknown>,\n closeables: Closeable[],\n): Promise<void> {\n const { createQueueClient } = await import(\"@celerity-sdk/queue\");\n const client = await createQueueClient({ provider: \"local\" });\n closeables.push(client);\n for (const info of infos) {\n handles.set(info.token, client.queue(physicalName(info, bp)));\n }\n}\n\nasync function createCacheHandles(\n infos: ResourceTokenInfo[],\n handles: Map<symbol, unknown>,\n closeables: Closeable[],\n): Promise<void> {\n const { createCacheClient } = await import(\"@celerity-sdk/cache\");\n // For local environments, read connection info from CELERITY_REDIS_ENDPOINT.\n const endpoint = process.env.CELERITY_REDIS_ENDPOINT ?? \"redis://localhost:6379\";\n const url = new URL(endpoint);\n const client = await createCacheClient({\n config: {\n host: url.hostname,\n port: Number.parseInt(url.port || \"6379\", 10),\n tls: false,\n clusterMode: false,\n authMode: \"password\" as const,\n connectionConfig: {\n connectTimeoutMs: 5000,\n commandTimeoutMs: 5000,\n keepAliveMs: 0,\n maxRetries: 3,\n retryDelayMs: 100,\n lazyConnect: false,\n },\n },\n });\n closeables.push(client);\n for (const info of infos) {\n handles.set(info.token, client.cache(info.name));\n }\n}\n\nasync function createBucketHandles(\n infos: ResourceTokenInfo[],\n bp: Map<string, BlueprintResource>,\n handles: Map<symbol, unknown>,\n closeables: Closeable[],\n): Promise<void> {\n const { createObjectStorage } = await import(\"@celerity-sdk/bucket\");\n const client = await createObjectStorage({ provider: \"local\" });\n closeables.push(client);\n for (const info of infos) {\n handles.set(info.token, client.bucket(physicalName(info, bp)));\n }\n}\n\nasync function createSqlHandles(\n infos: ResourceTokenInfo[],\n bp: Map<string, BlueprintResource>,\n handles: Map<symbol, unknown>,\n closeables: Closeable[],\n): Promise<void> {\n const connStr = process.env.CELERITY_LOCAL_SQL_DATABASE_ENDPOINT;\n if (!connStr) {\n throw new Error(\n \"CELERITY_LOCAL_SQL_DATABASE_ENDPOINT must be set for SQL database integration tests\",\n );\n }\n\n const { createKnexInstance } = await import(\"@celerity-sdk/sql-database\");\n\n // SQL tokens include a sub-type prefix in the name:\n // celerity:sqlDatabase:writer:auditDatabase → name = \"writer:auditDatabase\"\n // celerity:sqlDatabase:reader:auditDatabase → name = \"reader:auditDatabase\"\n // Multiple tokens may share the same underlying database, so we deduplicate\n // by resource name and share a single Knex instance per database.\n const knexByResource = new Map<string, ReturnType<typeof createKnexInstance>>();\n\n for (const info of infos) {\n const resourceName = sqlResourceName(info.name);\n const lookupInfo = { ...info, name: resourceName };\n const dbName = physicalName(lookupInfo, bp);\n\n if (!knexByResource.has(dbName)) {\n const url = new URL(connStr);\n const engine = sqlEngineFromProtocol(url.protocol);\n const defaultPort = engine === \"mysql\" ? \"3306\" : \"5432\";\n const knexPromise = createKnexInstance({\n credentials: {\n getConnectionInfo: async () => ({\n engine,\n host: url.hostname,\n port: Number.parseInt(url.port || defaultPort, 10),\n user: url.username,\n database: dbName,\n ssl: false,\n authMode: \"password\" as const,\n }),\n getPasswordAuth: async () => ({\n password: url.password,\n url: connStr,\n }),\n getIamAuth: async () => {\n throw new Error(\"IAM auth not supported in local mode\");\n },\n },\n deployTarget: \"functions\",\n });\n knexByResource.set(dbName, knexPromise);\n closeables.push({ close: async () => (await knexPromise).destroy() });\n }\n\n const knex = await knexByResource.get(dbName)!;\n handles.set(info.token, knex);\n }\n}\n\nfunction sqlEngineFromProtocol(protocol: string): \"postgres\" | \"mysql\" {\n if (protocol === \"mysql:\" || protocol === \"mysql2:\") return \"mysql\";\n return \"postgres\";\n}\n\n/**\n * Extract the resource name from a sqlDatabase token name.\n * Token names have the format \"writer:resourceName\", \"reader:resourceName\", etc.\n * Returns just the resource name part for blueprint lookup.\n */\nfunction sqlResourceName(tokenName: string): string {\n const colonIdx = tokenName.indexOf(\":\");\n if (colonIdx === -1) return tokenName;\n return tokenName.slice(colonIdx + 1);\n}\n","export type GenerateTestTokenOptions = {\n /** Subject claim (required by the dev auth server). Default: \"test-user\" */\n sub?: string;\n /** Arbitrary claims spread into the JWT payload (roles, permissions, org_id, etc.). */\n claims?: Record<string, unknown>;\n /** Token lifetime as a Go-style duration string. Default: \"1h\" */\n expiresIn?: string;\n};\n\n/**\n * Generate an RS256-signed JWT by calling the local dev auth server.\n *\n * The dev auth server runs as a sidecar in `celerity dev test` / `celerity dev run`\n * and is accessible via the `CELERITY_DEV_AUTH_BASE_URL` env var.\n *\n * @returns The signed access token string.\n * @throws If the dev auth server is unreachable or returns an error.\n */\nexport async function generateTestToken(options?: GenerateTestTokenOptions): Promise<string> {\n const baseURL = process.env.CELERITY_DEV_AUTH_BASE_URL ?? \"http://localhost:9099\";\n\n const body: Record<string, unknown> = {\n sub: options?.sub ?? \"test-user\",\n };\n if (options?.claims) {\n body.claims = options.claims;\n }\n if (options?.expiresIn) {\n body.expiresIn = options.expiresIn;\n }\n\n const response = await fetch(`${baseURL}/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Dev auth server returned ${response.status}: ${text}`);\n }\n\n const data = (await response.json()) as { access_token: string };\n return data.access_token;\n}\n","/**\n * Asserting HTTP client for API tests against a running application.\n * Reads `CELERITY_TEST_BASE_URL` (default http://localhost:8081).\n */\n\nexport type TestResponse<TBody = unknown> = {\n status: number;\n headers: Headers;\n body: TBody;\n text: string;\n};\n\ntype ExpectFn = (body: unknown) => void;\n\nexport class TestRequest<TBody = unknown> {\n private _headers: Record<string, string> = {};\n private _body?: unknown;\n private _expectations: Array<\n | { type: \"status\"; value: number }\n | { type: \"body\"; value: unknown | ExpectFn }\n | { type: \"header\"; key: string; value: string | RegExp }\n > = [];\n\n constructor(\n private baseUrl: string,\n private method: string,\n private path: string,\n ) {}\n\n /** Set an authorization bearer token. */\n auth(token: string): this {\n this._headers[\"Authorization\"] = `Bearer ${token}`;\n return this;\n }\n\n /** Set a request header. */\n set(key: string, value: string): this {\n this._headers[key] = value;\n return this;\n }\n\n /** Set the request JSON body. */\n send(body: unknown): this {\n this._body = body;\n return this;\n }\n\n /** Add an expectation. Overloaded: status code, body object/fn, or header. */\n expect(statusOrBodyOrFn: number | unknown | ExpectFn): this;\n expect(header: string, value: string | RegExp): this;\n expect(first: unknown, second?: unknown): this {\n if (typeof first === \"number\") {\n this._expectations.push({ type: \"status\", value: first });\n } else if (typeof first === \"string\" && second !== undefined) {\n this._expectations.push({\n type: \"header\",\n key: first.toLowerCase(),\n value: second as string | RegExp,\n });\n } else if (typeof first === \"function\") {\n this._expectations.push({ type: \"body\", value: first as ExpectFn });\n } else {\n this._expectations.push({ type: \"body\", value: first });\n }\n return this;\n }\n\n /** Execute the request and run all expectations. Returns the response. */\n async end(): Promise<TestResponse<TBody>> {\n const headers: Record<string, string> = { ...this._headers };\n if (this._body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const response = await fetch(`${this.baseUrl}${this.path}`, {\n method: this.method,\n headers,\n body: this._body !== undefined ? JSON.stringify(this._body) : undefined,\n });\n\n const text = await response.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n\n const result: TestResponse<TBody> = {\n status: response.status,\n headers: response.headers,\n body: body as TBody,\n text,\n };\n\n for (const exp of this._expectations) {\n this.assertExpectation(exp, result, text);\n }\n\n return result;\n }\n\n private assertExpectation(\n exp: TestRequest<TBody>[\"_expectations\"][number],\n result: TestResponse<TBody>,\n text: string,\n ): void {\n if (exp.type === \"status\") {\n if (result.status !== exp.value) {\n throw new Error(`Expected status ${exp.value} but got ${result.status}.\\nBody: ${text}`);\n }\n return;\n }\n\n if (exp.type === \"body\") {\n if (typeof exp.value === \"function\") {\n (exp.value as ExpectFn)(result.body);\n } else {\n const expected = JSON.stringify(exp.value);\n const actual = JSON.stringify(result.body);\n if (expected !== actual) {\n throw new Error(`Expected body ${expected} but got ${actual}`);\n }\n }\n return;\n }\n\n if (exp.type === \"header\") {\n this.assertHeader(exp.key, exp.value, result.headers);\n }\n }\n\n private assertHeader(key: string, expected: string | RegExp, headers: Headers): void {\n const actual = headers.get(key);\n if (expected instanceof RegExp) {\n if (!actual || !expected.test(actual)) {\n throw new Error(`Expected header \"${key}\" to match ${expected} but got \"${actual}\"`);\n }\n return;\n }\n if (actual !== expected) {\n throw new Error(`Expected header \"${key}\" to be \"${expected}\" but got \"${actual}\"`);\n }\n }\n\n /** Implements PromiseLike so the request chain can be awaited directly. */\n then<T>( // intentional thenable for fluent await syntax\n resolve: (value: TestResponse<TBody>) => T | PromiseLike<T>,\n reject?: (reason: unknown) => T | PromiseLike<T>,\n ): Promise<T> {\n return this.end().then(resolve, reject);\n }\n}\n\nexport class TestHttpClient {\n constructor(private baseUrl: string) {}\n\n get<TBody = Record<string, unknown>>(path: string): TestRequest<TBody> {\n return new TestRequest<TBody>(this.baseUrl, \"GET\", path);\n }\n\n post<TBody = Record<string, unknown>>(path: string): TestRequest<TBody> {\n return new TestRequest<TBody>(this.baseUrl, \"POST\", path);\n }\n\n put<TBody = Record<string, unknown>>(path: string): TestRequest<TBody> {\n return new TestRequest<TBody>(this.baseUrl, \"PUT\", path);\n }\n\n patch<TBody = Record<string, unknown>>(path: string): TestRequest<TBody> {\n return new TestRequest<TBody>(this.baseUrl, \"PATCH\", path);\n }\n\n delete<TBody = Record<string, unknown>>(path: string): TestRequest<TBody> {\n return new TestRequest<TBody>(this.baseUrl, \"DELETE\", path);\n }\n}\n\n/**\n * Create a test HTTP client for API tests.\n * Reads `CELERITY_TEST_BASE_URL` env var (default: http://localhost:8081).\n */\nexport function createTestClient(options?: { baseUrl?: string }): TestHttpClient {\n const baseUrl = options?.baseUrl ?? process.env.CELERITY_TEST_BASE_URL ?? \"http://localhost:8081\";\n return new TestHttpClient(baseUrl);\n}\n","/**\n * Polls a predicate function until it returns true or the timeout expires.\n *\n * @param predicate - Function that returns true when the condition is met.\n * @param options - Timeout (ms, default 5000) and poll interval (ms, default 100).\n */\nexport async function waitFor(\n predicate: () => Promise<boolean> | boolean,\n options?: { timeout?: number; interval?: number },\n): Promise<void> {\n const timeout = options?.timeout ?? 5_000;\n const interval = options?.interval ?? 100;\n const deadline = Date.now() + timeout;\n\n while (Date.now() < deadline) {\n const result = await predicate();\n if (result) return;\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n\n throw new Error(`waitFor timed out after ${timeout}ms`);\n}\n","/**\n * Sequential WebSocket test client for Celerity applications.\n *\n * Wraps `@celerity-sdk/ws-client` to provide an `await`-based message flow.\n * All runtime protocol concerns (heartbeat, capabilities negotiation, ack,\n * dedup) are handled by the underlying client — only application messages\n * surface to tests.\n *\n * Configuration is derived from the blueprint and `celerity dev test` env vars.\n */\n\nimport { generateTestToken, type GenerateTestTokenOptions } from \"./jwt\";\nimport { loadWebSocketConfig } from \"./blueprint\";\n\ntype AuthConfig = {\n strategy: \"authMessage\" | \"connect\";\n token: string | (() => Promise<string>);\n};\n\ntype WsClientModule = typeof import(\"@celerity-sdk/ws-client\");\ntype Unsubscribe = () => void;\n\n/** Structural type for the subset of CelerityWsClient used by TestWsClient. */\ntype WsClient = {\n on(event: string, handler: (...args: never[]) => void): Unsubscribe;\n connect(): Promise<void>;\n send(route: string, data: unknown): string;\n disconnect(): Promise<void>;\n destroy(): void;\n state: string;\n};\n\nexport type CreateTestWsClientOptions = {\n /** Override the WebSocket URL. Derived from CELERITY_TEST_BASE_URL + blueprint basePath if omitted. */\n url?: string;\n /** Token for auth. String = use directly. Object = options for generateTestToken(). Omit to skip auth entirely. */\n token?: string | GenerateTestTokenOptions | null;\n /** Path to the blueprint file (auto-detected if omitted). */\n blueprintPath?: string;\n /** Additional config passed through to createWsClient. */\n clientConfig?: Record<string, unknown>;\n};\n\nexport type ReceivedMessage = {\n route: string;\n data: unknown;\n};\n\n/**\n * Create a sequential WebSocket test client.\n *\n * Config is derived from the blueprint (base path, route key, auth strategy)\n * and `CELERITY_TEST_BASE_URL`. Pass `token: null` to skip authentication\n * (useful for testing unauthenticated rejection).\n *\n * @example\n * ```typescript\n * const ws = await createTestWsClient();\n * await ws.connect();\n *\n * ws.send(\"notifications\", { action: \"subscribe\", channels: [\"alerts\"] });\n * const msg = await ws.nextMessage();\n * expect(msg.data).toEqual({ subscribed: [\"alerts\"] });\n *\n * await ws.disconnect();\n * ```\n *\n * @example Skip auth for testing unauthenticated scenarios:\n * ```typescript\n * const ws = await createTestWsClient({ token: null });\n * ```\n */\nexport async function createTestWsClient(\n options?: CreateTestWsClientOptions,\n): Promise<TestWsClient> {\n const wsModule: WsClientModule = await import(\"@celerity-sdk/ws-client\");\n\n const wsConfig = loadWebSocketConfig(options?.blueprintPath);\n const basePath = wsConfig?.basePath ?? \"/ws\";\n const routeKey = wsConfig?.routeKey ?? \"action\";\n const authStrategy = wsConfig?.authStrategy ?? \"authMessage\";\n\n const baseUrl = process.env.CELERITY_TEST_BASE_URL ?? \"http://localhost:8081\";\n const wsUrl = options?.url ?? baseUrl.replace(/^http/, \"ws\") + basePath;\n\n const authConfig = resolveAuthConfig(options?.token, authStrategy);\n\n const innerClient = await wsModule.createWsClient({\n url: wsUrl,\n routeKey,\n auth: authConfig,\n ...options?.clientConfig,\n });\n\n return new TestWsClient(innerClient);\n}\n\n/**\n * Test-oriented WebSocket client with sequential `await`-based message flow.\n *\n * The underlying `CelerityWsClient` handles all runtime protocol messages\n * (heartbeat, capabilities, auth, ack, dedup) transparently.\n * Only application-level messages are surfaced via `nextMessage()`.\n */\nexport class TestWsClient {\n private inner: WsClient;\n private messageBuffer: ReceivedMessage[] = [];\n private waiters: Array<{\n resolve: (msg: ReceivedMessage) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n }> = [];\n private cleanups: Unsubscribe[] = [];\n private connectionError: Error | null = null;\n\n constructor(inner: WsClient) {\n this.inner = inner;\n }\n\n /**\n * Connect and complete the full handshake (including auth if configured).\n *\n * After connect resolves, `nextMessage()` will receive application messages.\n * If auth fails or connection is rejected, the promise rejects with the error.\n */\n async connect(): Promise<void> {\n // Listen for errors and propagate to any pending nextMessage() waiters\n const errorUnsub = this.inner.on(\"error\", (err: Error) => {\n this.connectionError = err;\n this.rejectAllWaiters(err);\n });\n this.cleanups.push(errorUnsub);\n\n const disconnectUnsub = this.inner.on(\"disconnected\", () => {\n this.rejectAllWaiters(new Error(\"WebSocket disconnected while waiting for message\"));\n });\n this.cleanups.push(disconnectUnsub);\n\n // Intercept all routed application messages via wildcard route (\"*\")\n const messageUnsub = this.inner.on(\"*\", (data: unknown, meta: unknown) => {\n const route = (meta as { route?: string } | undefined)?.route ?? \"\";\n const msg: ReceivedMessage = { route, data };\n\n if (this.waiters.length > 0) {\n const waiter = this.waiters.shift()!;\n clearTimeout(waiter.timer);\n waiter.resolve(msg);\n } else {\n this.messageBuffer.push(msg);\n }\n });\n this.cleanups.push(messageUnsub);\n\n await this.inner.connect();\n }\n\n /** Send a routed application message. Returns the message ID. */\n send(route: string, data: unknown): string {\n return this.inner.send(route, data);\n }\n\n /**\n * Wait for the next application message from the server.\n *\n * If a message is already buffered, resolves immediately.\n * Otherwise blocks until a message arrives, the connection closes, or timeout expires.\n *\n * @param timeout - Maximum wait time in ms. Default: 5000.\n */\n nextMessage(timeout = 5000): Promise<ReceivedMessage> {\n if (this.connectionError) {\n return Promise.reject(this.connectionError);\n }\n\n if (this.messageBuffer.length > 0) {\n return Promise.resolve(this.messageBuffer.shift()!);\n }\n\n return new Promise<ReceivedMessage>((resolve, reject) => {\n const timer = setTimeout(() => {\n const idx = this.waiters.findIndex((w) => w.resolve === resolve);\n if (idx !== -1) this.waiters.splice(idx, 1);\n reject(new Error(`nextMessage timed out after ${timeout}ms`));\n }, timeout);\n\n this.waiters.push({ resolve, reject, timer });\n });\n }\n\n /** Disconnect and clean up all listeners and pending waiters. */\n async disconnect(): Promise<void> {\n this.cleanup();\n await this.inner.disconnect();\n }\n\n /** Force destroy without waiting for close handshake. */\n destroy(): void {\n this.cleanup();\n this.inner.destroy();\n }\n\n /** Current connection state. */\n get state(): string {\n return this.inner.state;\n }\n\n /** Access the underlying CelerityWsClient for advanced usage. */\n get raw(): WsClient {\n return this.inner;\n }\n\n private cleanup(): void {\n for (const unsub of this.cleanups) unsub();\n this.cleanups = [];\n this.rejectAllWaiters(new Error(\"WebSocket client closed\"));\n this.messageBuffer = [];\n }\n\n private rejectAllWaiters(err: Error): void {\n for (const waiter of this.waiters) {\n clearTimeout(waiter.timer);\n waiter.reject(err);\n }\n this.waiters = [];\n }\n}\n\nfunction resolveAuthConfig(\n token: string | GenerateTestTokenOptions | null | undefined,\n authStrategy: \"authMessage\" | \"connect\",\n): AuthConfig | undefined {\n if (token === null) return undefined;\n if (typeof token === \"string\") return { strategy: authStrategy, token };\n\n const tokenOpts = token ?? { sub: \"test-user\", claims: { roles: [\"admin\"] } };\n return { strategy: authStrategy, token: () => generateTestToken(tokenOpts) };\n}\n","// Test app\nexport { createTestApp, TestApp } from \"./test-app\";\nexport type { CreateTestAppOptions } from \"./test-app\";\n\n// JWT\nexport { generateTestToken } from \"./jwt\";\nexport type { GenerateTestTokenOptions } from \"./jwt\";\n\n// HTTP client\nexport { createTestClient, TestHttpClient, TestRequest } from \"./http\";\nexport type { TestResponse } from \"./http\";\n\n// Async polling\nexport { waitFor } from \"./wait\";\n\n// Discovery (advanced usage)\nexport { discoverResourceTokens } from \"./discovery\";\nexport type { ResourceTokenInfo } from \"./discovery\";\n\n// WebSocket test client\nexport { createTestWsClient, TestWsClient } from \"./ws\";\nexport type { CreateTestWsClientOptions, ReceivedMessage } from \"./ws\";\n\n// Blueprint (advanced usage)\nexport { loadBlueprintResources, loadWebSocketConfig } from \"./blueprint\";\nexport type { BlueprintResource, WebSocketConfig } from \"./blueprint\";\n\n// Mock factories (advanced usage)\nexport { createResourceMock, createMocksForTokens } from \"./mocks\";\nexport type { MockFn, MockFnCreator } from \"./mocks\";\n\n// Re-export mock factories from @celerity-sdk/core for convenience\nexport {\n mockRequest,\n mockWebSocketMessage,\n mockConsumerEvent,\n mockScheduleEvent,\n} from \"@celerity-sdk/core\";\n"],"mappings":"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","names":["CelerityFactory","isRuntimeProvidedToken","buildModuleGraph","getClassDependencyTokens","discoverResourceTokens","rootModule","graph","buildModuleGraph","seen","Set","result","node","classes","controllers","guards","filter","g","provider","providers","push","useClass","cls","depTokens","getClassDependencyTokens","dep","isRuntimeProvidedToken","has","add","parsed","parseResourceToken","token","desc","description","parts","split","length","type","name","slice","join","readFileSync","existsSync","resolve","join","extname","yaml","stripJsonComments","loadBlueprintResources","blueprintPath","path","findBlueprintPath","Map","bp","parseBlueprint","resources","bpResources","id","resource","Object","entries","type","set","resourceId","physicalName","spec","name","loadWebSocketConfig","blueprintPath","path","findBlueprintPath","bp","parseBlueprint","resources","resource","Object","values","res","type","spec","routeKey","authStrategy","findWsProtocolConfig","protocols","basePath","findWsBasePath","domain","defaults","Array","isArray","proto","wsCfg","websocketConfig","cfg","basePaths","entry","protocol","filePath","content","readFileSync","ext","extname","JSON","parse","stripJsonComments","trailingCommas","yaml","load","cwd","process","candidates","join","candidate","existsSync","resolve","detectMockFnCreator","g","globalThis","jest","fn","vi","_args","undefined","createResourceMock","resourceType","mockFn","create","createDatastoreMock","createTopicMock","createQueueMock","createCacheMock","createBucketMock","createConfigMock","getItem","putItem","deleteItem","query","scan","batchGetItems","batchWriteItems","publish","publishBatch","sendMessage","sendMessageBatch","get","set","delete","incr","decr","incrFloat","mget","mset","mdelete","exists","expire","persist","ttl","rename","getSet","append","keyType","scanKeys","hashGet","hashSet","hashDelete","hashGetAll","hashExists","hashIncr","hashKeys","hashLen","listPush","listPop","listRange","listLen","listTrim","listIndex","setAdd","setRemove","setMembers","setIsMember","setLen","setUnion","setIntersect","setDiff","sortedSetAdd","sortedSetRemove","sortedSetScore","sortedSetRank","sortedSetRange","sortedSetRangeByScore","sortedSetIncr","sortedSetLen","transaction","put","info","list","copy","signUrl","getOrThrow","getAll","parse","createMocksForTokens","tokens","mocks","Map","mock","type","token","createRealClients","tokens","blueprintResources","handles","Map","closeables","byType","info","group","get","type","push","set","infos","createDatastoreHandles","createTopicHandles","createQueueHandles","createCacheHandles","createBucketHandles","createSqlHandles","createConfigHandles","err","pkg","Error","physicalName","bp","name","ConfigNamespaceImpl","LocalConfigBackend","backend","envKey","toUpperCase","storeId","process","env","ns","token","createDatastoreClient","client","provider","datastore","createTopicClient","topic","createQueueClient","queue","createCacheClient","endpoint","CELERITY_REDIS_ENDPOINT","url","URL","config","host","hostname","port","Number","parseInt","tls","clusterMode","authMode","connectionConfig","connectTimeoutMs","commandTimeoutMs","keepAliveMs","maxRetries","retryDelayMs","lazyConnect","cache","createObjectStorage","bucket","connStr","CELERITY_LOCAL_SQL_DATABASE_ENDPOINT","createKnexInstance","knexByResource","resourceName","sqlResourceName","lookupInfo","dbName","has","engine","sqlEngineFromProtocol","protocol","defaultPort","knexPromise","credentials","getConnectionInfo","user","username","database","ssl","getPasswordAuth","password","getIamAuth","deployTarget","close","destroy","knex","tokenName","colonIdx","indexOf","slice","TestApp","mocks","closeables","inner","injectHttp","request","injectWebSocket","route","message","injectConsumer","handlerTag","event","injectSchedule","injectCustom","name","payload","getContainer","getRegistry","getMock","token","mock","get","Error","String","getDatastoreMock","Symbol","for","getTopicMock","getQueueMock","getCacheMock","getBucketMock","getConfigMock","close","client","createTestApp","options","providers","controllers","guards","overrides","setupResources","container","provider","registerClass","register","provide","ctrl","has","guard","applyOverrides","module","rootModule","integration","blueprintPath","resourceInfos","discoverResourceTokens","Map","resourceHandles","blueprintResources","loadBlueprintResources","result","createRealClients","handles","createMocksForTokens","set","CelerityFactory","createTestingApp","systemLayers","handle","registerValue","value","Object","entries","sym","getOwnPropertySymbols","generateTestToken","options","baseURL","process","env","CELERITY_DEV_AUTH_BASE_URL","body","sub","claims","expiresIn","response","fetch","method","headers","JSON","stringify","ok","text","Error","status","data","json","access_token","TestRequest","_headers","_body","_expectations","baseUrl","method","path","auth","token","set","key","value","send","body","expect","first","second","push","type","undefined","toLowerCase","end","headers","response","fetch","JSON","stringify","text","parse","result","status","exp","assertExpectation","Error","expected","actual","assertHeader","get","RegExp","test","then","resolve","reject","TestHttpClient","post","put","patch","delete","createTestClient","options","process","env","CELERITY_TEST_BASE_URL","waitFor","predicate","options","timeout","interval","deadline","Date","now","result","Promise","resolve","setTimeout","Error","createTestWsClient","options","wsModule","wsConfig","loadWebSocketConfig","blueprintPath","basePath","routeKey","authStrategy","baseUrl","process","env","CELERITY_TEST_BASE_URL","wsUrl","url","replace","authConfig","resolveAuthConfig","token","innerClient","createWsClient","auth","clientConfig","TestWsClient","inner","messageBuffer","waiters","cleanups","connectionError","connect","errorUnsub","on","err","rejectAllWaiters","push","disconnectUnsub","Error","messageUnsub","data","meta","route","msg","length","waiter","shift","clearTimeout","timer","resolve","send","nextMessage","timeout","Promise","reject","setTimeout","idx","findIndex","w","splice","disconnect","cleanup","destroy","state","raw","unsub","undefined","strategy","tokenOpts","sub","claims","roles","generateTestToken","mockRequest","mockWebSocketMessage","mockConsumerEvent","mockScheduleEvent"]}
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@celerity-sdk/testing",
3
+ "version": "0.8.0",
4
+ "description": "Testing utilities for Celerity applications — createTestApp, mock factories, JWT generation, and HTTP client",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/newstack-cloud/celerity-node-sdk.git",
9
+ "directory": "packages/testing"
10
+ },
11
+ "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "import": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "require": {
19
+ "types": "./dist/index.d.cts",
20
+ "default": "./dist/index.cjs"
21
+ }
22
+ }
23
+ },
24
+ "main": "./dist/index.cjs",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "engines": {
31
+ "node": ">=24.0.0"
32
+ },
33
+ "dependencies": {
34
+ "jose": "^6.0.0",
35
+ "js-yaml": "^4.1.0",
36
+ "strip-json-comments": "^5.0.3",
37
+ "@celerity-sdk/common": "^0.8.0",
38
+ "@celerity-sdk/config": "^0.8.0",
39
+ "@celerity-sdk/core": "^0.8.0",
40
+ "@celerity-sdk/types": "^0.8.0"
41
+ },
42
+ "devDependencies": {
43
+ "@celerity-sdk/ws-client": "^0.3.0",
44
+ "@types/js-yaml": "^4.0.9",
45
+ "reflect-metadata": "^0.2.0",
46
+ "@celerity-sdk/bucket": "^0.8.0",
47
+ "@celerity-sdk/cache": "^0.8.0",
48
+ "@celerity-sdk/queue": "^0.8.0",
49
+ "@celerity-sdk/datastore": "^0.8.0",
50
+ "@celerity-sdk/topic": "^0.8.0",
51
+ "@celerity-sdk/sql-database": "^0.8.0"
52
+ },
53
+ "peerDependencies": {
54
+ "@celerity-sdk/ws-client": "^0.3.1",
55
+ "reflect-metadata": "^0.2.0",
56
+ "@celerity-sdk/bucket": "^0.8.0",
57
+ "@celerity-sdk/sql-database": "^0.8.0",
58
+ "@celerity-sdk/queue": "^0.8.0",
59
+ "@celerity-sdk/datastore": "^0.8.0",
60
+ "@celerity-sdk/topic": "^0.8.0",
61
+ "@celerity-sdk/cache": "^0.8.0"
62
+ },
63
+ "peerDependenciesMeta": {
64
+ "@celerity-sdk/ws-client": {
65
+ "optional": true
66
+ },
67
+ "@celerity-sdk/datastore": {
68
+ "optional": true
69
+ },
70
+ "@celerity-sdk/bucket": {
71
+ "optional": true
72
+ },
73
+ "@celerity-sdk/cache": {
74
+ "optional": true
75
+ },
76
+ "@celerity-sdk/queue": {
77
+ "optional": true
78
+ },
79
+ "@celerity-sdk/topic": {
80
+ "optional": true
81
+ },
82
+ "@celerity-sdk/sql-database": {
83
+ "optional": true
84
+ }
85
+ },
86
+ "publishConfig": {
87
+ "access": "public"
88
+ },
89
+ "scripts": {
90
+ "build": "tsup",
91
+ "dev": "tsup --watch",
92
+ "typecheck": "tsc --noEmit",
93
+ "clean": "rm -rf dist",
94
+ "test": "vitest run"
95
+ }
96
+ }