@open-operational-state/discovery 0.1.0

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/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # @open-operational-state/discovery
2
+
3
+ Discovery client for [Open Operational State](https://github.com/open-operational-state). Find and validate operational-state endpoints using HTTP Link headers and well-known paths.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @open-operational-state/discovery
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### `discover( baseUrl, options? )`
14
+
15
+ Discover operational-state resources following the priority hierarchy:
16
+
17
+ 1. Link-based discovery (HTTP `Link` headers with `rel="operational-state"`)
18
+ 2. Well-known path (`/.well-known/operational-state`)
19
+
20
+ ```js
21
+ import { discover } from '@open-operational-state/discovery';
22
+
23
+ const result = await discover( 'https://api.example.com' );
24
+
25
+ switch ( result.method ) {
26
+ case 'link-header':
27
+ console.log( 'Found via Link header:', result.links );
28
+ break;
29
+ case 'well-known':
30
+ console.log( 'Found via well-known:', result.document );
31
+ break;
32
+ case 'none':
33
+ console.log( 'No operational-state resources found' );
34
+ break;
35
+ }
36
+ ```
37
+
38
+ ### `parseLinkHeaders( headers )`
39
+
40
+ Parse HTTP `Link` headers and extract `rel="operational-state"` entries.
41
+
42
+ ```js
43
+ import { parseLinkHeaders } from '@open-operational-state/discovery';
44
+
45
+ const links = parseLinkHeaders(
46
+ '<https://api.example.com/health>; rel="operational-state"; profile="health"'
47
+ );
48
+ // [{ href: 'https://api.example.com/health', profile: 'health' }]
49
+ ```
50
+
51
+ ### `fetchDiscoveryDocument( baseUrl )`
52
+
53
+ Fetch and validate the discovery document from `/.well-known/operational-state`.
54
+
55
+ ### `validateDiscoveryDocument( doc )`
56
+
57
+ Validate the structure of a discovery document.
58
+
59
+ ```js
60
+ import { validateDiscoveryDocument } from '@open-operational-state/discovery';
61
+
62
+ const result = validateDiscoveryDocument( doc );
63
+ // { valid: true, errors: [], warnings: [] }
64
+ ```
65
+
66
+ ## Dependencies
67
+
68
+ - `@open-operational-state/types`
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Discovery Tests
3
+ *
4
+ * Tests Link header parsing and discovery document validation.
5
+ * (Network-dependent tests like fetch are skipped in unit testing.)
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=discovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/discovery.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Discovery Tests
3
+ *
4
+ * Tests Link header parsing and discovery document validation.
5
+ * (Network-dependent tests like fetch are skipped in unit testing.)
6
+ */
7
+ import { describe, it, expect } from 'bun:test';
8
+ import { parseLinkHeaders } from '../link-header.js';
9
+ import { validateDiscoveryDocument } from '../well-known.js';
10
+ // ---------------------------------------------------------------------------
11
+ // Link header parsing
12
+ // ---------------------------------------------------------------------------
13
+ describe('parseLinkHeaders', () => {
14
+ it('parses a simple operational-state link', () => {
15
+ const links = parseLinkHeaders('<https://api.example.com/health>; rel="operational-state"');
16
+ expect(links.length).toBe(1);
17
+ expect(links[0].href).toBe('https://api.example.com/health');
18
+ expect(links[0].profile).toBeUndefined();
19
+ });
20
+ it('parses a link with profile parameter', () => {
21
+ const links = parseLinkHeaders('<https://api.example.com/health>; rel="operational-state"; profile="health"');
22
+ expect(links.length).toBe(1);
23
+ expect(links[0].href).toBe('https://api.example.com/health');
24
+ expect(links[0].profile).toBe('health');
25
+ });
26
+ it('parses multiple links', () => {
27
+ const links = parseLinkHeaders('<https://api.example.com/health>; rel="operational-state"; profile="health", ' +
28
+ '<https://api.example.com/status>; rel="operational-state"; profile="status"');
29
+ expect(links.length).toBe(2);
30
+ expect(links[0].profile).toBe('health');
31
+ expect(links[1].profile).toBe('status');
32
+ });
33
+ it('filters non-operational-state links', () => {
34
+ const links = parseLinkHeaders('<https://example.com>; rel="self", ' +
35
+ '<https://api.example.com/health>; rel="operational-state"');
36
+ expect(links.length).toBe(1);
37
+ expect(links[0].href).toBe('https://api.example.com/health');
38
+ });
39
+ it('handles header object', () => {
40
+ const links = parseLinkHeaders({
41
+ 'Link': '<https://api.example.com/health>; rel="operational-state"',
42
+ 'Content-Type': 'application/json',
43
+ });
44
+ expect(links.length).toBe(1);
45
+ });
46
+ it('returns empty for no link header', () => {
47
+ const links = parseLinkHeaders({ 'Content-Type': 'application/json' });
48
+ expect(links.length).toBe(0);
49
+ });
50
+ });
51
+ // ---------------------------------------------------------------------------
52
+ // Discovery document validation
53
+ // ---------------------------------------------------------------------------
54
+ describe('validateDiscoveryDocument', () => {
55
+ it('validates a correct document', () => {
56
+ const doc = {
57
+ version: '1.0',
58
+ subject: {
59
+ id: 'payment-platform',
60
+ description: 'Payment Processing Platform',
61
+ },
62
+ resources: [
63
+ {
64
+ href: 'https://api.example.com/health',
65
+ profiles: ['liveness', 'readiness', 'health'],
66
+ serialization: 'application/health+json',
67
+ auth: 'none',
68
+ },
69
+ ],
70
+ };
71
+ const result = validateDiscoveryDocument(doc);
72
+ expect(result.valid).toBe(true);
73
+ expect(result.errors.length).toBe(0);
74
+ });
75
+ it('rejects missing version', () => {
76
+ const doc = {
77
+ subject: { id: 'test' },
78
+ resources: [],
79
+ };
80
+ const result = validateDiscoveryDocument(doc);
81
+ expect(result.valid).toBe(false);
82
+ expect(result.errors.some((e) => e.code === 'DISCOVERY_INVALID_VERSION')).toBe(true);
83
+ });
84
+ it('rejects missing subject', () => {
85
+ const doc = {
86
+ version: '1.0',
87
+ resources: [],
88
+ };
89
+ const result = validateDiscoveryDocument(doc);
90
+ expect(result.valid).toBe(false);
91
+ expect(result.errors.some((e) => e.code === 'DISCOVERY_MISSING_SUBJECT')).toBe(true);
92
+ });
93
+ it('rejects missing resources', () => {
94
+ const doc = {
95
+ version: '1.0',
96
+ subject: { id: 'test' },
97
+ };
98
+ const result = validateDiscoveryDocument(doc);
99
+ expect(result.valid).toBe(false);
100
+ expect(result.errors.some((e) => e.code === 'DISCOVERY_MISSING_RESOURCES')).toBe(true);
101
+ });
102
+ it('validates resource entries', () => {
103
+ const doc = {
104
+ version: '1.0',
105
+ subject: { id: 'test' },
106
+ resources: [
107
+ { profiles: ['health'], serialization: 'application/health+json' },
108
+ ],
109
+ };
110
+ const result = validateDiscoveryDocument(doc);
111
+ expect(result.valid).toBe(false);
112
+ expect(result.errors.some((e) => e.code === 'DISCOVERY_MISSING_HREF')).toBe(true);
113
+ });
114
+ it('rejects non-object input', () => {
115
+ const result = validateDiscoveryDocument(null);
116
+ expect(result.valid).toBe(false);
117
+ });
118
+ });
119
+ //# sourceMappingURL=discovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.test.js","sourceRoot":"","sources":["../../src/__tests__/discovery.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Unified Discovery Flow
3
+ *
4
+ * Implements the discovery priority hierarchy:
5
+ * 1. Link-based discovery (primary)
6
+ * 2. Well-known path (baseline fallback)
7
+ */
8
+ import type { DiscoveryDocument } from '@open-operational-state/types';
9
+ import type { OperationalStateLink } from './link-header.js';
10
+ export interface DiscoverOptions {
11
+ /** Skip Link header discovery */
12
+ skipLinkHeaders?: boolean;
13
+ /** Skip well-known path discovery */
14
+ skipWellKnown?: boolean;
15
+ /** Custom headers to send with requests */
16
+ headers?: Record<string, string>;
17
+ }
18
+ export interface DiscoverResult {
19
+ /** How the resources were discovered */
20
+ method: 'link-header' | 'well-known' | 'none';
21
+ /** Operational state links found via Link headers */
22
+ links: OperationalStateLink[];
23
+ /** Discovery document from well-known path (if found) */
24
+ document: DiscoveryDocument | null;
25
+ }
26
+ /**
27
+ * Discover operational-state resources for a given base URL.
28
+ *
29
+ * Follows the discovery priority hierarchy:
30
+ * 1. Check Link headers from a probe of the base URL
31
+ * 2. Fall back to /.well-known/operational-state
32
+ */
33
+ export declare function discover(baseUrl: string, options?: DiscoverOptions): Promise<DiscoverResult>;
34
+ //# sourceMappingURL=discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAO7D,MAAM,WAAW,eAAe;IAC5B,iCAAiC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qCAAqC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC3B,wCAAwC;IACxC,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,MAAM,CAAC;IAC9C,qDAAqD;IACrD,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,yDAAyD;IACzD,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACtC;AAMD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,GAC1B,OAAO,CAAC,cAAc,CAAC,CA2CzB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Unified Discovery Flow
3
+ *
4
+ * Implements the discovery priority hierarchy:
5
+ * 1. Link-based discovery (primary)
6
+ * 2. Well-known path (baseline fallback)
7
+ */
8
+ import { parseLinkHeaders } from './link-header.js';
9
+ import { fetchDiscoveryDocument } from './well-known.js';
10
+ // ---------------------------------------------------------------------------
11
+ // Public API
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * Discover operational-state resources for a given base URL.
15
+ *
16
+ * Follows the discovery priority hierarchy:
17
+ * 1. Check Link headers from a probe of the base URL
18
+ * 2. Fall back to /.well-known/operational-state
19
+ */
20
+ export async function discover(baseUrl, options) {
21
+ // ── 1. Link header discovery ───────────────────────────────────────
22
+ if (!options?.skipLinkHeaders) {
23
+ try {
24
+ const response = await fetch(baseUrl, {
25
+ method: 'HEAD',
26
+ headers: options?.headers,
27
+ });
28
+ const linkHeader = response.headers.get('link');
29
+ if (linkHeader) {
30
+ const links = parseLinkHeaders(linkHeader);
31
+ if (links.length > 0) {
32
+ return {
33
+ method: 'link-header',
34
+ links,
35
+ document: null,
36
+ };
37
+ }
38
+ }
39
+ }
40
+ catch {
41
+ // Link header discovery failed, fall through to well-known
42
+ }
43
+ }
44
+ // ── 2. Well-known path fallback ────────────────────────────────────
45
+ if (!options?.skipWellKnown) {
46
+ const doc = await fetchDiscoveryDocument(baseUrl);
47
+ if (doc) {
48
+ return {
49
+ method: 'well-known',
50
+ links: [],
51
+ document: doc,
52
+ };
53
+ }
54
+ }
55
+ // ── No discovery available ─────────────────────────────────────────
56
+ return {
57
+ method: 'none',
58
+ links: [],
59
+ document: null,
60
+ };
61
+ }
62
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAwBzD,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC1B,OAAe,EACf,OAAyB;IAEzB,sEAAsE;IACtE,IAAK,CAAC,OAAO,EAAE,eAAe,EAAG,CAAC;QAC9B,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAE,OAAO,EAAE;gBACnC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,OAAO,EAAE,OAAO;aAC5B,CAAE,CAAC;YAEJ,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAE,MAAM,CAAE,CAAC;YAClD,IAAK,UAAU,EAAG,CAAC;gBACf,MAAM,KAAK,GAAG,gBAAgB,CAAE,UAAU,CAAE,CAAC;gBAC7C,IAAK,KAAK,CAAC,MAAM,GAAG,CAAC,EAAG,CAAC;oBACrB,OAAO;wBACH,MAAM,EAAE,aAAa;wBACrB,KAAK;wBACL,QAAQ,EAAE,IAAI;qBACjB,CAAC;gBACN,CAAC;YACL,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,2DAA2D;QAC/D,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,IAAK,CAAC,OAAO,EAAE,aAAa,EAAG,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAE,OAAO,CAAE,CAAC;QACpD,IAAK,GAAG,EAAG,CAAC;YACR,OAAO;gBACH,MAAM,EAAE,YAAY;gBACpB,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,GAAG;aAChB,CAAC;QACN,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,OAAO;QACH,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,IAAI;KACjB,CAAC;AACN,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @open-operational-state/discovery
3
+ *
4
+ * Discovery client — well-known paths, Link header parsing,
5
+ * discovery document consumption.
6
+ *
7
+ * Depends on @open-operational-state/types.
8
+ */
9
+ export { parseLinkHeaders } from './link-header.js';
10
+ export type { OperationalStateLink } from './link-header.js';
11
+ export { fetchDiscoveryDocument, validateDiscoveryDocument } from './well-known.js';
12
+ export { discover } from './discover.js';
13
+ export type { DiscoverOptions, DiscoverResult } from './discover.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @open-operational-state/discovery
3
+ *
4
+ * Discovery client — well-known paths, Link header parsing,
5
+ * discovery document consumption.
6
+ *
7
+ * Depends on @open-operational-state/types.
8
+ */
9
+ export { parseLinkHeaders } from './link-header.js';
10
+ export { fetchDiscoveryDocument, validateDiscoveryDocument } from './well-known.js';
11
+ export { discover } from './discover.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Link Header Parsing
3
+ *
4
+ * Parses HTTP Link headers per RFC 8288, extracting
5
+ * rel="operational-state" entries with optional profile parameter.
6
+ */
7
+ export interface OperationalStateLink {
8
+ href: string;
9
+ profile?: string;
10
+ }
11
+ /**
12
+ * Parse HTTP Link headers and extract operational-state links.
13
+ *
14
+ * Input may be a single header string or an object with header key/values.
15
+ * Multiple Link headers are joined by comma (per HTTP spec).
16
+ */
17
+ export declare function parseLinkHeaders(headers: Record<string, string> | string): OperationalStateLink[];
18
+ //# sourceMappingURL=link-header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-header.d.ts","sourceRoot":"","sources":["../src/link-header.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GACzC,oBAAoB,EAAE,CAiCxB"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Link Header Parsing
3
+ *
4
+ * Parses HTTP Link headers per RFC 8288, extracting
5
+ * rel="operational-state" entries with optional profile parameter.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Public API
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * Parse HTTP Link headers and extract operational-state links.
12
+ *
13
+ * Input may be a single header string or an object with header key/values.
14
+ * Multiple Link headers are joined by comma (per HTTP spec).
15
+ */
16
+ export function parseLinkHeaders(headers) {
17
+ let raw;
18
+ if (typeof headers === 'string') {
19
+ raw = headers;
20
+ }
21
+ else {
22
+ // Find the Link header (case-insensitive)
23
+ raw = '';
24
+ for (const [key, value] of Object.entries(headers)) {
25
+ if (key.toLowerCase() === 'link') {
26
+ raw = value;
27
+ break;
28
+ }
29
+ }
30
+ }
31
+ if (!raw) {
32
+ return [];
33
+ }
34
+ const links = [];
35
+ // Split by comma (respecting angle brackets)
36
+ const entries = splitLinkEntries(raw);
37
+ for (const entry of entries) {
38
+ const parsed = parseLinkEntry(entry);
39
+ if (parsed && parsed.rel === 'operational-state') {
40
+ const link = { href: parsed.href };
41
+ if (parsed.profile) {
42
+ link.profile = parsed.profile;
43
+ }
44
+ links.push(link);
45
+ }
46
+ }
47
+ return links;
48
+ }
49
+ /**
50
+ * Split a Link header into individual entries, respecting angle brackets.
51
+ */
52
+ function splitLinkEntries(raw) {
53
+ const entries = [];
54
+ let depth = 0;
55
+ let start = 0;
56
+ for (let i = 0; i < raw.length; i++) {
57
+ if (raw[i] === '<') {
58
+ depth++;
59
+ }
60
+ else if (raw[i] === '>') {
61
+ depth--;
62
+ }
63
+ else if (raw[i] === ',' && depth === 0) {
64
+ entries.push(raw.slice(start, i).trim());
65
+ start = i + 1;
66
+ }
67
+ }
68
+ const last = raw.slice(start).trim();
69
+ if (last) {
70
+ entries.push(last);
71
+ }
72
+ return entries;
73
+ }
74
+ /**
75
+ * Parse a single Link entry: `<url>; rel="..."; profile="..."`
76
+ */
77
+ function parseLinkEntry(entry) {
78
+ // Extract URL from angle brackets
79
+ const hrefMatch = entry.match(/^<([^>]+)>(.*)$/);
80
+ if (!hrefMatch) {
81
+ return null;
82
+ }
83
+ const href = hrefMatch[1];
84
+ const params = hrefMatch[2];
85
+ // Extract parameters
86
+ let rel = '';
87
+ let profile;
88
+ const relMatch = params.match(/;\s*rel\s*=\s*"([^"]+)"/);
89
+ if (relMatch) {
90
+ rel = relMatch[1];
91
+ }
92
+ const profileMatch = params.match(/;\s*profile\s*=\s*"([^"]+)"/);
93
+ if (profileMatch) {
94
+ profile = profileMatch[1];
95
+ }
96
+ return { href, rel, profile };
97
+ }
98
+ //# sourceMappingURL=link-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-header.js","sourceRoot":"","sources":["../src/link-header.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Well-Known Path Resolution
3
+ *
4
+ * Fetch and validate discovery documents from /.well-known/operational-state
5
+ */
6
+ import type { DiscoveryDocument, ValidationResult } from '@open-operational-state/types';
7
+ /**
8
+ * Fetch the discovery document from /.well-known/operational-state.
9
+ *
10
+ * Returns null if the endpoint is not available or returns invalid data.
11
+ */
12
+ export declare function fetchDiscoveryDocument(baseUrl: string): Promise<DiscoveryDocument | null>;
13
+ /**
14
+ * Validate the structure of a discovery document.
15
+ */
16
+ export declare function validateDiscoveryDocument(doc: unknown): ValidationResult;
17
+ //# sourceMappingURL=well-known.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"well-known.d.ts","sourceRoot":"","sources":["../src/well-known.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACR,iBAAiB,EACjB,gBAAgB,EAGnB,MAAM,+BAA+B,CAAC;AAQvC;;;;GAIG;AACH,wBAAsB,sBAAsB,CACxC,OAAO,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAgBnC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAE,GAAG,EAAE,OAAO,GAAI,gBAAgB,CAmG1E"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Well-Known Path Resolution
3
+ *
4
+ * Fetch and validate discovery documents from /.well-known/operational-state
5
+ */
6
+ import { isProfileId } from '@open-operational-state/types';
7
+ // ---------------------------------------------------------------------------
8
+ // Public API
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * Fetch the discovery document from /.well-known/operational-state.
12
+ *
13
+ * Returns null if the endpoint is not available or returns invalid data.
14
+ */
15
+ export async function fetchDiscoveryDocument(baseUrl) {
16
+ const url = new URL('/.well-known/operational-state', baseUrl).href;
17
+ try {
18
+ const response = await fetch(url);
19
+ if (!response.ok) {
20
+ return null;
21
+ }
22
+ const body = await response.json();
23
+ const validation = validateDiscoveryDocument(body);
24
+ if (!validation.valid) {
25
+ return null;
26
+ }
27
+ return body;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * Validate the structure of a discovery document.
35
+ */
36
+ export function validateDiscoveryDocument(doc) {
37
+ const errors = [];
38
+ const warnings = [];
39
+ if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {
40
+ errors.push({
41
+ path: '',
42
+ message: 'Discovery document must be a non-null object',
43
+ code: 'DISCOVERY_INVALID_TYPE',
44
+ });
45
+ return { valid: false, errors, warnings };
46
+ }
47
+ const obj = doc;
48
+ // version
49
+ if (obj.version !== '1.0') {
50
+ errors.push({
51
+ path: 'version',
52
+ message: `Discovery document version must be '1.0', got '${obj.version}'`,
53
+ code: 'DISCOVERY_INVALID_VERSION',
54
+ });
55
+ }
56
+ // subject
57
+ if (!obj.subject || typeof obj.subject !== 'object' || Array.isArray(obj.subject)) {
58
+ errors.push({
59
+ path: 'subject',
60
+ message: 'Discovery document must have a subject object',
61
+ code: 'DISCOVERY_MISSING_SUBJECT',
62
+ });
63
+ }
64
+ else {
65
+ const subject = obj.subject;
66
+ if (typeof subject.id !== 'string' || !subject.id) {
67
+ errors.push({
68
+ path: 'subject.id',
69
+ message: 'Discovery document subject must have an id',
70
+ code: 'DISCOVERY_MISSING_SUBJECT_ID',
71
+ });
72
+ }
73
+ }
74
+ // resources
75
+ if (!Array.isArray(obj.resources)) {
76
+ errors.push({
77
+ path: 'resources',
78
+ message: 'Discovery document must have a resources array',
79
+ code: 'DISCOVERY_MISSING_RESOURCES',
80
+ });
81
+ }
82
+ else {
83
+ for (let i = 0; i < obj.resources.length; i++) {
84
+ const resource = obj.resources[i];
85
+ if (typeof resource.href !== 'string' || !resource.href) {
86
+ errors.push({
87
+ path: `resources[${i}].href`,
88
+ message: `Resource ${i} must have an href`,
89
+ code: 'DISCOVERY_MISSING_HREF',
90
+ });
91
+ }
92
+ if (!Array.isArray(resource.profiles) || resource.profiles.length === 0) {
93
+ errors.push({
94
+ path: `resources[${i}].profiles`,
95
+ message: `Resource ${i} must have a non-empty profiles array`,
96
+ code: 'DISCOVERY_MISSING_PROFILES',
97
+ });
98
+ }
99
+ else {
100
+ for (const p of resource.profiles) {
101
+ if (typeof p === 'string' && !isProfileId(p)) {
102
+ warnings.push({
103
+ path: `resources[${i}].profiles`,
104
+ message: `Unknown profile identifier: '${p}'`,
105
+ code: 'DISCOVERY_UNKNOWN_PROFILE',
106
+ });
107
+ }
108
+ }
109
+ }
110
+ if (typeof resource.serialization !== 'string' || !resource.serialization) {
111
+ errors.push({
112
+ path: `resources[${i}].serialization`,
113
+ message: `Resource ${i} must have a serialization`,
114
+ code: 'DISCOVERY_MISSING_SERIALIZATION',
115
+ });
116
+ }
117
+ // auth is RECOMMENDED, not REQUIRED — only warn
118
+ if (resource.auth !== undefined && resource.auth !== 'none' && resource.auth !== 'required') {
119
+ warnings.push({
120
+ path: `resources[${i}].auth`,
121
+ message: `Resource ${i} auth should be 'none' or 'required', got '${resource.auth}'`,
122
+ code: 'DISCOVERY_INVALID_AUTH',
123
+ });
124
+ }
125
+ }
126
+ }
127
+ return { valid: errors.length === 0, errors, warnings };
128
+ }
129
+ //# sourceMappingURL=well-known.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"well-known.js","sourceRoot":"","sources":["../src/well-known.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,OAAe;IAEf,MAAM,GAAG,GAAG,IAAI,GAAG,CAAE,gCAAgC,EAAE,OAAO,CAAE,CAAC,IAAI,CAAC;IAEtE,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAE,GAAG,CAAE,CAAC;QACpC,IAAK,CAAC,QAAQ,CAAC,EAAE,EAAG,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAEpC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,UAAU,GAAG,yBAAyB,CAAE,IAAI,CAAE,CAAC;QAErD,IAAK,CAAC,UAAU,CAAC,KAAK,EAAG,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAEzC,OAAO,IAAyB,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAE,GAAY;IACnD,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAwB,EAAE,CAAC;IAEzC,IAAK,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAE,GAAG,CAAE,EAAG,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAE;YACT,IAAI,EAAE,EAAE;YACR,OAAO,EAAE,8CAA8C;YACvD,IAAI,EAAE,wBAAwB;SACjC,CAAE,CAAC;QACJ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9C,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAE3C,UAAU;IACV,IAAK,GAAG,CAAC,OAAO,KAAK,KAAK,EAAG,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAE;YACT,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,kDAAkD,GAAG,CAAC,OAAO,GAAG;YACzE,IAAI,EAAE,2BAA2B;SACpC,CAAE,CAAC;IACR,CAAC;IAED,UAAU;IACV,IAAK,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAE,GAAG,CAAC,OAAO,CAAE,EAAG,CAAC;QACpF,MAAM,CAAC,IAAI,CAAE;YACT,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,+CAA+C;YACxD,IAAI,EAAE,2BAA2B;SACpC,CAAE,CAAC;IACR,CAAC;SAAM,CAAC;QACJ,MAAM,OAAO,GAAG,GAAG,CAAC,OAAkC,CAAC;QACvD,IAAK,OAAO,OAAO,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,EAAE,EAAG,CAAC;YAClD,MAAM,CAAC,IAAI,CAAE;gBACT,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,4CAA4C;gBACrD,IAAI,EAAE,8BAA8B;aACvC,CAAE,CAAC;QACR,CAAC;IACL,CAAC;IAED,YAAY;IACZ,IAAK,CAAC,KAAK,CAAC,OAAO,CAAE,GAAG,CAAC,SAAS,CAAE,EAAG,CAAC;QACpC,MAAM,CAAC,IAAI,CAAE;YACT,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,gDAAgD;YACzD,IAAI,EAAE,6BAA6B;SACtC,CAAE,CAAC;IACR,CAAC;SAAM,CAAC;QACJ,KAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAG,CAAC;YAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAA4B,CAAC;YAE7D,IAAK,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAG,CAAC;gBACxD,MAAM,CAAC,IAAI,CAAE;oBACT,IAAI,EAAE,aAAa,CAAC,QAAQ;oBAC5B,OAAO,EAAE,YAAY,CAAC,oBAAoB;oBAC1C,IAAI,EAAE,wBAAwB;iBACjC,CAAE,CAAC;YACR,CAAC;YAED,IAAK,CAAC,KAAK,CAAC,OAAO,CAAE,QAAQ,CAAC,QAAQ,CAAE,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAG,CAAC;gBAC1E,MAAM,CAAC,IAAI,CAAE;oBACT,IAAI,EAAE,aAAa,CAAC,YAAY;oBAChC,OAAO,EAAE,YAAY,CAAC,uCAAuC;oBAC7D,IAAI,EAAE,4BAA4B;iBACrC,CAAE,CAAC;YACR,CAAC;iBAAM,CAAC;gBACJ,KAAM,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAG,CAAC;oBAClC,IAAK,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAE,CAAC,CAAE,EAAG,CAAC;wBAC/C,QAAQ,CAAC,IAAI,CAAE;4BACX,IAAI,EAAE,aAAa,CAAC,YAAY;4BAChC,OAAO,EAAE,gCAAgC,CAAC,GAAG;4BAC7C,IAAI,EAAE,2BAA2B;yBACpC,CAAE,CAAC;oBACR,CAAC;gBACL,CAAC;YACL,CAAC;YAED,IAAK,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAG,CAAC;gBAC1E,MAAM,CAAC,IAAI,CAAE;oBACT,IAAI,EAAE,aAAa,CAAC,iBAAiB;oBACrC,OAAO,EAAE,YAAY,CAAC,4BAA4B;oBAClD,IAAI,EAAE,iCAAiC;iBAC1C,CAAE,CAAC;YACR,CAAC;YAED,gDAAgD;YAChD,IAAK,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAG,CAAC;gBAC5F,QAAQ,CAAC,IAAI,CAAE;oBACX,IAAI,EAAE,aAAa,CAAC,QAAQ;oBAC5B,OAAO,EAAE,YAAY,CAAC,8CAA8C,QAAQ,CAAC,IAAI,GAAG;oBACpF,IAAI,EAAE,wBAAwB;iBACjC,CAAE,CAAC;YACR,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC5D,CAAC"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@open-operational-state/discovery",
3
+ "version": "0.1.0",
4
+ "description": "Discovery client for locating Open Operational State resources",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/open-operational-state/status-tooling.git",
24
+ "directory": "packages/discovery"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "clean": "rm -rf dist",
29
+ "typecheck": "tsc --noEmit",
30
+ "test": "bun test"
31
+ },
32
+ "dependencies": {
33
+ "@open-operational-state/types": "^0.1.0"
34
+ },
35
+ "devDependencies": {
36
+ "typescript": "^5.8.0"
37
+ }
38
+ }