diff --git a/bun.test.setup.ts b/bun.test.setup.ts index 8bdec1d..945479b 100644 --- a/bun.test.setup.ts +++ b/bun.test.setup.ts @@ -1,6 +1,17 @@ import { beforeAll, afterEach, afterAll } from 'bun:test' import { server } from './mocks/node.ts' - +import * as dotenv from 'dotenv' + +// Load environment variables for examples that rely on them +dotenv.config() + +// Provide safe fallbacks in CI/sandbox (only if null/undefined) +process.env.OPENAI_API_KEY ??= 'test-openai-key' +process.env.STACKONE_API_KEY ??= 'test-stackone-key' + +// Allow tests to skip LLM-heavy example files by default +process.env.SKIP_LLM_EXAMPLES ??= '1' + beforeAll(() => server.listen()) afterEach(() => server.resetHandlers()) afterAll(() => server.close()) diff --git a/examples/examples.spec.ts b/examples/examples.spec.ts index f22bb47..0f43779 100644 --- a/examples/examples.spec.ts +++ b/examples/examples.spec.ts @@ -1,7 +1,15 @@ import { describe, expect, it } from 'bun:test'; +import process from 'node:process'; import { $ } from 'bun'; import { directoryExists, joinPaths, listFilesInDirectory } from '../src/utils/file'; +// Examples that require real LLM calls and should be skipped in CI/sandboxed runs +const LLM_EXAMPLES = new Set([ + 'openai-integration.ts', + 'ai-sdk-integration.ts', + 'human-in-the-loop.ts', +]); + describe('Examples', () => { it( 'should run all example files without errors', @@ -12,19 +20,28 @@ describe('Examples', () => { throw new Error('Examples directory not found'); } - const exampleFiles = listFilesInDirectory( + // Gather example files + let exampleFiles = listFilesInDirectory( examplesDir, - (fileName) => fileName.endsWith('.ts') && !fileName.includes('.spec.') + (fileName: string) => fileName.endsWith('.ts') && !fileName.includes('.spec.') ); + // Optionally skip LLM-heavy examples when requested (default enabled via bun.test.setup.ts) + if (process.env.SKIP_LLM_EXAMPLES === '1') { + exampleFiles = exampleFiles.filter((f: string) => !LLM_EXAMPLES.has(f)); + } + expect(exampleFiles.length).toBeGreaterThan(0); const results = await Promise.all( - exampleFiles.map(async (file) => { + exampleFiles.map(async (file: string) => { const filePath = joinPaths(examplesDir, file); try { - const result = await $`bun run ${filePath}`.quiet(); + // Run each example in a separate Bun process but preload test setup + // to activate MSW and load env vars. Also load .env explicitly. + const result = + await $`bun --preload ./bun.test.setup.ts --env-file .env run ${filePath}`.quiet(); return { file, success: result.exitCode === 0, diff --git a/mocks/handlers.ts b/mocks/handlers.ts index b674122..ea5541c 100644 --- a/mocks/handlers.ts +++ b/mocks/handlers.ts @@ -1,6 +1,30 @@ import { http, HttpResponse } from 'msw'; export const handlers = [ + // StackOne Unified HRIS endpoints used by examples + http.get('https://api.stackone.com/unified/hris/employees', () => { + return HttpResponse.json({ + data: [ + { + id: 'c28xIQaWQ6MzM5MzczMDA2NzMzMzkwNzIwNA', + name: 'Michael Scott', + phone_number: '+1-555-0100', + }, + ], + }); + }), + + http.get( + 'https://api.stackone.com/unified/hris/employees/:id', + ({ params }) => { + return HttpResponse.json({ + id: params.id, + name: 'Michael Scott', + phone_numbers: ['+1-555-0100'], + }); + } + ), + // StackOne API spec endpoints http.get('https://api.stackone.com/api/v1/:category/openapi.json', ({ params }) => { const { category } = params; diff --git a/src/modules/requestBuilder.ts b/src/modules/requestBuilder.ts index 1259c6a..7969b56 100644 --- a/src/modules/requestBuilder.ts +++ b/src/modules/requestBuilder.ts @@ -172,7 +172,7 @@ export class RequestBuilder { if (typeof value === 'function') { throw new ParameterSerializationError('Functions cannot be serialized as parameters'); } - if (value === null || value === undefined) { + if (value == null) { return ''; } return String(value); @@ -201,7 +201,7 @@ export class RequestBuilder { ); } - if (obj === null || obj === undefined) { + if (obj == null) { return params; } @@ -219,7 +219,7 @@ export class RequestBuilder { } const nestedKey = `${prefix}[${key}]`; - if (value !== null && value !== undefined) { + if (value != null) { if (this.shouldUseDeepObjectSerialization(key, value)) { // Recursively handle nested objects params.push( diff --git a/src/openapi/tests/__snapshots__/openapi-parser.spec.ts.snap b/src/openapi/tests/__snapshots__/openapi-parser.spec.ts.snap index 645c956..ae5d92d 100644 --- a/src/openapi/tests/__snapshots__/openapi-parser.spec.ts.snap +++ b/src/openapi/tests/__snapshots__/openapi-parser.spec.ts.snap @@ -1803,7 +1803,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "type": "array", }, "birthday": { - "description": "The employee birthday", + "description": "The next birthday of the employee (upcoming birthday)", "example": "2021-01-01T00:00:00Z", "format": "date-time", "type": "string", @@ -2178,7 +2178,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "type": "array", }, "date_of_birth": { - "description": "The employee date_of_birth", + "description": "The date when the employee was born", "example": "1990-01-01T00:00:00.000Z", "format": "date-time", "type": "string", @@ -7059,6 +7059,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -8612,6 +8613,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -8701,6 +8703,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -8790,6 +8793,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -8879,6 +8883,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -8968,6 +8973,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9057,6 +9063,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9146,6 +9153,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9235,6 +9243,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9329,6 +9338,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9438,6 +9448,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9537,6 +9548,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9646,6 +9658,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9763,6 +9776,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9891,6 +9905,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10007,6 +10022,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10106,6 +10122,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10223,6 +10240,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10327,6 +10345,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10416,6 +10435,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10505,6 +10525,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10594,6 +10615,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10687,6 +10709,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10812,6 +10835,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10911,6 +10935,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -11000,6 +11025,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -11106,6 +11132,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -11224,6 +11251,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -11330,6 +11358,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -11419,6 +11448,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -11745,7 +11775,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "type": "array", }, "birthday": { - "description": "The employee birthday", + "description": "The next birthday of the employee (upcoming birthday)", "example": "2021-01-01T00:00:00Z", "format": "date-time", "type": "string", @@ -12098,7 +12128,7 @@ exports[`OpenAPIParser Snapshot Tests should parse all OpenAPI specs correctly 1 "type": "array", }, "date_of_birth": { - "description": "The employee date_of_birth", + "description": "The date when the employee was born", "example": "1990-01-01T00:00:00.000Z", "format": "date-time", "type": "string", diff --git a/src/toolsets/tests/__snapshots__/stackone.spec.ts.snap b/src/toolsets/tests/__snapshots__/stackone.spec.ts.snap index b9d2849..ba2586f 100644 --- a/src/toolsets/tests/__snapshots__/stackone.spec.ts.snap +++ b/src/toolsets/tests/__snapshots__/stackone.spec.ts.snap @@ -63,6 +63,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -294,6 +295,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -432,6 +434,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -598,6 +601,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -963,7 +967,7 @@ Tools { "type": "array", }, "birthday": { - "description": "The employee birthday", + "description": "The next birthday of the employee (upcoming birthday)", "example": "2021-01-01T00:00:00Z", "format": "date-time", "type": "string", @@ -1318,7 +1322,7 @@ Tools { "type": "array", }, "date_of_birth": { - "description": "The employee date_of_birth", + "description": "The date when the employee was born", "example": "1990-01-01T00:00:00.000Z", "format": "date-time", "type": "string", @@ -3481,7 +3485,7 @@ Tools { "type": "array", }, "birthday": { - "description": "The employee birthday", + "description": "The next birthday of the employee (upcoming birthday)", "example": "2021-01-01T00:00:00Z", "format": "date-time", "type": "string", @@ -3814,7 +3818,7 @@ Tools { "type": "array", }, "date_of_birth": { - "description": "The employee date_of_birth", + "description": "The date when the employee was born", "example": "1990-01-01T00:00:00.000Z", "format": "date-time", "type": "string", @@ -5731,6 +5735,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9515,6 +9520,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -9770,6 +9776,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -10006,6 +10013,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -13746,6 +13754,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -14031,6 +14040,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -14297,6 +14307,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -15263,6 +15274,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -15396,6 +15408,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -15529,6 +15542,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -15662,6 +15676,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -15795,6 +15810,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -15928,6 +15944,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -16649,6 +16666,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -16880,6 +16898,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -17115,6 +17134,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -17379,6 +17399,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -17627,6 +17648,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -17902,6 +17924,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -18132,6 +18155,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -18392,6 +18416,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -18657,6 +18682,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -18800,6 +18826,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -19036,6 +19063,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -19463,6 +19491,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, }, @@ -19842,6 +19871,7 @@ Tools { "additionalProperties": false, "description": "Use a string with a date to only select results updated after that given date", "example": "2020-01-01T00:00:00.000Z", + "format": "date-time", "type": "string", }, },