Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a286549
Based on the staged changes, here is the conventional commit message:
ThePlenkov Dec 5, 2025
124bf1a
Based on the comprehensive refactoring from `-v2` suffix removal acro…
ThePlenkov Dec 7, 2025
e035dfe
refactor(adt-plugin-abapgit): remove deprecated speci adapter
ThePlenkov Dec 8, 2025
9eac1a8
Based on the comprehensive changes across the monorepo, here is the c…
ThePlenkov Dec 8, 2025
08703c2
Based on the comprehensive changes implementing XSD substitution grou…
ThePlenkov Dec 8, 2025
b9a4464
refactor(ts-xsd,adt-plugin-abapgit)!: reorganize generated types into…
ThePlenkov Dec 8, 2025
8a2432d
refactor(adt-plugin-abapgit)!: migrate to handler-based architecture …
ThePlenkov Dec 9, 2025
e764c28
Based on the comprehensive architectural changes implementing ADK-bas…
ThePlenkov Dec 10, 2025
388f31a
Based on the comprehensive changes to the XSD schema generator and ab…
ThePlenkov Dec 10, 2025
4d81cc6
refactor(ts-xsd)!: restructure type inference and add xs:redefine sup…
ThePlenkov Dec 10, 2025
3aa6143
feat(ts-xsd): add automatic schema discovery and resolution capabilities
ThePlenkov Dec 11, 2025
103c8ff
refactor(ts-xsd)!: consolidate schema resolution into single resolveS…
ThePlenkov Dec 11, 2025
e22cd37
refactor(ts-xsd): remove duplicate simple-interfaces generator
ThePlenkov Dec 11, 2025
69a20a9
docs(ts-xsd): fix outdated walker module comment
ThePlenkov Dec 11, 2025
504948f
```
ThePlenkov Dec 11, 2025
f846c65
```
ThePlenkov Dec 11, 2025
d04a300
refactor(ts-xsd,adt-schemas,adt-contracts): overhaul type generation …
ThePlenkov Dec 12, 2025
b018259
```
ThePlenkov Dec 12, 2025
328ce6e
```
ThePlenkov Dec 12, 2025
012235a
```
ThePlenkov Dec 12, 2025
2f52f07
docs(ts-xsd): update documentation with current architecture and flat…
ThePlenkov Dec 12, 2025
64736f3
```
ThePlenkov Dec 12, 2025
7ac639e
```
ThePlenkov Dec 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
85 changes: 85 additions & 0 deletions .agents/rules/development/tooling/nx-circular-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Nx Circular Dependencies: Config File Exclusions

## Problem

Nx analyzes ALL TypeScript files for dependencies, including:

- `*.config.ts` (tsdown, vitest, vite, etc.)
- `scripts/` directory
- `e2e/` tests

Config files often import from parent projects (e.g., `../../tsdown.config.ts` for shared base config), which creates **false circular dependencies** in the project graph.

## Solution

Exclude non-runtime files from **both** Nx and ESLint analysis.

### 1. Create `.nxignore`

```gitignore
# Ignore scripts from Nx source file analysis
scripts/

# Ignore e2e tests at root level
e2e/

# Ignore all config files from dependency analysis
*.config.ts
*.config.js
*.config.mjs
**/*.config.ts
**/*.config.js
**/*.config.mjs
```

### 2. Update `eslint.config.mjs`

Add to the `ignores` array:

```javascript
{
ignores: [
'**/dist',
// Exclude from dependency analysis
'scripts/**',
'e2e/**',
],
},
```

### 3. After Changes

Run `nx reset` in the workspace root to clear cached graph:

```bash
npx nx reset
```

Then restart ESLint server in your IDE.

## Why Two Files?

- **`.nxignore`**: Affects Nx project graph (build ordering, affected detection)
- **`eslint.config.mjs`**: Affects `@nx/enforce-module-boundaries` lint rule

Both use separate dependency analysis, so both need configuration.

## Common Patterns That Cause False Cycles

| Pattern | Why It's False |
| ----------------------------------------------------- | ----------------------------------- |
| `tsdown.config.ts` importing `../../tsdown.config.ts` | Shared build config, not runtime |
| `scripts/fetch-fixtures.ts` importing `@pkg/client` | Dev tooling, not package dependency |
| `vitest.config.ts` importing test utilities | Test config, not runtime |

## Verification

After applying fixes, verify with:

```bash
npx nx reset
npx nx graph --file=tmp/graph.json
cat tmp/graph.json | jq '.graph.dependencies["your-package"]'
```

The root project should have `[]` (no dependencies) if scripts are properly excluded.
11 changes: 11 additions & 0 deletions .nxignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Ignore scripts directory from Nx source file analysis
# This prevents scripts that import workspace packages from creating
# false dependencies in the project graph
scripts/

# Ignore e2e tests at root level (they have their own project)
e2e/

# NOTE: Do NOT ignore *.config.ts files here!
# The nx-tsdown and nx-vitest plugins need to detect tsdown.config.ts and vitest.config.ts
# False circular dependencies from config imports are handled via namedInputs in nx.json
99 changes: 99 additions & 0 deletions docs/changelogs/2024-12-12-1700-type-generation-overhaul.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Changelog: 2024-12-12 17:00

## Summary

Major refactoring of the type generation system in `ts-xsd` and `adt-schemas`. Introduced AST-based flattened type generation, resolved `isolatedDeclarations` incompatibility, and updated `adt-contracts` to use the new `InferTypedSchema` pattern for type extraction.

## Architecture

```mermaid
flowchart LR
subgraph Before
A[XSD] --> B[Schema Literal]
B --> C[Interface with extends]
C --> D[Consumer imports type directly]
end
subgraph After
E[XSD] --> F[Schema Literal]
F --> G[Flattened Self-Contained Type]
G --> H[TypedSchema wrapper]
H --> I[InferTypedSchema extracts type]
end
```

---

## Changes by Component

### `ts-xsd`

**What changed**: New AST-based type generation using ts-morph for fully flattened, self-contained types.

**Before → After**:

- **Before**: Generated interfaces with `extends` and cross-file imports
- **After**: Generates flattened types with all properties inlined

**Key decisions**:

- Use ts-morph for reliable AST manipulation
- Flatten all inherited types to avoid cross-schema dependencies
- Strip namespace prefixes from attributes (e.g., `xml:base` → `base`)

### `adt-schemas`

**What changed**: Disabled `isolatedDeclarations`, regenerated all types with flattening, removed intermediate type files.

**Before → After**:

- **Before**: `isolatedDeclarations: true`, types with inheritance
- **After**: `isolatedDeclarations: false`, flattened self-contained types

**Key decisions**:

- `isolatedDeclarations` incompatible with `as const satisfies Schema` pattern
- Remove unused intermediate types (`Ecore.types.ts`, `abapoo.types.ts`, `xml.types.ts`)
- Move `typedSchema` wrapper to `ts-xsd` package

### `adt-contracts`

**What changed**: Updated type imports to use `InferTypedSchema` pattern.

**Before → After**:

- **Before**: `import type { ClassAbapClass } from '../../schemas'`
- **After**: `import { type InferTypedSchema } from '../../schemas'` + `InferTypedSchema<typeof classesSchema>`

**Key decisions**:

- Use type inference from schema rather than importing raw types
- Cleaner API - consumers don't need to know internal type names

---

## Challenges & Resolutions

| Challenge | Resolution |
| ------------------------------------------------------------- | ------------------------------------------------- |
| `isolatedDeclarations` requires explicit types for `as const` | Disabled `isolatedDeclarations` for adt-schemas |
| Namespaced attributes (`xml:base`) causing invalid TS syntax | Strip namespace prefix in `collectAttributes` |
| Type cycles in flattening | Added cycle detection with `Set<string>` tracking |
| Missing type exports (`ClassAbapClass`, `IntfAbapInterface`) | Use `InferTypedSchema<typeof schema>` pattern |

## Open Points

- [ ] Consider re-enabling `isolatedDeclarations` with different approach
- [ ] Add more test coverage for ts-morph type flattening

## Next Steps

- Run full test suite across all packages
- Commit and push changes

## Related

- Packages affected: `ts-xsd`, `adt-schemas`, `adt-contracts`

---

_Generated by: Cascade via `/log` workflow_
94 changes: 94 additions & 0 deletions docs/changelogs/2024-12-13-0056-circular-ref-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Changelog: 2024-12-13 00:56

## Summary

Fixed circular reference stack overflow in ts-xsd type flattening (`expandTypeToString`), regenerated all adt-schemas with improved simpler types, and updated ts-xsd documentation to reflect current architecture including resolver, traverser, loader, and walker components.

## Architecture

```mermaid
flowchart LR
subgraph ts-xsd
XSD[xsd/] --> |parse| Schema
Schema --> |resolve| Resolved[Resolved Schema]
Resolved --> |codegen| TS[TypeScript]
end

subgraph "Key Components"
R[Resolver] --> |merges imports| Resolved
R --> |expands inheritance| Resolved
R --> |handles substitutionGroup| Resolved
T[Traverser] --> |OO traversal| R
W[Walker] --> |functional iteration| Codegen
end
```

---

## Changes by Component

### `ts-xsd/src/codegen/ts-morph.ts`

**What changed**: Added cycle detection in `expandTypeToString` function to prevent stack overflow on circular type references.

**Before → After**:
- **Before**: Interface lookups and base type expansion didn't track visited types, causing infinite recursion on complex schemas
- **After**: Added `visited` set tracking for interface name lookups and base type expansion

**Key decisions**:
- Return `unknown` when cycle detected (safe fallback)
- Track by type name/text representation for reliable cycle detection

### `adt-schemas/src/schemas/generated/`

**What changed**: Regenerated all 36 type files with new flattening logic.

**Before → After**:
- **Before**: Union types with unrelated alternatives (e.g., `| { mainObject } | { link }`)
- **After**: Single object type for root element only (cleaner, more correct)

**Key decisions**:
- Keep simpler generated types (5701 lines removed, 1916 added)
- All 44 tests still pass - no regressions

### `ts-xsd/README.md`, `AGENTS.md`, `docs/codegen.md`

**What changed**: Updated documentation to reflect complete architecture.

**Before → After**:
- **Before**: Missing resolver, traverser, loader, schema-like components
- **After**: Complete architecture with all modules documented

**Key decisions**:
- Added Key Components table (Resolver, Traverser, Walker, Loader)
- Removed obsolete speci reference
- Added adt-contracts and adt-plugin-abapgit to Related Packages
- Documented `flatten` option and cycle detection in codegen docs

---

## Challenges & Resolutions

| Challenge | Resolution |
|-----------|------------|
| Stack overflow on complex SAP ADT schemas (13 failures) | Added cycle detection in `expandTypeToString` for interface lookups and base type expansion |
| `typeName` variable out of scope in base type fallback | Used `textRepr` as cycle key instead |
| Generated types changed significantly | Verified all tests pass (adt-schemas: 44, adt-contracts: 172, adt-plugin-abapgit: 36) |

## Open Points

- [ ] `transportsearch.types.ts` has `requests?: string` due to XSD using `type="xsd:anyURI"` with `ecore:reference` annotation - may need ecore support
- [ ] Some `any` type parameters in ts-morph.ts (pre-existing, not introduced)

## Next Steps

- Consider adding `ecore:reference` annotation support for better type resolution
- Commit changes with semantic commit message

## Related

- Package: `@abapify/ts-xsd`
- Package: `@abapify/adt-schemas`

---
*Generated by: Cascade via `/log` workflow*
31 changes: 20 additions & 11 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ export default [
'**/dist',
'**/vite.config.*.timestamp*',
'**/vitest.config.*.timestamp*',
// Exclude scripts from dependency analysis to prevent false circular dependencies
'scripts/**',
'e2e/**',
],
},
{
Expand All @@ -43,6 +46,8 @@ export default [
allow: [
'^.*/eslint(\\.base)?\\.config\\.[cm]?js$',
'^.*/tsdown\\.config\\.(ts|js|mjs)$',
'^.*/samples/.*',
'^.*\\.config\\..*\\.ts$',
],
depConstraints: [
{
Expand All @@ -54,6 +59,19 @@ export default [
],
},
},
{
// Disable module boundaries for config files (not runtime code)
files: [
'**/*.config.ts',
'**/*.config.*.ts',
'**/*.config.js',
'**/*.config.mjs',
'**/samples/**',
],
rules: {
'@nx/enforce-module-boundaries': 'off',
},
},
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
// Override or add rules here
Expand All @@ -79,7 +97,7 @@ export default [
'import/resolver': {
// Let ESLint resolve TS paths and respect tsconfig for DX
typescript: {
project: true,
project: './tsconfig.base.json',
alwaysTryTypes: true,
},
node: {
Expand All @@ -90,16 +108,7 @@ export default [
rules: {
// Remove file extensions from internal imports (autofixable)
// Keeps package imports intact via "ignorePackages"
'import/extensions': [
'error',
'ignorePackages',
{
ts: 'never',
tsx: 'never',
js: 'never',
jsx: 'never',
},
],
'import/extensions': ['error', 'never'],
// Additional helpful fix: cleans up needless "./index" patterns
'import/no-useless-path-segments': ['error', { noUselessIndex: true }],
},
Expand Down
22 changes: 22 additions & 0 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"defaultBase": "main",
"nxCloudId": "689f2325a9081eb8eb04b58d",
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
"default",
"!{projectRoot}/**/*.config.ts",
"!{projectRoot}/**/*.config.js",
"!{projectRoot}/**/*.config.mjs",
"!{projectRoot}/**/tsdown.config.*",
"!{projectRoot}/**/vitest.config.*",
"!{projectRoot}/**/vite.config.*",
"!{projectRoot}/**/*.spec.ts",
"!{projectRoot}/**/*.test.ts",
"!{projectRoot}/**/tests/**/*"
],
"sharedGlobals": []
},
"pluginsConfig": {
"@nx/js": {
"analyzeSourceFiles": true,
"analyzePackageJson": true
}
},
"plugins": [
{
"plugin": "@nx/js/typescript",
Expand Down
Loading
Loading