Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions lib/setModel.js → lib/getModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import fs from 'fs'
import path from 'path'

// Ensures only one CDS model compilation is ever in-flight.
// The moment setModel is called, cds.model is set to a promise.
export default async function setModel(projectPath) {
// The moment getModel is called, cds.model is set to a promise.
export default async function getModel(projectPath) {
if (cds.model) {
// If cds.model is a promise, await it; if it's resolved, return it
if (typeof cds.model.then === 'function') await cds.model
return
return cds.model
}
// Assign a promise immediately to cds.model to prevent duplicate compilations
cds.model = (async () => {
Expand All @@ -18,6 +18,7 @@ export default async function setModel(projectPath) {
})()

await cds.model
return cds.model
}

// Loads and compiles the CDS model, returns the compiled model or throws on error
Expand Down Expand Up @@ -112,18 +113,20 @@ let changeWatcher = null
async function cdsFilesChanged(projectPath) {
// Recursively find all .cds files under root, ignoring node_modules
async function findCdsFiles(dir) {
let results = []
const entries = await fs.promises.readdir(dir, { withFileTypes: true })
for (const entry of entries) {
const promises = entries.map(async entry => {
const fullPath = path.join(dir, entry.name)
if (entry.isDirectory()) {
if (entry.name === 'node_modules') continue
results = results.concat(await findCdsFiles(fullPath))
if (entry.name === 'node_modules') return []
return await findCdsFiles(fullPath)
} else if (entry.isFile() && entry.name.endsWith('.cds')) {
results.push(fullPath)
return [fullPath]
} else {
return []
}
}
return results
})
const results = await Promise.all(promises)
return results.flat()
}

if (projectPath.endsWith('/')) projectPath = projectPath.slice(0, -1)
Expand Down
10 changes: 5 additions & 5 deletions lib/tools.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cds from '@sap/cds'
import { z } from 'zod'
import setModel from './setModel.js'
import getModel from './getModel.js'
import fuzzyTopN from './fuzzyTopN.js'

const tools = {
Expand All @@ -16,16 +16,16 @@ const tools = {
namesOnly: z.boolean().default(false).describe('If true, only return definition names (for overview)')
},
handler: async ({ projectPath, name, kind, topN, namesOnly }) => {
await setModel(projectPath)
const model = await getModel(projectPath)
const defNames = kind
? Object.entries(cds.model.definitions)
? Object.entries(model.definitions)
// eslint-disable-next-line no-unused-vars
.filter(([_k, v]) => v.kind === kind)
.map(([k]) => k)
: Object.keys(cds.model.definitions)
: Object.keys(model.definitions)
const scores = name ? fuzzyTopN(name, defNames, topN) : fuzzyTopN('', defNames, topN)
if (namesOnly) return scores.map(s => s.item)
return scores.map(s => cds.model.definitions[s.item])
return scores.map(s => model.definitions[s.item])
}
}
}
Expand Down