apcore-toolkit 0.10.2 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.11.1] - 2026-09-06
6
+
7
+ Patch release. Bumps the required `apcore-js` floor to `0.30.0`. apcore-js 0.30.0 adds `Config.projectRoot` / `userLevelConfigPaths()`, a new `Config.load` deprecation notice for out-of-tree relative path-typed values, discards a set-but-empty path-typed `APCORE_*` override, and fixes `loadBindingDir` to read `bindings.dir` from the passed `Config` instead of re-reading `APCORE_BINDINGS_DIR` directly — all `Config`/binding-loader internals this toolkit never touches. The complete apcore-js surface this toolkit imports is `ModuleAnnotations`, `ModuleExample`, `DEFAULT_ANNOTATIONS`, `annotationsFromJSON`, `annotationsToJSON`, `Context`, `FunctionModule`, `jsonSchemaToTypeBox`, `ErrorCodes` and `ModuleError` (confirmed via grep: no `Config`, `loadBindingDir`, `ACL`, `ApprovalRequest`, `CancelToken` or `Executor` reference exists in `src/`). No code or API changes; all 680 tests pass unmodified against apcore-js 0.30.0. `pre-commit run --all-files` (`apdev-js check-chars`, `apdev-js check-imports`, `tsc --noEmit`) and `pnpm build` clean.
8
+
9
+ ## [0.11.0] - 2026-09-05
10
+
11
+ Feature release: ships `OpenAPIScanner` and `TuiViewModel`, version-aligned with the Python and Rust SDKs.
12
+
13
+ ### Added
14
+
15
+ - **`OpenAPIScanner`, `deriveModuleId`** (`src/openapi-scanner.ts`) and **`loadSpec`** (`src/openapi-loader.ts`, Node-only — kept in a separate file so `OpenAPIScanner` stays importable from `apcore-toolkit/browser`) — turn an OpenAPI 3.0/3.1 document into a `ScannedModule[]`, one module per operation. Re-exported from the package root and (excluding `loadSpec`) from `apcore-toolkit/browser`.
16
+ - **`TuiViewModel`, `Column`, `Row`, `Cell`, `Sort`, `Filter`, `TonePalette`, `ToneRule`, `Group`, `modulesToViewModel`, `formatViewModel`** (`src/tui-view-model.ts`) — byte-equivalent module-list view-model builder and canonical JSON encoder. Re-exported from the package root and `apcore-toolkit/browser` (pure, no Node dependency).
17
+ - 40 new tests: 35 conformance cases against the shared corpus in `apcore-toolkit/conformance/fixtures/` (`tests/openapi-scan-conformance.test.ts`, `tests/view-model-conformance.test.ts`), plus hand-written regression tests (`tests/openapi-scanner.test.ts`, `tests/tui-view-model.test.ts`).
18
+
19
+ ### Changed
20
+
21
+ - **Required `apcore-js` floor raised to `0.29.0`.** apcore-js 0.29.0 adds `ApprovalRequest.callerId` / `.action` and `CancelToken.raiseIfCancelled()` (both additive), changes `AsyncTaskManager.startReaper()` to return `Promise<ReaperHandle>` (breaking only for a caller that does not `await` it), and closes the ACL pattern-array shape at every entry point — `callers` / `targets` of `[]`, `['$or']`, `['$not']` or the multi-operand `['$not', p1, p2]` are now refused with `ACLRuleError` instead of silently matching nothing ([apcore#112](https://github.com/aiperceivable/apcore/issues/112)). None of it touches the surface this toolkit imports: `FunctionModule`, `Registry`, `jsonSchemaToTypeBox`, `ModuleAnnotations`, `ModuleExample`, `Context`, `DEFAULT_ANNOTATIONS`, `annotationsToJSON` and `annotationsFromJSON` are the complete set (confirmed by grepping every `from 'apcore-js'` in `src/`; no `ACL`, `ApprovalRequest`, `CancelToken` or `AsyncTaskManager` reference exists). No code or API changes; all 657 tests pass unmodified against apcore-js 0.29.0, and `apdev-js check-imports --package apcore-js` is clean.
22
+
23
+ ### Fixed
24
+
25
+ - **`TuiViewModel`'s `Filter.annotations` silently excluded every module when filtering by `requires_approval` or `open_world`.** The filter's flag names are the spec's snake_case (matching Python/Rust), but the installed `apcore-js` `ModuleAnnotations` type uses camelCase fields, so the raw property lookup always returned `undefined`. Fixed with an explicit snake_case → camelCase name mapping; regression tests added. Single-word flags (`readonly`, `destructive`, `idempotent`, `streaming`, `cacheable`, `paginated`, `discoverable`) were unaffected.
26
+ - **`OpenAPIScanner`'s `deprecated` field used truthy coercion instead of a strict boolean check.** A malformed non-boolean value (e.g. the string `"false"`) was treated as deprecated; now requires the literal `true`, matching Rust.
27
+ - Non-string `operationId` no longer leaks into `metadata.openapi.operation_id`.
28
+
29
+ All 657 tests pass (was 652 at 0.10.2). `tsc --noEmit` and `npm run build` clean.
30
+
5
31
  ## [0.10.2] - 2026-09-01
6
32
 
7
33
  Patch release. Bumps the required `apcore-js` floor to `0.28.0`. The 0.28.0 release is scoped entirely to the ACL/Executor governance layer (argument-scoped approval, `ACL.defaultEffect`/`rules` accessors, `ACL.validateRules()`, `ExecutionPolicy.resolve()` call-site parameters, `Executor.governanceState()`) — none of it touches `Registry`, `FunctionModule`, `jsonSchemaToTypeBox`, or module annotations, which is all this toolkit uses (confirmed via grep). No code or API changes; all 617 tests pass unmodified against apcore-js 0.28.0.
package/README.md CHANGED
@@ -80,7 +80,7 @@ const regWriter = new RegistryWriter();
80
80
  await regWriter.write(modules, registry);
81
81
 
82
82
  // Or use the factory
83
- const writer = getWriter('yaml'); // 'yaml' | 'typescript' | 'registry'
83
+ const writer = getWriter('yaml'); // 'yaml' | 'typescript' | 'registry' | 'http-proxy'
84
84
  ```
85
85
 
86
86
  ### Conformance Verification
@@ -225,16 +225,33 @@ The **Browser** column marks whether a symbol is also re-exported from
225
225
  | `HTTPProxyRegistryWriter` | ✓ | Registers modules as HTTP-proxied entries in an in-memory registry. Each module's `execute()` forwards inputs to a backend URL via global `fetch`. Works in any runtime with `fetch` (Node 20+, browsers, edge, workers). |
226
226
  | `HTTPProxyRegistryWriterError` | ✓ | Error class thrown when HTTP fields cannot be extracted from a `ScannedModule` |
227
227
  | `getWriter()` | | Factory for writer instances |
228
- | `assertAnnotationsPreserved()` | | Conformance check for adapter test suites: registers a module and asserts its behavioral annotations (`requiresApproval` / `destructive`) survive `getDefinition`; throws otherwise. Guards against a writer silently disabling approval/ACL gating |
228
+ | `assertAnnotationsPreserved()` | | Conformance check for adapter test suites: registers a module and asserts its behavioral annotations (`requiresApproval` / `destructive`) survive `getDefinition`; throws otherwise. Guards against a writer silently disabling approval/ACL gating |
229
229
  | `extractInputSchema()` | ✓ | Extract input schema from OpenAPI operation |
230
230
  | `extractOutputSchema()` | ✓ | Extract output schema from OpenAPI operation |
231
231
  | `resolveRef()` | ✓ | Resolve `$ref` in OpenAPI documents |
232
232
  | `resolveSchema()` | ✓ | Resolve schema with single-level `$ref` support |
233
233
  | `deepResolveRefs()` | ✓ | Recursively resolve all nested `$ref` pointers in a schema |
234
234
  | `enrichSchemaDescriptions()` | ✓ | Merge parameter descriptions into schema |
235
+ | `OpenAPIScanner` _(v0.11.0)_ | ✓ | Turn an OpenAPI 3.x document into `ScannedModule[]`. Pure and synchronous — no I/O |
236
+ | `OpenAPIScanOptions` _(v0.11.0)_ | ✓ | Options for `OpenAPIScanner.scan()` |
237
+ | `deriveModuleId()` _(v0.11.0)_ | ✓ | Derive a stable, byte-identical `moduleId` for an OpenAPI operation; primary subject of the cross-SDK conformance corpus |
238
+ | `InvalidSpecError` _(v0.11.0)_ | ✓ | Thrown by `OpenAPIScanner.scan()` when the input isn't a recognisable OpenAPI 3.0.x/3.1.x document |
239
+ | `loadSpec()` _(v0.11.0)_ | | Fetch/parse an OpenAPI document from a local filesystem path or an `http(s)://` URL |
240
+ | `LoadSpecOptions` _(v0.11.0)_ | | Options for `loadSpec()` |
235
241
  | `toMarkdown()` | ✓ | Convert dict to formatted Markdown |
236
- | `formatCsv()` _(v0.7.0)_ | | Byte-equivalent RFC 4180 CSV. Header = union of keys; canonical JSON for nested cells; CRLF terminator |
237
- | `formatJsonl()` _(v0.7.0)_ | | Byte-equivalent JSON Lines. Compact JSON per row, LF terminator |
242
+ | `formatCsv()` _(v0.7.0)_ | | Byte-equivalent RFC 4180 CSV. Header = union of keys; canonical JSON for nested cells; CRLF terminator |
243
+ | `formatJsonl()` _(v0.7.0)_ | | Byte-equivalent JSON Lines. Compact JSON per row, LF terminator |
244
+ | `TuiViewModel` _(v0.11.0)_ | ✓ | The V1 `TuiViewModel` wire-format envelope: columns, rows, sort/filter intent, tone palette |
245
+ | `modulesToViewModel()` _(v0.11.0)_ | ✓ | Build a byte-equivalent `TuiViewModel` from scanned modules |
246
+ | `formatViewModel()` _(v0.11.0)_ | ✓ | Canonical, byte-identical compact JSON encoding of a `TuiViewModel` |
247
+ | `Column` _(v0.11.0)_ | ✓ | A view-model column: render order and `Row.cells` index lookup |
248
+ | `Row` _(v0.11.0)_ | ✓ | A view-model row; `cells[i]` corresponds to `columns[i]` |
249
+ | `Cell` _(v0.11.0)_ | ✓ | A single table cell (discriminated union by `kind`) |
250
+ | `Sort` _(v0.11.0)_ | ✓ | Annotates which sort the toolkit (or the caller) applied |
251
+ | `Filter` _(v0.11.0)_ | ✓ | Annotates which filter the toolkit applied |
252
+ | `TonePalette` _(v0.11.0)_ | ✓ | A named, ordered set of `ToneRule` |
253
+ | `ToneRule` _(v0.11.0)_ | ✓ | First-match-wins rule mapping a tag to a semantic tone |
254
+ | `Group` _(v0.11.0)_ | ✓ | A named group of row indices, present only when `kind === "grouped"` |
238
255
  | `moduleToDict()` | ✓ | Serialize module to snake_case dict |
239
256
  | `modulesToDicts()` | ✓ | Batch serialize modules |
240
257
  | `annotationsToDict()` | ✓ | Convert annotations to plain dict |
@@ -14,4 +14,8 @@ export { WriteError, InvalidFormatError } from '../output/errors.js';
14
14
  export { RegistryVerifier, runVerifierChain } from '../output/verify-core.js';
15
15
  export { HTTPProxyRegistryWriter, HTTPProxyRegistryWriterError, } from '../output/http-proxy-writer.js';
16
16
  export type { HTTPProxyRegistryWriterOptions, ProxyRegistry, } from '../output/http-proxy-writer.js';
17
+ export { OpenAPIScanner, deriveModuleId, InvalidSpecError } from '../openapi-scanner.js';
18
+ export type { OpenAPIScanOptions } from '../openapi-scanner.js';
19
+ export { modulesToViewModel, formatViewModel } from '../tui-view-model.js';
20
+ export type { TuiViewModel, Column, Row, Cell, Sort, Filter, TonePalette, ToneRule, Group, View, Justify, Exposure, Direction, Tone, CellKind, ModulesToViewModelOptions, } from '../tui-view-model.js';
17
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAkBA,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOpD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK/D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAMrE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAO9E,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,8BAA8B,EAC9B,aAAa,GACd,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAkBA,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOpD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK/D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAMrE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAO9E,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,8BAA8B,EAC9B,aAAa,GACd,MAAM,gCAAgC,CAAC;AAOxC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC3E,YAAY,EACV,YAAY,EACZ,MAAM,EACN,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,WAAW,EACX,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC"}
@@ -43,4 +43,12 @@ export { RegistryVerifier, runVerifierChain } from '../output/verify-core.js';
43
43
  // Works in any environment where `fetch` is available (Node 20+, browsers,
44
44
  // Deno, workers).
45
45
  export { HTTPProxyRegistryWriter, HTTPProxyRegistryWriterError, } from '../output/http-proxy-writer.js';
46
+ // ---- OpenAPI scanner (pure — no I/O) --------------------------------------
47
+ // `OpenAPIScanner.scan()` and `deriveModuleId` are pure document traversal
48
+ // with no Node.js dependency. `loadSpec` (in `../openapi-loader.js`) is
49
+ // intentionally NOT re-exported here — its local-file-path branch needs
50
+ // Node's `fs`, matching how `BindingLoader` stays Node-only above.
51
+ export { OpenAPIScanner, deriveModuleId, InvalidSpecError } from '../openapi-scanner.js';
52
+ // ---- TUI view model (pure data, no Node.js dependency) --------------------
53
+ export { modulesToViewModel, formatViewModel } from '../tui-view-model.js';
46
54
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,0EAA0E;AAC1E,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,sBAAsB;AACtB,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,0EAA0E;AAC1E,0EAA0E;AAC1E,wEAAwE;AACxE,qEAAqE;AACrE,yEAAyE;AACzE,MAAM;AAIN,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,6EAA6E;AAC7E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,6EAA6E;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,6EAA6E;AAC7E,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAC3E,qDAAqD;AACrD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAErE,6EAA6E;AAC7E,gFAAgF;AAChF,2EAA2E;AAC3E,4BAA4B;AAC5B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE9E,6EAA6E;AAC7E,sEAAsE;AACtE,yEAAyE;AACzE,2EAA2E;AAC3E,kBAAkB;AAClB,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,0EAA0E;AAC1E,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,sBAAsB;AACtB,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,0EAA0E;AAC1E,0EAA0E;AAC1E,wEAAwE;AACxE,qEAAqE;AACrE,yEAAyE;AACzE,MAAM;AAIN,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,6EAA6E;AAC7E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,6EAA6E;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,6EAA6E;AAC7E,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAC3E,qDAAqD;AACrD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAErE,6EAA6E;AAC7E,gFAAgF;AAChF,2EAA2E;AAC3E,4BAA4B;AAC5B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE9E,6EAA6E;AAC7E,sEAAsE;AACtE,yEAAyE;AACzE,2EAA2E;AAC3E,kBAAkB;AAClB,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC;AAMxC,8EAA8E;AAC9E,2EAA2E;AAC3E,wEAAwE;AACxE,wEAAwE;AACxE,mEAAmE;AACnE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzF,8EAA8E;AAC9E,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export { AIEnhancer } from './ai-enhancer.js';
12
12
  export type { AIEnhancerOptions, Enhancer } from './ai-enhancer.js';
13
13
  export { DisplayResolver } from './display/resolver.js';
14
14
  export type { DisplayResolveOptions, DisplayMetadata, SurfaceDisplay, } from './display/resolver.js';
15
- export { BindingLoader, BindingLoadError } from './binding-loader.js';
15
+ export { BindingLoader, BindingLoadError, BindingParser, parseBindingDocument, } from './binding-loader.js';
16
16
  export type { BindingLoadOptions } from './binding-loader.js';
17
17
  export { YAMLWriter } from './output/yaml-writer.js';
18
18
  export { TypeScriptWriter } from './output/typescript-writer.js';
@@ -20,6 +20,12 @@ export { RegistryWriter } from './output/registry-writer.js';
20
20
  export { HTTPProxyRegistryWriter, HTTPProxyRegistryWriterError, } from './output/http-proxy-writer.js';
21
21
  export type { HTTPProxyRegistryWriterOptions, ProxyRegistry, } from './output/http-proxy-writer.js';
22
22
  export { getWriter } from './output/factory.js';
23
+ export { OpenAPIScanner, deriveModuleId, InvalidSpecError } from './openapi-scanner.js';
24
+ export type { OpenAPIScanOptions } from './openapi-scanner.js';
25
+ export { loadSpec } from './openapi-loader.js';
26
+ export type { LoadSpecOptions } from './openapi-loader.js';
27
+ export { modulesToViewModel, formatViewModel } from './tui-view-model.js';
28
+ export type { TuiViewModel, Column, Row, Cell, Sort, Filter, TonePalette, ToneRule, Group, View, Justify, Exposure, Direction, Tone, CellKind, ModulesToViewModelOptions, } from './tui-view-model.js';
23
29
  export { assertAnnotationsPreserved, DEFAULT_CONFORMANCE_FIELDS } from './conformance.js';
24
30
  export type { AnnotationCarryingRegistry, AnnotationWriter } from './conformance.js';
25
31
  export type { WriteResult, VerifyResult, Verifier } from './output/types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAU9D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,EACT,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EACV,qBAAqB,EACrB,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,8BAA8B,EAC9B,aAAa,GACd,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC1F,YAAY,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrF,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAK/B,eAAO,MAAM,OAAO,EAAE,MAAqB,CAAC;AAQ5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAE5E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,12 +15,15 @@ export { resolveTarget } from './resolve-target.js';
15
15
  export { toMarkdown, formatSchema, formatModule, formatModules, formatCsv, formatJsonl, } from './formatting/index.js';
16
16
  export { AIEnhancer } from './ai-enhancer.js';
17
17
  export { DisplayResolver } from './display/resolver.js';
18
- export { BindingLoader, BindingLoadError } from './binding-loader.js';
18
+ export { BindingLoader, BindingLoadError, BindingParser, parseBindingDocument, } from './binding-loader.js';
19
19
  export { YAMLWriter } from './output/yaml-writer.js';
20
20
  export { TypeScriptWriter } from './output/typescript-writer.js';
21
21
  export { RegistryWriter } from './output/registry-writer.js';
22
22
  export { HTTPProxyRegistryWriter, HTTPProxyRegistryWriterError, } from './output/http-proxy-writer.js';
23
23
  export { getWriter } from './output/factory.js';
24
+ export { OpenAPIScanner, deriveModuleId, InvalidSpecError } from './openapi-scanner.js';
25
+ export { loadSpec } from './openapi-loader.js';
26
+ export { modulesToViewModel, formatViewModel } from './tui-view-model.js';
24
27
  export { assertAnnotationsPreserved, DEFAULT_CONFORMANCE_FIELDS } from './conformance.js';
25
28
  // TS-only ergonomic factory: Python/Rust callers construct WriteResult directly
26
29
  // via dataclass/struct literals. No counterpart in apcore-toolkit-python/-rust.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9D,2BAA2B;AAC3B,2BAA2B;AAC3B,+EAA+E;AAC/E,0EAA0E;AAC1E,4EAA4E;AAC5E,+CAA+C;AAC/C,yDAAyD;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,EACT,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAU/B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMxD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEtE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC;AAKvC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAG1F,gFAAgF;AAChF,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAwB,CAAC;AAChE,MAAM,CAAC,MAAM,OAAO,GAAW,IAAI,CAAC,OAAO,CAAC;AAE5C,iEAAiE;AACjE,2EAA2E;AAC3E,oEAAoE;AACpE,mEAAmE;AACnE,sEAAsE;AACtE,8BAA8B;AAC9B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAG3D;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAc;IACvD,OAAO,YAAY,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACzD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9D,2BAA2B;AAC3B,2BAA2B;AAC3B,+EAA+E;AAC/E,0EAA0E;AAC1E,4EAA4E;AAC5E,+CAA+C;AAC/C,yDAAyD;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,EACT,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAU/B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMxD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC;AAKvC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExF,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAmB1E,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAG1F,gFAAgF;AAChF,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAwB,CAAC;AAChE,MAAM,CAAC,MAAM,OAAO,GAAW,IAAI,CAAC,OAAO,CAAC;AAE5C,iEAAiE;AACjE,2EAA2E;AAC3E,oEAAoE;AACpE,mEAAmE;AACnE,sEAAsE;AACtE,8BAA8B;AAC9B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAG3D;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAc;IACvD,OAAO,YAAY,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * `loadSpec` — fetch/parse an OpenAPI document from a local path or
3
+ * `http(s)://` URL.
4
+ *
5
+ * Convenience helper, explicitly outside the conformance corpus (I/O
6
+ * behaviour is deliberately not byte-specified). The URL/path is taken
7
+ * verbatim — no candidate paths are probed. See `Contract: load_spec` in
8
+ * `apcore-toolkit/docs/features/openapi-scanner.md`.
9
+ *
10
+ * Kept in its own file (not `openapi-scanner.ts`) because it needs Node's
11
+ * `fs` for the local-file-path branch, and `OpenAPIScanner` /
12
+ * `deriveModuleId` are pure and re-exported from `apcore-toolkit/browser`.
13
+ * Mirrors the existing `binding-parser.ts` (pure) / `binding-loader.ts`
14
+ * (Node-only) split in this package.
15
+ *
16
+ * Security: `source` is trusted input. Callers taking a URL from an
17
+ * untrusted source are responsible for their own allowlisting (SSRF) — see
18
+ * the spec doc's Security Considerations.
19
+ */
20
+ /** Options for {@link loadSpec}. */
21
+ export interface LoadSpecOptions {
22
+ /** Extra request headers (API-version headers, tenant selectors, ...). Ignored for local files. */
23
+ headers?: Record<string, string>;
24
+ /** Callable returning auth headers, invoked once per fetch. Ignored for local files. */
25
+ authHeaderFactory?: () => Record<string, string>;
26
+ /** Request timeout in milliseconds. Defaults to 30_000 (30s). Ignored for local files. */
27
+ timeout?: number;
28
+ /** Optional fetch implementation (primarily for tests). Defaults to the global `fetch`. */
29
+ fetchImpl?: typeof fetch;
30
+ }
31
+ /**
32
+ * Load and parse an OpenAPI document from a local filesystem path or an
33
+ * `http(s)://` URL, taken verbatim (no candidate paths are probed).
34
+ *
35
+ * JSON-or-YAML is sniffed from the trimmed text: `{`/`[` parses as JSON
36
+ * (via `JSON.parse`, whose `SyntaxError` propagates on malformed input);
37
+ * anything else parses as YAML via `js-yaml` (already a dependency of this
38
+ * package), with parse errors normalised to `SyntaxError` for the same
39
+ * cross-SDK error contract.
40
+ *
41
+ * @throws {Error} File not found/unreadable, or HTTP non-2xx / network failure.
42
+ * @throws {SyntaxError} Malformed JSON or YAML.
43
+ */
44
+ export declare function loadSpec(source: string, options?: LoadSpecOptions): Promise<Record<string, unknown>>;
45
+ //# sourceMappingURL=openapi-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-loader.d.ts","sourceRoot":"","sources":["../src/openapi-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,mGAAmG;IACnG,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,wFAAwF;IACxF,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAsBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA4ClC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * `loadSpec` — fetch/parse an OpenAPI document from a local path or
3
+ * `http(s)://` URL.
4
+ *
5
+ * Convenience helper, explicitly outside the conformance corpus (I/O
6
+ * behaviour is deliberately not byte-specified). The URL/path is taken
7
+ * verbatim — no candidate paths are probed. See `Contract: load_spec` in
8
+ * `apcore-toolkit/docs/features/openapi-scanner.md`.
9
+ *
10
+ * Kept in its own file (not `openapi-scanner.ts`) because it needs Node's
11
+ * `fs` for the local-file-path branch, and `OpenAPIScanner` /
12
+ * `deriveModuleId` are pure and re-exported from `apcore-toolkit/browser`.
13
+ * Mirrors the existing `binding-parser.ts` (pure) / `binding-loader.ts`
14
+ * (Node-only) split in this package.
15
+ *
16
+ * Security: `source` is trusted input. Callers taking a URL from an
17
+ * untrusted source are responsible for their own allowlisting (SSRF) — see
18
+ * the spec doc's Security Considerations.
19
+ */
20
+ import * as fs from 'node:fs';
21
+ import * as yaml from 'js-yaml';
22
+ function parseDocument(text, source) {
23
+ const stripped = text.trimStart();
24
+ if (stripped.startsWith('{') || stripped.startsWith('[')) {
25
+ // JSON.parse throws SyntaxError natively on malformed input, matching
26
+ // the doc's Contract ("Malformed JSON/YAML: ... TypeScript SyntaxError").
27
+ return JSON.parse(text);
28
+ }
29
+ let loaded;
30
+ try {
31
+ loaded = yaml.load(text);
32
+ }
33
+ catch (err) {
34
+ const msg = err instanceof Error ? err.message : String(err);
35
+ throw new SyntaxError(`loadSpec: malformed YAML spec at ${source}: ${msg}`);
36
+ }
37
+ if (typeof loaded !== 'object' || loaded === null || Array.isArray(loaded)) {
38
+ throw new SyntaxError(`loadSpec: malformed spec at ${source}: expected an object, got ${typeof loaded}`);
39
+ }
40
+ return loaded;
41
+ }
42
+ /**
43
+ * Load and parse an OpenAPI document from a local filesystem path or an
44
+ * `http(s)://` URL, taken verbatim (no candidate paths are probed).
45
+ *
46
+ * JSON-or-YAML is sniffed from the trimmed text: `{`/`[` parses as JSON
47
+ * (via `JSON.parse`, whose `SyntaxError` propagates on malformed input);
48
+ * anything else parses as YAML via `js-yaml` (already a dependency of this
49
+ * package), with parse errors normalised to `SyntaxError` for the same
50
+ * cross-SDK error contract.
51
+ *
52
+ * @throws {Error} File not found/unreadable, or HTTP non-2xx / network failure.
53
+ * @throws {SyntaxError} Malformed JSON or YAML.
54
+ */
55
+ export async function loadSpec(source, options = {}) {
56
+ const { headers, authHeaderFactory, timeout = 30_000, fetchImpl } = options;
57
+ if (source.startsWith('http://') || source.startsWith('https://')) {
58
+ const f = fetchImpl ?? globalThis.fetch;
59
+ if (!f) {
60
+ throw new Error('loadSpec: global fetch is unavailable — pass `fetchImpl` explicitly or run on Node 20+.');
61
+ }
62
+ const requestHeaders = { ...(headers ?? {}) };
63
+ if (authHeaderFactory) {
64
+ Object.assign(requestHeaders, authHeaderFactory());
65
+ }
66
+ const controller = new AbortController();
67
+ const timer = setTimeout(() => controller.abort(), timeout);
68
+ let response;
69
+ try {
70
+ response = await f(source, { headers: requestHeaders, signal: controller.signal });
71
+ }
72
+ catch (err) {
73
+ const msg = err instanceof Error ? err.message : String(err);
74
+ throw new Error(`loadSpec: request to ${source} failed: ${msg}`);
75
+ }
76
+ finally {
77
+ clearTimeout(timer);
78
+ }
79
+ if (!response.ok) {
80
+ throw new Error(`loadSpec: request to ${source} failed with status ${response.status} ${response.statusText}`);
81
+ }
82
+ const text = await response.text();
83
+ return parseDocument(text, source);
84
+ }
85
+ let text;
86
+ try {
87
+ text = fs.readFileSync(source, 'utf-8');
88
+ }
89
+ catch (err) {
90
+ const msg = err instanceof Error ? err.message : String(err);
91
+ throw new Error(`loadSpec: failed to read ${source}: ${msg}`);
92
+ }
93
+ return parseDocument(text, source);
94
+ }
95
+ //# sourceMappingURL=openapi-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-loader.js","sourceRoot":"","sources":["../src/openapi-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * OpenAPIScanner — turn an OpenAPI 3.x document into a `ScannedModule[]`.
3
+ *
4
+ * Document-level traversal layered on top of the shipped operation-level
5
+ * primitives in `./openapi.js` (`extractInputSchema`, `extractOutputSchema`,
6
+ * `resolveRef`) and `BaseScanner.inferAnnotationsFromMethod`.
7
+ *
8
+ * Pure and synchronous — no I/O. See `./openapi-loader.js` for the
9
+ * (Node-only) `loadSpec` convenience helper, which is intentionally kept in
10
+ * a separate file so this module stays importable from
11
+ * `apcore-toolkit/browser` (see `src/browser/index.ts`).
12
+ *
13
+ * See `apcore-toolkit/docs/features/openapi-scanner.md` for the full V1
14
+ * specification, worked examples, and conformance corpus.
15
+ */
16
+ import { BaseScanner } from './scanner.js';
17
+ import type { ScannedModule } from './types.js';
18
+ /**
19
+ * Thrown by {@link OpenAPIScanner.scan} when the input document is not a
20
+ * recognisable OpenAPI 3.0.x/3.1.x document (missing `openapi` key, or an
21
+ * OpenAPI 2.0 / Swagger document). Matches the doc's Contract: "TypeScript
22
+ * throws `InvalidSpecError`".
23
+ */
24
+ export declare class InvalidSpecError extends Error {
25
+ constructor(message: string);
26
+ }
27
+ /**
28
+ * Derive a stable, byte-identical `moduleId` for an OpenAPI operation.
29
+ *
30
+ * See `apcore-toolkit/docs/features/openapi-scanner.md` § `module_id`
31
+ * Derivation for the algorithm and worked examples. This function is the
32
+ * primary subject of the cross-SDK conformance corpus — implementations
33
+ * MUST match it byte-for-byte.
34
+ *
35
+ * @param path - The OpenAPI path template (e.g. `"/users/{user_id}"`).
36
+ * @param method - The HTTP method key as written in the document (e.g. `"get"`).
37
+ * @param operation - The operation object, consulted only for `operationId`.
38
+ * @returns The derived module ID. Never empty — falls back to `"root.<method>"`.
39
+ */
40
+ export declare function deriveModuleId(path: string, method: string, operation: Record<string, unknown>): string;
41
+ /**
42
+ * Options for {@link OpenAPIScanner.scan}. See
43
+ * `apcore-toolkit/docs/features/openapi-scanner.md` § Contract:
44
+ * OpenAPIScanner.scan and § Extension Hooks.
45
+ */
46
+ export interface OpenAPIScanOptions {
47
+ /** Regex forwarded to `filterModules`; only matching module IDs are kept. */
48
+ include?: string;
49
+ /** Regex forwarded to `filterModules`; matching module IDs are removed. */
50
+ exclude?: string;
51
+ /** Prepended to every derived `moduleId` as `"<prefix>.<id>"`, before filtering/dedup. */
52
+ basePathPrefix?: string;
53
+ /** When `false`, operations with `deprecated: true` are omitted entirely. Default `true`. */
54
+ includeDeprecated?: boolean;
55
+ /** Patch or normalise an operation before extraction. Returning `null` skips it entirely. */
56
+ transformOperation?: (path: string, method: string, operation: Record<string, unknown>) => Record<string, unknown> | null;
57
+ /** Override the naming algorithm. Returning `null` falls back to {@link deriveModuleId}. */
58
+ deriveModuleId?: (path: string, method: string, operation: Record<string, unknown>) => string | null;
59
+ /** Adjust the finished module. Returning `null` drops it from the result. */
60
+ transformModule?: (module: ScannedModule) => ScannedModule | null;
61
+ }
62
+ /**
63
+ * Turn an OpenAPI 3.0/3.1 document into a list of `ScannedModule`.
64
+ *
65
+ * Pure and synchronous: `scan()` accepts an already-parsed document and
66
+ * performs no I/O. Use `loadSpec` (from `./openapi-loader.js`) to
67
+ * fetch/parse a document first.
68
+ */
69
+ export declare class OpenAPIScanner extends BaseScanner {
70
+ scan(spec: Record<string, unknown>, options?: OpenAPIScanOptions): ScannedModule[];
71
+ getSourceName(): string;
72
+ }
73
+ //# sourceMappingURL=openapi-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-scanner.d.ts","sourceRoot":"","sources":["../src/openapi-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAyCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,CAsBR;AAiHD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,6FAA6F;IAC7F,kBAAkB,CAAC,EAAE,CACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpC,4FAA4F;IAC5F,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,IAAI,CAAC;IACrG,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,aAAa,GAAG,IAAI,CAAC;CACnE;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAC7C,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAE,kBAAuB,GAAG,aAAa,EAAE;IAiJtF,aAAa,IAAI,MAAM;CAGxB"}