Skip to content

Commit 501d4be

Browse files
committed
Standardize json reading
1 parent 2988e23 commit 501d4be

1 file changed

Lines changed: 33 additions & 28 deletions

File tree

packages/app/src/cli/models/extensions/specifications/ui_extension.ts

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -282,21 +282,11 @@ const uiExtensionSpec = createExtensionSpecification({
282282
let toolsTypeDefinition = ''
283283
if (toolsDefinition) {
284284
try {
285-
const toolsFilePath = joinPath(extension.directory, toolsDefinition)
286-
if (await fileExists(toolsFilePath)) {
287-
// Read and parse the tools JSON file
288-
const toolsContent = await readFile(toolsFilePath)
289-
const tools = ToolsFileSchema.safeParse(JSON.parse(toolsContent))
290-
if (tools.success) {
291-
// Generate tools type definition
292-
toolsTypeDefinition = await createToolsTypeDefinition(tools.data)
293-
} else {
294-
outputWarn(
295-
`Invalid tools definition in "${toolsDefinition}": ${tools.error.issues
296-
.map((issue) => issue.message)
297-
.join(', ')}`,
298-
)
299-
}
285+
const tools = await readAndValidateJsonAsset(extension.directory, toolsDefinition, ToolsFileSchema)
286+
if (tools.status === 'ok') {
287+
toolsTypeDefinition = await createToolsTypeDefinition(tools.data)
288+
} else if (tools.status === 'invalid') {
289+
outputWarn(`Invalid tools definition in "${toolsDefinition}": ${tools.issues}`)
300290
}
301291
// eslint-disable-next-line no-catch-all/no-catch-all
302292
} catch (error) {
@@ -378,26 +368,41 @@ function addDistPathToAssets(extP: NewExtensionPointSchemaType & {build_manifest
378368
}
379369
}
380370

371+
type JsonAssetResult<T> = {status: 'ok'; data: T} | {status: 'missing'} | {status: 'invalid'; issues: string}
372+
373+
async function readAndValidateJsonAsset<T>(
374+
extensionDirectory: string,
375+
relativePath: string,
376+
schema: zod.ZodType<T>,
377+
): Promise<JsonAssetResult<T>> {
378+
const filePath = joinPath(extensionDirectory, relativePath)
379+
const exists = await fileExists(filePath)
380+
if (!exists) return {status: 'missing'}
381+
382+
const content = await readFile(filePath)
383+
const parsed = schema.safeParse(JSON.parse(content))
384+
if (!parsed.success) {
385+
return {
386+
status: 'invalid',
387+
issues: parsed.error.issues.map((issue) => issue.message).join(', '),
388+
}
389+
}
390+
391+
return {status: 'ok', data: parsed.data}
392+
}
393+
381394
async function parseIntentTypeDefinitions(
382395
extensionDirectory: string,
383396
intents: NonNullable<NewExtensionPointSchemaType['intents']>,
384397
): Promise<GeneratedIntentTypeDefinition[]> {
385398
const parsedIntentDefinitions = await Promise.all(
386399
intents.map(async (intent) => {
387400
try {
388-
const intentSchemaFilePath = joinPath(extensionDirectory, intent.schema)
389-
const schemaExists = await fileExists(intentSchemaFilePath)
390-
if (!schemaExists) return null
391-
392-
const intentSchemaContent = await readFile(intentSchemaFilePath)
393-
const intentSchema = IntentSchemaFileSchema.safeParse(JSON.parse(intentSchemaContent))
394-
395-
if (!intentSchema.success) {
396-
outputWarn(
397-
`Invalid intent schema in "${intent.schema}": ${intentSchema.error.issues
398-
.map((issue) => issue.message)
399-
.join(', ')}`,
400-
)
401+
const intentSchema = await readAndValidateJsonAsset(extensionDirectory, intent.schema, IntentSchemaFileSchema)
402+
if (intentSchema.status === 'missing') return null
403+
404+
if (intentSchema.status === 'invalid') {
405+
outputWarn(`Invalid intent schema in "${intent.schema}": ${intentSchema.issues}`)
401406
return null
402407
}
403408

0 commit comments

Comments
 (0)