Skip to content

Commit dd31780

Browse files
committed
wip
1 parent de4e28e commit dd31780

File tree

14 files changed

+169
-115
lines changed

14 files changed

+169
-115
lines changed

docs/docs/development/type-generation.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,26 @@ export default defineConfig({
4242

4343
When the frontend is served through AppKit in dev mode, AppKit's dev server already includes `appKitTypesPlugin()` internally. You still want it in your client build pipeline if you run `vite build` separately.
4444

45-
## CLI: `appkit-generate-types`
45+
## CLI: `appkit generate-types`
4646

4747
For manual type generation or CI/CD pipelines, use the CLI command:
4848

4949
```bash
5050
# Requires DATABRICKS_WAREHOUSE_ID (or pass as 3rd arg)
51-
npx appkit-generate-types [rootDir] [outFile] [warehouseId]
51+
npx appkit generate-types [rootDir] [outFile] [warehouseId]
5252
```
5353

5454
### Examples
5555

5656
```bash
5757
# Generate types using warehouse ID from environment
58-
npx appkit-generate-types . client/src/appKitTypes.d.ts
58+
npx appkit generate-types . client/src/appKitTypes.d.ts
5959

6060
# Force regeneration (skip cache)
61-
npx appkit-generate-types --no-cache
61+
npx appkit generate-types --no-cache
6262

6363
# Specify warehouse ID explicitly
64-
npx appkit-generate-types . client/src/appKitTypes.d.ts abc123...
64+
npx appkit generate-types . client/src/appKitTypes.d.ts abc123...
6565
```
6666

6767
## How It Works

packages/appkit-ui/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
"build:watch": "tsdown --config tsdown.config.ts --watch",
3939
"clean:full": "rm -rf dist node_modules tmp",
4040
"clean": "rm -rf dist tmp",
41-
"dist": "tsx ../../tools/dist.ts",
42-
"tarball": "rm -rf tmp && tsx ../../tools/dist.ts && npm pack ./tmp --pack-destination ./tmp",
41+
"dist": "pnpm --filter=docs build && tsx ../../tools/dist.ts",
42+
"tarball": "rm -rf tmp && pnpm dist && npm pack ./tmp --pack-destination ./tmp",
4343
"typecheck": "tsc --noEmit"
4444
},
4545
"dependencies": {

packages/appkit/bin/generate-types.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

packages/appkit/package.json

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,16 @@
2727
},
2828
"./package.json": "./package.json"
2929
},
30-
"bin": {
31-
"appkit-generate-types": "./bin/generate-types.js",
32-
"appkit-lint": "./bin/appkit-lint.js"
33-
},
3430
"scripts": {
3531
"build:package": "tsdown --config tsdown.config.ts",
3632
"build:watch": "tsdown --config tsdown.config.ts --watch",
3733
"clean:full": "rm -rf dist node_modules tmp",
3834
"clean": "rm -rf dist tmp",
39-
"dist": "tsx ../../tools/dist.ts",
40-
"tarball": "rm -rf tmp && tsx ../../tools/dist.ts && npm pack ./tmp --pack-destination ./tmp",
35+
"dist": "pnpm --filter=docs build && tsx ../../tools/dist.ts",
36+
"tarball": "rm -rf tmp && pnpm dist && npm pack ./tmp --pack-destination ./tmp",
4137
"typecheck": "tsc --noEmit"
4238
},
4339
"dependencies": {
44-
"@ast-grep/napi": "^0.37.0",
4540
"@databricks/sdk-experimental": "^0.15.0",
4641
"@opentelemetry/api": "^1.9.0",
4742
"@opentelemetry/api-logs": "^0.208.0",

packages/shared/bin/appkit.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env node
2+
3+
import "../dist/cli/index.js";

packages/shared/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
}
3434
},
3535
"dependencies": {
36+
"@ast-grep/napi": "^0.37.0",
37+
"commander": "^12.1.0",
3638
"fast-glob": "^3.3.3"
3739
}
3840
}

packages/shared/scripts/postinstall.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
console.log("");
33
console.log("[@databricks/appkit] To setup AI assistant instructions, run:");
44
console.log("");
5-
console.log(" npx appkit-setup --write");
5+
console.log(" npx appkit setup --write");
66
console.log("");
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Command } from "commander";
2+
import path from "node:path";
3+
4+
/**
5+
* Generate types command implementation
6+
*/
7+
async function runGenerateTypes(
8+
rootDir?: string,
9+
outFile?: string,
10+
warehouseId?: string,
11+
options?: { noCache?: boolean }
12+
) {
13+
try {
14+
// Try to import the type generator from @databricks/appkit
15+
const { generateFromEntryPoint } = await import(
16+
"@databricks/appkit/dist/type-generator/index.js"
17+
);
18+
19+
const resolvedRootDir = rootDir || process.cwd();
20+
const resolvedOutFile =
21+
outFile || path.join(process.cwd(), "client/src/appKitTypes.d.ts");
22+
23+
const queryFolder = path.join(resolvedRootDir, "config/queries");
24+
25+
const resolvedWarehouseId =
26+
warehouseId || process.env.DATABRICKS_WAREHOUSE_ID;
27+
if (!resolvedWarehouseId) {
28+
console.error(
29+
"Error: DATABRICKS_WAREHOUSE_ID is not set. Please provide it as an argument or environment variable."
30+
);
31+
process.exit(1);
32+
}
33+
34+
await generateFromEntryPoint({
35+
queryFolder,
36+
outFile: resolvedOutFile,
37+
warehouseId: resolvedWarehouseId,
38+
noCache: options?.noCache || false,
39+
});
40+
} catch (error) {
41+
if (
42+
error instanceof Error &&
43+
error.message.includes("Cannot find module")
44+
) {
45+
console.error(
46+
"Error: The 'generate-types' command is only available in @databricks/appkit."
47+
);
48+
console.error(
49+
"Please install @databricks/appkit to use this command."
50+
);
51+
process.exit(1);
52+
}
53+
throw error;
54+
}
55+
}
56+
57+
export const generateTypesCommand = new Command("generate-types")
58+
.description("Generate TypeScript types from SQL queries")
59+
.argument("[rootDir]", "Root directory of the project", process.cwd())
60+
.argument(
61+
"[outFile]",
62+
"Output file path",
63+
path.join(process.cwd(), "client/src/appKitTypes.d.ts")
64+
)
65+
.argument("[warehouseId]", "Databricks warehouse ID")
66+
.option("--no-cache", "Disable caching for type generation")
67+
.action(runGenerateTypes);
Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
#!/usr/bin/env node
2-
/**
3-
* AST-based linting using ast-grep.
4-
* Catches patterns that ESLint/TypeScript miss or handle poorly.
5-
* Usage: npx appkit-lint
6-
*/
1+
import { Command } from "commander";
72
import { parse, Lang } from "@ast-grep/napi";
83
import fs from "node:fs";
94
import path from "node:path";
105

11-
const rules = [
6+
interface Rule {
7+
id: string;
8+
pattern: string;
9+
message: string;
10+
includeTests?: boolean;
11+
filter?: (code: string) => boolean;
12+
}
13+
14+
const rules: Rule[] = [
1215
{
1316
id: "no-double-type-assertion",
1417
pattern: "$X as unknown as $Y",
@@ -37,13 +40,13 @@ const rules = [
3740
},
3841
];
3942

40-
function isTestFile(filePath) {
43+
function isTestFile(filePath: string): boolean {
4144
return (
4245
/\.(test|spec)\.(ts|tsx)$/.test(filePath) || filePath.includes("/tests/")
4346
);
4447
}
4548

46-
function findTsFiles(dir, files = []) {
49+
function findTsFiles(dir: string, files: string[] = []): string[] {
4750
const entries = fs.readdirSync(dir, { withFileTypes: true });
4851

4952
for (const entry of entries) {
@@ -61,8 +64,17 @@ function findTsFiles(dir, files = []) {
6164
return files;
6265
}
6366

64-
function lintFile(filePath, rules) {
65-
const violations = [];
67+
interface Violation {
68+
file: string;
69+
line: number;
70+
column: number;
71+
rule: string;
72+
message: string;
73+
code: string;
74+
}
75+
76+
function lintFile(filePath: string, rules: Rule[]): Violation[] {
77+
const violations: Violation[] = [];
6678
const content = fs.readFileSync(filePath, "utf-8");
6779
const lang = filePath.endsWith(".tsx") ? Lang.Tsx : Lang.TypeScript;
6880
const testFile = isTestFile(filePath);
@@ -96,13 +108,16 @@ function lintFile(filePath, rules) {
96108
return violations;
97109
}
98110

99-
function main() {
111+
/**
112+
* Lint command implementation
113+
*/
114+
function runLint() {
100115
const rootDir = process.cwd();
101116
const files = findTsFiles(rootDir);
102117

103118
console.log(`Scanning ${files.length} TypeScript files...\n`);
104119

105-
const allViolations = [];
120+
const allViolations: Violation[] = [];
106121

107122
for (const file of files) {
108123
const violations = lintFile(file, rules);
@@ -126,4 +141,6 @@ function main() {
126141
process.exit(1);
127142
}
128143

129-
main();
144+
export const lintCommand = new Command("lint")
145+
.description("Run AST-based linting on TypeScript files")
146+
.action(runLint);
Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
#!/usr/bin/env node
2-
3-
/**
4-
* CLI tool to setup CLAUDE.md for Databricks AppKit packages.
5-
*
6-
* This bin is included in both @databricks/appkit and @databricks/appkit-ui
7-
* so it's available regardless of which package the user installs.
8-
*
9-
* Usage:
10-
* npx appkit-setup # Show detected packages and content
11-
* npx appkit-setup --write # Create or update CLAUDE.md file
12-
*/
13-
1+
import { Command } from "commander";
142
import fs from "node:fs";
153
import path from "node:path";
164

@@ -26,15 +14,15 @@ const SECTION_START = "<!-- appkit-instructions-start -->";
2614
const SECTION_END = "<!-- appkit-instructions-end -->";
2715

2816
/**
29-
* Find which AppKit packages are installed by checking for CLAUDE.md
17+
* Find which AppKit packages are installed by checking for package.json
3018
*/
3119
function findInstalledPackages() {
3220
const cwd = process.cwd();
3321
const installed = [];
3422

3523
for (const pkg of PACKAGES) {
36-
const claudePath = path.join(cwd, "node_modules", pkg.name, "package.json");
37-
if (fs.existsSync(claudePath)) {
24+
const packagePath = path.join(cwd, "node_modules", pkg.name, "package.json");
25+
if (fs.existsSync(packagePath)) {
3826
installed.push(pkg);
3927
}
4028
}
@@ -45,7 +33,7 @@ function findInstalledPackages() {
4533
/**
4634
* Generate the AppKit section content
4735
*/
48-
function generateSection(packages) {
36+
function generateSection(packages: typeof PACKAGES) {
4937
const links = packages
5038
.map((pkg) => {
5139
const docPath = `./node_modules/${pkg.name}/CLAUDE.md`;
@@ -65,7 +53,7 @@ ${SECTION_END}`;
6553
/**
6654
* Generate standalone CLAUDE.md content (when no existing file)
6755
*/
68-
function generateStandalone(packages) {
56+
function generateStandalone(packages: typeof PACKAGES) {
6957
const links = packages
7058
.map((pkg) => {
7159
const docPath = `./node_modules/${pkg.name}/CLAUDE.md`;
@@ -88,7 +76,7 @@ ${SECTION_END}
8876
/**
8977
* Update existing content with AppKit section
9078
*/
91-
function updateContent(existingContent, packages) {
79+
function updateContent(existingContent: string, packages: typeof PACKAGES) {
9280
const newSection = generateSection(packages);
9381

9482
// Check if AppKit section already exists
@@ -107,27 +95,10 @@ function updateContent(existingContent, packages) {
10795
}
10896

10997
/**
110-
* Main CLI logic
98+
* Setup command implementation
11199
*/
112-
function main() {
113-
const args = process.argv.slice(2);
114-
const shouldWrite = args.includes("--write") || args.includes("-w");
115-
const help = args.includes("--help") || args.includes("-h");
116-
117-
if (help) {
118-
console.log(`
119-
Usage: npx appkit-setup [options]
120-
121-
Options:
122-
--write, -w Create or update CLAUDE.md file in current directory
123-
--help, -h Show this help message
124-
125-
Examples:
126-
npx appkit-setup # Show detected packages and preview content
127-
npx appkit-setup --write # Create or update CLAUDE.md
128-
`);
129-
return;
130-
}
100+
function runSetup(options: { write?: boolean }) {
101+
const shouldWrite = options.write;
131102

132103
// Find installed packages
133104
const installed = findInstalledPackages();
@@ -151,8 +122,8 @@ Examples:
151122
? fs.readFileSync(claudePath, "utf-8")
152123
: null;
153124

154-
let finalContent;
155-
let action;
125+
let finalContent: string;
126+
let action: string;
156127

157128
if (existingContent) {
158129
finalContent = updateContent(existingContent, installed);
@@ -168,7 +139,7 @@ Examples:
168139
console.log(` Path: ${claudePath}`);
169140
} else {
170141
console.log("\nTo create/update CLAUDE.md, run:");
171-
console.log(" npx appkit-setup --write\n");
142+
console.log(" npx appkit setup --write\n");
172143

173144
if (existingContent) {
174145
console.log(
@@ -187,4 +158,7 @@ Examples:
187158
}
188159
}
189160

190-
main();
161+
export const setupCommand = new Command("setup")
162+
.description("Setup CLAUDE.md with AppKit package references")
163+
.option("-w, --write", "Create or update CLAUDE.md file in current directory")
164+
.action(runSetup);

0 commit comments

Comments
 (0)