Skip to content

Commit be997b9

Browse files
committed
MLE-24194 Initial TS support
Just doing the database config. Everything done by Copilot here, including the README that will either get updated or folded into the CONTRIBUTING at some point.
1 parent 15308b2 commit be997b9

File tree

9 files changed

+421
-10
lines changed

9 files changed

+421
-10
lines changed

Jenkinsfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ def runLint() {
6969
'''
7070
}
7171

72+
def runTypeCheck() {
73+
sh label: 'run-type-check', script: '''
74+
export PATH=${NODE_HOME_DIR}/bin:$PATH
75+
cd node-client-api
76+
npm ci
77+
npm run test:types
78+
'''
79+
}
80+
7281
def runE2ETests() {
7382
sh label: 'run-e2e-tests', script: '''
7483
export PATH=${NODE_HOME_DIR}/bin:$PATH
@@ -130,6 +139,7 @@ pipeline {
130139
steps {
131140
runAuditReport()
132141
runLint()
142+
runTypeCheck()
133143
runDockerCompose('ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-12')
134144
runTests()
135145
runE2ETests()

marklogic.d.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Type definitions for marklogic
2+
// Definitions by: GitHub Copilot
3+
// Project: https://github.com/marklogic/node-client-api
4+
// Documentation: https://docs.marklogic.com/guide/node-dev
5+
6+
/**
7+
* MarkLogic Node.js Client API
8+
*
9+
* IMPORTANT: This library uses CommonJS exports. Import patterns:
10+
*
11+
* For TypeScript/ES Modules:
12+
* import marklogic from 'marklogic'; // Preferred
13+
* const db = marklogic.createDatabaseClient({...});
14+
*
15+
* For CommonJS:
16+
* const marklogic = require('marklogic');
17+
* const db = marklogic.createDatabaseClient({...});
18+
*/
19+
20+
declare module 'marklogic' {
21+
/**
22+
* Configuration object for creating a database client.
23+
* Used by the createDatabaseClient function to establish connection parameters.
24+
*/
25+
export interface DatabaseClientConfig {
26+
/** The host with the REST server for the database (defaults to 'localhost') */
27+
host?: string;
28+
/** The port with the REST server for the database (defaults to 8000) */
29+
port?: number;
30+
/** The user with permission to access the database */
31+
user?: string;
32+
/** The password for the user with permission to access the database */
33+
password?: string;
34+
/** The name of the database to access (defaults to the database for the REST server) */
35+
database?: string;
36+
/** The authentication type (defaults to 'digest') */
37+
authType?: 'basic' | 'digest' | 'application-level' | 'certificate' | 'kerberos' | 'saml' | 'cloud';
38+
/** Whether the REST server uses SSL (defaults to false) */
39+
ssl?: boolean;
40+
/** The trusted certificate(s), if required for SSL */
41+
ca?: string | string[] | Buffer | Buffer[];
42+
/** The public x509 certificate to use for SSL */
43+
cert?: string | Buffer;
44+
/** The private key to use for SSL */
45+
key?: string | Buffer;
46+
/** The public x509 certificate and private key as a single PKCS12 file to use for SSL */
47+
pfx?: Buffer;
48+
/** The passphrase for the PKCS12 file or private key */
49+
passphrase?: string;
50+
/** Whether to reject unauthorized SSL certificates (defaults to true) */
51+
rejectUnauthorized?: boolean;
52+
/** The SAML token to use for authentication with the REST server */
53+
token?: string;
54+
/** Connection pooling agent */
55+
agent?: any;
56+
/** API version to use */
57+
apiVersion?: string;
58+
}
59+
60+
/**
61+
* A database client object returned by createDatabaseClient.
62+
* Provides access to document, graph, and query operations.
63+
*/
64+
export interface DatabaseClient {
65+
// Methods will be added as we expand the type definitions
66+
// For now, this is a placeholder to enable basic typing
67+
}
68+
69+
/**
70+
* Creates a DatabaseClient object for accessing a database.
71+
* @param config - Configuration for connecting to the database
72+
* @returns A DatabaseClient object for performing database operations
73+
*/
74+
export function createDatabaseClient(config: DatabaseClientConfig): DatabaseClient;
75+
76+
const marklogic: {
77+
createDatabaseClient: typeof createDatabaseClient;
78+
};
79+
80+
export default marklogic;
81+
}

package-lock.json

Lines changed: 24 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,19 @@
66
"version": "4.0.1",
77
"license": "Apache-2.0",
88
"main": "./lib/marklogic.js",
9+
"types": "marklogic.d.ts",
10+
"files": [
11+
"lib",
12+
"marklogic.d.ts",
13+
"README.md",
14+
"NOTICE.txt",
15+
"LICENSE.txt",
16+
"CHANGELOG.txt"
17+
],
918
"scripts": {
1019
"doc": "jsdoc -c jsdoc.json lib/*.js README.md",
11-
"lint": "gulp lint"
20+
"lint": "gulp lint",
21+
"test:types": "tsc --noEmit"
1222
},
1323
"keywords": [
1424
"marklogic",
@@ -43,6 +53,7 @@
4353
},
4454
"devDependencies": {
4555
"@jsdoc/salty": "0.2.9",
56+
"@types/node": "22.10.1",
4657
"ajv": "8.17.1",
4758
"ast-types": "0.14.2",
4859
"astring": "1.9.0",
@@ -60,7 +71,8 @@
6071
"moment": "2.30.1",
6172
"sanitize-html": "2.17.0",
6273
"should": "13.2.3",
63-
"stream-to-array": "2.3.0"
74+
"stream-to-array": "2.3.0",
75+
"typescript": "5.7.2"
6476
},
6577
"optionalDependencies": {
6678
"kerberos": "^2.0.1",

test-typescript/README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# TypeScript Type Definitions Testing
2+
3+
This directory contains TypeScript tests to verify that the type definitions in `marklogic.d.ts` work correctly.
4+
5+
## How to Test Types
6+
7+
Run the type checking with:
8+
9+
```bash
10+
npm run test:types
11+
```
12+
13+
This command runs `tsc --noEmit`, which checks for TypeScript errors without generating JavaScript files.
14+
15+
## What Gets Tested
16+
17+
### ✅ Type Constraints
18+
- Valid values for `authType` (basic, digest, application-level, certificate, kerberos, saml, cloud)
19+
- Optional vs required properties
20+
- Union types (string | Buffer for certificates)
21+
- Array types (string[] for multiple certificates)
22+
23+
### ✅ Type Safety
24+
If you uncomment the error examples in the test files, TypeScript will catch:
25+
- Invalid `authType` values
26+
- Incorrect property types
27+
- Missing required properties
28+
29+
## Test Files
30+
31+
### `type-constraints.test.ts`
32+
Tests the `DatabaseClientConfig` interface constraints without importing the module. This works immediately without needing to simulate package installation.
33+
34+
### `basic-types.test.ts` (currently excluded)
35+
Full integration test that imports the `marklogic` module. To use this:
36+
1. Build/link the package locally (`npm link`)
37+
2. Remove it from the exclude list in `tsconfig.json`
38+
3. Run `npm run test:types` again
39+
40+
## Adding More Type Tests
41+
42+
As you add more interfaces to `marklogic.d.ts`, add corresponding test files here. The pattern is:
43+
44+
1. Create a `.test.ts` file
45+
2. Write TypeScript code that uses the types
46+
3. Include examples that should work AND commented examples that should fail
47+
4. Run `npm run test:types` to verify
48+
49+
## Why This Approach?
50+
51+
TypeScript's compiler is the best way to test type definitions because:
52+
- It catches type errors at compile time (before runtime)
53+
- It validates type constraints (like union types for `authType`)
54+
- It ensures IntelliSense and autocomplete will work for users
55+
- It's fast and doesn't require running actual code
56+
57+
## Example: Testing for Type Errors
58+
59+
```typescript
60+
// This should work fine ✅
61+
const good: DatabaseClientConfig = {
62+
authType: 'digest'
63+
};
64+
65+
// This should fail ❌ (uncomment to test)
66+
// const bad: DatabaseClientConfig = {
67+
// authType: 'invalid-type'
68+
// };
69+
```
70+
71+
When you uncomment the error example and run `npm run test:types`, you'll see:
72+
```
73+
error TS2322: Type '"invalid-type"' is not assignable to type 'basic' | 'digest' | ...
74+
```
75+
76+
This confirms your types are working correctly!
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// This file tests that TypeScript types work correctly
2+
// Run with: npm run test:types
3+
import marklogic from 'marklogic';
4+
5+
// Test 1: Valid configuration should compile without errors
6+
const validConfig: marklogic.DatabaseClientConfig = {
7+
host: 'localhost',
8+
port: 8000,
9+
user: 'admin',
10+
password: 'admin',
11+
authType: 'digest'
12+
};
13+
14+
const db = marklogic.createDatabaseClient(validConfig);
15+
16+
// Test 2: Another valid configuration with SSL
17+
const sslConfig: marklogic.DatabaseClientConfig = {
18+
host: 'secure.marklogic.com',
19+
port: 8443,
20+
user: 'admin',
21+
password: 'admin',
22+
authType: 'basic',
23+
ssl: true,
24+
rejectUnauthorized: true
25+
};
26+
27+
const secureDb = marklogic.createDatabaseClient(sslConfig);
28+
29+
// Test 3: This should cause a type error if uncommented (invalid authType)
30+
// const invalidConfig: marklogic.DatabaseClientConfig = {
31+
// host: 'localhost',
32+
// authType: 'invalid-auth-type' // ERROR: not a valid authType
33+
// };
34+
35+
// Test 4: Type inference should work (no explicit type annotation needed)
36+
const inferredConfig = {
37+
host: 'localhost',
38+
port: 8000,
39+
user: 'admin',
40+
password: 'admin'
41+
};
42+
const db2 = marklogic.createDatabaseClient(inferredConfig);
43+
44+
// Test 5: Testing optional fields - this should compile fine
45+
const minimalConfig: marklogic.DatabaseClientConfig = {
46+
user: 'admin',
47+
password: 'admin'
48+
};
49+
50+
// Test 6: Testing all auth types (all should be valid)
51+
const authTypes: Array<marklogic.DatabaseClientConfig['authType']> = [
52+
'basic',
53+
'digest',
54+
'application-level',
55+
'certificate',
56+
'kerberos',
57+
'saml',
58+
'cloud'
59+
];
60+
61+
// Test 7: Testing SSL certificate options
62+
const certConfig: marklogic.DatabaseClientConfig = {
63+
host: 'localhost',
64+
ssl: true,
65+
ca: Buffer.from('certificate'),
66+
cert: 'string-cert',
67+
key: Buffer.from('key')
68+
};
69+
70+
console.log('✅ TypeScript types validated successfully!');

0 commit comments

Comments
 (0)