Skip to content

feat: add OGC Connected Systems API (CSAPI) support#136

Open
Sam-Bolling wants to merge 17 commits intocamptocamp:mainfrom
OS4CSAPI:clean-pr
Open

feat: add OGC Connected Systems API (CSAPI) support#136
Sam-Bolling wants to merge 17 commits intocamptocamp:mainfrom
OS4CSAPI:clean-pr

Conversation

@Sam-Bolling
Copy link
Copy Markdown

@Sam-Bolling Sam-Bolling commented Feb 21, 2026

Summary

Resolves #118

Adds client-side support for the OGC API — Connected Systems standard (Parts 1 & 2) to ogc-client. This enables discovery, navigation, and querying of IoT sensor systems, observations, datastreams, commands, and related resources through Connected Systems-enabled OGC API endpoints.

Motivation

The OGC API — Connected Systems standard (OGC 23-001, OGC 23-002) defines a REST API for managing sensor systems, observations, and tasking — extending the OGC API family into the IoT/sensor domain. There is currently no JavaScript/TypeScript client library with CSAPI support. This contribution fills that gap within ogc-client's existing architecture.

Architecture (Phase 6 update)

CSAPI is implemented as a fully decoupled sub-path module — it can be imported independently without pulling in the core library, and the core library compiles and runs without CSAPI present.

Key design points:

  • @camptocamp/ogc-client/csapi sub-path export with 171 public symbols
  • createCSAPIBuilder() async factory replaces the former endpoint.csapi() method
  • Zero runtime imports from core → one-way dependency (litmus-tested: core compiles with CSAPI removed)
  • hasConnectedSystems and csapiCollections remain on OgcApiEndpoint (zero CSAPI imports)
  • package.json declares "sideEffects": false for bundler tree-shaking

Consumer guide

CSAPI is available as an opt-in sub-path export. Users install one package (npm install @camptocamp/ogc-client) — same as before. CSAPI code is only included in production bundles if explicitly imported. No configuration required; modern bundlers (Webpack 5+, Vite, Rollup, esbuild) handle this automatically.

If you don't need Connected Systems — nothing changes:

import { OgcApiEndpoint, WmsEndpoint } from '@camptocamp/ogc-client';

CSAPI code will not be included in your bundle.

If you need Connected Systems — add a second import:

import { OgcApiEndpoint } from '@camptocamp/ogc-client';
import { createCSAPIBuilder } from '@camptocamp/ogc-client/csapi';

const endpoint = new OgcApiEndpoint('https://api.example.org');

if (await endpoint.hasConnectedSystems) {
  const builder = await createCSAPIBuilder(endpoint, 'weather-stations');
  const systemsUrl = builder.getSystems({ limit: 50 });
  const dsUrl = builder.getDataStreams();
}

The createCSAPIBuilder() factory connects to the endpoint and discovers available resources. The returned CSAPIQueryBuilder provides methods for all 9 resource types: systems, deployments, sampling features, procedures, properties, datastreams, observations, control streams, and commands.

Why a separate import path? The OGC Connected Systems standard spans 9 resource types across 2 specification parts with multiple response formats (GeoJSON, SWE Common, SensorML). By isolating CSAPI behind a sub-path export, users who only need WMS/WFS/WMTS/etc. don't pay the bundle-size cost for functionality they're not using.

A note on PR size and maintainability

This contribution is ~32k lines across 86 files, and I want to address that directly. This is primarily because OGC API — Connected Systems Parts 1 & 2 represents a complex standard that spans both feature-style metadata resources and dynamic data interactions (observations, commands, events), and covers multiple resource families and response models. As a result, a complete client implementation requires substantial type coverage, URL/query builders, and format parsing logic, along with support for resource lifecycle operations, advanced filtering, and the standard's optional pagination patterns.

A significant portion of the line count is test coverage and inline documentation/JSDoc added to keep the module understandable and maintainable, rather than implementation logic alone. The integration impact on existing ogc-client behavior is intentionally small: CSAPI is implemented as a self-contained module, with only a small set of upstream touchpoints (endpoint discovery, conformance typing, and MIME type registration), no new dependencies, and no breaking API changes. I'm committed to maintaining the CSAPI module and responding to follow-up issues, and I'm also happy to refactor, split, or defer portions of the contribution if that would make review and upstream acceptance easier.

Quality assurance

This contribution has been incrementally code reviewed and smoke tested throughout development. All reports are maintained in our development archive repo https://github.com/OS4CSAPI/ogc-client-CSAPI_2

32 code review reports - incremental reviews conducted after each implementation phase, covering type safety, standards compliance, error handling, and test coverage. Reports are located in https://github.com/OS4CSAPI/ogc-client-CSAPI_2/tree/main/docs/implementation; the latest is https://github.com/OS4CSAPI/ogc-client-CSAPI_2/blob/phase-7/docs/implementation/phase-7.1-code-review.md.

25 live server smoke tests - tested against two live CSAPI servers: OpenSensorHub (http://45.55.99.236:8080/sensorhub/api) and 52°North (https://csa.demo.52north.org/), validating endpoint discovery, resource navigation, format parsing, and content negotiation against real-world implementations. Reports are also in https://github.com/OS4CSAPI/ogc-client-CSAPI_2/tree/main/docs/implementation; the latest is https://github.com/OS4CSAPI/ogc-client-CSAPI_2/blob/phase-7/docs/implementation/live-server-smoke-test-post-phase-7.md.

Usability - A separate Webapp project was created solely to evaluate the usability of the full range of functionality and compliance of the CSAPI client library. It has been assessed extensively against the two live CSAPI server implementations. The CSAPI explorer demo webapp with setup instructions is available here https://github.com/OS4CSAPI/ogc-csapi-explorer.

Phase 6 verification (12 gates):

  • V1–V4: Boundary checks — zero CSAPI imports outside src/ogc-api/csapi/
  • C1–C5: CI gates — format, typecheck, lint, browser tests, node tests all pass
  • A4: Litmus test — core compiles with CSAPI directory removed
  • B1–B3: Behavioral tests — hasConnectedSystems, csapiCollections, all non-CSAPI functionality unchanged

What's included

86 files across 17 commits (13 feature + 1 architecture refactoring + 1 docs + 1 quality hardening + 1 code review cleanup):

  • 34 source files (type definitions, URL builder, helpers, format parsers, barrel file, factory, shared utilities)
  • 32 test files (unit tests, integration tests, endpoint discovery tests)
  • 17 fixture files (mock CSAPI API responses including multi-hub and live-validated resources)
  • 3 config/docs files (.gitignore, package.json, README.md)

Modified upstream files (9 files)

File Change
.gitignore Added .vscode and test-output entries
README.md Added CSAPI to supported standards list; added consumer guide section
package.json Added ./csapi sub-path export, sideEffects: false
src/index.ts CSAPI exports removed (decoupled to sub-path in Phase 6)
src/ogc-api/endpoint.ts Added hasConnectedSystems, csapiCollections; csapi() method removed (decoupled to factory in Phase 6); root/getCollectionDocument made public
src/ogc-api/endpoint.spec.ts Added CSAPI endpoint discovery tests; removed 3 migrated/obsolete tests in Phase 6
src/ogc-api/info.ts Extended info types with CSAPI conformance classes
src/shared/mime-type.ts Registered CSAPI MIME types (SWE Common, SensorML)
src/shared/mime-type.spec.ts Tests for CSAPI MIME type registration

Commits 1–13: CSAPI implementation

  • Type system, URL builder, helpers, format parsers (GeoJSON, SWE Common, SensorML, Part 2)
  • Integration tests, test fixtures, endpoint discovery, MIME type registration

Commit 14: Architecture refactoring (Phase 6)

Decouples CSAPI from OgcApiEndpoint into an independent sub-path module:

File Change
src/ogc-api/csapi/index.ts Created — barrel file re-exporting 171 public symbols
src/ogc-api/csapi/factory.ts CreatedcreateCSAPIBuilder() async factory function
src/ogc-api/csapi/factory.spec.ts Created — 2 migrated tests
src/ogc-api/endpoint.ts Modified — removed csapi() method, CSAPI imports, cache; made root/getCollectionDocument public
src/ogc-api/endpoint.spec.ts Modified — removed 3 migrated/obsolete tests
src/index.ts Modified — removed ~186 CSAPI export lines
package.json Modified — added ./csapi sub-path export, sideEffects: false

Commit 15: Consumer documentation

File Change
README.md Modified — added CSAPI to supported standards list; added consumer guide with sub-path export usage, examples, and bundle-size rationale

Commit 16: Code quality hardening

Post-merge code audit improvements (no new features, no API changes):

  • Replace unsafe double cast with runtime type guard in factory.ts
  • Remove stale as any cast and outdated comment in factory.ts
  • Rename SystemTypeUris to SYSTEM_TYPE_RECOGNITION_VALUES (avoids shadowing the type export of the same name)
  • Extract shared SensorML parsing helpers to _helpers.ts (reduces duplication across aggregate-process, physical-system, physical-component)
  • Consolidate duplicate isRecord() type guard into shared _parse-utils.ts
  • Remove unused imports in SensorML parsers
  • Reword @see tag to use plain URL (avoids false grep matches)
  • Apply Prettier formatting to all source files
  • Expand factory tests from 2 to 6 cases
  • Expand endpoint CSAPI tests from 3 to 7 cases
  • Add live-validated Property resource fixtures and test cases

Commit 17: Code review cleanup (Phase 7)

Comprehensive cleanup from a senior-developer-level code review — 17 issues resolved across 20 execution passes (no new features, no API changes):

  • DRY refactors: requireObject helper, parseBaseStream shared fields, build() URL construction wrapper (rewrites 87 methods)
  • Type safety: parseItem callback for parseCollectionResponse, null guard in extractCSAPIFeature, explicit SensorML field extraction, subPath union type constraint
  • Bug fixes: paramsSchema fallback for older servers, parseValidTime .. sentinel, observedProperties label fallback
  • Security: URL scheme validation in scanCsapiLinks, assertResourceAvailable removal (33+39 methods), nested parent ID parameters
  • Cleanup: redundant as Record cast removal (27 instances), createCommands delegation, shared test fixture extraction, @see link precision
  • Validated against 3 live CSAPI servers (ST#24, ST#25) — 30 test suites, 1,349 tests passing

What's NOT included

  • No breaking changes to existing APIs
  • No new dependencies
  • Detailed documentation is maintained separately in our development fork

How to test

npm install
npm test -- --testPathPattern="csapi"

All test files can run independently. Integration tests use the included fixtures.

Standards references

@Sam-Bolling
Copy link
Copy Markdown
Author

Greetings, @jahow I hope all is going well! I opened this up as a draft because I have a friend that will review it within the next week.

Respectfully,
Sam

@jahow
Copy link
Copy Markdown
Member

jahow commented Feb 23, 2026

Impressive work @Sam-Bolling, thank you for the contribution. It is indeed a very large amount of code and doc :)

I'm willing to take you at your word and consider this as a separate module which you, @Sam-Bolling, will be in charge to maintain (at least in the near future, maybe other parties will join in later). I have neither the time nor expertise to review all of it.

This being said, I would request one major thing: that all things related to the CS API not be part of the main index.ts file, but instead imported through @camptocamp/ogc-client/csapi. Basically I want to make sure that anyone using the library as before do not end up with all this code in their bundle overnight.

This means that:

  • anything part of the src/ogc-api/csapi should not be included in the root index.ts file.
  • anything not part of the src/ogc-api/csapi should not import things from the CSAPI code at all

(unless we find a better way to handle tree-shaking).

I'm going to review the changes to the existing code and give you a more thorough feedback.

@jahow
Copy link
Copy Markdown
Member

jahow commented Feb 23, 2026

@Sam-Bolling also could you please give me a rough time frame for when this would be ready? I'd really like to do a 2.0 release for the library soon, and I'd like to know if this will be in it or in a subsequent release. Thank you again!

@Sam-Bolling
Copy link
Copy Markdown
Author

Impressive work @Sam-Bolling, thank you for the contribution. It is indeed a very large amount of code and doc :)

I'm willing to take you at your word and consider this as a separate module which you, @Sam-Bolling, will be in charge to maintain (at least in the near future, maybe other parties will join in later). I have neither the time nor expertise to review all of it.

This being said, I would request one major thing: that all things related to the CS API not be part of the main index.ts file, but instead imported through @camptocamp/ogc-client/csapi. Basically I want to make sure that anyone using the library as before do not end up with all this code in their bundle overnight.

This means that:

  • anything part of the src/ogc-api/csapi should not be included in the root index.ts file.
  • anything not part of the src/ogc-api/csapi should not import things from the CSAPI code at all

(unless we find a better way to handle tree-shaking).

I'm going to review the changes to the existing code and give you a more thorough feedback.

Greetings, @jahow , thank you for the positive reception and for the clear architectural guidance and acceptance criteria. I fully agree with the separate entry point approach and will accept responsibility to maintain the CSAPI component of the library.

To make sure I understand the requirements, here's my understanding of what needs to change:

  • Remove all CSAPI exports from the root index.ts. consumers would instead import from @camptocamp/ogc-client/csapi
  • Move the CSAPI-related additions out of endpoint.ts, info.ts, and mime-type.ts so nothing outside csapi imports from the CSAPI module
  • Add a "./csapi" entry to the "exports" field in package.json withits own types, import, and browser paths
  • Restructure the public API so the CSAPI module wraps or extends the endpoint rather than the endpoint importing CSAPI code directly
  • The CSAPI internals and test suites wouldn't need significant changes, these changes are mainly focused on the integration surface that needs to be refactored

Regarding timeline, I estimate 1-2 weeks to complete the refactoring, re-verify all tests, and get the CI checks passing. I noticed the formatting check failed because I hadn't run Prettier against your config, which I'll fix as part of this. What does your target timeline for 2.0 look like? I'd like to calibrate against that so we can figure out whether this lands in 2.0 or a follow-on release. Either way works for me, I want to get the architecture right instead of rush it.

Respectfully,
Sam

Sam-Bolling referenced this pull request in OS4CSAPI/ogc-client-CSAPI_2 Feb 23, 2026
…ernal research plans

- Archive v1 research strategy to docs/research/phase-6/archive/
- Add Plans 04-05: TypeScript Sub-Module API Design Patterns (industry
  case studies) and Module Decoupling Patterns (architectural patterns)
- Add formal Boundary Conditions section with jahow's four non-negotiable
  rules from PR #136 review
- Scope all research questions to respect constraints (excluded patterns
  section, boundary verification checklists)
- Renumber former Plans 05-06 to 07-08
- Add notes document capturing analysis rationale
- Total plans: 6 -> 8, estimated time: 16-24 hours
Sam-Bolling referenced this pull request in OS4CSAPI/ogc-client-CSAPI_2 Feb 24, 2026
Add scope-alignment-review-notes.md documenting the review of all 8 research
plans against jahow's actual PR #136 acceptance requirements. The review
confirms research scope is appropriate (broad research informs good design
choices) while adding implementation scope gates to prevent research findings
from expanding work beyond jahow's requirements.

Changes:
- New: scope-alignment-review-notes.md (two-part assessment)
- Plan 06: Added 'Implementation Scope Gate' section and success criterion
- Plan 08: Added 'Implementation Scope Gate' section and success criterion
- research-strategy.md: Added 'Implementation Scope Principle' section

Key principle: Research broadly, implement minimally.
Sam-Bolling referenced this pull request in OS4CSAPI/ogc-client-CSAPI_2 Feb 24, 2026
…attern Analysis

Execute Research Plan 02 and produce structured findings report answering
all 35 detailed questions across 5 sub-topics:

1. EDR Integration Inventory (Q1-8): 1 import, 3 public members, 0 info.ts
   imports, 0 index.ts exports, ~45 lines EDR types in shared model.ts
2. CSAPI Integration Inventory (Q9-16): 2 imports, 4 public members + 1
   private helper, 0 info.ts imports, 183 lines index.ts exports, 0 types
   in shared model.ts
3. Scale Comparison (Q17-23): CSAPI is 18x larger (11,767 vs 656 lines),
   9x more files (27 vs 3), 4 sub-directories vs 0
4. Info.ts and Model.ts Analysis (Q24-29): info.ts has zero imports from
   either module; EDR types in shared model are architecturally appropriate;
   CSAPI types correctly self-contained
5. Architectural Boundary Analysis (Q30-35): jahow's exact requirements
   extracted from PR #136; boundary between embed and separate has 3
   dimensions (public API surface, import direction, module self-containment)

Key finding: The integration pattern is identical for both EDR and CSAPI.
The pattern itself is not the problem — the scale is. CSAPI's 183 lines of
root exports and 2 reverse imports violate jahow's two explicit constraints.

Feeds into: Plan 06 (Endpoint Decoupling Architecture), Plan 08 (Changelist)
Sam-Bolling referenced this pull request in OS4CSAPI/ogc-client-CSAPI_2 Feb 24, 2026
Defines Phase 6 scope, acceptance criteria, and contribution definition
based on jahow's PR #136 review feedback and the 8-plan research arc.
Traces all architectural decisions to research findings and jahow's
explicit requirements.
Sam-Bolling referenced this pull request in OS4CSAPI/ogc-client-CSAPI_2 Feb 24, 2026
Evaluates all 5 open deferred issues (#98, #100, #102, #110, #111) against
Phase 6 acceptance criteria (jahow's PR #136 requirements). All 5 operate
in the CSAPI internal business logic layer while Phase 6 operates at the
module boundary/entry point layer — zero overlap.

Recommendation: Continue deferring all 5. None serve jahow's requirements,
and inclusion would expand the PR diff, mix structural with behavioral
changes, and increase regression risk for zero acceptance gain.
@Sam-Bolling Sam-Bolling force-pushed the clean-pr branch 2 times, most recently from bf5c90c to 6e759a6 Compare February 26, 2026 05:17
@Sam-Bolling
Copy link
Copy Markdown
Author

@Sam-Bolling also could you please give me a rough time frame for when this would be ready? I'd really like to do a 2.0 release for the library soon, and I'd like to know if this will be in it or in a subsequent release. Thank you again!

Greetings, @jahow, the refactoring is complete. Here's how it maps to your requirements:

  1. CSAPI removed from root index.ts
    All ~186 CSAPI export lines were removed (commit 14). CSAPI is now available exclusively through @camptocamp/ogc-client/csapi.

  2. Nothing outside csapi imports from CSAPI code
    Verified — zero imports from csapi exist anywhere in the core library. The two CSAPI-aware properties on OgcApiEndpoint (hasConnectedSystems and csapiCollections) work purely through conformance class string matching and collection link inspection — no CSAPI module imports.

  3. Sub-path export in package.json
    Added "./csapi" entry with types, import, and browser paths, plus "sideEffects": false for tree-shaking. Existing users' bundles are completely unaffected.

  4. Code quality (commit 16)
    Ran Prettier against your config, resolved all ESLint violations, and fixed TypeScript strict-mode errors. All 5 QA gates pass (format, typecheck, lint, browser tests, node tests).

This is ready now and available to land in 2.0 if the timing works, or a subsequent release — whatever suits your plan.

You mentioned you'd review the changes to existing code more thoroughly I welcome that whenever you're ready. The modified upstream files are: endpoint.ts, endpoint.spec.ts, info.ts, mime-type.ts, mime-type.spec.ts, package.json, .gitignore, and README.md.

Respectfully,
Sam

@Sam-Bolling Sam-Bolling marked this pull request as ready for review February 26, 2026 05:35
Sam-Bolling added a commit to OS4CSAPI/ogc-client-CSAPI_2 that referenced this pull request Feb 28, 2026
Documents the discovery that compiled OpenSensorHub server JARs use
different JSON property names than the OGC spec and newer source code:
- `paramsSchema` vs `parametersSchema` in control stream schema responses
- `params` vs `parameters` in command payloads

Includes bytecode decompilation evidence, cross-server comparison,
impact assessment on the upstream PR (camptocamp#136),
and the local fix already applied in ogc-csapi-explorer.
@jahow
Copy link
Copy Markdown
Member

jahow commented Mar 3, 2026

Thanks, this looks good so far. @Sam-Bolling is it OK if I add a commit or two to adjust a few things related to the integration with the core library and the documentation?

@Sam-Bolling
Copy link
Copy Markdown
Author

Thanks, this looks good so far. @Sam-Bolling is it OK if I add a commit or two to adjust a few things related to the integration with the core library and the documentation?

By all means, @jahow please do!

Respectfully,
Sam

@Sam-Bolling
Copy link
Copy Markdown
Author

Greetings, @jahow, I have a quick update:

My senior dev friend came through with a code review over the weekend, and since it came after the refactoring, all the findings were internal to the CSAPI module — nothing touching the integration surface you are working on. I went ahead and knocked them all out in a single commit (Commit 17). QA workflow passes all 5 gates.

Respectfully,
Sam

Add core TypeScript interfaces and types for OGC API - Connected Systems
(CSAPI) Part 1 and Part 2 resources:

- System, Deployment, Procedure, SamplingFeature (Part 1)
- DataStream, Observation, ControlStream, Command, CommandStatus (Part 2)
- Query option types for all resource collections
- CSAPIResourceTypes enum mapping resource names to URL segments
- ResourceLink and navigation types for @link relations
Implement CSAPIQueryBuilder class that constructs endpoint URLs for all
Connected Systems resource types with full query parameter support:

- 50+ methods covering systems, deployments, procedures, sampling features,
  datastreams, observations, control streams, commands, and command status
- GET (list/byId), POST (create), PUT (update), DELETE operations
- Typed query options: bbox, datetime, limit, statusCode, controlledProperty
- Nested resource navigation (e.g., system -> datastreams -> observations)
- Automatic URL encoding and query string assembly
Add shared utility functions and command dispatch logic:

- encodeResourceId(): safe URL encoding for resource identifiers
- scanCsapiLinks(): extract CSAPI link relations from API root documents
- Resource-type validation and date/time parameter formatting
- Command routing: dispatches command requests through the correct
  control-stream -> command path for Part 2 command operations
Extract typed resources from GeoJSON feature collections per the
Connected Systems Part 1 standard:

- constants.ts: resource-type link relation URIs, media type strings
- property.ts: extract typed properties from GeoJSON feature objects
- classification.ts: parse classifier/taxonomy term arrays
- geojson.ts: parseResourceRef() for @link navigation, parseValidTime()
  for temporal extent extraction, GeoJSON-to-typed-resource mapping
Implement parsers for the OGC SWE Common Data Model JSON encoding,
used by CSAPI Part 2 for observation and command result schemas:

- types.ts: SWE Common interfaces (DataRecord, DataArray, scalar/range types)
- components.ts: parse Quantity, Count, Boolean, Text, Category, Time components
- data-record.ts: parse DataRecord structures with nested fields
- data-array.ts: parse DataArray with encoding support (JSON, text, CSV)
- parser.ts: top-level dispatch that routes to the correct component parser
- Full test coverage for all component types and encoding formats
Implement parsers for SensorML JSON encoding (application/sml+json),
used by CSAPI to describe sensor and actuator procedures:

- types.ts: SensorML interfaces (PhysicalSystem, SimpleProcess, AggregateProcess)
- physical-system.ts: parse physical sensor systems with position/components
- simple-process.ts: parse single-step processing descriptions
- aggregate-process.ts: parse multi-component process chains
- parser.ts: top-level dispatch routing to the correct process type parser
- errors.ts: SensorML-specific error classes
- Full test coverage for all three process types and edge cases
Implement parsers for Connected Systems Part 2 dynamic data resources:

- Observation parser: extract result, phenomenonTime, resultTime, datastream ref
- Command parser: extract parameters, issueTime, control-stream ref
- CommandStatus parser: extract statusCode, percentComplete, timestamps
- Shared parseValidTime() reuse from GeoJSON module for temporal extents
- Comprehensive tests covering all Part 2 resource types and edge cases
Add the format orchestration layer that ties together all individual
format parsers into a unified pipeline:

- response.ts: Response wrapper that normalizes parsed CSAPI responses
  into a consistent structure with metadata and typed content
- schema-response.ts: Schema-response parser for SWE Common observation
  schemas, bridging schema definitions to typed format handling
- formats/index.ts: Barrel module re-exporting all format parsers
  (GeoJSON Part 1, SWE Common, SensorML, Part 2) with pipeline
  orchestration for content-type-based format selection

Includes comprehensive test suites for response handling,
schema-response parsing, and format module exports/pipeline behavior.
Add mock API response fixtures for a sample CSAPI-enabled OGC API
endpoint (sample-data-hub):

- sample-data-hub.json: Root landing page with CSAPI conformance links
- sample-data-hub/conformance.json: Conformance declaration including
  CSAPI conformance classes
- sample-data-hub/collections.json: Collections listing with
  CSAPI-enabled collection metadata
- sample-data-hub/collections/iot-sensors.json: Individual collection
  detail with connected systems properties

These fixtures support integration tests for endpoint discovery,
conformance checking, and collection-level CSAPI capability detection.
Add end-to-end integration tests that exercise the full CSAPI module
stack against mock fixtures:

- discovery.spec.ts: Tests for CSAPI endpoint discovery, conformance
  class detection, and collection-level capability enumeration
- navigation.spec.ts: Tests for hierarchical system/subsystem
  navigation and parent-child relationship traversal
- command.spec.ts: Tests for command (tasking) operations including
  CRUD lifecycle and status tracking
- observation.spec.ts: Tests for observation retrieval with temporal
  filtering, format negotiation, and result parsing
- pipeline.spec.ts: Tests for the full request/response pipeline
  including URL construction, format selection, and response parsing

These tests validate cross-cutting behavior across the URL builder,
format parsers, helpers, and command routing layers.
Wire the CSAPI module into the existing ogc-client infrastructure by
extending 5 upstream files with CSAPI awareness:

- endpoint.ts: Add CSAPI collection detection, hasConnectedSystems
  flag, and CSAPI query method to OgcApiEndpoint class (+136 lines)
- endpoint.spec.ts: Add tests for CSAPI endpoint discovery and
  collection capability detection (+53 lines)
- info.ts: Extend OGC API info types with CSAPI conformance classes
  and collection-level connected systems metadata (+31 lines)
- mime-type.ts: Register CSAPI-specific MIME types (SWE Common,
  SensorML, SOS observation formats) in the shared registry (+64 lines)
- mime-type.spec.ts: Add tests for CSAPI MIME type registration
  and content-type negotiation (+111 lines)

This commit represents the integration point where the standalone
CSAPI module (commits 1-10) connects to the existing ogc-client
library architecture.
Extend the library's public API surface in src/index.ts to re-export
all CSAPI types, interfaces, and enums for consumer use:

- CSAPI model types (system, observation, command, collection info)
- URL builder types (query parameters, filter options, pagination)
- Format parser types (SWE Common, SensorML, GeoJSON Part 1, Part 2)
- Response wrapper types and schema-response interfaces
- Helper utility types and command routing enums

This makes the full CSAPI type system available to downstream
consumers via the main ogc-client package entry point.
Add editor-specific and test artifact patterns to .gitignore:

- .vscode: VS Code workspace settings (editor-specific)
- test-output*.txt: Temporary test output capture files
…port

Phase 6 architecture refactoring — moves CSAPI from tightly-coupled
endpoint method to independent sub-path module.

Created:
  - src/ogc-api/csapi/index.ts: barrel file re-exporting 171 public symbols
  - src/ogc-api/csapi/factory.ts: createCSAPIBuilder() async factory function
  - src/ogc-api/csapi/factory.spec.ts: 2 migrated tests from endpoint.spec.ts

Modified:
  - src/ogc-api/endpoint.ts: removed csapi() method, CSAPI imports, cache;
    made root and getCollectionDocument public
  - src/ogc-api/endpoint.spec.ts: removed 3 migrated/obsolete CSAPI tests
  - src/index.ts: removed ~186 CSAPI export lines (zero CSAPI references)
  - package.json: added ./csapi sub-path export, sideEffects: false

Consumer API: import { ... } from '@camptocamp/ogc-client/csapi'
One-way dependency: core compiles without CSAPI (litmus-tested).
All 12 verification gates green (V1-V4, C1-C5, A4, B1-B3).

Closes camptocamp#120, Closes camptocamp#121, Closes camptocamp#122, Closes camptocamp#123, Closes camptocamp#124
Adds Connected Systems (CSAPI) to the supported standards list and
a new section documenting the sub-path export consumer API:
  - What CSAPI is (OGC API Parts 1 & 2)
  - How to opt in via '@camptocamp/ogc-client/csapi' import
  - Usage example with createCSAPIBuilder()
  - Why a separate import path (bundle-size isolation)
- Replace unsafe double cast with runtime type guard in factory.ts
- Remove stale `as any` cast and outdated comment in factory.ts
- Rename SystemTypeUris to SYSTEM_TYPE_RECOGNITION_VALUES (avoids
  shadowing the type export of the same name)
- Extract shared SensorML parsing helpers to _helpers.ts (reduces
  duplication across aggregate-process, physical-system, physical-component)
- Consolidate duplicate isRecord() type guard into shared _parse-utils.ts
- Remove unused imports in SensorML parsers
- Reword @see tag to use plain URL (avoids false grep matches)
- Apply Prettier formatting to all source files
- Expand factory tests from 2 to 6 cases
- Expand endpoint CSAPI tests from 3 to 7 cases
- Add live-validated Property resource fixtures and test cases
Port all 20 execution passes of the Phase 7 code review cleanup plan:

Phase A: camptocamp#98 (@see link), #148 (redundant Record casts)
Phase B: #149 (requireObject helper), #146 (parseBaseStream), #140 (paramsSchema)
Phase C: #154/#155 (parseItem callback), #143 (null guard), #144 (SensorML spread)
Phase D: #142 (subPath constraint), #139 (deploymentSystems), #156/#157 (remove
assertResourceAvailable), camptocamp#102 (nested parent IDs), #158/#159/#160 (build()
wrapper, resolves camptocamp#111), #150 (createCommands delegates)
Phase E: #147 (URL scheme validation)
Phase F: #151 (shared test fixtures)

Also includes post-ST#24 fixes: #162 (..' sentinel), #163 (toArray defensive),
#164 (202 JSDoc), #165 (label fallback)

Source: OS4CSAPI/ogc-client-CSAPI_2 branch phase-7, commit b11f893
Validation: tsc 0 errors, 30 CSAPI suites / 1,349 tests all passing
@jahow
Copy link
Copy Markdown
Member

jahow commented Mar 25, 2026

hey @Sam-Bolling , sorry for not answering sooner, other stuff got in the way. I still want to do a 2.0 release with this merged but I need some time to properly work on it. Thank you for your understanding, I hope you can use a fork in the meantime

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for OGC API - Connected Systems

2 participants