diff --git a/apps/docs/content/docs/en/integrations/gong.mdx b/apps/docs/content/docs/en/integrations/gong.mdx index fd259ebd4fb..1404409ef05 100644 --- a/apps/docs/content/docs/en/integrations/gong.mdx +++ b/apps/docs/content/docs/en/integrations/gong.mdx @@ -247,6 +247,7 @@ Retrieve detailed call data including trackers, topics, highlights, and AI spotl | ↳ `section` | string | Outline section name | | ↳ `startTime` | number | Section start in seconds from call start | | ↳ `duration` | number | Section duration in seconds | +| ↳ `items` | array | Bullet items within the section | | ↳ `keyPoints` | array | AI-generated key points of the call | | ↳ `text` | string | Key point text | | ↳ `callOutcome` | object | AI-determined call outcome \(Call Spotlight\) | @@ -273,6 +274,9 @@ Retrieve detailed call data including trackers, topics, highlights, and AI spotl | ↳ `occurrences` | array | Details per occurrence | | ↳ `highlights` | array | AI-generated highlights including next steps, action items, and key moments | | ↳ `title` | string | Title of the highlight | +| ↳ `items` | array | Individual highlight items | +| ↳ `text` | string | Text of the highlight item | +| ↳ `startTimes` | array | Start times in seconds from call start | | ↳ `interaction` | object | Interaction statistics | | ↳ `interactionStats` | array | Interaction stat measurements \(Longest Monologue, Interactivity, Patience, etc.\) | | ↳ `name` | string | Stat name | diff --git a/apps/docs/content/docs/en/integrations/google_forms.mdx b/apps/docs/content/docs/en/integrations/google_forms.mdx index 048f339ed8f..f92423bfabc 100644 --- a/apps/docs/content/docs/en/integrations/google_forms.mdx +++ b/apps/docs/content/docs/en/integrations/google_forms.mdx @@ -146,6 +146,16 @@ Apply multiple updates to a form (add items, update info, change settings, etc.) | ↳ `quizSettings` | object | Quiz settings | | ↳ `isQuiz` | boolean | Whether the form is a quiz | | ↳ `emailCollectionType` | string | Email collection type | +| ↳ `items` | array | The form items \(questions, sections, etc.\) | +| ↳ `itemId` | string | Item ID | +| ↳ `title` | string | Item title | +| ↳ `description` | string | Item description | +| ↳ `questionItem` | json | Question item configuration | +| ↳ `questionGroupItem` | json | Question group configuration | +| ↳ `pageBreakItem` | json | Page break configuration | +| ↳ `textItem` | json | Text item configuration | +| ↳ `imageItem` | json | Image item configuration | +| ↳ `videoItem` | json | Video item configuration | | ↳ `revisionId` | string | The revision ID of the form | | ↳ `responderUri` | string | The URI to share with responders | | ↳ `linkedSheetId` | string | The ID of the linked Google Sheet | diff --git a/apps/docs/content/docs/en/integrations/onepassword.mdx b/apps/docs/content/docs/en/integrations/onepassword.mdx index 48f4c3ab250..e6b5ee5fda3 100644 --- a/apps/docs/content/docs/en/integrations/onepassword.mdx +++ b/apps/docs/content/docs/en/integrations/onepassword.mdx @@ -59,6 +59,7 @@ List all vaults accessible by the Connect token or Service Account | ↳ `description` | string | Vault description | | ↳ `attributeVersion` | number | Vault attribute version | | ↳ `contentVersion` | number | Vault content version | +| ↳ `items` | number | Number of items in the vault | | ↳ `type` | string | Vault type \(USER_CREATED, PERSONAL, or EVERYONE\) | | ↳ `createdAt` | string | Creation timestamp | | ↳ `updatedAt` | string | Last update timestamp | diff --git a/apps/docs/content/docs/en/integrations/sap_concur.mdx b/apps/docs/content/docs/en/integrations/sap_concur.mdx index d9a76371e63..8d45db8825b 100644 --- a/apps/docs/content/docs/en/integrations/sap_concur.mdx +++ b/apps/docs/content/docs/en/integrations/sap_concur.mdx @@ -1479,6 +1479,7 @@ List allocations on an expense (GET /expensereports/v4/users/\{userId\}/context/ | --------- | ---- | ----------- | | `status` | number | HTTP status code returned by Concur | | `data` | json | Allocations list payload | +| ↳ `items` | array | Array of allocation objects \(allocationId, accountCode, percentage, allocationAmount, approvedAmount, claimedAmount, customData, expenseId, isSystemAllocation, isPercentEdited, overLimitAccountCode\) | ### SAP Concur List Attendee Associations @@ -1547,6 +1548,12 @@ List budget categories (GET /budget/v4/budgetCategory). | --------- | ---- | ----------- | | `status` | number | HTTP status code returned by Concur | | `data` | json | Budget categories collection payload | +| ↳ `items` | array | Array of budget category objects | +| ↳ `id` | string | Category ID | +| ↳ `name` | string | Admin-facing category name | +| ↳ `description` | string | Friendly name | +| ↳ `statusType` | string | Status: OPEN or REMOVED | +| ↳ `expenseTypes` | array | Expense types in this category \(id, featureTypeCode, expenseTypeCode, name\) | ### SAP Concur List Budgets @@ -1573,6 +1580,7 @@ List budget item headers (GET /budget/v4/budgetItemHeader). | --------- | ---- | ----------- | | `status` | number | HTTP status code returned by Concur | | `data` | json | Budget headers collection payload | +| ↳ `items` | array | Array of budget item header summaries \(id, name, description, budgetItemStatusType, budgetType, currencyCode, fiscalYear, budgetAmounts, owner, ...\) | | ↳ `offset` | number | Page offset | | ↳ `limit` | number | Page size | | ↳ `totalCount` | number | Total result count | diff --git a/apps/docs/content/docs/en/integrations/sharepoint.mdx b/apps/docs/content/docs/en/integrations/sharepoint.mdx index 1ef3f2e74ab..a2014e1e1d2 100644 --- a/apps/docs/content/docs/en/integrations/sharepoint.mdx +++ b/apps/docs/content/docs/en/integrations/sharepoint.mdx @@ -267,6 +267,9 @@ Get metadata (and optionally columns/items) for a SharePoint list | ↳ `lastModifiedDateTime` | string | When the list was last modified | | ↳ `list` | object | List properties \(e.g., template\) | | ↳ `columns` | array | List column definitions | +| ↳ `items` | array | List items \(with fields when expanded\) | +| ↳ `id` | string | Item ID | +| ↳ `fields` | object | Field values for the item | | `lists` | array | All lists in the site when no listId/title provided | | `items` | array | List items with expanded fields when reading list items | | ↳ `id` | string | Item ID | diff --git a/apps/docs/content/docs/en/integrations/stripe.mdx b/apps/docs/content/docs/en/integrations/stripe.mdx index 87d35f3db4a..f9b6eebb366 100644 --- a/apps/docs/content/docs/en/integrations/stripe.mdx +++ b/apps/docs/content/docs/en/integrations/stripe.mdx @@ -961,6 +961,20 @@ Create a new subscription for a customer | ↳ `description` | string | Subscription description \(max 500 characters\) | | ↳ `discount` | json | Discount that applies to the subscription | | ↳ `ended_at` | number | Unix timestamp when the subscription ended | +| ↳ `items` | object | List of subscription items | +| ↳ `object` | string | String representing the object type \(list\) | +| ↳ `data` | array | Array of subscription items | +| ↳ `id` | string | Unique identifier for the subscription item | +| ↳ `object` | string | String representing the object type \(subscription_item\) | +| ↳ `billing_thresholds` | json | Billing thresholds for the subscription item | +| ↳ `created` | number | Unix timestamp when the item was added | +| ↳ `metadata` | json | Set of key-value pairs for storing additional information | +| ↳ `price` | json | Price object for this subscription item | +| ↳ `quantity` | number | Quantity of the plan to subscribe to | +| ↳ `subscription` | string | ID of the subscription this item belongs to | +| ↳ `tax_rates` | array | Tax rates applied to this subscription item | +| ↳ `has_more` | boolean | Whether there are more items | +| ↳ `url` | string | URL to fetch more items | | ↳ `latest_invoice` | string | ID of the most recent invoice | | ↳ `livemode` | boolean | Whether object exists in live mode or test mode | | ↳ `metadata` | json | Set of key-value pairs for storing additional information | @@ -1024,6 +1038,20 @@ Retrieve an existing subscription by ID | ↳ `description` | string | Subscription description \(max 500 characters\) | | ↳ `discount` | json | Discount that applies to the subscription | | ↳ `ended_at` | number | Unix timestamp when the subscription ended | +| ↳ `items` | object | List of subscription items | +| ↳ `object` | string | String representing the object type \(list\) | +| ↳ `data` | array | Array of subscription items | +| ↳ `id` | string | Unique identifier for the subscription item | +| ↳ `object` | string | String representing the object type \(subscription_item\) | +| ↳ `billing_thresholds` | json | Billing thresholds for the subscription item | +| ↳ `created` | number | Unix timestamp when the item was added | +| ↳ `metadata` | json | Set of key-value pairs for storing additional information | +| ↳ `price` | json | Price object for this subscription item | +| ↳ `quantity` | number | Quantity of the plan to subscribe to | +| ↳ `subscription` | string | ID of the subscription this item belongs to | +| ↳ `tax_rates` | array | Tax rates applied to this subscription item | +| ↳ `has_more` | boolean | Whether there are more items | +| ↳ `url` | string | URL to fetch more items | | ↳ `latest_invoice` | string | ID of the most recent invoice | | ↳ `livemode` | boolean | Whether object exists in live mode or test mode | | ↳ `metadata` | json | Set of key-value pairs for storing additional information | @@ -1090,6 +1118,20 @@ Update an existing subscription | ↳ `description` | string | Subscription description \(max 500 characters\) | | ↳ `discount` | json | Discount that applies to the subscription | | ↳ `ended_at` | number | Unix timestamp when the subscription ended | +| ↳ `items` | object | List of subscription items | +| ↳ `object` | string | String representing the object type \(list\) | +| ↳ `data` | array | Array of subscription items | +| ↳ `id` | string | Unique identifier for the subscription item | +| ↳ `object` | string | String representing the object type \(subscription_item\) | +| ↳ `billing_thresholds` | json | Billing thresholds for the subscription item | +| ↳ `created` | number | Unix timestamp when the item was added | +| ↳ `metadata` | json | Set of key-value pairs for storing additional information | +| ↳ `price` | json | Price object for this subscription item | +| ↳ `quantity` | number | Quantity of the plan to subscribe to | +| ↳ `subscription` | string | ID of the subscription this item belongs to | +| ↳ `tax_rates` | array | Tax rates applied to this subscription item | +| ↳ `has_more` | boolean | Whether there are more items | +| ↳ `url` | string | URL to fetch more items | | ↳ `latest_invoice` | string | ID of the most recent invoice | | ↳ `livemode` | boolean | Whether object exists in live mode or test mode | | ↳ `metadata` | json | Set of key-value pairs for storing additional information | @@ -1155,6 +1197,20 @@ Cancel a subscription | ↳ `description` | string | Subscription description \(max 500 characters\) | | ↳ `discount` | json | Discount that applies to the subscription | | ↳ `ended_at` | number | Unix timestamp when the subscription ended | +| ↳ `items` | object | List of subscription items | +| ↳ `object` | string | String representing the object type \(list\) | +| ↳ `data` | array | Array of subscription items | +| ↳ `id` | string | Unique identifier for the subscription item | +| ↳ `object` | string | String representing the object type \(subscription_item\) | +| ↳ `billing_thresholds` | json | Billing thresholds for the subscription item | +| ↳ `created` | number | Unix timestamp when the item was added | +| ↳ `metadata` | json | Set of key-value pairs for storing additional information | +| ↳ `price` | json | Price object for this subscription item | +| ↳ `quantity` | number | Quantity of the plan to subscribe to | +| ↳ `subscription` | string | ID of the subscription this item belongs to | +| ↳ `tax_rates` | array | Tax rates applied to this subscription item | +| ↳ `has_more` | boolean | Whether there are more items | +| ↳ `url` | string | URL to fetch more items | | ↳ `latest_invoice` | string | ID of the most recent invoice | | ↳ `livemode` | boolean | Whether object exists in live mode or test mode | | ↳ `metadata` | json | Set of key-value pairs for storing additional information | @@ -1218,6 +1274,20 @@ Resume a subscription that was scheduled for cancellation | ↳ `description` | string | Subscription description \(max 500 characters\) | | ↳ `discount` | json | Discount that applies to the subscription | | ↳ `ended_at` | number | Unix timestamp when the subscription ended | +| ↳ `items` | object | List of subscription items | +| ↳ `object` | string | String representing the object type \(list\) | +| ↳ `data` | array | Array of subscription items | +| ↳ `id` | string | Unique identifier for the subscription item | +| ↳ `object` | string | String representing the object type \(subscription_item\) | +| ↳ `billing_thresholds` | json | Billing thresholds for the subscription item | +| ↳ `created` | number | Unix timestamp when the item was added | +| ↳ `metadata` | json | Set of key-value pairs for storing additional information | +| ↳ `price` | json | Price object for this subscription item | +| ↳ `quantity` | number | Quantity of the plan to subscribe to | +| ↳ `subscription` | string | ID of the subscription this item belongs to | +| ↳ `tax_rates` | array | Tax rates applied to this subscription item | +| ↳ `has_more` | boolean | Whether there are more items | +| ↳ `url` | string | URL to fetch more items | | ↳ `latest_invoice` | string | ID of the most recent invoice | | ↳ `livemode` | boolean | Whether object exists in live mode or test mode | | ↳ `metadata` | json | Set of key-value pairs for storing additional information | @@ -1284,6 +1354,20 @@ List all subscriptions | ↳ `description` | string | Subscription description \(max 500 characters\) | | ↳ `discount` | json | Discount that applies to the subscription | | ↳ `ended_at` | number | Unix timestamp when the subscription ended | +| ↳ `items` | object | List of subscription items | +| ↳ `object` | string | String representing the object type \(list\) | +| ↳ `data` | array | Array of subscription items | +| ↳ `id` | string | Unique identifier for the subscription item | +| ↳ `object` | string | String representing the object type \(subscription_item\) | +| ↳ `billing_thresholds` | json | Billing thresholds for the subscription item | +| ↳ `created` | number | Unix timestamp when the item was added | +| ↳ `metadata` | json | Set of key-value pairs for storing additional information | +| ↳ `price` | json | Price object for this subscription item | +| ↳ `quantity` | number | Quantity of the plan to subscribe to | +| ↳ `subscription` | string | ID of the subscription this item belongs to | +| ↳ `tax_rates` | array | Tax rates applied to this subscription item | +| ↳ `has_more` | boolean | Whether there are more items | +| ↳ `url` | string | URL to fetch more items | | ↳ `latest_invoice` | string | ID of the most recent invoice | | ↳ `livemode` | boolean | Whether object exists in live mode or test mode | | ↳ `metadata` | json | Set of key-value pairs for storing additional information | @@ -1347,6 +1431,20 @@ Search for subscriptions using query syntax | ↳ `description` | string | Subscription description \(max 500 characters\) | | ↳ `discount` | json | Discount that applies to the subscription | | ↳ `ended_at` | number | Unix timestamp when the subscription ended | +| ↳ `items` | object | List of subscription items | +| ↳ `object` | string | String representing the object type \(list\) | +| ↳ `data` | array | Array of subscription items | +| ↳ `id` | string | Unique identifier for the subscription item | +| ↳ `object` | string | String representing the object type \(subscription_item\) | +| ↳ `billing_thresholds` | json | Billing thresholds for the subscription item | +| ↳ `created` | number | Unix timestamp when the item was added | +| ↳ `metadata` | json | Set of key-value pairs for storing additional information | +| ↳ `price` | json | Price object for this subscription item | +| ↳ `quantity` | number | Quantity of the plan to subscribe to | +| ↳ `subscription` | string | ID of the subscription this item belongs to | +| ↳ `tax_rates` | array | Tax rates applied to this subscription item | +| ↳ `has_more` | boolean | Whether there are more items | +| ↳ `url` | string | URL to fetch more items | | ↳ `latest_invoice` | string | ID of the most recent invoice | | ↳ `livemode` | boolean | Whether object exists in live mode or test mode | | ↳ `metadata` | json | Set of key-value pairs for storing additional information | diff --git a/scripts/generate-docs.test.ts b/scripts/generate-docs.test.ts new file mode 100644 index 00000000000..c449320db82 --- /dev/null +++ b/scripts/generate-docs.test.ts @@ -0,0 +1,79 @@ +import { describe, expect, it } from 'vitest' +import { parseConstProperties, parsePropertiesContent } from './generate-docs' + +describe('documentation output property parsing', () => { + it('keeps a response field named items inside an array element', () => { + const properties = parsePropertiesContent(` + vaults: { + type: 'array', + description: 'List of accessible vaults', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Vault ID' }, + items: { type: 'number', description: 'Number of items in the vault' }, + }, + }, + }, + `) + + expect(Object.keys(properties)).toEqual(['vaults']) + expect(properties.vaults.items.properties.items).toEqual({ + type: 'number', + description: 'Number of items in the vault', + }) + }) + + it('keeps a response field named items that directly references a constant', () => { + const properties = parsePropertiesContent('items: ATTENDEES_OUTPUT,', 'calcom') + + expect(properties.items).toMatchObject({ + type: 'array', + description: 'List of attendees', + }) + }) + + it('keeps a response field named items that references a constant property', () => { + const properties = parsePropertiesContent('items: EVENT_TYPE_OUTPUT_PROPERTIES.id,', 'calcom') + + expect(properties.items).toEqual({ + type: 'number', + description: 'Event type ID', + }) + }) + + it('keeps items fields in constant-defined property maps', () => { + const typesContent = ` + export const RECORD_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Record ID' }, + } + ` + const properties = parseConstProperties( + ` + items: { + type: 'object', + description: 'Result page', + properties: { + object: { type: 'string', description: 'Page type' }, + data: { + type: 'array', + description: 'Result records', + items: { type: 'object', properties: RECORD_OUTPUT_PROPERTIES }, + }, + hasMore: { type: 'boolean', description: 'Whether more results exist' }, + }, + }, + `, + 'test', + typesContent, + 0 + ) + + expect(Object.keys(properties)).toEqual(['items']) + expect(Object.keys(properties.items.properties)).toEqual(['object', 'data', 'hasMore']) + expect(properties.items.properties.data.items.properties.id).toEqual({ + type: 'string', + description: 'Record ID', + }) + }) +}) diff --git a/scripts/generate-docs.ts b/scripts/generate-docs.ts index c3e3da3089c..12af628583c 100755 --- a/scripts/generate-docs.ts +++ b/scripts/generate-docs.ts @@ -7,8 +7,6 @@ import { glob } from 'glob' import type { BlockCategory } from '../apps/sim/blocks/types' import { IntegrationType } from '../apps/sim/blocks/types' -console.log('Starting documentation generator...') - /** * Cache for resolved const definitions from types files. * Key: "toolPrefix:constName" (e.g., "calcom:SCHEDULE_DATA_OUTPUT_PROPERTIES") @@ -1671,7 +1669,7 @@ function resolveConstReference( /** * Parse properties from a const definition, resolving nested const references. */ -function parseConstProperties( +export function parseConstProperties( content: string, toolPrefix: string, typesContent: string, @@ -1705,10 +1703,6 @@ function parseConstProperties( const propName = match[1] const constRef = match[2] - if (propName === 'items') { - continue - } - const beforeMatch = content.substring(0, match.index) const openBraces = (beforeMatch.match(/\{/g) || []).length const closeBraces = (beforeMatch.match(/\}/g) || []).length @@ -1725,7 +1719,13 @@ function parseConstProperties( const propContent = content.substring(startPos + 1, endPos - 1).trim() // If it starts with 'type:', it's an output field definition - process it if (propContent.match(/^\s*type\s*:/)) { - const parsedProp = parseConstFieldContent(propContent, toolPrefix, typesContent, depth) + const parsedProp = parseConstFieldContent( + propContent, + toolPrefix, + typesContent, + depth, + propName + ) if (parsedProp) { properties[propName] = parsedProp } @@ -1747,7 +1747,13 @@ function parseConstProperties( if (endPos !== -1) { const propContent = content.substring(startPos + 1, endPos - 1).trim() - const parsedProp = parseConstFieldContent(propContent, toolPrefix, typesContent, depth) + const parsedProp = parseConstFieldContent( + propContent, + toolPrefix, + typesContent, + depth, + propName + ) if (parsedProp) { properties[propName] = parsedProp } @@ -1830,7 +1836,8 @@ function parseConstFieldContent( fieldContent: string, toolPrefix: string, typesContent: string, - depth: number + depth: number, + propertyName?: string ): any { const typeMatch = fieldContent.match(/type\s*:\s*['"]([^'"]+)['"]/) const description = extractDescription(fieldContent) @@ -1845,7 +1852,7 @@ function parseConstFieldContent( } if (fieldType === 'object' || fieldType === 'json') { - const propsConstMatch = fieldContent.match(/properties\s*:\s*([A-Z][A-Z_0-9]+)/) + const propsConstMatch = matchSchemaKeyword(fieldContent, propertyName, PROPERTIES_CONST_PATTERN) if (propsConstMatch) { const resolvedProps = resolveConstFromTypesContent( propsConstMatch[1], @@ -1857,7 +1864,11 @@ function parseConstFieldContent( result.properties = resolvedProps } } else { - const propertiesStart = fieldContent.search(/properties\s*:\s*\{/) + const propertiesStart = findSchemaKeyword( + fieldContent, + propertyName, + PROPERTIES_INLINE_PATTERN + ) if (propertiesStart !== -1) { const braceStart = fieldContent.indexOf('{', propertiesStart) const braceEnd = findMatchingClose(fieldContent, braceStart) @@ -1875,7 +1886,7 @@ function parseConstFieldContent( } } - const itemsConstMatch = fieldContent.match(/items\s*:\s*([A-Z][A-Z_0-9]+)/) + const itemsConstMatch = matchSchemaKeyword(fieldContent, propertyName, ITEMS_CONST_PATTERN) if (itemsConstMatch) { const resolvedItems = resolveConstFromTypesContent( itemsConstMatch[1], @@ -1887,7 +1898,7 @@ function parseConstFieldContent( result.items = resolvedItems } } else { - const itemsStart = fieldContent.search(/items\s*:\s*\{/) + const itemsStart = findSchemaKeyword(fieldContent, propertyName, ITEMS_INLINE_PATTERN) if (itemsStart !== -1) { const braceStart = fieldContent.indexOf('{', itemsStart) const braceEnd = findMatchingClose(fieldContent, braceStart) @@ -2438,7 +2449,44 @@ function isAtDepthZero(content: string, matchIndex: number): boolean { return depth === 0 } -function parseFieldContent(fieldContent: string, toolPrefix?: string): any { +function findTopLevelMatch(content: string, pattern: RegExp): RegExpExecArray | null { + const flags = pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g` + const regex = new RegExp(pattern.source, flags) + let match: RegExpExecArray | null + + while ((match = regex.exec(content)) !== null) { + if (isAtDepthZero(content, match.index)) { + return match + } + } + + return null +} + +const PROPERTIES_CONST_PATTERN = /properties\s*:\s*([A-Z][A-Z_0-9]+)/ +const PROPERTIES_INLINE_PATTERN = /properties\s*:\s*{/ +const ITEMS_CONST_PATTERN = /items\s*:\s*([A-Z][A-Z_0-9]+)/ +const ITEMS_INLINE_PATTERN = /items\s*:\s*{/ + +function matchSchemaKeyword( + content: string, + propertyName: string | undefined, + pattern: RegExp +): RegExpExecArray | null { + return propertyName === 'items' ? findTopLevelMatch(content, pattern) : content.match(pattern) +} + +function findSchemaKeyword( + content: string, + propertyName: string | undefined, + pattern: RegExp +): number { + return propertyName === 'items' + ? (findTopLevelMatch(content, pattern)?.index ?? -1) + : content.search(pattern) +} + +function parseFieldContent(fieldContent: string, toolPrefix?: string, propertyName?: string): any { // Only match `type:` that is at the top level of fieldContent (depth 0). // Child objects like `title: { type: 'string', ... }` also contain `type:` but at depth 1. const typeRegex = /type\s*:\s*['"]([^'"]+)['"]/g @@ -2492,15 +2540,18 @@ function parseFieldContent(fieldContent: string, toolPrefix?: string): any { if (fieldType === 'object' || fieldType === 'json') { // Check for const reference first (e.g., properties: SCHEDULE_DATA_OUTPUT_PROPERTIES) - const propsConstMatch = fieldContent.match(/properties\s*:\s*([A-Z][A-Z_0-9]+)/) + const propsConstMatch = matchSchemaKeyword(fieldContent, propertyName, PROPERTIES_CONST_PATTERN) if (propsConstMatch && toolPrefix) { const resolvedProps = resolveConstReference(propsConstMatch[1], toolPrefix) if (resolvedProps) { result.properties = resolvedProps } } else { - const propertiesRegex = /properties\s*:\s*{/ - const propertiesStart = fieldContent.search(propertiesRegex) + const propertiesStart = findSchemaKeyword( + fieldContent, + propertyName, + PROPERTIES_INLINE_PATTERN + ) if (propertiesStart !== -1) { const braceStart = fieldContent.indexOf('{', propertiesStart) @@ -2515,15 +2566,14 @@ function parseFieldContent(fieldContent: string, toolPrefix?: string): any { } // Check for items const reference (e.g., items: ATTENDEES_OUTPUT) - const itemsConstMatch = fieldContent.match(/items\s*:\s*([A-Z][A-Z_0-9]+)/) + const itemsConstMatch = matchSchemaKeyword(fieldContent, propertyName, ITEMS_CONST_PATTERN) if (itemsConstMatch && toolPrefix) { const resolvedItems = resolveConstReference(itemsConstMatch[1], toolPrefix) if (resolvedItems) { result.items = resolvedItems } } else { - const itemsRegex = /items\s*:\s*{/ - const itemsStart = fieldContent.search(itemsRegex) + const itemsStart = findSchemaKeyword(fieldContent, propertyName, ITEMS_INLINE_PATTERN) if (itemsStart !== -1) { const braceStart = fieldContent.indexOf('{', itemsStart) @@ -2586,7 +2636,7 @@ function parseFieldContent(fieldContent: string, toolPrefix?: string): any { return result } -function parsePropertiesContent( +export function parsePropertiesContent( propertiesContent: string, toolPrefix?: string ): Record { @@ -2602,7 +2652,7 @@ function parsePropertiesContent( const propName = constMatch[1] const constName = constMatch[2] - if (propName === 'items' || propName === 'properties' || propName === 'type') { + if (propName === 'properties' || propName === 'type') { continue } @@ -2627,7 +2677,7 @@ function parsePropertiesContent( const constName = propAccessMatch[2] const accessedProp = propAccessMatch[3] - if (propName === 'items' || propName === 'properties' || propName === 'type') { + if (propName === 'properties' || propName === 'type') { continue } @@ -2675,7 +2725,7 @@ function parsePropertiesContent( while ((match = propStartRegex.exec(propertiesContent)) !== null) { const propName = match[1] - if (propName === 'items' || propName === 'properties') { + if (propName === 'properties') { continue } @@ -2719,7 +2769,7 @@ function parsePropertiesContent( } propPositions.forEach((prop) => { - const parsedProp = parseFieldContent(prop.content, toolPrefix) + const parsedProp = parseFieldContent(prop.content, toolPrefix, prop.name) if (parsedProp) { properties[prop.name] = parsedProp } @@ -3855,17 +3905,20 @@ function updateMetaJson() { console.log(`Updated meta.json with ${items.length} entries`) } -generateAllBlockDocs() - .then((success) => { - if (success) { - console.log('Documentation generation completed successfully') - process.exit(0) - } else { - console.error('Documentation generation failed') +if (import.meta.main) { + console.log('Starting documentation generator...') + generateAllBlockDocs() + .then((success) => { + if (success) { + console.log('Documentation generation completed successfully') + process.exit(0) + } else { + console.error('Documentation generation failed') + process.exit(1) + } + }) + .catch((error) => { + console.error('Fatal error:', error) process.exit(1) - } - }) - .catch((error) => { - console.error('Fatal error:', error) - process.exit(1) - }) + }) +}