Skip to content

Commit

Permalink
feat(cli): add tsx support (#1021)
Browse files Browse the repository at this point in the history
Co-authored-by: Shinigami92 <[email protected]>
  • Loading branch information
remidewitte and Shinigami92 authored Aug 31, 2024
1 parent 80c4a99 commit c1513e5
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 18 deletions.
57 changes: 54 additions & 3 deletions .github/workflows/postgres-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ jobs:
DATABASE_URL: postgres://ubuntu:ubuntu@localhost:5432/integration_test
SCHEMA: myschema

typescript-migration-test:
typescript-migration-via-ts-node-test:
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -599,7 +599,7 @@ jobs:
# Maps tcp port 5432 on service container to the host
- 5432:5432

name: 'TypeScript Migration Test: pg-${{ matrix.postgres_version }}, node-${{ matrix.node_version }}, ubuntu-latest'
name: 'TypeScript Migration Test with ts-node: pg-${{ matrix.postgres_version }}, node-${{ matrix.node_version }}, ubuntu-latest'
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
Expand All @@ -620,7 +620,58 @@ jobs:
run: pnpm run build

- name: Integration Test
run: pnpm run migrate up --tsconfig tsconfig.json -m test/ts/migrations && pnpm run migrate down 0 --tsconfig tsconfig.json -m test/ts/migrations --timestamps
run: pnpm run migrate up --tsconfig tsconfig.json --ts-node -m test/ts/migrations && pnpm run migrate down 0 --tsconfig tsconfig.json --ts-node -m test/ts/migrations --timestamps
env:
DATABASE_URL: postgres://ubuntu:ubuntu@localhost:5432/integration_test

typescript-migration-via-tsx-test:
runs-on: ubuntu-latest
strategy:
matrix:
node_version: [20]
postgres_version: [16.2]
fail-fast: false
timeout-minutes: 10

services:
postgres:
image: postgres:${{ matrix.postgres_version }}-alpine
env:
POSTGRES_USER: ubuntu
POSTGRES_PASSWORD: ubuntu
POSTGRES_DB: integration_test
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps tcp port 5432 on service container to the host
- 5432:5432

name: 'TypeScript Migration Test with tsx: pg-${{ matrix.postgres_version }}, node-${{ matrix.node_version }}, ubuntu-latest'
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Install pnpm
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0

- name: Set node version to ${{ matrix.node_version }}
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: ${{ matrix.node_version }}
cache: 'pnpm'

- name: Install deps
run: pnpm install

- name: Build
run: pnpm run build

- name: Integration Test
run: pnpm run migrate up --tsconfig tsconfig.json --tsx -m test/ts/migrations && pnpm run migrate down 0 --tsconfig tsconfig.json --tsx -m test/ts/migrations --timestamps
env:
DATABASE_URL: postgres://ubuntu:ubuntu@localhost:5432/integration_test

Expand Down
57 changes: 46 additions & 11 deletions bin/node-pg-migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ process.on('uncaughtException', (err) => {

const crossRequire = createRequire(resolve('_'));

/**
* Try to require a module and return null if it doesn't exist.
*
* @param moduleName The name of the module to require.
*/
function tryRequire<TModule = unknown>(moduleName: string): TModule | null {
try {
return crossRequire(moduleName);
Expand Down Expand Up @@ -60,6 +65,8 @@ const dryRunArg = 'dry-run';
const fakeArg = 'fake';
const decamelizeArg = 'decamelize';
const tsconfigArg = 'tsconfig';
const tsNodeArg = 'ts-node';
const tsxArg = 'tsx';
const verboseArg = 'verbose';
const rejectUnauthorizedArg = 'reject-unauthorized';
const envPathArg = 'envPath';
Expand Down Expand Up @@ -162,6 +169,16 @@ const parser = yargs(process.argv.slice(2))
describe: 'Path to tsconfig.json file',
type: 'string',
},
[tsNodeArg]: {
default: true,
describe: 'Use ts-node for typescript files',
type: 'boolean',
},
[tsxArg]: {
default: false,
describe: 'Use tsx for typescript files',
type: 'boolean',
},
[envPathArg]: {
describe: 'Path to the .env file that should be used for configuration',
type: 'string',
Expand Down Expand Up @@ -255,8 +272,10 @@ let CHECK_ORDER = argv[checkOrderArg];
let VERBOSE = argv[verboseArg];
let DECAMELIZE = argv[decamelizeArg];
let tsconfigPath = argv[tsconfigArg];
let useTsNode = argv[tsNodeArg];
let useTsx = argv[tsxArg];

function readTsconfig() {
function readTsconfig(): void {
if (tsconfigPath) {
let tsconfig;
const json5 = tryRequire<typeof import('json5')>('json5');
Expand All @@ -283,18 +302,24 @@ function readTsconfig() {
console.error("Can't load tsconfig.json:", error);
}

const tsnode = tryRequire<typeof import('ts-node')>('ts-node');
if (!tsnode) {
console.error("For TypeScript support, please install 'ts-node' module");
}
if (useTsx) {
process.env.TSX_TSCONFIG_PATH = tsconfigPath;
} else if (useTsNode) {
const tsnode = tryRequire<typeof import('ts-node')>('ts-node');
if (!tsnode) {
console.error(
"For TypeScript support, please install 'ts-node' module"
);
}

if (tsconfig && tsnode) {
tsnode.register(tsconfig);
if (!MIGRATIONS_FILE_LANGUAGE) {
MIGRATIONS_FILE_LANGUAGE = 'ts';
if (tsconfig && tsnode) {
tsnode.register(tsconfig);
if (!MIGRATIONS_FILE_LANGUAGE) {
MIGRATIONS_FILE_LANGUAGE = 'ts';
}
} else {
process.exit(1);
}
} else {
process.exit(1);
}
}
}
Expand Down Expand Up @@ -393,6 +418,8 @@ function readJson(json: unknown): void {
typeof val === 'string' || typeof val === 'object'
);
tsconfigPath = applyIf(tsconfigPath, tsconfigArg, json, isString);
useTsNode = applyIf(useTsNode, tsNodeArg, json, isBoolean);
useTsx = applyIf(useTsx, tsxArg, json, isBoolean);

if ('url' in json && json.url) {
DB_CONNECTION ??= json.url;
Expand Down Expand Up @@ -430,6 +457,14 @@ if (configFileName) {

readTsconfig();

if (useTsx) {
const tsx =
tryRequire<typeof import('tsx/dist/cjs/api/index.cjs')>('tsx/cjs');
if (!tsx) {
console.error("For TSX support, please install 'tsx' module");
}
}

const action = argv._.shift();

// defaults
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"rimraf": "6.0.1",
"ts-node": "10.9.2",
"tsup": "8.2.4",
"tsx": "4.19.0",
"typescript": "5.5.4",
"vitepress": "1.3.4",
"vitest": "2.0.5"
Expand Down
36 changes: 32 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c1513e5

Please sign in to comment.