Task
Extend the existing format detector (src/shared/mime-type.ts) with CSAPI media type detection functions and add routing logic that maps detected media types to the appropriate format handlers.
ROADMAP Reference: Phase 3, Task 2 — Format Detector Extensions (~1-2 hours, Low complexity)
Files to Create or Modify
| File |
Action |
Est. Lines |
Purpose |
src/shared/mime-type.ts |
Modify |
~30-40 (add ~20-28) |
Add isMimeTypeSmlJson, isMimeTypeSweJson, isMimeTypeSweText, isMimeTypeSweCsv, isMimeTypeSweBinary detection functions |
src/shared/mime-type.spec.ts |
Modify |
~100-130 (add ~65-95) |
Add tests for all new detection functions, routing logic, and fallback detection |
Blueprint Reference
Follow the existing pattern in src/shared/mime-type.ts (12 lines) — each detection function is a pure function taking a mimeType: string parameter and returning boolean. The existing functions use indexOf for simple substring matching and regex for more complex patterns. Follow the existing test pattern in src/shared/mime-type.spec.ts (35 lines) — each function gets a describe block with positive and negative test cases including variations (with/without application/ prefix, case variations).
Usage blueprint: src/ogc-api/endpoint.ts (lines 45-47, 550-552) — shows how isMimeType* functions are used for content negotiation: link selection by testing link.type against each detector in priority order.
Scope — What to Implement
New Detection Functions
Add these pure functions to src/shared/mime-type.ts, following the existing isMimeType* pattern:
isMimeTypeSmlJson(mimeType: string): boolean — Detects application/sml+json (SensorML JSON encoding)
isMimeTypeSweJson(mimeType: string): boolean — Detects application/swe+json (SWE Common JSON encoding)
isMimeTypeSweText(mimeType: string): boolean — Detects application/swe+text (SWE Common Text encoding)
isMimeTypeSweCsv(mimeType: string): boolean — Detects application/swe+csv (SWE Common CSV encoding — note: this is a constrained variant of SWE Text with tokenSeparator="," and blockSeparator="\n")
isMimeTypeSweBinary(mimeType: string): boolean — Detects application/swe+binary (SWE Common Binary encoding)
Each function should:
- Match the canonical IANA media type (e.g.,
application/sml+json)
- Handle case-insensitive matching
- Handle common shorthand forms (e.g.,
sml+json, swe+json)
- Return
false for unrelated types
Media Type Routing Logic
Document (via JSDoc comments on each function) which handler each media type routes to:
The routing documentation prepares for future integration (Issue #30 — Format Index). The actual routing implementation happens in formats/constants.ts (Issue #29) and formats/index.ts (Issue #30). This issue only adds the detection functions.
JSDoc Requirements
- Document each function with its media type, what format it detects, and the encoding type
- Add
@see links to OGC API - Connected Systems Part 1 (23-001) for application/sml+json and Part 2 (23-002) for application/swe+* types
- Add
@see link to RFC 6838 (Media Type Specifications)
- Follow the JSDoc style in existing
src/shared/mime-type.ts (currently undocumented — add JSDoc to existing functions as well if touching them, but do NOT refactor the function implementations)
Testing Requirements
- Extend
src/shared/mime-type.spec.ts (~65-95 new lines)
- Test each new detection function with:
- Canonical media type (e.g.,
application/sml+json → true)
- Shorthand (e.g.,
sml+json → true)
- Case variation (e.g.,
APPLICATION/SML+JSON → true)
- Negative: unrelated JSON types (e.g.,
application/json → false, application/geo+json → false)
- Negative: other SWE types don't cross-match (e.g.,
isMimeTypeSweText('application/swe+json') → false)
- Test CSV vs Text distinction:
isMimeTypeSweCsv('application/swe+text') → false and vice versa
- Follow test patterns from
src/shared/mime-type.spec.ts
Scope — What NOT to Touch
Acceptance Criteria
Dependencies
Blocked by: Nothing — detection functions are standalone utilities
Blocks: Issue #29 (Format Constants — uses these detectors for routing table), Issue #30 (Format Index — wires detectors to handlers)
Operational Constraints
⚠️ MANDATORY: Before starting work on this issue, review docs/governance/AI_OPERATIONAL_CONSTRAINTS.md.
Key constraints for this task:
- Precedence: OGC specifications → AI Collaboration Agreement → This issue description → Existing code → Conversational context
- No scope expansion: Do not infer unstated requirements or add unrequested features
- No refactoring: Do not rename, restructure, or "improve" code outside this issue's scope
- Minimal diffs: Prefer the smallest change that satisfies the acceptance criteria
- Ask when unclear: If intent is ambiguous, stop and ask for clarification
References
Read these documents before starting implementation. They are ordered by priority.
Primary References (must read)
| # |
Document |
Section/Lines |
What It Provides |
| 1 |
docs/planning/csapi-implementation-guide.md |
§7 Format Detector (Lines 3088-3115) |
Detection strategy, media type routing table, detection methods (Content-Type parsing, Accept negotiation, structure fallback) |
| 2 |
src/shared/mime-type.ts |
Full file (12 lines) |
Blueprint — existing isMimeType* function pattern |
| 3 |
src/shared/mime-type.spec.ts |
Full file (35 lines) |
Blueprint — test pattern for media type detection |
| 4 |
src/ogc-api/endpoint.ts |
Lines 42-48, 550-552 |
Usage pattern — how isMimeType* functions are called for content negotiation |
Upstream Type/Import References (files this task imports from)
| # |
Document |
What to Import |
| — |
No imports needed |
Detection functions are standalone (string → boolean) |
Research References (context, not required reading)
| # |
Document |
What It Provides |
| 1 |
docs/planning/ROADMAP.md (Lines 358-370) |
Task scope definition |
| 2 |
docs/planning/csapi-implementation-guide.md (Lines 2065-2080) |
Directory structure showing where formats/constants.ts will live (Issue #29) |
Specification References (for @see links and field accuracy)
| # |
Document |
Use |
| 1 |
OGC API - Connected Systems Part 1 (23-001) |
application/sml+json media type definition |
| 2 |
docs/research/standards/ogcapi-connectedsystems-1.bundled.oas31.yaml (Lines 5121, 5167, 5236) |
Part 1 application/sml+json usage in OpenAPI spec |
| 3 |
OGC API - Connected Systems Part 2 (23-002) |
application/swe+json, application/swe+text, application/swe+csv, application/swe+binary media type definitions |
| 4 |
docs/research/standards/ogcapi-connectedsystems-2.bundled.oas31.yaml (Lines 1598-1636) |
Part 2 encoding discriminator showing all 5 SWE format variants (JSON, Text, CSV, Binary, Protobuf) |
| 5 |
RFC 6838 (Media Type Specifications) |
Media type format and registration rules |
Convention Quick Reference
| Rule |
Example |
Use .js extension for relative imports |
import { X } from './file.js' |
Use import type for interfaces/types |
import type { Y } from './model.js' |
| Three-tier hierarchy: import from lower tiers only |
shared → ogc-api → csapi |
| Named exports for types and utilities |
export function isMimeTypeSmlJson(...) { ... } |
HTTP mocking: globalThis.fetch = jest.fn() |
Never use nock, msw, or other libraries |
| Meaningful tests only |
Verify behavior, not that code runs without throwing |
Task
Extend the existing format detector (
src/shared/mime-type.ts) with CSAPI media type detection functions and add routing logic that maps detected media types to the appropriate format handlers.ROADMAP Reference: Phase 3, Task 2 — Format Detector Extensions (~1-2 hours, Low complexity)
Files to Create or Modify
src/shared/mime-type.tsisMimeTypeSmlJson,isMimeTypeSweJson,isMimeTypeSweText,isMimeTypeSweCsv,isMimeTypeSweBinarydetection functionssrc/shared/mime-type.spec.tsBlueprint Reference
Follow the existing pattern in
src/shared/mime-type.ts(12 lines) — each detection function is a pure function taking amimeType: stringparameter and returningboolean. The existing functions useindexOffor simple substring matching and regex for more complex patterns. Follow the existing test pattern insrc/shared/mime-type.spec.ts(35 lines) — each function gets a describe block with positive and negative test cases including variations (with/withoutapplication/prefix, case variations).Usage blueprint:
src/ogc-api/endpoint.ts(lines 45-47, 550-552) — shows howisMimeType*functions are used for content negotiation: link selection by testinglink.typeagainst each detector in priority order.Scope — What to Implement
New Detection Functions
Add these pure functions to
src/shared/mime-type.ts, following the existingisMimeType*pattern:isMimeTypeSmlJson(mimeType: string): boolean— Detectsapplication/sml+json(SensorML JSON encoding)isMimeTypeSweJson(mimeType: string): boolean— Detectsapplication/swe+json(SWE Common JSON encoding)isMimeTypeSweText(mimeType: string): boolean— Detectsapplication/swe+text(SWE Common Text encoding)isMimeTypeSweCsv(mimeType: string): boolean— Detectsapplication/swe+csv(SWE Common CSV encoding — note: this is a constrained variant of SWE Text withtokenSeparator=","andblockSeparator="\n")isMimeTypeSweBinary(mimeType: string): boolean— Detectsapplication/swe+binary(SWE Common Binary encoding)Each function should:
application/sml+json)sml+json,swe+json)falsefor unrelated typesMedia Type Routing Logic
Document (via JSDoc comments on each function) which handler each media type routes to:
application/sml+json→ SensorML Handler (Issue Phase 3, Task 9: SensorML Main Parser #22)application/swe+json→ SWE Common Handler JSON (Issue Phase 3, Task 14: SWE Common Main Parser #27)application/swe+text→ SWE Common Handler Text (Issue Phase 3, Task 14: SWE Common Main Parser #27)application/swe+csv→ SWE Common Handler CSV (Issue Phase 3, Task 14: SWE Common Main Parser #27)application/swe+binary→ SWE Common Handler Binary (Issue Phase 3, Task 14: SWE Common Main Parser #27)The routing documentation prepares for future integration (Issue #30 — Format Index). The actual routing implementation happens in
formats/constants.ts(Issue #29) andformats/index.ts(Issue #30). This issue only adds the detection functions.JSDoc Requirements
@seelinks to OGC API - Connected Systems Part 1 (23-001) forapplication/sml+jsonand Part 2 (23-002) forapplication/swe+*types@seelink to RFC 6838 (Media Type Specifications)src/shared/mime-type.ts(currently undocumented — add JSDoc to existing functions as well if touching them, but do NOT refactor the function implementations)Testing Requirements
src/shared/mime-type.spec.ts(~65-95 new lines)application/sml+json→true)sml+json→true)APPLICATION/SML+JSON→true)application/json→false,application/geo+json→false)isMimeTypeSweText('application/swe+json')→false)isMimeTypeSweCsv('application/swe+text')→falseand vice versasrc/shared/mime-type.spec.tsScope — What NOT to Touch
src/ogc-api/csapi/formats/constants.ts— that belongs to Issue Phase 3, Task 16: Format Constants #29 (Format Constants)src/ogc-api/csapi/formats/index.ts— that belongs to Issue Phase 3, Task 17: Format Index #30 (Format Index)isMimeTypeGeoJsonalready exists and CSAPI GeoJSON detection viafeatureTypeanalysis belongs to Issue Phase 3.1: GeoJSON Handler Extensions #14 (GeoJSON Handler Extensions)type: PhysicalSystem,type: DataRecord, etc.) is part of the actual parser implementations (Issues Phase 3, Task 6: SensorML Simple Process Parser #19-Phase 3, Task 15: SWE Common Index #28)src/ogc-api/endpoint.tsorsrc/ogc-api/info.ts— integration of new detectors into endpoint logic is a future concernisMimeType*function implementationsAcceptance Criteria
src/shared/mime-type.tsexports 5 new detection functions:isMimeTypeSmlJson,isMimeTypeSweJson,isMimeTypeSweText,isMimeTypeSweCsv,isMimeTypeSweBinary@seespec referencessrc/shared/mime-type.spec.tshas tests for all 5 new functions with positive and negative casesnpm test)Dependencies
Blocked by: Nothing — detection functions are standalone utilities
Blocks: Issue #29 (Format Constants — uses these detectors for routing table), Issue #30 (Format Index — wires detectors to handlers)
Operational Constraints
Key constraints for this task:
References
Read these documents before starting implementation. They are ordered by priority.
Primary References (must read)
docs/planning/csapi-implementation-guide.mdsrc/shared/mime-type.tsisMimeType*function patternsrc/shared/mime-type.spec.tssrc/ogc-api/endpoint.tsisMimeType*functions are called for content negotiationUpstream Type/Import References (files this task imports from)
Research References (context, not required reading)
docs/planning/ROADMAP.md(Lines 358-370)docs/planning/csapi-implementation-guide.md(Lines 2065-2080)formats/constants.tswill live (Issue #29)Specification References (for
@seelinks and field accuracy)application/sml+jsonmedia type definitiondocs/research/standards/ogcapi-connectedsystems-1.bundled.oas31.yaml(Lines 5121, 5167, 5236)application/sml+jsonusage in OpenAPI specapplication/swe+json,application/swe+text,application/swe+csv,application/swe+binarymedia type definitionsdocs/research/standards/ogcapi-connectedsystems-2.bundled.oas31.yaml(Lines 1598-1636)Convention Quick Reference
.jsextension for relative importsimport { X } from './file.js'import typefor interfaces/typesimport type { Y } from './model.js'export function isMimeTypeSmlJson(...) { ... }globalThis.fetch = jest.fn()