Skip to content

Commit 19cebef

Browse files
author
Terry Zhao
committed
better schema
1 parent 1342c53 commit 19cebef

File tree

9 files changed

+84
-15
lines changed

9 files changed

+84
-15
lines changed

src/{{ project_name_snake }}/export_types.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import jsonref
1818
from pydantic import BaseModel
1919
import click
20+
import re
2021

2122

2223
def run_command(cmd: str):
@@ -51,9 +52,43 @@ def generate_typescript_interfaces(schema_dir: Path):
5152
run_command(
5253
f"npx -y json-schema-to-typescript@15.0.4 -i '{schema_dir / '*.json'}' -o {schema_dir}"
5354
)
55+
post_process_typescript_declarations(schema_dir)
5456
run_command(f"npx -y prettier@3.5.1 --write {schema_dir}")
5557

5658

59+
def post_process_typescript_declarations(schema_dir: Path) -> None:
60+
"""Replace index signature value type with JSONObject and insert import.
61+
62+
- Turns `[k: string]: unknown;` and `[k: string]: any;` into `[k: string]: JSONObject;`
63+
- Adds `import type { JSONObject } from '@llamaindex/ui';` if needed
64+
"""
65+
index_signature_unknown_pattern = re.compile(r"\[k:\s*string\]:\s*unknown;?")
66+
index_signature_any_pattern = re.compile(r"\[k:\s*string\]:\s*any;?")
67+
import_statement = "import type { JSONObject } from '@llamaindex/ui';\n"
68+
import_regex = re.compile(r"import\s+type\s+\{\s*JSONObject\s*\}\s+from\s+'@llamaindex/ui';")
69+
70+
for dts_path in schema_dir.glob("*.d.ts"):
71+
content = dts_path.read_text(encoding="utf-8")
72+
73+
# Replace index signature value types
74+
new_content = index_signature_unknown_pattern.sub("[k: string]: JSONObject;", content)
75+
new_content = index_signature_any_pattern.sub("[k: string]: JSONObject;", new_content)
76+
77+
# Insert import if JSONObject is used and import not present
78+
if "JSONObject" in new_content and not import_regex.search(new_content):
79+
# Try to place after the generator banner if present, else at file start
80+
insertion_index = 0
81+
banner_end = new_content.find("*/")
82+
if banner_end != -1:
83+
# Move to the next newline after banner
84+
next_newline = new_content.find("\n", banner_end + 2)
85+
insertion_index = next_newline + 1 if next_newline != -1 else banner_end + 2
86+
new_content = new_content[:insertion_index] + import_statement + new_content[insertion_index:]
87+
88+
if new_content != content:
89+
dts_path.write_text(new_content, encoding="utf-8")
90+
91+
5792
def load_module_from_path(module_name: str, file_path: Path) -> ModuleType:
5893
spec = importlib.util.spec_from_file_location(module_name, file_path)
5994
if spec is None or spec.loader is None:

test-proj/src/test_proj/export_types.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import jsonref
1818
from pydantic import BaseModel
1919
import click
20+
import re
2021

2122

2223
def run_command(cmd: str):
@@ -51,9 +52,43 @@ def generate_typescript_interfaces(schema_dir: Path):
5152
run_command(
5253
f"npx -y json-schema-to-typescript@15.0.4 -i '{schema_dir / '*.json'}' -o {schema_dir}"
5354
)
55+
post_process_typescript_declarations(schema_dir)
5456
run_command(f"npx -y prettier@3.5.1 --write {schema_dir}")
5557

5658

59+
def post_process_typescript_declarations(schema_dir: Path) -> None:
60+
"""Replace index signature value type with JSONObject and insert import.
61+
62+
- Turns `[k: string]: unknown;` and `[k: string]: any;` into `[k: string]: JSONObject;`
63+
- Adds `import type { JSONObject } from '@llamaindex/ui';` if needed
64+
"""
65+
index_signature_unknown_pattern = re.compile(r"\[k:\s*string\]:\s*unknown;?")
66+
index_signature_any_pattern = re.compile(r"\[k:\s*string\]:\s*any;?")
67+
import_statement = "import type { JSONObject } from '@llamaindex/ui';\n"
68+
import_regex = re.compile(r"import\s+type\s+\{\s*JSONObject\s*\}\s+from\s+'@llamaindex/ui';")
69+
70+
for dts_path in schema_dir.glob("*.d.ts"):
71+
content = dts_path.read_text(encoding="utf-8")
72+
73+
# Replace index signature value types
74+
new_content = index_signature_unknown_pattern.sub("[k: string]: JSONObject;", content)
75+
new_content = index_signature_any_pattern.sub("[k: string]: JSONObject;", new_content)
76+
77+
# Insert import if JSONObject is used and import not present
78+
if "JSONObject" in new_content and not import_regex.search(new_content):
79+
# Try to place after the generator banner if present, else at file start
80+
insertion_index = 0
81+
banner_end = new_content.find("*/")
82+
if banner_end != -1:
83+
# Move to the next newline after banner
84+
next_newline = new_content.find("\n", banner_end + 2)
85+
insertion_index = next_newline + 1 if next_newline != -1 else banner_end + 2
86+
new_content = new_content[:insertion_index] + import_statement + new_content[insertion_index:]
87+
88+
if new_content != content:
89+
dts_path.write_text(new_content, encoding="utf-8")
90+
91+
5792
def load_module_from_path(module_name: str, file_path: Path) -> ModuleType:
5893
spec = importlib.util.spec_from_file_location(module_name, file_path)
5994
if spec is None or spec.loader is None:

test-proj/ui/src/lib/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ cloudApiClient.setConfig({
2626
});
2727

2828
const agentClient = createCloudAgentClient<
29-
ExtractedData<MySchema & JSONObject>
29+
ExtractedData<MySchema>
3030
>({
3131
baseUrl: apiBaseUrl,
3232
apiKey: platformToken,

test-proj/ui/src/pages/ItemPage.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
AcceptReject,
44
ExtractedDataDisplay,
55
FilePreview,
6-
JSONObject,
76
useItemData,
87
type Highlight,
98
} from "@llamaindex/ui";
@@ -23,7 +22,7 @@ export default function ItemPage() {
2322
const [highlight, setHighlight] = useState<Highlight | undefined>(undefined);
2423

2524
// Use the hook to fetch item data
26-
const itemHookData = useItemData<MySchema & JSONObject>({
25+
const itemHookData = useItemData<MySchema>({
2726
// order/remove fields as needed here
2827
jsonSchema: modifyJsonSchema(MyJsonSchema as any, {}),
2928
itemId: itemId as string,
@@ -116,11 +115,11 @@ export default function ItemPage() {
116115
<div className="flex-1 bg-white h-full overflow-y-auto">
117116
<div className="p-4 space-y-4">
118117
{/* Extracted Data */}
119-
<ExtractedDataDisplay<MySchema & JSONObject>
118+
<ExtractedDataDisplay<MySchema>
120119
extractedData={itemData.data}
121120
title="Extracted Data"
122121
onChange={(updatedData) => {
123-
updateData(updatedData as any);
122+
updateData(updatedData);
124123
}}
125124
onClickField={(args) => {
126125
// TODO: set multiple highlights

test-proj/ui/src/schemas/MySchema.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable */
1+
import type { JSONObject } from "@llamaindex/ui";
22
/**
33
* This file was automatically generated by json-schema-to-typescript.
44
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
@@ -9,5 +9,5 @@ export type Hello = string;
99

1010
export interface MySchema {
1111
hello: Hello;
12-
[k: string]: unknown;
12+
[k: string]: JSONObject;
1313
}

ui/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
"dependencies": {
1717
"@babel/runtime": "^7.27.6",
1818
"@lezer/highlight": "^1.2.1",
19-
"@llamaindex/cloud": "^4.0.28",
20-
"@llamaindex/ui": "file:/Users/terryzhao/work/llama-ui/packages/ui",
19+
"@llamaindex/ui": "^0.5.0",
2120
"@radix-ui/themes": "^3.2.1",
2221
"class-variance-authority": "^0.7.1",
2322
"clsx": "^2.1.1",
23+
"llama-cloud-services": "^0.3.3",
2424
"lucide-react": "^0.514.0",
2525
"react": "^18.3.0",
2626
"react-dom": "^18.3.0",

ui/src/lib/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { MySchema } from "@/schemas/MySchema";
22
import { ExtractedData } from "llama-cloud-services/beta/agent";
3-
import { ApiClients, JSONObject } from "@llamaindex/ui";
3+
import { ApiClients } from "@llamaindex/ui";
44
import {
55
createCloudAgentClient,
66
createLlamaDeployClient,
@@ -26,7 +26,7 @@ cloudApiClient.setConfig({
2626
});
2727

2828
const agentClient = createCloudAgentClient<
29-
ExtractedData<MySchema & JSONObject>
29+
ExtractedData<MySchema>
3030
>({
3131
baseUrl: apiBaseUrl,
3232
apiKey: platformToken,

ui/src/pages/ItemPage.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
AcceptReject,
44
ExtractedDataDisplay,
55
FilePreview,
6-
JSONObject,
76
useItemData,
87
type Highlight,
98
} from "@llamaindex/ui";
@@ -23,7 +22,7 @@ export default function ItemPage() {
2322
const [highlight, setHighlight] = useState<Highlight | undefined>(undefined);
2423

2524
// Use the hook to fetch item data
26-
const itemHookData = useItemData<MySchema & JSONObject>({
25+
const itemHookData = useItemData<MySchema>({
2726
// order/remove fields as needed here
2827
jsonSchema: modifyJsonSchema(MyJsonSchema as any, {}),
2928
itemId: itemId as string,
@@ -116,7 +115,7 @@ export default function ItemPage() {
116115
<div className="flex-1 bg-white h-full overflow-y-auto">
117116
<div className="p-4 space-y-4">
118117
{/* Extracted Data */}
119-
<ExtractedDataDisplay<MySchema & JSONObject>
118+
<ExtractedDataDisplay<MySchema>
120119
extractedData={itemData.data}
121120
title="Extracted Data"
122121
onChange={(updatedData) => {

ui/src/schemas/MySchema.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-disable */
2+
import type { JSONObject } from "@llamaindex/ui";
23
/**
34
* This file was automatically generated by json-schema-to-typescript.
45
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
@@ -9,5 +10,5 @@ export type Hello = string;
910

1011
export interface MySchema {
1112
hello: Hello;
12-
[k: string]: unknown;
13+
[k: string]: JSONObject;
1314
}

0 commit comments

Comments
 (0)