mirror of
https://github.com/langgenius/dify.git
synced 2026-07-24 21:18:35 +08:00
120 lines
4.2 KiB
JavaScript
120 lines
4.2 KiB
JavaScript
import { execFileSync } from 'node:child_process'
|
|
import { createHash } from 'node:crypto'
|
|
import { mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { dirname, join, resolve } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { getStreamingOperationIds } from './knowledge-fs-contract-utils.mjs'
|
|
|
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
|
const workspaceRoot = resolve(packageRoot, '../..')
|
|
const repository = resolve(
|
|
process.env.KNOWLEDGE_FS_REPO ?? resolve(workspaceRoot, '../knowledge-fs'),
|
|
)
|
|
const temporaryDirectory = await mkdtemp(join(tmpdir(), 'dify-knowledge-fs-types-'))
|
|
|
|
try {
|
|
const openapiPath = join(temporaryDirectory, 'knowledge-fs.console.json')
|
|
run(
|
|
'uv',
|
|
[
|
|
'run',
|
|
'--project',
|
|
resolve(workspaceRoot, 'api'),
|
|
resolve(workspaceRoot, 'api/dev/generate_knowledge_fs_contract.py'),
|
|
'--repository',
|
|
repository,
|
|
'--check',
|
|
'--output-openapi',
|
|
openapiPath,
|
|
],
|
|
workspaceRoot,
|
|
)
|
|
run('pnpm', ['exec', 'openapi-ts', '-f', 'openapi-ts.knowledge-fs.config.ts'], packageRoot, {
|
|
KNOWLEDGE_FS_OPENAPI: openapiPath,
|
|
})
|
|
await patchStreamingContracts(openapiPath)
|
|
run('pnpm', ['exec', 'vp', 'fmt', 'generated/knowledge-fs'], packageRoot)
|
|
await writeContractMetadata(openapiPath, await generatedArtifactSha256())
|
|
run('pnpm', ['exec', 'vp', 'fmt', 'generated/knowledge-fs/metadata.gen.ts'], packageRoot)
|
|
} finally {
|
|
await rm(temporaryDirectory, { force: true, recursive: true })
|
|
}
|
|
|
|
async function patchStreamingContracts(openapiPath) {
|
|
const document = JSON.parse(await readFile(openapiPath, 'utf8'))
|
|
const streamingOperationIds = getStreamingOperationIds(document)
|
|
if (streamingOperationIds.length === 0) return
|
|
|
|
const outputPath = join(packageRoot, 'generated/knowledge-fs/orpc.gen.ts')
|
|
let source = await readFile(outputPath, 'utf8')
|
|
source = replaceOnce(
|
|
source,
|
|
"import { oc } from '@orpc/contract'",
|
|
"import { eventIterator, oc } from '@orpc/contract'",
|
|
)
|
|
|
|
for (const operationId of streamingOperationIds) {
|
|
const responseSchema = `z${capitalize(operationId)}Response`
|
|
source = replaceOnce(
|
|
source,
|
|
`.output(${responseSchema})`,
|
|
`.output(eventIterator(${responseSchema}))`,
|
|
)
|
|
}
|
|
|
|
await writeFile(outputPath, source)
|
|
}
|
|
|
|
function capitalize(value) {
|
|
return value.charAt(0).toUpperCase() + value.slice(1)
|
|
}
|
|
|
|
function replaceOnce(source, target, replacement) {
|
|
const firstIndex = source.indexOf(target)
|
|
if (firstIndex === -1 || source.indexOf(target, firstIndex + target.length) !== -1)
|
|
throw new Error(`Expected exactly one generated occurrence of ${target}`)
|
|
|
|
return source.slice(0, firstIndex) + replacement + source.slice(firstIndex + target.length)
|
|
}
|
|
|
|
async function generatedArtifactSha256() {
|
|
const generatedDirectory = join(packageRoot, 'generated/knowledge-fs')
|
|
const fileNames = (await readdir(generatedDirectory))
|
|
.filter((fileName) => fileName.endsWith('.gen.ts') && fileName !== 'metadata.gen.ts')
|
|
.sort()
|
|
|
|
return Object.fromEntries(
|
|
await Promise.all(
|
|
fileNames.map(async (fileName) => [
|
|
fileName,
|
|
createHash('sha256')
|
|
.update(await readFile(join(generatedDirectory, fileName)))
|
|
.digest('hex'),
|
|
]),
|
|
),
|
|
)
|
|
}
|
|
|
|
async function writeContractMetadata(openapiPath, artifactSha256) {
|
|
const document = JSON.parse(await readFile(openapiPath, 'utf8'))
|
|
const source = [
|
|
'// This file is auto-generated by scripts/generate-knowledge-fs-contract.mjs.',
|
|
'// Do not edit it manually.',
|
|
'',
|
|
`export const knowledgeFsSourceOpenapiSha256 = ${JSON.stringify(document['x-dify-source-openapi-sha256'])}`,
|
|
`export const knowledgeFsConsoleDeclarationsSha256 = ${JSON.stringify(document['x-dify-console-declarations-sha256'])}`,
|
|
`export const knowledgeFsGeneratedArtifactSha256 = ${JSON.stringify(artifactSha256, null, 2)} as const`,
|
|
'',
|
|
].join('\n')
|
|
await writeFile(join(packageRoot, 'generated/knowledge-fs/metadata.gen.ts'), source)
|
|
}
|
|
|
|
function run(command, args, cwd, extraEnv = {}) {
|
|
execFileSync(command, args, {
|
|
cwd,
|
|
env: { ...process.env, ...extraEnv },
|
|
stdio: 'inherit',
|
|
})
|
|
}
|