diff --git a/.gitignore b/.gitignore index 5598f296..441e8861 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,7 @@ test-app/containerLogs test-complete-app/build test-complete-app/.gradle test-complete-app-mlDeploy/build -test-complete-app-mlDeploy/.gradle \ No newline at end of file +test-complete-app-mlDeploy/.gradle + +# Compiled TypeScript test files +test-typescript/*.js diff --git a/Jenkinsfile b/Jenkinsfile index 14216749..12f8be71 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -78,6 +78,17 @@ def runTypeCheck() { ''' } +def runTypeScriptTests() { + sh label: 'run-typescript-tests', script: ''' + export PATH=${NODE_HOME_DIR}/bin:$PATH + cd node-client-api + npm ci + npm run test:compile + ./node_modules/.bin/mocha --timeout 10000 test-typescript/*.js --reporter mocha-junit-reporter --reporter-options mochaFile=$WORKSPACE/test-typescript-reports.xml || true + ''' + junit '**/*test-typescript-reports.xml' +} + def runE2ETests() { sh label: 'run-e2e-tests', script: ''' export PATH=${NODE_HOME_DIR}/bin:$PATH @@ -142,6 +153,7 @@ pipeline { runTypeCheck() runDockerCompose('ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-12') runTests() + runTypeScriptTests() runE2ETests() } post { @@ -165,6 +177,7 @@ pipeline { steps { runDockerCompose('ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-11') runTests() + runTypeScriptTests() runE2ETests() } post { @@ -185,6 +198,7 @@ pipeline { steps { runDockerCompose('ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-12') runTests() + runTypeScriptTests() runE2ETests() } post { @@ -205,6 +219,7 @@ pipeline { steps { runDockerCompose('ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-10') runTests() + runTypeScriptTests() runE2ETests() } post { diff --git a/lib/responder.js b/lib/responder.js index 412ca64d..b1f48f05 100644 --- a/lib/responder.js +++ b/lib/responder.js @@ -1224,7 +1224,7 @@ function operationResultStream() { function operationErrorListener(error) { /*jshint validthis:true */ const operation = this; - if(operation.client.connectionParams.apiKey){ + if(operation.client.connectionParams && operation.client.connectionParams.apiKey){ if(error.statusCode === 401 && operation.expiration <= (new Date())){ if(!operation.lockAccessToken){ operation.lockAccessToken = true; diff --git a/marklogic.d.ts b/marklogic.d.ts index c91aa0b0..6c75f1a7 100644 --- a/marklogic.d.ts +++ b/marklogic.d.ts @@ -79,10 +79,11 @@ declare module 'marklogic' { export interface DatabaseClient { /** * Tests if a connection is successful. + * Call .result() to get a promise. * @since 2.1 - * @returns A promise that resolves to an object indicating connection status + * @returns A result provider with a result() method */ - checkConnection(): Promise; + checkConnection(): ResultProvider; /** * Releases the client and destroys the agent. @@ -92,6 +93,20 @@ declare module 'marklogic' { release(): void; } + /** + * A result provider that wraps asynchronous operations. + * Call .result() to get a Promise for the result. + */ + export interface ResultProvider { + /** + * Gets a promise for the operation result. + * @param onFulfilled - Optional callback for success + * @param onRejected - Optional callback for errors + * @returns A promise that resolves to the result + */ + result(onFulfilled?: (value: T) => void, onRejected?: (reason: any) => void): Promise; + } + /** * Creates a DatabaseClient object for accessing a database. * @param config - Configuration for connecting to the database diff --git a/package-lock.json b/package-lock.json index eccae9c0..b72cfb09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ }, "devDependencies": { "@jsdoc/salty": "0.2.9", + "@types/mocha": "10.0.10", "@types/node": "22.10.1", "ajv": "8.17.1", "ast-types": "0.14.2", @@ -460,6 +461,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.10.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", diff --git a/package.json b/package.json index 2ff3638f..f76806c4 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,9 @@ "scripts": { "doc": "jsdoc -c jsdoc.json lib/*.js README.md", "lint": "gulp lint", - "test:types": "tsc --noEmit" + "test:types": "tsc --noEmit", + "test:compile": "tsc test-typescript/checkConnection-runtime.test.ts", + "pretest:typescript": "npm run test:compile" }, "keywords": [ "marklogic", @@ -53,6 +55,7 @@ }, "devDependencies": { "@jsdoc/salty": "0.2.9", + "@types/mocha": "10.0.10", "@types/node": "22.10.1", "ajv": "8.17.1", "ast-types": "0.14.2", diff --git a/test-typescript/README.md b/test-typescript/README.md index 2f9bcf4f..79a07786 100644 --- a/test-typescript/README.md +++ b/test-typescript/README.md @@ -2,23 +2,72 @@ This directory contains TypeScript tests to verify that the type definitions in `marklogic.d.ts` work correctly. -## How to Test Types +## Types of Tests + +### 1. Compile-Only Tests (Type Checking) +Files like `basic-types.test.ts`, `connection-methods.test.ts`, `type-constraints.test.ts`, `error-examples.test.ts` + +- **Purpose**: Verify that TypeScript code compiles without errors +- **Execution**: Not executed at runtime - only compiled +- **Speed**: Very fast (seconds) +- **Requirements**: No MarkLogic server needed +- **Run with**: `npm run test:types` + +These tests validate: +- Type definitions are syntactically correct +- Type constraints work (e.g., `authType` only accepts valid values) +- IntelliSense will work for users +- Type errors are caught at compile time + +### 2. Runtime Tests +Files like `checkConnection-runtime.test.ts` -Run the type checking with: +- **Purpose**: Verify that TypeScript definitions match actual runtime behavior +- **Execution**: Compiled to JavaScript and executed with mocha +- **Speed**: Slower (requires MarkLogic) +- **Requirements**: MarkLogic server running +- **Run with**: `npm run test:compile && npx mocha test-typescript/*.js` +These tests validate: +- Types compile correctly (compile-time check) +- Real API calls return the expected types (runtime check) +- TypeScript definitions accurately reflect the actual JavaScript behavior + +## How to Test Types + +### Type Checking Only ```bash npm run test:types ``` -This command runs `tsc --noEmit`, which checks for TypeScript errors without generating JavaScript files. +This runs `tsc --noEmit`, which checks for TypeScript errors without generating JavaScript files. + +### Runtime Tests +```bash +npm run test:compile # Compile TypeScript tests to JavaScript +npx mocha test-typescript/*.js # Run compiled tests against MarkLogic +``` + +Or in one command: +```bash +npm run test:compile && npx mocha test-typescript/*.js +``` + +## Why Two Approaches? -## Why This Approach? +**Compile-only tests** are great for: +- Fast feedback during development +- Catching type definition errors quickly +- CI/CD pre-flight checks (before spinning up MarkLogic) +- Validating that autocomplete/IntelliSense will work -TypeScript's compiler is the best way to test type definitions because: -- It catches type errors at compile time (before runtime) -- It validates type constraints (like union types for `authType`) -- It ensures IntelliSense and autocomplete will work for users -- It's fast and doesn't require running actual code +**Runtime tests** are essential for: +- Ensuring type definitions match actual behavior +- Catching mismatches between declared types and runtime values +- Integration testing with real MarkLogic instances +- Preventing issues like returning `{}` when a `Promise` was expected + +Both approaches complement each other for comprehensive type safety validation. ## Example: Testing for Type Errors @@ -40,3 +89,22 @@ error TS2322: Type '"invalid-type"' is not assignable to type 'basic' | 'digest' ``` This confirms your types are working correctly! + +## Adding New Tests + +### To add a compile-only test: +1. Create a `.test.ts` file in this directory +2. Use `/// ` to load types +3. Import types with: `type MyType = import('marklogic').MyType;` +4. Write code that should compile (or intentionally fail) +5. Run `npm run test:types` to verify + +### To add a runtime test: +1. Create a `.test.ts` file in this directory +2. Use the same reference and import pattern as above +3. Import test framework: `import should = require('should');` +4. Use `describe`/`it` blocks like normal mocha tests +5. Make actual API calls to MarkLogic +6. Compile with `npm run test:compile` and run with mocha + +**Note**: Compiled `.js` files are gitignored and regenerated on each test run. diff --git a/test-typescript/checkConnection-runtime.test.ts b/test-typescript/checkConnection-runtime.test.ts new file mode 100644 index 00000000..5c79aa28 --- /dev/null +++ b/test-typescript/checkConnection-runtime.test.ts @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. + */ + +/// + +/** + * TypeScript runtime test to validate that checkConnection returns ResultProvider. + * This test ensures the TypeScript definitions match the actual runtime behavior + * by making real calls to MarkLogic AND verifying types at compile time. + */ + +import should = require('should'); +const marklogic = require('..'); +const testconfig = require('../etc/test-config-qa.js'); + +const db = marklogic.createDatabaseClient(testconfig.restReaderConnection); + +// Type alias for easier reference +type ResultProvider = import('marklogic').ResultProvider; +type ConnectionCheckResult = import('marklogic').ConnectionCheckResult; +type DatabaseClientConfig = import('marklogic').DatabaseClientConfig; + +describe('checkConnection ResultProvider validation', function() { + + it('should return ResultProvider with .result() method', function(done) { + // This validates that checkConnection returns a ResultProvider + // TypeScript will verify the type at compile time + const resultProvider: ResultProvider = db.checkConnection(); + + // Verify it has a .result() method (core requirement for ResultProvider) + should(resultProvider).have.property('result'); + should(resultProvider.result).be.a.Function(); + + // Call .result() to get a Promise + const promise: Promise = resultProvider.result(); + + // Verify .result() returns a Promise (thenable) + should(promise).have.property('then'); + should(promise.then).be.a.Function(); + + // Verify the Promise resolves to ConnectionCheckResult + promise.then((response: ConnectionCheckResult) => { + should(response).have.property('connected'); + should(response.connected).be.a.Boolean(); + + if (response.connected === true) { + done(); + } else { + done(new Error('Expected connection to succeed but got: ' + JSON.stringify(response))); + } + }).catch(done); + }); + + it('should work with async/await pattern', async function() { + // TypeScript verifies the return type matches ConnectionCheckResult + const result: ConnectionCheckResult = await db.checkConnection().result(); + + // Verify result shape matches ConnectionCheckResult + should(result).have.property('connected'); + should(result.connected).be.a.Boolean(); + should(result.connected).equal(true); + }); + + it('should have error properties when connection fails', function(done) { + // Test with wrong password to get a failed connection + const config: DatabaseClientConfig = { + host: testconfig.restReaderConnection.host, + user: testconfig.restReaderConnection.user, + password: 'wrongpassword', // Invalid password + port: testconfig.restReaderConnection.port, + authType: testconfig.restReaderConnection.authType + }; + const db1 = marklogic.createDatabaseClient(config); + + db1.checkConnection().result().then((response: ConnectionCheckResult) => { + should(response).have.property('connected'); + should(response.connected).be.a.Boolean(); + + if (response.connected === false) { + // When connected is false, optional error properties should exist + should(response).have.property('httpStatusCode'); + should(response.httpStatusCode).be.a.Number(); + should(response).have.property('httpStatusMessage'); + should(response.httpStatusMessage).be.a.String(); + } + + db1.release(); + done(); + }).catch(done); + }); + + after(function(done) { + db.release(); + done(); + }); +}); diff --git a/test-typescript/connection-methods.test.ts b/test-typescript/connection-methods.test.ts index c3571ba4..65bb61bc 100644 --- a/test-typescript/connection-methods.test.ts +++ b/test-typescript/connection-methods.test.ts @@ -2,6 +2,8 @@ * Copyright (c) 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. */ +/// + /** * TypeScript type checking tests for connection-related methods. * @@ -14,42 +16,14 @@ * Run with: npm run test:types */ -// Create test types that should match the actual marklogic types -type ConnectionCheckResult = { - connected: boolean; - httpStatusCode?: number; - httpStatusMessage?: string; -}; - -type DatabaseClient = { - checkConnection(): Promise; - release(): void; -}; - -type DatabaseClientConfig = { - host?: string; - port?: number; - user?: string; - password?: string; -}; - -// Simulate the marklogic module interface -type MarkLogicModule = { - createDatabaseClient(config: DatabaseClientConfig): DatabaseClient; - releaseClient(client: DatabaseClient): void; -}; +import type { DatabaseClient, ConnectionCheckResult } from 'marklogic'; +import * as marklogic from 'marklogic'; // Test checkConnection() return type -async function testCheckConnection(marklogic: MarkLogicModule) { - const client = marklogic.createDatabaseClient({ - host: 'localhost', - port: 8000, - user: 'admin', - password: 'admin' - }); - - // Should return a Promise - const result = await client.checkConnection(); +async function testCheckConnection(client: DatabaseClient) { + // Should return a ResultProvider + const resultProvider = client.checkConnection(); + const result = await resultProvider.result(); // result.connected should be boolean const isConnected: boolean = result.connected; @@ -66,14 +40,7 @@ async function testCheckConnection(marklogic: MarkLogicModule) { } // Test release() method on client -function testRelease(marklogic: MarkLogicModule) { - const client = marklogic.createDatabaseClient({ - host: 'localhost', - port: 8000, - user: 'admin', - password: 'admin' - }); - +function testRelease(client: DatabaseClient) { // Should be callable with no return value client.release(); @@ -81,14 +48,7 @@ function testRelease(marklogic: MarkLogicModule) { } // Test releaseClient() standalone function -function testReleaseClientFunction(marklogic: MarkLogicModule) { - const client = marklogic.createDatabaseClient({ - host: 'localhost', - port: 8000, - user: 'admin', - password: 'admin' - }); - +function testReleaseClientFunction(client: DatabaseClient) { // Should accept a DatabaseClient and return void marklogic.releaseClient(client); @@ -96,16 +56,9 @@ function testReleaseClientFunction(marklogic: MarkLogicModule) { } // Test proper cleanup pattern -async function testProperCleanupPattern(marklogic: MarkLogicModule) { - const client = marklogic.createDatabaseClient({ - host: 'localhost', - port: 8000, - user: 'admin', - password: 'admin' - }); - +async function testProperCleanupPattern(client: DatabaseClient) { try { - const result = await client.checkConnection(); + const result = await client.checkConnection().result(); if (result.connected) { console.log('Connected successfully!'); // Do database operations... diff --git a/test-typescript/error-examples.test.ts b/test-typescript/error-examples.test.ts index ee059cb3..ebfd0b7c 100644 --- a/test-typescript/error-examples.test.ts +++ b/test-typescript/error-examples.test.ts @@ -2,50 +2,35 @@ * Copyright (c) 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. */ +/// + // This file demonstrates TypeScript catching type errors // To see the errors, uncomment sections below and run: npm run test:types -type ConfigType = { - host?: string; - port?: number; - user?: string; - password?: string; - database?: string; - authType?: 'basic' | 'digest' | 'application-level' | 'certificate' | 'kerberos' | 'saml' | 'cloud'; - ssl?: boolean; - ca?: string | string[] | Buffer | Buffer[]; - cert?: string | Buffer; - key?: string | Buffer; - pfx?: Buffer; - passphrase?: string; - rejectUnauthorized?: boolean; - token?: string; - agent?: any; - apiVersion?: string; -}; +import type { DatabaseClientConfig } from 'marklogic'; // ✅ This works - valid authType -const validConfig: ConfigType = { +const validConfig: DatabaseClientConfig = { authType: 'digest' }; // ❌ UNCOMMENT THIS to see TypeScript catch an invalid authType: -// const invalidAuthType: ConfigType = { +// const invalidAuthType: DatabaseClientConfig = { // authType: 'invalid-type' // Error: Type '"invalid-type"' is not assignable to type 'basic' | 'digest' | ... // }; // ❌ UNCOMMENT THIS to see TypeScript catch wrong type for port: -// const invalidPort: ConfigType = { +// const invalidPort: DatabaseClientConfig = { // port: 'not-a-number' // Error: Type 'string' is not assignable to type 'number' // }; // ❌ UNCOMMENT THIS to see TypeScript catch wrong type for ssl: -// const invalidSsl: ConfigType = { +// const invalidSsl: DatabaseClientConfig = { // ssl: 'yes' // Error: Type 'string' is not assignable to type 'boolean' // }; // ❌ UNCOMMENT THIS to see TypeScript catch invalid certificate type: -// const invalidCert: ConfigType = { +// const invalidCert: DatabaseClientConfig = { // cert: 123 // Error: Type 'number' is not assignable to type 'string | Buffer' // }; diff --git a/test-typescript/type-constraints.test.ts b/test-typescript/type-constraints.test.ts index 424fcddc..fe4fb9ea 100644 --- a/test-typescript/type-constraints.test.ts +++ b/test-typescript/type-constraints.test.ts @@ -2,37 +2,16 @@ * Copyright (c) 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. */ +/// + // Simple TypeScript type checking test // This test validates the DatabaseClientConfig interface without needing the actual module // Run with: npm run test:types -/** - * To test the types, we'll reference them directly from the .d.ts file - * This simulates what would happen when a user imports the module - */ - -// Test by creating a type that should match DatabaseClientConfig -type TestConfig = { - host?: string; - port?: number; - user?: string; - password?: string; - database?: string; - authType?: 'basic' | 'digest' | 'application-level' | 'certificate' | 'kerberos' | 'saml' | 'cloud'; - ssl?: boolean; - ca?: string | string[] | Buffer | Buffer[]; - cert?: string | Buffer; - key?: string | Buffer; - pfx?: Buffer; - passphrase?: string; - rejectUnauthorized?: boolean; - token?: string; - agent?: any; - apiVersion?: string; -}; +import type { DatabaseClientConfig } from 'marklogic'; // Valid configurations that should work -const validConfig1: TestConfig = { +const validConfig1: DatabaseClientConfig = { host: 'localhost', port: 8000, user: 'admin', @@ -40,7 +19,7 @@ const validConfig1: TestConfig = { authType: 'digest' }; -const validConfig2: TestConfig = { +const validConfig2: DatabaseClientConfig = { host: 'secure.marklogic.com', port: 8443, user: 'admin', @@ -53,12 +32,12 @@ const validConfig2: TestConfig = { // Testing type constraints - these should cause errors if uncommented: // Error: Invalid authType -// const invalidAuth: TestConfig = { +// const invalidAuth: DatabaseClientConfig = { // authType: 'invalid-type' as any // }; // Testing that authType is properly restricted -const validAuthTypes: Array = [ +const validAuthTypes: Array = [ 'basic', 'digest', 'application-level', @@ -70,13 +49,13 @@ const validAuthTypes: Array = [ ]; // Testing Buffer and string union types for certificates -const certTest1: TestConfig = { +const certTest1: DatabaseClientConfig = { ca: 'string cert', cert: Buffer.from('cert'), key: 'string key' }; -const certTest2: TestConfig = { +const certTest2: DatabaseClientConfig = { ca: ['cert1', 'cert2'], cert: 'string cert', key: Buffer.from('key') diff --git a/tsconfig.json b/tsconfig.json index ff1e0892..12b781b5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,11 +5,12 @@ "lib": ["ES2020"], "strict": true, "esModuleInterop": true, - "skipLibCheck": false, + "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "moduleResolution": "node", "resolveJsonModule": true, - "noEmit": true + "noEmit": false, + "outDir": "test-typescript" }, "include": ["test-typescript/**/*"], "exclude": ["node_modules", "test-typescript/basic-types.test.ts"] diff --git a/typescript-test-project/package.json b/typescript-test-project/package.json index 7f38c134..38ba9c39 100644 --- a/typescript-test-project/package.json +++ b/typescript-test-project/package.json @@ -6,7 +6,9 @@ "scripts": { "setup": "npm install .. && npm install", "typecheck": "tsc --noEmit", - "test": "npm run typecheck" + "build": "tsc", + "start": "node test.js", + "test": "npm run build && npm run start" }, "keywords": [ "marklogic", diff --git a/typescript-test-project/test.ts b/typescript-test-project/test.ts index 2c58e4ba..dc45f1fe 100644 --- a/typescript-test-project/test.ts +++ b/typescript-test-project/test.ts @@ -2,97 +2,27 @@ * Copyright (c) 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. */ -/** - * Realistic TypeScript usage example for MarkLogic Node.js Client - * - * This file demonstrates how users will consume the library with TypeScript. - * - * Setup: - * npm run setup # First time only - * npm test # Check types - * - * Try this: - * - Start typing to see autocomplete - * - Hover over methods to see documentation - * - Uncomment error examples to see TypeScript catch mistakes - */ - import * as marklogic from 'marklogic'; -// Example: Create a client with autocomplete support -const client = marklogic.createDatabaseClient({ - host: 'localhost', - port: 8000, - user: 'admin', - password: 'admin', - authType: 'digest' // Try typing here - autocomplete suggests all valid auth types! -}); - -// Example: Test connection with proper typing -async function testConnection() { - const result = await client.checkConnection(); - - // TypeScript knows the shape of ConnectionCheckResult - if (result.connected) { - console.log('✅ Connected successfully!'); - } else { - // These optional properties only exist when connected = false - console.error(`❌ Connection failed: ${result.httpStatusCode} - ${result.httpStatusMessage}`); - } - - return result; -} - -// Example: Proper cleanup pattern -async function properUsagePattern() { - const db = marklogic.createDatabaseClient({ - host: 'localhost', - port: 8000, - user: 'admin', - password: 'admin' - }); +const testConfig = require('../etc/test-config.js'); +const client = marklogic.createDatabaseClient(testConfig.restWriterConnection); +async function run() { try { - const status = await db.checkConnection(); - if (status.connected) { - console.log('Ready to work with database'); - // Do your database operations here... + const result = await client.checkConnection().result(); + + if (result.connected) { + console.log('✅ Connected successfully!'); + } else { + console.error(`❌ Connection failed: ${result.httpStatusCode} - ${result.httpStatusMessage}`); + process.exit(1); } } finally { - // Always clean up - TypeScript knows this method exists - db.release(); - - // Alternative: use the standalone function - // marklogic.releaseClient(db); + client.release(); } } -// ============================================================================= -// ERROR EXAMPLES - Uncomment these to see TypeScript catch mistakes! -// ============================================================================= - -// ❌ Error: Invalid authType value -// const badAuthType = marklogic.createDatabaseClient({ -// authType: 'invalid-type' -// }); - -// ❌ Error: port should be number, not string -// const badPort = marklogic.createDatabaseClient({ -// port: '8000' -// }); - -// ❌ Error: ConnectionCheckResult.connected must be boolean -// const badResult: marklogic.ConnectionCheckResult = { -// connected: 'yes' // Error: string is not assignable to boolean -// }; - -// ❌ Error: httpStatusCode must be number -// const badStatusCode: marklogic.ConnectionCheckResult = { -// connected: false, -// httpStatusCode: 'error' // Error: string is not assignable to number -// }; - -console.log('✅ TypeScript validation complete!'); - -// Export functions to prevent unused warnings -export { testConnection, properUsagePattern }; +run().catch((error) => { + console.error('❌ Test failed:', error); + process.exit(1); +}); diff --git a/typescript-test-project/tsconfig.json b/typescript-test-project/tsconfig.json index bdc0577a..efc3c3cb 100644 --- a/typescript-test-project/tsconfig.json +++ b/typescript-test-project/tsconfig.json @@ -24,7 +24,8 @@ "noFallthroughCasesInSwitch": true, /* Emit */ - "noEmit": true, + "noEmit": false, + "outDir": "./", "esModuleInterop": true, "forceConsistentCasingInFileNames": true,