Skip to content

Commit 37bb197

Browse files
authored
feat: add function-kysely-tailordb-codegen (#37)
1 parent f278473 commit 37bb197

11 files changed

Lines changed: 1412 additions & 0 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Publish npm package function-kysely-tailordb-codegen
2+
3+
on:
4+
workflow_dispatch:
5+
6+
permissions:
7+
contents: read
8+
9+
defaults:
10+
run:
11+
shell: bash
12+
13+
jobs:
14+
publish:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
20+
with:
21+
node-version-file: packages/kysely-tailordb-codegen/package.json
22+
registry-url: https://registry.npmjs.org
23+
24+
- name: Update corepack
25+
run: |
26+
npm i -g corepack@latest
27+
28+
- name: Publish
29+
working-directory: packages/kysely-tailordb-codegen
30+
run: |
31+
corepack enable
32+
pnpm install
33+
pnpm run build
34+
pnpm publish --no-git-checks --access public
35+
env:
36+
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Test packages/kysely-tailordb-codegen
2+
3+
on: workflow_call
4+
5+
jobs:
6+
test:
7+
timeout-minutes: 10
8+
runs-on: ubuntu-latest
9+
permissions:
10+
contents: read
11+
pull-requests: write
12+
13+
steps:
14+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
15+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
16+
with:
17+
node-version-file: packages/kysely-tailordb/package.json
18+
registry-url: https://registry.npmjs.org
19+
20+
- name: Setup pnpm
21+
run: |
22+
npm i -g corepack@latest
23+
corepack enable
24+
25+
- name: Install deps
26+
working-directory: packages/kysely-tailordb-codegen
27+
run: |
28+
pnpm install
29+
30+
- name: Lint
31+
working-directory: packages/kysely-tailordb-codegen
32+
run: |
33+
pnpm run check
34+
35+
- name: Run type-check
36+
working-directory: packages/kysely-tailordb-codegen
37+
run: |
38+
pnpm run type-check
39+
40+
- name: Build
41+
working-directory: packages/kysely-tailordb-codegen
42+
run: |
43+
pnpm run build

.github/workflows/test.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ jobs:
1111
action: ${{ steps.changes.outputs.action }}
1212
renovate: ${{ steps.changes.outputs.renovate }}
1313
kysely-tailordb: ${{ steps.changes.outputs.kysely-tailordb }}
14+
kysely-tailordb-codegen: ${{ steps.changes.outputs.kysely-tailordb-codegen }}
1415
types: ${{ steps.changes.outputs.types }}
1516
runs-on: ubuntu-latest
1617
permissions:
@@ -28,6 +29,8 @@ jobs:
2829
- renovate.json
2930
kysely-tailordb:
3031
- packages/kysely-tailordb/**
32+
kysely-tailordb-codegen:
33+
- packages/kysely-tailordb-codegen/**
3134
types:
3235
- packages/types/**
3336
@@ -38,6 +41,7 @@ jobs:
3841
- action
3942
- renovate
4043
- kysely-tailordb
44+
- kysely-tailordb-codegen
4145
permissions: {}
4246
if: failure()
4347
steps:
@@ -64,3 +68,11 @@ jobs:
6468
permissions:
6569
contents: read
6670
pull-requests: write
71+
72+
kysely-tailordb-codegen:
73+
uses: ./.github/workflows/test-function-kysely-tailordb-codegen.yaml
74+
needs: path-filter
75+
if: needs.path-filter.outputs.kysely-tailordb-codegen == 'true'
76+
permissions:
77+
contents: read
78+
pull-requests: write
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# @tailor-platform/function-kysely-tailordb-codegen
2+
3+
Generate [Kysely](https://github.com/kysely-org/kysely) code for TailorDB
4+
5+
## Usage
6+
7+
```sh
8+
npm install -D @tailor-platform/function-kysely-tailordb-codegen
9+
npx kysely-tailordb-codegen -h
10+
```
11+
12+
```
13+
Usage: kysely-tailordb-codegen [options]
14+
15+
Generate Kysely code for TailorDB
16+
17+
Options:
18+
-a, --app <string> App name
19+
-n, --namespace <string> TailorDB namespace
20+
-m, --machineuser <string> Machine user name
21+
-o, --output <string> Output file name
22+
-h, --help display help for command
23+
```
24+
25+
## Requirements
26+
27+
This command uses `tailorctl` internally to run the code generation script on the Tailor Platform.
28+
Therefore, please make sure `tailorctl` is installed and the correct workspace is selected before running the command.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
3+
"formatter": {
4+
"enabled": true,
5+
"indentStyle": "space",
6+
"indentWidth": 2,
7+
"formatWithErrors": false
8+
},
9+
"javascript": {
10+
"formatter": {
11+
"quoteStyle": "double",
12+
"semicolons": "always",
13+
"trailingCommas": "all"
14+
}
15+
},
16+
"linter": {
17+
"enabled": true,
18+
"ignore": ["**/node_modules/**", "**/dist/**"],
19+
"rules": {
20+
"recommended": true
21+
}
22+
},
23+
"organizeImports": {
24+
"enabled": true
25+
},
26+
"vcs": {
27+
"enabled": true,
28+
"clientKind": "git",
29+
"useIgnoreFile": true
30+
}
31+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { createRequire } from "node:module";
2+
import path from "node:path";
3+
import { build } from "esbuild";
4+
import { nodeless } from "unenv";
5+
6+
const require = createRequire(import.meta.url);
7+
8+
// When importing the Node API (e.g., `import path from "node:path"`),
9+
// the unenv package should be bundled to run even in the Function service.
10+
// Functions that are difficult to execute in the Function service (e.g., `fs.writeFile`)
11+
// will be bundled as mocks and will throw a "not implemented" error at runtime.
12+
const unenvAlias = {
13+
name: "unenv-alias",
14+
setup(build) {
15+
const alias = nodeless.alias;
16+
const re = new RegExp(`^(${Object.keys(alias).join("|")})$`);
17+
18+
build.onResolve({ filter: re }, (args) => {
19+
const resolved = require.resolve(alias[args.path]);
20+
// Since require.resolve() always resolves to cjs,
21+
// it needs to be converted to mjs when this callback is invoked via import.
22+
const path =
23+
args.kind === "require-call"
24+
? resolved
25+
: resolved.replace(/\.cjs$/, ".mjs");
26+
return { path };
27+
});
28+
},
29+
};
30+
31+
// Inject the unenv package to emulate the behavior of global variables (e.g., process)
32+
// that do not exist within the Function service.
33+
const unenvInject = {
34+
name: "unenv-inject",
35+
setup(build) {
36+
const inject = nodeless.inject;
37+
const re = /unenv-inject-([^.]+)\.js$/;
38+
const prefix = path.join(import.meta.dirname, "unenv-inject-");
39+
40+
build.initialOptions.inject = [
41+
...(build.initialOptions.inject ?? []),
42+
...Object.keys(inject).map((globalName) => `${prefix}${globalName}.js`),
43+
];
44+
45+
build.onResolve({ filter: re }, ({ path }) => ({ path }));
46+
47+
build.onLoad({ filter: re }, ({ path }) => {
48+
const globalName = path.match(re)[1];
49+
return {
50+
contents: getInjectContent(globalName, inject[globalName]),
51+
};
52+
});
53+
},
54+
};
55+
56+
const getInjectContent = (globalName, globalInject) => {
57+
if (typeof globalInject === "string") {
58+
return `import globalVar from "${globalInject}"; globalThis.${globalName} = globalVar;`;
59+
}
60+
const [moduleSpecifier, exportName] = globalInject;
61+
return `import { ${exportName} } from "${moduleSpecifier}"; globalThis.${globalName} = ${exportName};`;
62+
};
63+
64+
// Due to the use of dynamic require, bundling `git-diff` is difficult.
65+
// However, since it's not used in this use case, we can mock it instead.
66+
const mockGitDiff = {
67+
name: "mock-git-diff",
68+
setup(build) {
69+
build.onResolve({ filter: /^git-diff$/ }, (args) => {
70+
return { path: args.path, namespace: "git-diff" };
71+
});
72+
build.onLoad({ filter: /.*/, namespace: "git-diff" }, () => {
73+
return { contents: "export default null" };
74+
});
75+
},
76+
};
77+
78+
build({
79+
entryPoints: ["src/function.ts"],
80+
outfile: "dist/function.js",
81+
format: "esm",
82+
bundle: true,
83+
minify: true,
84+
define: {
85+
global: "globalThis",
86+
},
87+
plugins: [unenvAlias, unenvInject, mockGitDiff],
88+
// Unused drivers are left unbundled as-is.
89+
// Note that future updates to `kysely-codegen` may introduce new drivers.
90+
external: [
91+
"@libsql/kysely-libsql",
92+
"@tediousjs/connection-string",
93+
"better-sqlite3",
94+
"bun:sqlite",
95+
"kysely-bun-sqlite",
96+
"mysql2",
97+
"pg",
98+
"tarn",
99+
"tedious",
100+
],
101+
});
102+
103+
build({
104+
entryPoints: ["src/cli.ts"],
105+
outfile: "dist/cli.js",
106+
format: "esm",
107+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@tailor-platform/function-kysely-tailordb-codegen",
3+
"version": "0.1.0",
4+
"description": "Generate Kysely code for TailorDB",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/tailor-platform/function",
8+
"directory": "packages/kysely-tailordb-codegen"
9+
},
10+
"type": "module",
11+
"bin": {
12+
"kysely-tailordb-codegen": "./dist/cli.js"
13+
},
14+
"files": ["dist"],
15+
"scripts": {
16+
"build": "node ./build.js",
17+
"check": "biome check .",
18+
"check-write": "biome check --write .",
19+
"type-check": "tsc"
20+
},
21+
"dependencies": {
22+
"commander": "^14.0.0",
23+
"zx": "^8.5.4"
24+
},
25+
"devDependencies": {
26+
"@biomejs/biome": "^1.9.4",
27+
"@tailor-platform/function-kysely-tailordb": "^0.1.2",
28+
"@tailor-platform/function-types": "^0.2.0",
29+
"@types/fs-extra": "^11.0.4",
30+
"@types/node": "^22.15.24",
31+
"esbuild": "^0.25.5",
32+
"kysely": "^0.27.5",
33+
"kysely-codegen": "^0.18.5",
34+
"typescript": "^5.8.3",
35+
"unenv": "^1.10.0"
36+
},
37+
"engines": {
38+
"node": "22.x"
39+
},
40+
"packageManager": "pnpm@10.11.0",
41+
"pnpm": {
42+
"onlyBuiltDependencies": ["@biomejs/biome", "esbuild"]
43+
}
44+
}

0 commit comments

Comments
 (0)