- Handle type arrays: type: ['string', 'null'] → string | null - Handle const keyword: const: "active" → 'active' literal type - Handle nullable (OpenAPI 3.0 backward compatibility) - Extract and display webhook count in metadata - Add security escaping for string literals and JSDoc comments - Add OpenAPI 3.1 test fixture and 12 unit tests Fixes #365 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
| openproject |
|---|
| 365 |
Task: OpenAPI 3.1 TypeScript Generation Support
Related Documents
- Analysis:
docs/analysis/feature-enhancements-analysis.md(Feature 2) - OpenProject: #365
- Branch:
feature/365-openapi-31-support(fromdev)
Priority
NORMAL
Objective
Enhance TypeScript generation to properly handle OpenAPI 3.1-specific JSON Schema features. While parsing already works via swagger-parser, the generate-types tool doesn't handle 3.1's array types, const keyword, or webhook extraction.
Definition of Done
- Code implemented per specification
- TypeScript compilation CLEAN
- Lint checks PASSED (no lint script configured)
- ALL tests passing (12/12)
- Manual verification completed
- PROOF PROVIDED
Scope
IN SCOPE
- Handle
typeas array:type: ['string', 'null']→string | null - Handle
constkeyword:const: "value"→ literal type'value' - Extract
webhookscount in metadata - Display webhook count in formatted output
- Test fixture with OpenAPI 3.1 spec
OUT OF SCOPE
- Full JSON Schema 2020-12 support (only common features)
$refwith sibling properties (complex edge case)pathItemsin components (rarely used)- Batch operations (separate feature)
Sub-Tasks
Phase 1: Type Array Handling
1.1 Update schemaToType() for array types
- Details: Detect when
typeis an array and map each type, joining with| - Files:
src/tools/generate.ts - Code:
if (Array.isArray(s.type)) { return s.type.map(t => t === 'null' ? 'null' : mapPrimitiveType(t)).join(' | '); } - Testing: Generate types from spec with
type: ['string', 'null']
1.2 Handle nullable migration
- Details: OpenAPI 3.1 replaces
nullable: truewithtype: ['T', 'null'] - Files:
src/tools/generate.ts - Testing: Both 3.0
nullableand 3.1 array types produceT | null
Phase 2: Const Keyword Support
2.1 Implement const type generation
- Details: When
constis present, output a literal type - Files:
src/tools/generate.ts - Code:
if (s.const !== undefined) { return typeof s.const === 'string' ? `'${s.const}'` : String(s.const); } - Testing: Schema with
const: "active"generates'active'
Phase 3: Webhook Metadata Extraction
3.1 Add webhookCount to ParsedSpec
- Details: Add optional
webhookCountfield to ParsedSpec interface - Files:
src/lib/types.ts - Testing: Type compiles
3.2 Extract webhooks in parseSpec()
- Details: Count webhooks from
spec.webhooksif present - Files:
src/lib/parser.ts - Code:
webhookCount: spec.webhooks ? Object.keys(spec.webhooks).length : undefined - Testing: Parse 3.1 spec with webhooks, verify count
3.3 Display webhook count in formatted output
- Details: Show webhook count in human-readable output when present
- Files:
src/utils/format.ts - Testing: Format output includes "Webhooks: N"
Phase 4: Testing
4.1 Create OpenAPI 3.1 test fixture
- Details: Create a 3.1 spec with array types, const, and webhooks
- Files:
test/fixtures/openapi-31.yaml(NEW) - Testing: Fixture parses successfully
4.2 Add unit tests for 3.1 features
- Details: Test type generation for all new features
- Files:
scripts/self-testing/openapi-31-test.ts(NEW) - Testing: All tests pass
4.3 Verify backward compatibility
- Details: Ensure existing 3.0 and 2.0 specs still work
- Files: Existing test fixtures
- Testing: No regression in existing functionality
Files to Modify
| File | Change |
|---|---|
src/tools/generate.ts |
Handle array types, const keyword |
src/lib/types.ts |
Add webhookCount?: number to ParsedSpec |
src/lib/parser.ts |
Extract webhook count from spec |
src/utils/format.ts |
Display webhook count |
test/fixtures/openapi-31.yaml |
NEW: 3.1 test fixture |
scripts/self-testing/openapi-31-test.ts |
NEW: Unit tests |
Risks & Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Complex array type combinations | LOW | Map each type individually, join with | |
const with complex objects |
LOW | Use JSON.stringify for non-primitives |
| Breaking existing 3.0 specs | LOW | Changes are additive, test backward compat |
| Type guard complexity for 3.1 detection | LOW | Use existing isOpenAPI31() guard |
Testing Strategy
- Build:
npm run build- must pass - Lint:
npm run lint- must pass - Unit tests:
npx tsx scripts/self-testing/openapi-31-test.ts - Manual: Generate types from 3.1 spec, verify output
Implementation Notes
- The
isOpenAPI31()type guard already exists insrc/lib/spec-guards.ts - swagger-parser v10.1.1 already parses 3.1 specs correctly
- Changes should be additive - don't break 3.0/2.0 compatibility
- For const with objects, use
typeof value === 'object' ? 'object' : ...