Skip to content

Commit 2670c2f

Browse files
authored
Add development support Typescript source files (knex#5144)
1 parent 1525f0f commit 2670c2f

9 files changed

+150
-12
lines changed

.github/workflows/coverage.yml

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ jobs:
3636
- name: Install pg-native
3737
run: npm i pg-native
3838

39+
- run: npm run build
40+
3941
- name: Run Tests
4042
run: npm run test:coverage || true
4143
env:

.github/workflows/integration-tests.yml

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ jobs:
6262
run: ./scripts/oracledb-install-driver-libs.sh run
6363
if: matrix.database-type == 'oracledb'
6464

65+
- run: npm run build
66+
6567
- name: Run Tests
6668
run: npm run test:db
6769
if: matrix.database-type != 'oracledb'

.github/workflows/unit-tests.yml

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ jobs:
3434
- name: Run npm install
3535
run: npm install
3636

37+
- run: npm run build
38+
3739
- name: Run Tests
3840
run: npm run test:unit
3941
env:

CONTRIBUTING.md

+10
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ Once this is done, check it works by attempting to login:
169169
psql -h localhost -U postgres -d knex_test
170170
```
171171
172+
## Typescript source files
173+
174+
> TL;DR: Starting with release 2.0.0 Knex is adding support for Typescript source files. Thus to develop in this repo you will need to run `npm run build` to generate the resulting `.js` files, even when developing in Javascript. It is encouraged that new functionality and sources be written in Typescript but this is not required.
175+
176+
Starting with release 2.0.0, Knex is support source additions in Typescript! This allows for better safety in the code added. However, pre-2.0.0 Knex was always written in pure Javascript and thus a "hybrid" approach is being used for 2.0.0 to allow for the new `.ts` files to exist along `.js` files that make up the majority of this repository.
177+
178+
To develop in this repository use the `npm run build` command. If you wish to have the `tsc` compiled watch and recompile on changes then run `npm run build:ts -- --watch`. Note that for easy integration with Javascript the outputted files are done in a "side-by-side" manner meaning that `lib/foo/bar.ts` will result in `lib/foo/bar.js`.
179+
180+
The script file `./scripts/update_gitignore_for_tsc_output.js` file is called as part of the `npm run build` command which will update the `lib/.gitignore` file which is used to ensure generated `.js` and related files from `tsc` compilation are not checked into the git repo.
181+
172182
## Want to be Collaborator?
173183
174184
There is always room for more collaborators. Be active on resolving github issues / sending pull requests / reviewing code and we will ask you to join.

lib/.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# DO NOT EDIT, GENERATED BY: scripts/update_gitignore_for_tsc_output.js
2+
3+
# Do not include tsc generated type definitions
4+
**/*.d.ts
5+
6+
# Do not include tsc source maps
7+
**/*.js.map
8+
9+
# Do not include .js files from .ts files
10+
dialects/index.js
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const { resolveClientNameWithAliases } = require('../util/helpers');
1+
const { resolveClientNameWithAliases } = require('../util/helpers')
22

3-
const dbNameToDialectLoader = Object.freeze({
3+
const dbNameToDialectLoader: Record<string, () => any> = Object.freeze({
44
'better-sqlite3': () => require('./better-sqlite3'),
55
cockroachdb: () => require('./cockroachdb'),
66
mssql: () => require('./mssql'),
@@ -12,7 +12,7 @@ const dbNameToDialectLoader = Object.freeze({
1212
postgres: () => require('./postgres'),
1313
redshift: () => require('./redshift'),
1414
sqlite3: () => require('./sqlite3'),
15-
});
15+
})
1616

1717
/**
1818
* Gets the Dialect object with the given client name or throw an
@@ -21,15 +21,11 @@ const dbNameToDialectLoader = Object.freeze({
2121
* NOTE: This is a replacement for prior practice of doing dynamic
2222
* string construction for imports of Dialect objects.
2323
*/
24-
function getDialectByNameOrAlias(clientName) {
25-
const resolvedClientName = resolveClientNameWithAliases(clientName);
26-
const dialectLoader = dbNameToDialectLoader[resolvedClientName];
24+
export function getDialectByNameOrAlias(clientName: string) {
25+
const resolvedClientName = resolveClientNameWithAliases(clientName)
26+
const dialectLoader = dbNameToDialectLoader[resolvedClientName]
2727
if (!dialectLoader) {
28-
throw new Error(`Invalid clientName given: ${clientName}`);
28+
throw new Error(`Invalid clientName given: ${clientName}`)
2929
}
3030
return dialectLoader();
3131
}
32-
33-
module.exports = {
34-
getDialectByNameOrAlias,
35-
};

package.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
"node": ">=12"
99
},
1010
"scripts": {
11+
"build": "npm run build:gitignore && npm run build:ts",
12+
"build:ts": "tsc",
13+
"build:gitignore": "./scripts/update_gitignore_for_tsc_output.js run",
1114
"format": "prettier --write \"{lib,bin,scripts,test}/**/*.js\"",
1215
"debug:test": "mocha --inspect-brk --exit -t 0 test/all-tests-suite.js",
1316
"debug:tape": "node --inspect-brk test/tape/index.js",
@@ -52,7 +55,8 @@
5255
"stress:init": "docker-compose -f scripts/stress-test/docker-compose.yml up --no-start && docker-compose -f scripts/stress-test/docker-compose.yml start",
5356
"stress:test": "node scripts/stress-test/knex-stress-test.js | grep -A 5 -B 60 -- '- STATS '",
5457
"stress:destroy": "docker-compose -f scripts/stress-test/docker-compose.yml stop",
55-
"prepare": "husky install"
58+
"prepare": "husky install",
59+
"prepublishOnly": "npm run build"
5660
},
5761
"dependencies": {
5862
"colorette": "2.0.16",
@@ -100,6 +104,7 @@
100104
]
101105
},
102106
"devDependencies": {
107+
"@tsconfig/recommended": "^1.0.1",
103108
"@types/node": "^17.0.25",
104109
"better-sqlite3": "^7.5.1",
105110
"chai": "^4.3.6",
@@ -215,6 +220,10 @@
215220
"files": [
216221
"bin/*",
217222
"lib/*",
223+
"!lib/**/*.ts",
224+
"!lib/**/*.d.ts",
225+
"!lib/**/*.js.map",
226+
"!lib/.gitignore",
218227
"scripts/*",
219228
"types/index.d.ts",
220229
"types/result.d.ts",
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env node
2+
3+
const path = require('path')
4+
const fs = require('fs')
5+
6+
// Directory constants
7+
const scriptDirectory = __dirname
8+
const repoDirectory = path.join(scriptDirectory, '..')
9+
const libDirectory = path.join(repoDirectory, 'lib')
10+
11+
const helpText = `
12+
Helper script to update lib/.gitignore for all .js files from .ts files.
13+
14+
update_gitignore_for_tsc_output.js COMMAND
15+
16+
COMMAND:
17+
run: Update lib/.gitignore file.
18+
help: Print this menu.
19+
20+
NOTES FOR USAGE:
21+
1. This script is tested to work on Ubuntu 18.04 LTS.
22+
`
23+
24+
const gitignoreHeader = `# DO NOT EDIT, GENERATED BY: scripts/update_gitignore_for_tsc_output.js
25+
26+
# Do not include tsc generated type definitions
27+
**/*.d.ts
28+
29+
# Do not include tsc source maps
30+
**/*.js.map
31+
32+
# Do not include .js files from .ts files
33+
`
34+
35+
function main(cliCommand) {
36+
if (cliCommand === 'run') {
37+
console.log('Generating lib/.gitignore ...')
38+
39+
// Find all .ts files in lib/
40+
const directoriesToProcess = [libDirectory]
41+
const tsFiles = []
42+
while (directoriesToProcess.length > 0) {
43+
const directory = directoriesToProcess.pop()
44+
if (!fs.existsSync(directory)) {
45+
throw new Error("Directory doesn't exist:", directory)
46+
}
47+
48+
const files = fs.readdirSync(directory)
49+
files.forEach((file) => {
50+
const filename = path.join(directory, file)
51+
const stat = fs.lstatSync(filename)
52+
if (stat.isDirectory()) {
53+
directoriesToProcess.push(filename)
54+
} else if (filename.endsWith('.ts') && !filename.endsWith('.d.ts')) {
55+
tsFiles.push(filename)
56+
console.log('Found .ts file:', filename)
57+
}
58+
})
59+
}
60+
61+
// Get paths of .js files to ignore
62+
const jsFilesToIgnore = tsFiles.map((filepath) => {
63+
// Cuts off `${libDirectory}/`
64+
const relativeTsPath = filepath.slice(libDirectory.length + 1)
65+
// Swaps .ts for .js file ending
66+
const relativeJsPath = relativeTsPath.slice(0, relativeTsPath.length - 3) + '.js'
67+
return relativeJsPath
68+
})
69+
const jsFilesToIgnoreString = jsFilesToIgnore.join('\n')
70+
const libGitignorePath = path.join(libDirectory, '.gitignore')
71+
fs.writeFileSync(libGitignorePath, gitignoreHeader + jsFilesToIgnoreString + '\n')
72+
console.log('DONE')
73+
} else if (['help', '--help', '-h', undefined].includes(cliCommand)) {
74+
console.log(helpText)
75+
} else {
76+
console.log(`Unsupported command: ${cliCommand}`)
77+
console.log("Try running with 'help' to see supported commands.")
78+
process.exit(1)
79+
}
80+
}
81+
82+
// Main script logic
83+
const cliCommand = process.argv[2]
84+
// Start the bash app's main function
85+
main(cliCommand)

tsconfig.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"extends": "@tsconfig/node12/tsconfig.json",
3+
"compilerOptions": {
4+
"strict": true,
5+
"esModuleInterop": true,
6+
"forceConsistentCasingInFileNames": true,
7+
"moduleResolution": "node",
8+
"declaration": false,
9+
"rootDirs": [
10+
"lib"
11+
],
12+
"importHelpers": false,
13+
"sourceMap": true,
14+
"baseUrl": ".",
15+
},
16+
"include": [
17+
"lib/**/*.ts"
18+
],
19+
"exclude": [
20+
"node_modules",
21+
]
22+
}

0 commit comments

Comments
 (0)