@123toto/ai-app-assistant-server 0.2.2 → 0.2.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/nest.cjs CHANGED
@@ -26,6 +26,7 @@ __export(nest_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(nest_exports);
28
28
  var import_common = require("@nestjs/common");
29
+ var OPENAPI_EXCLUDE_CONTROLLER_METADATA = "swagger/apiExcludeController";
29
30
  var MANAGED_AI_APP_ASSISTANT_SERVER = /* @__PURE__ */ Symbol.for("@123toto/ai-app-assistant-server/managed");
30
31
  function createManagedAiAppAssistantNestModule(options) {
31
32
  const route = options.path?.replace(/^\/+|\/+$/g, "") || "ai-app-assistant";
@@ -43,6 +44,7 @@ function createManagedAiAppAssistantNestModule(options) {
43
44
  (0, import_common.Res)()(ManagedAiAppAssistantNestController.prototype, "handle", 1);
44
45
  const descriptor = Object.getOwnPropertyDescriptor(ManagedAiAppAssistantNestController.prototype, "handle");
45
46
  if (descriptor) (0, import_common.All)(["", "*path"])(ManagedAiAppAssistantNestController.prototype, "handle", descriptor);
47
+ Reflect.defineMetadata(OPENAPI_EXCLUDE_CONTROLLER_METADATA, [true], ManagedAiAppAssistantNestController);
46
48
  (0, import_common.Controller)(route)(ManagedAiAppAssistantNestController);
47
49
  class ManagedAiAppAssistantNestModule {
48
50
  }
package/dist/nest.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/nest.ts"],"sourcesContent":["import {\n All,\n Controller,\n Inject,\n Injectable,\n Module,\n Req,\n Res,\n type DynamicModule,\n type FactoryProvider,\n type ModuleMetadata,\n type Provider\n} from \"@nestjs/common\";\nimport type { ManagedAiAppAssistantServer } from \"./managed-server.js\";\n\n/** Injection token exported so a host can update documents after Swagger bootstrap. */\nexport const MANAGED_AI_APP_ASSISTANT_SERVER = Symbol.for(\"@123toto/ai-app-assistant-server/managed\");\n\nexport interface AiAppAssistantNestRequest {\n method?: string;\n originalUrl?: string;\n url?: string;\n protocol?: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n on?(event: string, listener: () => void): unknown;\n off?(event: string, listener: () => void): unknown;\n [key: string]: unknown;\n}\n\nexport interface AiAppAssistantNestResponse {\n statusCode: number;\n setHeader(name: string, value: string): unknown;\n write(chunk: Uint8Array): boolean;\n end(chunk?: string): unknown;\n once?(event: string, listener: () => void): unknown;\n destroyed?: boolean;\n}\n\nexport interface AiAppAssistantNestModuleOptions<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n> extends Pick<ModuleMetadata, \"imports\"> {\n /** Nest controller path. The application's global prefix is applied normally. */\n path?: string;\n inject?: FactoryProvider[\"inject\"];\n // Nest factories intentionally accept host-defined constructor signatures.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useFactory: (...dependencies: any[]) =>\n | AiAppAssistantNestManagedServer<TRequest>\n | Promise<AiAppAssistantNestManagedServer<TRequest>>;\n}\n\n/** Structural server contract avoids leaking framework-internal types across package entry points. */\nexport type AiAppAssistantNestManagedServer<TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest> = Pick<\n ManagedAiAppAssistantServer<{ id: string; label: string }, TRequest>,\n \"fetch\" | \"dispose\"\n>;\n\n/**\n * Creates a dynamic Nest module with one catch-all controller owned by the\n * connector. Consumer applications declare no AI App Assistant endpoints or DTOs.\n */\nexport function createManagedAiAppAssistantNestModule<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n>(options: AiAppAssistantNestModuleOptions<TRequest>): DynamicModule {\n const route = options.path?.replace(/^\\/+|\\/+$/g, \"\") || \"ai-app-assistant\";\n\n class ManagedAiAppAssistantNestController {\n public constructor(\n readonly server: AiAppAssistantNestManagedServer<TRequest>\n ) {}\n\n public handle(request: TRequest, response: AiAppAssistantNestResponse): Promise<void> {\n return handleManagedAiAppAssistantNestRequest(this.server, request, response);\n }\n }\n\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestController, undefined, 0);\n Req()(ManagedAiAppAssistantNestController.prototype, \"handle\", 0);\n Res()(ManagedAiAppAssistantNestController.prototype, \"handle\", 1);\n const descriptor = Object.getOwnPropertyDescriptor(ManagedAiAppAssistantNestController.prototype, \"handle\");\n if (descriptor) All([\"\", \"*path\"])(ManagedAiAppAssistantNestController.prototype, \"handle\", descriptor);\n Controller(route)(ManagedAiAppAssistantNestController);\n\n class ManagedAiAppAssistantNestModule {}\n class ManagedAiAppAssistantNestLifecycle {\n public constructor(readonly server: AiAppAssistantNestManagedServer<TRequest>) {}\n public onApplicationShutdown(): void {\n this.server.dispose();\n }\n }\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestLifecycle, undefined, 0);\n Injectable()(ManagedAiAppAssistantNestLifecycle);\n const serverProvider: Provider = {\n provide: MANAGED_AI_APP_ASSISTANT_SERVER,\n inject: options.inject ?? [],\n useFactory: options.useFactory\n };\n Module({\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n })(ManagedAiAppAssistantNestModule);\n\n return {\n module: ManagedAiAppAssistantNestModule,\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n };\n}\n\n/** Adapts parsed Nest requests and streamed Fetch responses without Express coupling. */\nexport async function handleManagedAiAppAssistantNestRequest<\n TRequest extends AiAppAssistantNestRequest\n>(\n server: AiAppAssistantNestManagedServer<TRequest>,\n request: TRequest,\n response: AiAppAssistantNestResponse\n): Promise<void> {\n const abortController = new AbortController();\n const abort = (): void => abortController.abort(new DOMException(\"Client disconnected\", \"AbortError\"));\n request.on?.(\"close\", abort);\n try {\n const webRequest = toFetchRequest(request, abortController.signal);\n await writeFetchResponse(response, await server.fetch.handle(webRequest, request));\n } finally {\n request.off?.(\"close\", abort);\n }\n}\n\nfunction toFetchRequest(request: AiAppAssistantNestRequest, signal: AbortSignal): Request {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (Array.isArray(value)) value.forEach((item) => headers.append(name, item));\n else if (value !== undefined) headers.set(name, value);\n }\n const method = request.method?.toUpperCase() || \"GET\";\n const host = headers.get(\"host\") || \"localhost\";\n const protocol = request.protocol || headers.get(\"x-forwarded-proto\") || \"http\";\n const url = new URL(request.originalUrl || request.url || \"/\", `${protocol}://${host}`);\n const hasBody = method !== \"GET\" && method !== \"HEAD\" && request.body !== undefined;\n return new Request(url, {\n method,\n headers,\n signal,\n ...(hasBody ? { body: serializeBody(request.body, headers) } : {})\n });\n}\n\nfunction serializeBody(body: unknown, headers: Headers): string {\n if (typeof body === \"string\") return body;\n if (body instanceof Uint8Array) return new TextDecoder().decode(body);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n return JSON.stringify(body);\n}\n\nasync function writeFetchResponse(response: AiAppAssistantNestResponse, result: Response): Promise<void> {\n response.statusCode = result.status;\n result.headers.forEach((value, name) => response.setHeader(name, value));\n if (!result.body) {\n response.end();\n return;\n }\n const reader = result.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (!response.write(value) && response.once) {\n await new Promise<void>((resolve) => response.once!(\"drain\", resolve));\n }\n }\n if (!response.destroyed) response.end();\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/nest.ts"],"sourcesContent":["import {\n All,\n Controller,\n Inject,\n Injectable,\n Module,\n Req,\n Res,\n type DynamicModule,\n type FactoryProvider,\n type ModuleMetadata,\n type Provider\n} from \"@nestjs/common\";\nimport type { ManagedAiAppAssistantServer } from \"./managed-server.js\";\n\n// Same metadata key used by @nestjs/swagger's ApiExcludeController decorator.\n// Keeping it local avoids making Swagger a dependency of the optional Nest connector.\nconst OPENAPI_EXCLUDE_CONTROLLER_METADATA = \"swagger/apiExcludeController\";\n\n/** Injection token exported so a host can update documents after Swagger bootstrap. */\nexport const MANAGED_AI_APP_ASSISTANT_SERVER = Symbol.for(\"@123toto/ai-app-assistant-server/managed\");\n\nexport interface AiAppAssistantNestRequest {\n method?: string;\n originalUrl?: string;\n url?: string;\n protocol?: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n on?(event: string, listener: () => void): unknown;\n off?(event: string, listener: () => void): unknown;\n [key: string]: unknown;\n}\n\nexport interface AiAppAssistantNestResponse {\n statusCode: number;\n setHeader(name: string, value: string): unknown;\n write(chunk: Uint8Array): boolean;\n end(chunk?: string): unknown;\n once?(event: string, listener: () => void): unknown;\n destroyed?: boolean;\n}\n\nexport interface AiAppAssistantNestModuleOptions<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n> extends Pick<ModuleMetadata, \"imports\"> {\n /** Nest controller path. The application's global prefix is applied normally. */\n path?: string;\n inject?: FactoryProvider[\"inject\"];\n // Nest factories intentionally accept host-defined constructor signatures.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useFactory: (...dependencies: any[]) =>\n | AiAppAssistantNestManagedServer<TRequest>\n | Promise<AiAppAssistantNestManagedServer<TRequest>>;\n}\n\n/** Structural server contract avoids leaking framework-internal types across package entry points. */\nexport type AiAppAssistantNestManagedServer<TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest> = Pick<\n ManagedAiAppAssistantServer<{ id: string; label: string }, TRequest>,\n \"fetch\" | \"dispose\"\n>;\n\n/**\n * Creates a dynamic Nest module with one catch-all controller owned by the\n * connector. Consumer applications declare no AI App Assistant endpoints or DTOs.\n */\nexport function createManagedAiAppAssistantNestModule<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n>(options: AiAppAssistantNestModuleOptions<TRequest>): DynamicModule {\n const route = options.path?.replace(/^\\/+|\\/+$/g, \"\") || \"ai-app-assistant\";\n\n class ManagedAiAppAssistantNestController {\n public constructor(\n readonly server: AiAppAssistantNestManagedServer<TRequest>\n ) {}\n\n public handle(request: TRequest, response: AiAppAssistantNestResponse): Promise<void> {\n return handleManagedAiAppAssistantNestRequest(this.server, request, response);\n }\n }\n\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestController, undefined, 0);\n Req()(ManagedAiAppAssistantNestController.prototype, \"handle\", 0);\n Res()(ManagedAiAppAssistantNestController.prototype, \"handle\", 1);\n const descriptor = Object.getOwnPropertyDescriptor(ManagedAiAppAssistantNestController.prototype, \"handle\");\n if (descriptor) All([\"\", \"*path\"])(ManagedAiAppAssistantNestController.prototype, \"handle\", descriptor);\n // A catch-all Nest route is exposed as the non-standard HTTP verb `all` by\n // Swagger. Exclude this transport controller so it cannot invalidate the\n // consuming application's OpenAPI document.\n Reflect.defineMetadata(OPENAPI_EXCLUDE_CONTROLLER_METADATA, [true], ManagedAiAppAssistantNestController);\n Controller(route)(ManagedAiAppAssistantNestController);\n\n class ManagedAiAppAssistantNestModule {}\n class ManagedAiAppAssistantNestLifecycle {\n public constructor(readonly server: AiAppAssistantNestManagedServer<TRequest>) {}\n public onApplicationShutdown(): void {\n this.server.dispose();\n }\n }\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestLifecycle, undefined, 0);\n Injectable()(ManagedAiAppAssistantNestLifecycle);\n const serverProvider: Provider = {\n provide: MANAGED_AI_APP_ASSISTANT_SERVER,\n inject: options.inject ?? [],\n useFactory: options.useFactory\n };\n Module({\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n })(ManagedAiAppAssistantNestModule);\n\n return {\n module: ManagedAiAppAssistantNestModule,\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n };\n}\n\n/** Adapts parsed Nest requests and streamed Fetch responses without Express coupling. */\nexport async function handleManagedAiAppAssistantNestRequest<\n TRequest extends AiAppAssistantNestRequest\n>(\n server: AiAppAssistantNestManagedServer<TRequest>,\n request: TRequest,\n response: AiAppAssistantNestResponse\n): Promise<void> {\n const abortController = new AbortController();\n const abort = (): void => abortController.abort(new DOMException(\"Client disconnected\", \"AbortError\"));\n request.on?.(\"close\", abort);\n try {\n const webRequest = toFetchRequest(request, abortController.signal);\n await writeFetchResponse(response, await server.fetch.handle(webRequest, request));\n } finally {\n request.off?.(\"close\", abort);\n }\n}\n\nfunction toFetchRequest(request: AiAppAssistantNestRequest, signal: AbortSignal): Request {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (Array.isArray(value)) value.forEach((item) => headers.append(name, item));\n else if (value !== undefined) headers.set(name, value);\n }\n const method = request.method?.toUpperCase() || \"GET\";\n const host = headers.get(\"host\") || \"localhost\";\n const protocol = request.protocol || headers.get(\"x-forwarded-proto\") || \"http\";\n const url = new URL(request.originalUrl || request.url || \"/\", `${protocol}://${host}`);\n const hasBody = method !== \"GET\" && method !== \"HEAD\" && request.body !== undefined;\n return new Request(url, {\n method,\n headers,\n signal,\n ...(hasBody ? { body: serializeBody(request.body, headers) } : {})\n });\n}\n\nfunction serializeBody(body: unknown, headers: Headers): string {\n if (typeof body === \"string\") return body;\n if (body instanceof Uint8Array) return new TextDecoder().decode(body);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n return JSON.stringify(body);\n}\n\nasync function writeFetchResponse(response: AiAppAssistantNestResponse, result: Response): Promise<void> {\n response.statusCode = result.status;\n result.headers.forEach((value, name) => response.setHeader(name, value));\n if (!result.body) {\n response.end();\n return;\n }\n const reader = result.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (!response.write(value) && response.once) {\n await new Promise<void>((resolve) => response.once!(\"drain\", resolve));\n }\n }\n if (!response.destroyed) response.end();\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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","names":[]}
package/dist/nest.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  Req,
9
9
  Res
10
10
  } from "@nestjs/common";
11
+ var OPENAPI_EXCLUDE_CONTROLLER_METADATA = "swagger/apiExcludeController";
11
12
  var MANAGED_AI_APP_ASSISTANT_SERVER = /* @__PURE__ */ Symbol.for("@123toto/ai-app-assistant-server/managed");
12
13
  function createManagedAiAppAssistantNestModule(options) {
13
14
  const route = options.path?.replace(/^\/+|\/+$/g, "") || "ai-app-assistant";
@@ -25,6 +26,7 @@ function createManagedAiAppAssistantNestModule(options) {
25
26
  Res()(ManagedAiAppAssistantNestController.prototype, "handle", 1);
26
27
  const descriptor = Object.getOwnPropertyDescriptor(ManagedAiAppAssistantNestController.prototype, "handle");
27
28
  if (descriptor) All(["", "*path"])(ManagedAiAppAssistantNestController.prototype, "handle", descriptor);
29
+ Reflect.defineMetadata(OPENAPI_EXCLUDE_CONTROLLER_METADATA, [true], ManagedAiAppAssistantNestController);
28
30
  Controller(route)(ManagedAiAppAssistantNestController);
29
31
  class ManagedAiAppAssistantNestModule {
30
32
  }
package/dist/nest.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/nest.ts"],"sourcesContent":["import {\n All,\n Controller,\n Inject,\n Injectable,\n Module,\n Req,\n Res,\n type DynamicModule,\n type FactoryProvider,\n type ModuleMetadata,\n type Provider\n} from \"@nestjs/common\";\nimport type { ManagedAiAppAssistantServer } from \"./managed-server.js\";\n\n/** Injection token exported so a host can update documents after Swagger bootstrap. */\nexport const MANAGED_AI_APP_ASSISTANT_SERVER = Symbol.for(\"@123toto/ai-app-assistant-server/managed\");\n\nexport interface AiAppAssistantNestRequest {\n method?: string;\n originalUrl?: string;\n url?: string;\n protocol?: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n on?(event: string, listener: () => void): unknown;\n off?(event: string, listener: () => void): unknown;\n [key: string]: unknown;\n}\n\nexport interface AiAppAssistantNestResponse {\n statusCode: number;\n setHeader(name: string, value: string): unknown;\n write(chunk: Uint8Array): boolean;\n end(chunk?: string): unknown;\n once?(event: string, listener: () => void): unknown;\n destroyed?: boolean;\n}\n\nexport interface AiAppAssistantNestModuleOptions<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n> extends Pick<ModuleMetadata, \"imports\"> {\n /** Nest controller path. The application's global prefix is applied normally. */\n path?: string;\n inject?: FactoryProvider[\"inject\"];\n // Nest factories intentionally accept host-defined constructor signatures.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useFactory: (...dependencies: any[]) =>\n | AiAppAssistantNestManagedServer<TRequest>\n | Promise<AiAppAssistantNestManagedServer<TRequest>>;\n}\n\n/** Structural server contract avoids leaking framework-internal types across package entry points. */\nexport type AiAppAssistantNestManagedServer<TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest> = Pick<\n ManagedAiAppAssistantServer<{ id: string; label: string }, TRequest>,\n \"fetch\" | \"dispose\"\n>;\n\n/**\n * Creates a dynamic Nest module with one catch-all controller owned by the\n * connector. Consumer applications declare no AI App Assistant endpoints or DTOs.\n */\nexport function createManagedAiAppAssistantNestModule<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n>(options: AiAppAssistantNestModuleOptions<TRequest>): DynamicModule {\n const route = options.path?.replace(/^\\/+|\\/+$/g, \"\") || \"ai-app-assistant\";\n\n class ManagedAiAppAssistantNestController {\n public constructor(\n readonly server: AiAppAssistantNestManagedServer<TRequest>\n ) {}\n\n public handle(request: TRequest, response: AiAppAssistantNestResponse): Promise<void> {\n return handleManagedAiAppAssistantNestRequest(this.server, request, response);\n }\n }\n\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestController, undefined, 0);\n Req()(ManagedAiAppAssistantNestController.prototype, \"handle\", 0);\n Res()(ManagedAiAppAssistantNestController.prototype, \"handle\", 1);\n const descriptor = Object.getOwnPropertyDescriptor(ManagedAiAppAssistantNestController.prototype, \"handle\");\n if (descriptor) All([\"\", \"*path\"])(ManagedAiAppAssistantNestController.prototype, \"handle\", descriptor);\n Controller(route)(ManagedAiAppAssistantNestController);\n\n class ManagedAiAppAssistantNestModule {}\n class ManagedAiAppAssistantNestLifecycle {\n public constructor(readonly server: AiAppAssistantNestManagedServer<TRequest>) {}\n public onApplicationShutdown(): void {\n this.server.dispose();\n }\n }\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestLifecycle, undefined, 0);\n Injectable()(ManagedAiAppAssistantNestLifecycle);\n const serverProvider: Provider = {\n provide: MANAGED_AI_APP_ASSISTANT_SERVER,\n inject: options.inject ?? [],\n useFactory: options.useFactory\n };\n Module({\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n })(ManagedAiAppAssistantNestModule);\n\n return {\n module: ManagedAiAppAssistantNestModule,\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n };\n}\n\n/** Adapts parsed Nest requests and streamed Fetch responses without Express coupling. */\nexport async function handleManagedAiAppAssistantNestRequest<\n TRequest extends AiAppAssistantNestRequest\n>(\n server: AiAppAssistantNestManagedServer<TRequest>,\n request: TRequest,\n response: AiAppAssistantNestResponse\n): Promise<void> {\n const abortController = new AbortController();\n const abort = (): void => abortController.abort(new DOMException(\"Client disconnected\", \"AbortError\"));\n request.on?.(\"close\", abort);\n try {\n const webRequest = toFetchRequest(request, abortController.signal);\n await writeFetchResponse(response, await server.fetch.handle(webRequest, request));\n } finally {\n request.off?.(\"close\", abort);\n }\n}\n\nfunction toFetchRequest(request: AiAppAssistantNestRequest, signal: AbortSignal): Request {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (Array.isArray(value)) value.forEach((item) => headers.append(name, item));\n else if (value !== undefined) headers.set(name, value);\n }\n const method = request.method?.toUpperCase() || \"GET\";\n const host = headers.get(\"host\") || \"localhost\";\n const protocol = request.protocol || headers.get(\"x-forwarded-proto\") || \"http\";\n const url = new URL(request.originalUrl || request.url || \"/\", `${protocol}://${host}`);\n const hasBody = method !== \"GET\" && method !== \"HEAD\" && request.body !== undefined;\n return new Request(url, {\n method,\n headers,\n signal,\n ...(hasBody ? { body: serializeBody(request.body, headers) } : {})\n });\n}\n\nfunction serializeBody(body: unknown, headers: Headers): string {\n if (typeof body === \"string\") return body;\n if (body instanceof Uint8Array) return new TextDecoder().decode(body);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n return JSON.stringify(body);\n}\n\nasync function writeFetchResponse(response: AiAppAssistantNestResponse, result: Response): Promise<void> {\n response.statusCode = result.status;\n result.headers.forEach((value, name) => response.setHeader(name, value));\n if (!result.body) {\n response.end();\n return;\n }\n const reader = result.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (!response.write(value) && response.once) {\n await new Promise<void>((resolve) => response.once!(\"drain\", resolve));\n }\n }\n if (!response.destroyed) response.end();\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/nest.ts"],"sourcesContent":["import {\n All,\n Controller,\n Inject,\n Injectable,\n Module,\n Req,\n Res,\n type DynamicModule,\n type FactoryProvider,\n type ModuleMetadata,\n type Provider\n} from \"@nestjs/common\";\nimport type { ManagedAiAppAssistantServer } from \"./managed-server.js\";\n\n// Same metadata key used by @nestjs/swagger's ApiExcludeController decorator.\n// Keeping it local avoids making Swagger a dependency of the optional Nest connector.\nconst OPENAPI_EXCLUDE_CONTROLLER_METADATA = \"swagger/apiExcludeController\";\n\n/** Injection token exported so a host can update documents after Swagger bootstrap. */\nexport const MANAGED_AI_APP_ASSISTANT_SERVER = Symbol.for(\"@123toto/ai-app-assistant-server/managed\");\n\nexport interface AiAppAssistantNestRequest {\n method?: string;\n originalUrl?: string;\n url?: string;\n protocol?: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n on?(event: string, listener: () => void): unknown;\n off?(event: string, listener: () => void): unknown;\n [key: string]: unknown;\n}\n\nexport interface AiAppAssistantNestResponse {\n statusCode: number;\n setHeader(name: string, value: string): unknown;\n write(chunk: Uint8Array): boolean;\n end(chunk?: string): unknown;\n once?(event: string, listener: () => void): unknown;\n destroyed?: boolean;\n}\n\nexport interface AiAppAssistantNestModuleOptions<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n> extends Pick<ModuleMetadata, \"imports\"> {\n /** Nest controller path. The application's global prefix is applied normally. */\n path?: string;\n inject?: FactoryProvider[\"inject\"];\n // Nest factories intentionally accept host-defined constructor signatures.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useFactory: (...dependencies: any[]) =>\n | AiAppAssistantNestManagedServer<TRequest>\n | Promise<AiAppAssistantNestManagedServer<TRequest>>;\n}\n\n/** Structural server contract avoids leaking framework-internal types across package entry points. */\nexport type AiAppAssistantNestManagedServer<TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest> = Pick<\n ManagedAiAppAssistantServer<{ id: string; label: string }, TRequest>,\n \"fetch\" | \"dispose\"\n>;\n\n/**\n * Creates a dynamic Nest module with one catch-all controller owned by the\n * connector. Consumer applications declare no AI App Assistant endpoints or DTOs.\n */\nexport function createManagedAiAppAssistantNestModule<\n TRequest extends AiAppAssistantNestRequest = AiAppAssistantNestRequest\n>(options: AiAppAssistantNestModuleOptions<TRequest>): DynamicModule {\n const route = options.path?.replace(/^\\/+|\\/+$/g, \"\") || \"ai-app-assistant\";\n\n class ManagedAiAppAssistantNestController {\n public constructor(\n readonly server: AiAppAssistantNestManagedServer<TRequest>\n ) {}\n\n public handle(request: TRequest, response: AiAppAssistantNestResponse): Promise<void> {\n return handleManagedAiAppAssistantNestRequest(this.server, request, response);\n }\n }\n\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestController, undefined, 0);\n Req()(ManagedAiAppAssistantNestController.prototype, \"handle\", 0);\n Res()(ManagedAiAppAssistantNestController.prototype, \"handle\", 1);\n const descriptor = Object.getOwnPropertyDescriptor(ManagedAiAppAssistantNestController.prototype, \"handle\");\n if (descriptor) All([\"\", \"*path\"])(ManagedAiAppAssistantNestController.prototype, \"handle\", descriptor);\n // A catch-all Nest route is exposed as the non-standard HTTP verb `all` by\n // Swagger. Exclude this transport controller so it cannot invalidate the\n // consuming application's OpenAPI document.\n Reflect.defineMetadata(OPENAPI_EXCLUDE_CONTROLLER_METADATA, [true], ManagedAiAppAssistantNestController);\n Controller(route)(ManagedAiAppAssistantNestController);\n\n class ManagedAiAppAssistantNestModule {}\n class ManagedAiAppAssistantNestLifecycle {\n public constructor(readonly server: AiAppAssistantNestManagedServer<TRequest>) {}\n public onApplicationShutdown(): void {\n this.server.dispose();\n }\n }\n Inject(MANAGED_AI_APP_ASSISTANT_SERVER)(ManagedAiAppAssistantNestLifecycle, undefined, 0);\n Injectable()(ManagedAiAppAssistantNestLifecycle);\n const serverProvider: Provider = {\n provide: MANAGED_AI_APP_ASSISTANT_SERVER,\n inject: options.inject ?? [],\n useFactory: options.useFactory\n };\n Module({\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n })(ManagedAiAppAssistantNestModule);\n\n return {\n module: ManagedAiAppAssistantNestModule,\n imports: options.imports ?? [],\n controllers: [ManagedAiAppAssistantNestController],\n providers: [serverProvider, ManagedAiAppAssistantNestLifecycle],\n exports: [MANAGED_AI_APP_ASSISTANT_SERVER]\n };\n}\n\n/** Adapts parsed Nest requests and streamed Fetch responses without Express coupling. */\nexport async function handleManagedAiAppAssistantNestRequest<\n TRequest extends AiAppAssistantNestRequest\n>(\n server: AiAppAssistantNestManagedServer<TRequest>,\n request: TRequest,\n response: AiAppAssistantNestResponse\n): Promise<void> {\n const abortController = new AbortController();\n const abort = (): void => abortController.abort(new DOMException(\"Client disconnected\", \"AbortError\"));\n request.on?.(\"close\", abort);\n try {\n const webRequest = toFetchRequest(request, abortController.signal);\n await writeFetchResponse(response, await server.fetch.handle(webRequest, request));\n } finally {\n request.off?.(\"close\", abort);\n }\n}\n\nfunction toFetchRequest(request: AiAppAssistantNestRequest, signal: AbortSignal): Request {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (Array.isArray(value)) value.forEach((item) => headers.append(name, item));\n else if (value !== undefined) headers.set(name, value);\n }\n const method = request.method?.toUpperCase() || \"GET\";\n const host = headers.get(\"host\") || \"localhost\";\n const protocol = request.protocol || headers.get(\"x-forwarded-proto\") || \"http\";\n const url = new URL(request.originalUrl || request.url || \"/\", `${protocol}://${host}`);\n const hasBody = method !== \"GET\" && method !== \"HEAD\" && request.body !== undefined;\n return new Request(url, {\n method,\n headers,\n signal,\n ...(hasBody ? { body: serializeBody(request.body, headers) } : {})\n });\n}\n\nfunction serializeBody(body: unknown, headers: Headers): string {\n if (typeof body === \"string\") return body;\n if (body instanceof Uint8Array) return new TextDecoder().decode(body);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n return JSON.stringify(body);\n}\n\nasync function writeFetchResponse(response: AiAppAssistantNestResponse, result: Response): Promise<void> {\n response.statusCode = result.status;\n result.headers.forEach((value, name) => response.setHeader(name, value));\n if (!result.body) {\n response.end();\n return;\n }\n const reader = result.body.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (!response.write(value) && response.once) {\n await new Promise<void>((resolve) => response.once!(\"drain\", resolve));\n }\n }\n if (!response.destroyed) response.end();\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@123toto/ai-app-assistant-server",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "license": "MIT",
5
5
  "description": "Framework-neutral Node.js backend for contextual in-app AI assistants",
6
6
  "engines": {
@@ -77,7 +77,7 @@
77
77
  "@ai-sdk/openai": "^3.0.0",
78
78
  "ai": "^6.0.0",
79
79
  "zod": "^4.0.0",
80
- "@123toto/ai-app-assistant-contracts": "0.2.2"
80
+ "@123toto/ai-app-assistant-contracts": "0.2.3"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@nestjs/common": "~11.1.29",