(fieldContent: string, toolPrefix?: string)
| 2203 | } |
| 2204 | |
| 2205 | function parseFieldContent(fieldContent: string, toolPrefix?: string): any { |
| 2206 | // Only match `type:` that is at the top level of fieldContent (depth 0). |
| 2207 | // Child objects like `title: { type: 'string', ... }` also contain `type:` but at depth 1. |
| 2208 | const typeRegex = /type\s*:\s*['"]([^'"]+)['"]/g |
| 2209 | let typeMatch: RegExpExecArray | null = null |
| 2210 | let m: RegExpExecArray | null |
| 2211 | while ((m = typeRegex.exec(fieldContent)) !== null) { |
| 2212 | if (isAtDepthZero(fieldContent, m.index)) { |
| 2213 | typeMatch = m |
| 2214 | break |
| 2215 | } |
| 2216 | } |
| 2217 | const description = extractDescription(fieldContent) |
| 2218 | |
| 2219 | // Check for spread operator at the start of field content (e.g., ...SUBSCRIPTION_OUTPUT) |
| 2220 | // This pattern is used when a field spreads a complete output definition and optionally overrides properties |
| 2221 | const spreadMatch = fieldContent.match(/^\s*\.\.\.([A-Z][A-Z_0-9]+)\s*,/) |
| 2222 | if (spreadMatch && toolPrefix && !typeMatch) { |
| 2223 | const constName = spreadMatch[1] |
| 2224 | const resolvedConst = resolveConstReference(constName, toolPrefix) |
| 2225 | if (resolvedConst && typeof resolvedConst === 'object') { |
| 2226 | // Start with the resolved const and override with inline properties |
| 2227 | const result: any = { ...resolvedConst } |
| 2228 | // Override description if provided inline |
| 2229 | if (description) { |
| 2230 | result.description = description |
| 2231 | } |
| 2232 | return result |
| 2233 | } |
| 2234 | } |
| 2235 | |
| 2236 | if (!typeMatch) { |
| 2237 | // No top-level `type` key — check if the content contains named child fields that each |
| 2238 | // have their own `type` property. This is the "implicit object" pattern used in trigger |
| 2239 | // outputs (e.g., Cal.com's `payload`, Linear's `data`). |
| 2240 | const properties = parsePropertiesContent(fieldContent, toolPrefix) |
| 2241 | if (Object.keys(properties).length > 0) { |
| 2242 | return { |
| 2243 | type: 'object', |
| 2244 | description: description || '', |
| 2245 | properties, |
| 2246 | } |
| 2247 | } |
| 2248 | return null |
| 2249 | } |
| 2250 | |
| 2251 | const fieldType = typeMatch[1] |
| 2252 | |
| 2253 | const result: any = { |
| 2254 | type: fieldType, |
| 2255 | description: description || '', |
| 2256 | } |
| 2257 | |
| 2258 | if (fieldType === 'object' || fieldType === 'json') { |
| 2259 | // Check for const reference first (e.g., properties: SCHEDULE_DATA_OUTPUT_PROPERTIES) |
| 2260 | const propsConstMatch = fieldContent.match(/properties\s*:\s*([A-Z][A-Z_0-9]+)/) |
| 2261 | if (propsConstMatch && toolPrefix) { |
| 2262 | const resolvedProps = resolveConstReference(propsConstMatch[1], toolPrefix) |
no test coverage detected