Conversation
…he actual oas state from Xano)
WalkthroughThis pull request introduces a feature to conditionally include table schemas in OpenAPI specification generation. A new Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/CLI
participant CLI as CLI Command<br/>(generate/index.ts)
participant OasWizard as OAS Wizard<br/>(oas-spec.ts)
participant Core as Core Implementation<br/>(generate-oas.ts)
participant OasGen as OAS Patcher<br/>(patch-oas-spec.ts)
User->>CLI: Execute with --include-tables flag
CLI->>OasWizard: updateOasWizard(opts.includeTables)
OasWizard->>Core: updateOpenapiSpecImplementation({includeTables})
Core->>Core: updateSpecForGroup for each group<br/>(pass includeTables)
Core->>OasGen: patchOasSpec({oas, includeTables})
alt includeTables is true
OasGen->>OasGen: Generate table schemas<br/>tableSchemas = {...}
else includeTables is false
OasGen->>OasGen: Skip table schemas<br/>tableSchemas = {}
end
OasGen->>OasGen: extractTagsToGlobal(paths)<br/>to populate tags array
OasGen->>OasGen: Enhance error schemas with<br/>format and maxLength constraints
OasGen-->>Core: Return updated OAS spec
Core-->>OasWizard: Return generated items
OasWizard-->>CLI: Return OAS output
CLI-->>User: Save OAS spec to disk
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/core/src/features/oas/generate/methods/update-spec-for-group.ts (1)
9-27: Type definition inconsistency.The
includeTablesparameter has a default value on line 15 (includeTables = false) but is typed as required (not optional) on line 23 (includeTables: boolean).For consistency and correctness, it should be marked as optional in the type definition.
Apply this diff to fix the type definition:
async function updateSpecForGroup({ group, instanceConfig, workspaceConfig, storage, core, includeTables = false, }: { group: any; instanceConfig: any; workspaceConfig: any; branchConfig: any; storage: any; core: any; - includeTables: boolean; + includeTables?: boolean; }): Promise<{packages/core/src/features/oas/generate/methods/do-oas-update.ts (1)
14-26: Type definition inconsistency.Similar to
update-spec-for-group.ts, theincludeTablesparameter has a default value on line 19 (includeTables = false) but is typed as required on line 25 (includeTables: boolean).Apply this diff to fix the type definition:
async function doOasUpdate({ inputOas, instanceConfig, workspaceConfig, storage, includeTables = false, }: { inputOas: any; instanceConfig: any; workspaceConfig: any; storage: any; - includeTables: boolean; + includeTables?: boolean; }): Promise<DoOasUpdateOutput> {packages/core/src/features/oas/generate/methods/patch-oas-spec.ts (1)
93-116: Replace non-standardformat: 'const'with theconstkeyword.The
format: 'const'value is not a standard JSON Schema format. JSON Schema Draft 2020-12 (which OpenAPI 3.1 uses) defines standard formats only as:date-time,date,time,duration,idn-email,hostname,idn-hostname,ipv4,ipv6,uri,uri-reference,iri,iri-reference,uri-template,uuid,json-pointer,relative-json-pointer, andregex.To enforce constant string values, use the
constkeyword instead:"code": { "type": "string", "const": "ERROR_CODE_ACCESS_DENIED" }This approach is standard, properly enforces exact value matching, and will be correctly recognized by OpenAPI tooling and validators.
🧹 Nitpick comments (1)
packages/core/src/index.ts (1)
144-164: Update JSDoc to document the newincludeTablesparameter.The
updateOpenapiSpecmethod now accepts an optionalincludeTablesparameter, but the JSDoc block (lines 114-143) doesn't document it. Consider adding:* @param groups - Array of API group names to generate specs for, or ['all'] for all groups + * @param startDir - Starting directory for the operation + * @param includeTables - Whether to include table schemas in the generated OAS (default: false) * @returns Promise resolving to array of generated OAS documents with metadata
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
.changeset/gentle-trees-tan.md(1 hunks).changeset/tangy-windows-taste.md(1 hunks)packages/cli/src/commands/generate/implementation/oas-spec.ts(3 hunks)packages/cli/src/commands/generate/index.ts(2 hunks)packages/core/src/features/oas/generate/methods/do-oas-update.ts(1 hunks)packages/core/src/features/oas/generate/methods/extract-tags-to-global-level.ts(1 hunks)packages/core/src/features/oas/generate/methods/patch-oas-spec.ts(8 hunks)packages/core/src/features/oas/generate/methods/update-spec-for-group.ts(2 hunks)packages/core/src/implementations/generate-oas.ts(2 hunks)packages/core/src/index.ts(4 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
packages/*/src/**/*.ts?(x)
📄 CodeRabbit inference engine (AGENTS.md)
packages/*/src/**/*.ts?(x): Use TypeScript for all source code in the monorepo
Configure and use Eslint and Prettier for linting and formatting with default configs
Files:
packages/cli/src/commands/generate/index.tspackages/core/src/implementations/generate-oas.tspackages/core/src/features/oas/generate/methods/extract-tags-to-global-level.tspackages/core/src/index.tspackages/core/src/features/oas/generate/methods/patch-oas-spec.tspackages/cli/src/commands/generate/implementation/oas-spec.tspackages/core/src/features/oas/generate/methods/do-oas-update.tspackages/core/src/features/oas/generate/methods/update-spec-for-group.ts
packages/cli/src/**/*.ts?(x)
📄 CodeRabbit inference engine (AGENTS.md)
Use Commander.js for CLI command registration and parsing
Files:
packages/cli/src/commands/generate/index.tspackages/cli/src/commands/generate/implementation/oas-spec.ts
**/*.ts?(x)
📄 CodeRabbit inference engine (AGENTS.md)
Use js-yaml for YAML processing
Files:
packages/cli/src/commands/generate/index.tspackages/core/src/implementations/generate-oas.tspackages/core/src/features/oas/generate/methods/extract-tags-to-global-level.tspackages/core/src/index.tspackages/core/src/features/oas/generate/methods/patch-oas-spec.tspackages/cli/src/commands/generate/implementation/oas-spec.tspackages/core/src/features/oas/generate/methods/do-oas-update.tspackages/core/src/features/oas/generate/methods/update-spec-for-group.ts
packages/core/src/index.ts
📄 CodeRabbit inference engine (AGENTS.md)
Core logic entry point is packages/core/src/index.ts
Files:
packages/core/src/index.ts
🧠 Learnings (1)
📚 Learning: 2025-11-28T05:59:33.267Z
Learnt from: CR
Repo: calycode/xano-tools PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T05:59:33.267Z
Learning: Organize code into logical package separation: calycode/cli, calycode/core, calycode/types, and calycode/utils
Applied to files:
.changeset/tangy-windows-taste.md
🧬 Code graph analysis (4)
packages/cli/src/commands/generate/index.ts (1)
packages/cli/src/utils/commands/option-sets.ts (1)
addPrintOutputFlag(49-51)
packages/core/src/index.ts (1)
packages/core/src/features/oas/generate/methods/generate-table-schemas.ts (1)
generateTableSchemas(4-52)
packages/core/src/features/oas/generate/methods/patch-oas-spec.ts (2)
packages/core/src/features/oas/generate/methods/generate-table-schemas.ts (2)
generateTableSchemas(54-54)generateTableSchemas(4-52)packages/core/src/features/oas/generate/methods/extract-tags-to-global-level.ts (1)
extractTagsToGlobal(29-29)
packages/core/src/features/oas/generate/methods/do-oas-update.ts (1)
packages/core/src/features/oas/generate/methods/patch-oas-spec.ts (1)
patchOasSpec(282-282)
🔍 Remote MCP DeepWiki
Relevant facts to help review PR #180 (chore: oas related changes):
-
Where to inspect (call flow): CLI generate-oas → core.updateOpenapiSpec → per-group updateSpecForGroup → doOasUpdate → patchOasSpec. Confirm includeTables threads through these call sites and public method signatures.
-
Intent & default: includeTables is optional and defaults to false — table schemas should be omitted by default (tableSchemas = {}) and only generated when --include-tables / includeTables=true is passed. Verify default behavior in CLI flag handling and core.updateOpenapiSpec implementation.
-
Tags change: new extractTagsToGlobal(paths) is added and assigned to newOas.tags before components are built — check it preserves existing tags and generated descriptions.
-
Schema tweaks: Error schemas were extended with format: 'const' and maxLength (e.g., payload maxLength: 1024) for code/message/payload variants to satisfy Spectral rules — verify these constraints don't break codegen, tests, or downstream consumers.
-
Review checklist (quick):
- Confirm function signatures updated and exported API surfaces adjusted (packages/core/src/index.ts).
- Verify CLI flag wiring: packages/cli/src/commands/generate/index.ts and oas-spec.ts pass opts.includeTables through.
- Validate patchOasSpec uses includeTables to skip/generate table schemas conditionally.
- Run/generate spec.json locally and run generate-code to ensure openapi-generator still accepts the spec.
- Run run-test (if available) or unit tests that rely on OAS to detect regressions (responseSchema assertion default is typically off).
- Ensure docs/changesets are present and CI release/docs workflows will behave as expected.
-
Files to focus on in this PR (practical):
- packages/core/src/features/oas/generate/methods/patch-oas-spec.ts (includeTables logic, extractTagsToGlobal import/use).
- packages/core/src/features/oas/generate/methods/extract-tags-to-global-level.ts.
- packages/core/src/features/oas/generate/methods/do-oas-update.ts.
- packages/cli/src/commands/generate/index.ts and packages/cli/src/commands/generate/implementation/oas-spec.ts (flag + propagation).
- .changeset/* (version bump / release metadata).
-
CI/Release note: repository uses Changesets + GitHub workflows that auto-generate docs for changeset PRs and publish on merge; merging this will trigger the usual docs/release flow — expect a changeset-release PR and CI doc commits.
Tooling/docs sources consulted:,,
🔇 Additional comments (15)
.changeset/gentle-trees-tan.md (1)
1-6: LGTM! Changeset appropriately documents the new feature.The changeset correctly bumps both packages to minor versions, which is appropriate for introducing a new optional feature (the
--include-tablesflag). The description clearly explains the default behavior.packages/cli/src/commands/generate/index.ts (2)
111-114: LGTM! CLI flag correctly defined.The
--include-tablesoption is properly registered using Commander.js conventions, with a clear description explaining the default behavior.
116-129: LGTM! Flag propagation is correct.The
includeTablesoption is properly passed through toupdateOasWizardviaopts.includeTables, maintaining the optional nature of the parameter..changeset/tangy-windows-taste.md (1)
1-8: LGTM! Changeset appropriately documents compliance improvements.The changeset correctly uses patch-level bumps for schema refinements and OWASP compliance fixes. The specific references to OWASP rules provide helpful traceability.
packages/cli/src/commands/generate/implementation/oas-spec.ts (2)
10-28: LGTM! Parameter signature and default value correctly defined.The
includeTablesparameter is properly added as optional with a sensible default offalse, maintaining backward compatibility. The TypeScript typing is correct.
60-67: LGTM! Flag correctly propagated to core.The
includeTablesparameter is properly passed through tocore.updateOpenapiSpec, threading the flag deeper into the OAS generation pipeline.packages/core/src/features/oas/generate/methods/update-spec-for-group.ts (1)
36-42: LGTM! Flag correctly propagated to doOasUpdate.The
includeTablesparameter is properly passed through todoOasUpdate, continuing the thread through the OAS generation pipeline.packages/core/src/implementations/generate-oas.ts (2)
5-16: LGTM! Optional parameter correctly added.The
includeTablesparameter is properly typed as optional in the options object, maintaining backward compatibility.
39-47: LGTM! Safe default value handling.The use of the nullish coalescing operator (
?? false) ensures thatincludeTablesalways has a boolean value when passed toupdateSpecForGroup, properly handling undefined values.packages/core/src/features/oas/generate/methods/do-oas-update.ts (1)
28-34: LGTM! Flag correctly propagated to patchOasSpec.The
includeTablesparameter is properly passed through topatchOasSpec, completing the threading of the flag through the entire OAS generation pipeline.packages/core/src/index.ts (1)
391-410: LGTM!The
includeTablesparameter is correctly added with a default offalse, ensuring backward compatibility and aligning with the PR objective that table schemas are not included by default. The parameter is properly threaded to the underlyingdoOasUpdateimplementation.packages/core/src/features/oas/generate/methods/patch-oas-spec.ts (4)
2-2: LGTM!Import of
extractTagsToGlobalaligns with the PR objective to extract tags from individual queries to the global level.
5-19: LGTM!The
includeTablesparameter with defaultfalsecorrectly implements the PR objective. Table schemas are conditionally generated only when explicitly requested, andextractTagsToGlobalis appropriately called to populate global tags.
263-263: LGTM!The
tableSchemasspread correctly includes table schemas only whenincludeTablesis true (otherwise it's an empty object with no effect).
282-282: LGTM!Export statement correctly exports
patchOasSpec.
| function extractTagsToGlobal(paths) { | ||
| // 1. Collect all tags used in operations | ||
| const tagSet = new Set(); | ||
| for (const [path, methods] of Object.entries(paths || {})) { | ||
| for (const [method, operation] of Object.entries(methods)) { | ||
| if (operation.tags && Array.isArray(operation.tags)) { | ||
| operation.tags.forEach((tag) => tagSet.add(tag)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // 2. Build the global tags array if not present | ||
| let tags = Array.from(tagSet).map((tag) => ({ | ||
| name: tag, | ||
| description: `Auto-generated tag for ${tag}`, | ||
| })); | ||
|
|
||
| // (Optional) If you want to preserve existing tags and only add missing ones: | ||
| const existingTags = (tags || []).map((t) => t.name); | ||
| const allTags = Array.from(new Set([...existingTags, ...tagSet])); | ||
| tags = allTags.map((tag) => ({ | ||
| name: tag, | ||
| description: `Auto-generated tag for ${tag}`, | ||
| })); | ||
|
|
||
| return tags; | ||
| } |
There was a problem hiding this comment.
Redundant logic in tag preservation.
The function has confusing and redundant logic:
- Lines 13-16 build a
tagsarray fromtagSet - Line 19 references
tags(just created) as if it were pre-existing input - Lines 20-24 completely rebuild the
tagsarray, making lines 13-16 unnecessary
The comment on line 18 mentions "preserve existing tags," but the function doesn't accept any existing tags as input. Either:
- The function should accept an
existingTagsparameter to truly preserve them, or - Lines 18-24 should be removed as they just recreate what lines 13-16 already built
Apply this diff to simplify the function:
function extractTagsToGlobal(paths) {
// 1. Collect all tags used in operations
const tagSet = new Set();
for (const [path, methods] of Object.entries(paths || {})) {
for (const [method, operation] of Object.entries(methods)) {
if (operation.tags && Array.isArray(operation.tags)) {
operation.tags.forEach((tag) => tagSet.add(tag));
}
}
}
- // 2. Build the global tags array if not present
- let tags = Array.from(tagSet).map((tag) => ({
+ // 2. Build the global tags array
+ const tags = Array.from(tagSet).map((tag) => ({
name: tag,
description: `Auto-generated tag for ${tag}`,
}));
- // (Optional) If you want to preserve existing tags and only add missing ones:
- const existingTags = (tags || []).map((t) => t.name);
- const allTags = Array.from(new Set([...existingTags, ...tagSet]));
- tags = allTags.map((tag) => ({
- name: tag,
- description: `Auto-generated tag for ${tag}`,
- }));
-
return tags;
}If you truly need to preserve existing tags from the OpenAPI spec, modify the signature:
-function extractTagsToGlobal(paths) {
+function extractTagsToGlobal(paths, existingTags = []) {
// 1. Collect all tags used in operations
const tagSet = new Set();
for (const [path, methods] of Object.entries(paths || {})) {
for (const [method, operation] of Object.entries(methods)) {
if (operation.tags && Array.isArray(operation.tags)) {
operation.tags.forEach((tag) => tagSet.add(tag));
}
}
}
- // 2. Build the global tags array if not present
- let tags = Array.from(tagSet).map((tag) => ({
- name: tag,
- description: `Auto-generated tag for ${tag}`,
- }));
-
- // (Optional) If you want to preserve existing tags and only add missing ones:
- const existingTags = (tags || []).map((t) => t.name);
+ // 2. Preserve existing tags and add discovered ones
+ const existingTagNames = existingTags.map((t) => t.name);
- const allTags = Array.from(new Set([...existingTags, ...tagSet]));
- tags = allTags.map((tag) => ({
+ const allTags = Array.from(new Set([...existingTagNames, ...tagSet]));
+ const tags = allTags.map((tag) => ({
name: tag,
description: `Auto-generated tag for ${tag}`,
}));
return tags;
}🤖 Prompt for AI Agents
In
packages/core/src/features/oas/generate/methods/extract-tags-to-global-level.ts
lines 1-27, the function builds a tags array from operations then immediately
recomputes it as if preserving pre-existing tags though no such input exists;
remove the redundant intermediate build and the "preserve existing tags" block
(lines that compute existingTags, allTags and rebuild tags) OR change the
function signature to accept an existingTags parameter and merge
operation-derived tags with that input (deduplicate) before returning the final
tags array — implement one of these two fixes so the function is no longer doing
confusing duplicate work.
Summary by CodeRabbit
Release Notes
New Features
--include-tablesCLI flag to optionally include table schemas in OpenAPI specification generation.Chores
✏️ Tip: You can customize this high-level summary in your review settings.