Skip to content

Commit 32d4bc3

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(docs): cover shared items output parsing
1 parent d495994 commit 32d4bc3

4 files changed

Lines changed: 116 additions & 18 deletions

File tree

apps/docs/content/docs/en/integrations/netsuite.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
2727
- Record fields and supported actions vary by account, enabled features, custom records, forms, role, and permissions. Use **List Record Types** and **Get Record Metadata** before constructing create, update, upsert, action, or transform bodies. Sim intentionally accepts JSON for these dynamic record shapes instead of guessing a fixed schema.
2828
- Paged operations return one page only. The default limit is 100, the maximum is 1,000, and the offset must be a non-negative multiple of the limit. Sim never fetches later pages automatically. NetSuite limits ordinary collection traversal to 1,000 pages and SuiteQL queries to 100,000 results.
2929
- Homogeneous batch operations accept 1–100 records of one record type and always run asynchronously. Preserve the returned `location` or `jobId`, use **Get Async Task Status** with **List Tasks** to collect task IDs, check each ID with **Task Status**, then use completed IDs with **Get Async Operation Result**.
30+
- Sim limits each materialized request body and successful SuiteTalk response to 16 MiB. Split work into smaller pages or batches when a request or response would exceed that ceiling, even if NetSuite would otherwise accept the payload.
3031
- When attaching a contact with a role, provide either the role's internal ID or external ID, not both. File attachments do not use a contact role.
3132
- **Attach/Detach**, homogeneous batch operations, **Get Record Form**, and **Get Select Options** require a NetSuite 2026.1-compatible account. Oracle introduced these SuiteTalk REST capabilities in [NetSuite 2026.1](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_N3950559.html).
3233
- **Get Governance Limits** returns data only for roles allowed by NetSuite; Oracle documents Administrator access for that operation.

apps/sim/tools/netsuite/netsuite.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ const ASYNC_RESULT_SOURCE =
140140
'https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/subsect_161252889998.html'
141141

142142
/**
143-
* Executable Oracle source matrix. Besides documenting each contract, this table drives the
144-
* method/path/query/header/body/status tests below so implementation and citations cannot drift.
143+
* Executable Oracle source matrix. This table centralizes the reviewed documentation links and
144+
* drives the method/path/query/header/body/status tests below. The links are review evidence, not
145+
* live assertions against Oracle's documentation.
145146
*/
146147
const SOURCE_MATRIX: SourceMatrixEntry[] = [
147148
{

scripts/generate-docs.test.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { parsePropertiesContent } from './generate-docs'
3+
4+
describe('documentation output-property parsing', () => {
5+
it('retains representative non-NetSuite response properties named items', () => {
6+
const googleFormsProperties = parsePropertiesContent(`
7+
formId: {
8+
type: 'string',
9+
description: 'The form identifier',
10+
},
11+
items: {
12+
type: 'array',
13+
description: 'The form items',
14+
items: {
15+
type: 'object',
16+
properties: {
17+
itemId: {
18+
type: 'string',
19+
description: 'The item identifier',
20+
},
21+
},
22+
},
23+
},
24+
`)
25+
const onePasswordProperties = parsePropertiesContent(`
26+
id: {
27+
type: 'string',
28+
description: 'The vault identifier',
29+
},
30+
items: {
31+
type: 'number',
32+
description: 'The number of items in the vault',
33+
},
34+
`)
35+
36+
expect(googleFormsProperties.items).toMatchObject({
37+
type: 'array',
38+
description: 'The form items',
39+
items: {
40+
type: 'object',
41+
properties: {
42+
itemId: {
43+
type: 'string',
44+
description: 'The item identifier',
45+
},
46+
},
47+
},
48+
})
49+
expect(onePasswordProperties.items).toEqual({
50+
type: 'number',
51+
description: 'The number of items in the vault',
52+
})
53+
})
54+
55+
it('does not promote nested array-schema items to response properties', () => {
56+
const gongProperties = parsePropertiesContent(`
57+
outline: {
58+
type: 'array',
59+
description: 'The call outline',
60+
items: {
61+
type: 'object',
62+
properties: {
63+
section: {
64+
type: 'string',
65+
description: 'The outline section',
66+
},
67+
items: {
68+
type: 'array',
69+
description: 'The section items',
70+
items: {
71+
type: 'string',
72+
description: 'An outline item',
73+
},
74+
},
75+
},
76+
},
77+
},
78+
`)
79+
80+
expect(Object.keys(gongProperties)).toEqual(['outline'])
81+
expect(gongProperties.outline.items.properties.items).toMatchObject({
82+
type: 'array',
83+
description: 'The section items',
84+
items: {
85+
type: 'string',
86+
description: 'An outline item',
87+
},
88+
})
89+
})
90+
})

scripts/generate-docs.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import { glob } from 'glob'
77
import type { BlockCategory } from '../apps/sim/blocks/types'
88
import { IntegrationType } from '../apps/sim/blocks/types'
99

10-
console.log('Starting documentation generator...')
11-
1210
/**
1311
* Cache for resolved const definitions from types files.
1412
* Key: "toolPrefix:constName" (e.g., "calcom:SCHEDULE_DATA_OUTPUT_PROPERTIES")
@@ -2586,7 +2584,12 @@ function parseFieldContent(fieldContent: string, toolPrefix?: string): any {
25862584
return result
25872585
}
25882586

2589-
function parsePropertiesContent(
2587+
/**
2588+
* Parses the properties of an inline tool output schema.
2589+
*
2590+
* Exported so parser behavior can be tested without generating documentation.
2591+
*/
2592+
export function parsePropertiesContent(
25902593
propertiesContent: string,
25912594
toolPrefix?: string
25922595
): Record<string, any> {
@@ -3857,17 +3860,20 @@ function updateMetaJson() {
38573860
console.log(`Updated meta.json with ${items.length} entries`)
38583861
}
38593862

3860-
generateAllBlockDocs()
3861-
.then((success) => {
3862-
if (success) {
3863-
console.log('Documentation generation completed successfully')
3864-
process.exit(0)
3865-
} else {
3866-
console.error('Documentation generation failed')
3863+
if (import.meta.main) {
3864+
console.log('Starting documentation generator...')
3865+
generateAllBlockDocs()
3866+
.then((success) => {
3867+
if (success) {
3868+
console.log('Documentation generation completed successfully')
3869+
process.exit(0)
3870+
} else {
3871+
console.error('Documentation generation failed')
3872+
process.exit(1)
3873+
}
3874+
})
3875+
.catch((error) => {
3876+
console.error('Fatal error:', error)
38673877
process.exit(1)
3868-
}
3869-
})
3870-
.catch((error) => {
3871-
console.error('Fatal error:', error)
3872-
process.exit(1)
3873-
})
3878+
})
3879+
}

0 commit comments

Comments
 (0)