@oasisomniverse/web7-api 1.0.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,132 @@
1
+ # @oasisomniverse/web7-api
2
+
3
+ Isomorphic (Node 18+ and browser) JavaScript/TypeScript-friendly client for the
4
+ **WEB7 OASIS Symbiosis API** - consenting bio-signal symbiosis sessions and
5
+ shared collective-consciousness fields built on the OASIS2 WEB7 WebAPI.
6
+
7
+ Zero dependencies. Wraps the global `fetch`. Works the same in Node and the
8
+ browser.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @oasisomniverse/web7-api
14
+ ```
15
+
16
+ ## Quick start
17
+
18
+ ```js
19
+ const { Web7Client } = require('@oasisomniverse/web7-api');
20
+ // or: import { Web7Client } from '@oasisomniverse/web7-api';
21
+
22
+ const web7 = new Web7Client({ baseUrl: 'https://api.web7.oasisomniverse.one' });
23
+
24
+ const { isError, message, result } = await web7.symbiosis.startSession({ consentGranted: true });
25
+ if (isError) throw new Error(message);
26
+ console.log(result);
27
+ ```
28
+
29
+ ## Calling any endpoint
30
+
31
+ Every controller on the OASIS2 WEB7 WebAPI is reachable as a lowerCamel
32
+ property on the client (`web7.symbiosis`, `web7.collectiveConsciousness`).
33
+ Every generated method takes a single args object:
34
+
35
+ - Any key matching a `{token}` in the route template is consumed and
36
+ substituted into the URL (case-insensitive match).
37
+ - Any remaining keys become the query string (GET/DELETE) or JSON body
38
+ (POST/PUT) - **matching the real `[FromQuery]`/`[FromBody]` binding of the
39
+ underlying C# action**, not just the HTTP verb. `endpoints.json` records
40
+ exactly which arg names are query-bound per operation (see
41
+ [`docs/`](./docs/README.md) for the per-method breakdown).
42
+
43
+ ```js
44
+ // GET v1/symbiosis/sessions/{sessionId} -> sessionId consumed as a route token
45
+ const session = await web7.symbiosis.getSession({ sessionId });
46
+
47
+ // POST v1/symbiosis/sessions/{sessionId}/signals -> sessionId consumed, samples becomes the body
48
+ await web7.symbiosis.submitSignals({ sessionId, samples: [{ type: 'HeartRate', value: 72 }] });
49
+
50
+ // POST v1/symbiosis/sessions -> consentGranted/retention are [FromQuery] even
51
+ // though this is a POST, so they're sent on the URL, not as a JSON body
52
+ const session2 = await web7.symbiosis.startSession({ consentGranted: true, retention: 'Ephemeral' });
53
+ ```
54
+
55
+ Every response has the shape:
56
+
57
+ ```ts
58
+ interface OASISResponse<T = any> {
59
+ isError: boolean;
60
+ message: string | null;
61
+ result: T;
62
+ raw: any;
63
+ statusCode: number;
64
+ }
65
+ ```
66
+
67
+ ## Auth
68
+
69
+ WEB7 is an internal bio-symbiosis layer that sits behind the same OASIS
70
+ avatar identity as WEB4/WEB5/WEB6 - it has no avatar/login endpoints of its
71
+ own. Reuse a JWT you've already obtained elsewhere (e.g. from
72
+ `web4-oasis-api`'s `client.auth.login()`):
73
+
74
+ ```js
75
+ web7.setToken(jwtToken);
76
+ ```
77
+
78
+ ## Module examples
79
+
80
+ ### Symbiosis (`web7.symbiosis`)
81
+
82
+ ```js
83
+ const session = await web7.symbiosis.startSession({ consentGranted: true, retention: 'Ephemeral' });
84
+ const intentionState = await web7.symbiosis.submitSignals({
85
+ sessionId: session.result.id,
86
+ samples: [{ type: 'HeartRate', value: 72, timestamp: new Date().toISOString() }]
87
+ });
88
+ await web7.symbiosis.endSession({ sessionId: session.result.id });
89
+ ```
90
+
91
+ ### Collective Consciousness (`web7.collectiveConsciousness`)
92
+
93
+ ```js
94
+ const space = await web7.collectiveConsciousness.createSpace({ name: 'Morning Meditation' });
95
+ await web7.collectiveConsciousness.joinSpace({ spaceId: space.result.id, sessionId: session.result.id });
96
+ const field = await web7.collectiveConsciousness.getAggregateField({ spaceId: space.result.id });
97
+ ```
98
+
99
+ ## Module reference
100
+
101
+ 2 modules, 7 operations in total. Full per-method tables live in
102
+ [`docs/`](./docs/README.md).
103
+
104
+ | Client property | Route prefix | Operations |
105
+ | --- | --- | --- |
106
+ | `web7.collectiveConsciousness` | `v1/collective-consciousness` | 3 |
107
+ | `web7.symbiosis` | `v1/symbiosis` | 4 |
108
+
109
+ See [`docs/README.md`](./docs/README.md) for the full generated reference,
110
+ or [`docs/modules/`](./docs/modules) for per-module method tables with
111
+ parameter and route details.
112
+
113
+ ## Regenerating
114
+
115
+ The generated modules, type declarations and docs are produced from
116
+ `endpoints.json` (extracted from the WEB7 WebAPI controller source):
117
+
118
+ ```bash
119
+ npm run generate # src/modules/*.js + src/modules/index.js
120
+ npm run types # src/modules/*.d.ts + index.d.ts + src/core/types.d.ts
121
+ npm run docs # docs/README.md + docs/modules/*.md
122
+ ```
123
+
124
+ ## Testing
125
+
126
+ ```bash
127
+ npm test
128
+ ```
129
+
130
+ ## License
131
+
132
+ MIT
package/docs/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # WEB7 Symbiosis & Collective Consciousness API — JavaScript SDK Reference
2
+
3
+ Generated from `endpoints.json` (extracted from the WebAPI controllers) by
4
+ `scripts/generate-full-docs.js`. Regenerate the full pipeline after the API
5
+ changes:
6
+
7
+ ```
8
+ node scripts/extract-endpoints.js
9
+ node scripts/generate-modules.js
10
+ node scripts/generate-full-docs.js
11
+ ```
12
+
13
+ - [Module Reference](#module-reference) (2 modules, 7 operations)
14
+
15
+ ## Module Reference
16
+
17
+ | Client property | Route prefix | Operations |
18
+ | --- | --- | --- |
19
+ | [`web7.collectiveConsciousness`](modules/CollectiveConsciousness.md) | `v1/collective-consciousness` | 3 |
20
+ | [`web7.symbiosis`](modules/Symbiosis.md) | `v1/symbiosis` | 4 |
@@ -0,0 +1,162 @@
1
+ # CollectiveConsciousness — `web7.collectiveConsciousness`
2
+
3
+ Source controller: [`CollectiveConsciousnessController.cs`](https://github.com/NextGenSoftwareUK/OASIS2/blob/main/WEB7/NextGenSoftware.OASIS.Web7.WebAPI/Controllers/CollectiveConsciousnessController.cs)
4
+ Route prefix: `v1/collective-consciousness`
5
+ 3 operation(s).
6
+
7
+ Every method takes a single args object: any key matching a `{token}` in the route is substituted into the URL; everything else becomes the query string (GET/DELETE) or JSON body (POST/PUT). Every call resolves to the standard OASIS envelope:
8
+
9
+ ```ts
10
+ {
11
+ isError: boolean;
12
+ isWarning: boolean;
13
+ message: string;
14
+ errorCode?: string;
15
+ result: T; // see each endpoint's Response section below
16
+ }
17
+ ```
18
+
19
+ ## Operations
20
+
21
+ ### `createSpace`
22
+
23
+ Shared intention fields where multiple consenting symbiosis sessions co-create. Only the aggregate state is ever exposed.
24
+
25
+ **POST** `v1/collective-consciousness/spaces`
26
+
27
+ **Request**
28
+
29
+ Body fields:
30
+
31
+ | Field | Type |
32
+ | --- | --- |
33
+ | `name` | `string` |
34
+
35
+ **Response**
36
+
37
+ Standard `OASISResult` envelope (see top of this page) with:
38
+
39
+ `result` type: `CollectiveConsciousnessSpace`
40
+
41
+ | Field | Type |
42
+ | --- | --- |
43
+ | `Id` | `Guid` |
44
+ | `Name` | `string` |
45
+ | `ParticipantSessionIds` | `List<Guid>` |
46
+ | `AggregateState` | `IntentionState` |
47
+ | `CreatedUtc` | `DateTime` |
48
+
49
+ **Example**
50
+
51
+ ```js
52
+ const { isError, message, result } = await web7.collectiveConsciousness.createSpace({
53
+ name: 'example string'
54
+ });
55
+ if (isError) throw new Error(message);
56
+ console.log(result);
57
+ ```
58
+
59
+ Example response:
60
+
61
+ ```json
62
+ {
63
+ "isError": false,
64
+ "message": "",
65
+ "result": { "Id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "Name": "example string", "ParticipantSessionIds": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], "AggregateState": { "Focus": 1.0, "EmotionalValence": 1.0, "Arousal": 1.0, "CognitiveLoad": 1.0, "Features": { "<string>": 1.0 }, "ComputedUtc": "2026-01-01T00:00:00Z" }, "CreatedUtc": "2026-01-01T00:00:00Z" }
66
+ }
67
+ ```
68
+
69
+ ---
70
+
71
+ ### `getAggregateField`
72
+
73
+ **GET** `v1/collective-consciousness/spaces/{spaceId}/field`
74
+
75
+ Route parameters:
76
+
77
+ | Field | Type |
78
+ | --- | --- |
79
+ | `spaceId` | `Guid` |
80
+
81
+ **Request**
82
+
83
+ No request body.
84
+
85
+ **Response**
86
+
87
+ Standard `OASISResult` envelope (see top of this page) with:
88
+
89
+ `result` type: `CollectiveConsciousnessSpace`
90
+
91
+ | Field | Type |
92
+ | --- | --- |
93
+ | `Id` | `Guid` |
94
+ | `Name` | `string` |
95
+ | `ParticipantSessionIds` | `List<Guid>` |
96
+ | `AggregateState` | `IntentionState` |
97
+ | `CreatedUtc` | `DateTime` |
98
+
99
+ **Example**
100
+
101
+ ```js
102
+ const { isError, message, result } = await web7.collectiveConsciousness.getAggregateField({
103
+ spaceId: '<spaceId>'
104
+ });
105
+ if (isError) throw new Error(message);
106
+ console.log(result);
107
+ ```
108
+
109
+ Example response:
110
+
111
+ ```json
112
+ {
113
+ "isError": false,
114
+ "message": "",
115
+ "result": { "Id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "Name": "example string", "ParticipantSessionIds": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], "AggregateState": { "Focus": 1.0, "EmotionalValence": 1.0, "Arousal": 1.0, "CognitiveLoad": 1.0, "Features": { "<string>": 1.0 }, "ComputedUtc": "2026-01-01T00:00:00Z" }, "CreatedUtc": "2026-01-01T00:00:00Z" }
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ### `joinSpace`
122
+
123
+ **POST** `v1/collective-consciousness/spaces/{spaceId}/join/{sessionId}`
124
+
125
+ Route parameters:
126
+
127
+ | Field | Type |
128
+ | --- | --- |
129
+ | `spaceId` | `Guid` |
130
+ | `sessionId` | `Guid` |
131
+
132
+ **Request**
133
+
134
+ No request body.
135
+
136
+ **Response**
137
+
138
+ Standard `OASISResult` envelope (see top of this page) with:
139
+
140
+ `result` type: `bool`
141
+
142
+ **Example**
143
+
144
+ ```js
145
+ const { isError, message, result } = await web7.collectiveConsciousness.joinSpace({
146
+ spaceId: '<spaceId>',
147
+ sessionId: '<sessionId>'
148
+ });
149
+ if (isError) throw new Error(message);
150
+ console.log(result);
151
+ ```
152
+
153
+ Example response:
154
+
155
+ ```json
156
+ {
157
+ "isError": false,
158
+ "message": "",
159
+ "result": true
160
+ }
161
+ ```
162
+
@@ -0,0 +1,238 @@
1
+ # Symbiosis — `web7.symbiosis`
2
+
3
+ Source controller: [`SymbiosisController.cs`](https://github.com/NextGenSoftwareUK/OASIS2/blob/main/WEB7/NextGenSoftware.OASIS.Web7.WebAPI/Controllers/SymbiosisController.cs)
4
+ Route prefix: `v1/symbiosis`
5
+ 4 operation(s).
6
+
7
+ Every method takes a single args object: any key matching a `{token}` in the route is substituted into the URL; everything else becomes the query string (GET/DELETE) or JSON body (POST/PUT). Every call resolves to the standard OASIS envelope:
8
+
9
+ ```ts
10
+ {
11
+ isError: boolean;
12
+ isWarning: boolean;
13
+ message: string;
14
+ errorCode?: string;
15
+ result: T; // see each endpoint's Response section below
16
+ }
17
+ ```
18
+
19
+ ## Operations
20
+
21
+ ### `endSession`
22
+
23
+ Ends the session instantly - with Ephemeral retention (the default), all signal-derived data is wiped immediately.
24
+
25
+ **POST** `v1/symbiosis/sessions/{sessionId}/end`
26
+
27
+ Route parameters:
28
+
29
+ | Field | Type |
30
+ | --- | --- |
31
+ | `sessionId` | `Guid` |
32
+
33
+ **Request**
34
+
35
+ No request body.
36
+
37
+ **Response**
38
+
39
+ Standard `OASISResult` envelope (see top of this page) with:
40
+
41
+ `result` type: `bool`
42
+
43
+ **Example**
44
+
45
+ ```js
46
+ const { isError, message, result } = await web7.symbiosis.endSession({
47
+ sessionId: '<sessionId>'
48
+ });
49
+ if (isError) throw new Error(message);
50
+ console.log(result);
51
+ ```
52
+
53
+ Example response:
54
+
55
+ ```json
56
+ {
57
+ "isError": false,
58
+ "message": "",
59
+ "result": true
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ### `getSession`
66
+
67
+ **GET** `v1/symbiosis/sessions/{sessionId}`
68
+
69
+ Route parameters:
70
+
71
+ | Field | Type |
72
+ | --- | --- |
73
+ | `sessionId` | `Guid` |
74
+
75
+ **Request**
76
+
77
+ No request body.
78
+
79
+ **Response**
80
+
81
+ Standard `OASISResult` envelope (see top of this page) with:
82
+
83
+ `result` type: `SymbiosisSession`
84
+
85
+ | Field | Type |
86
+ | --- | --- |
87
+ | `Id` | `Guid` |
88
+ | `AvatarId` | `Guid` |
89
+ | `ConsentGranted` | `bool` |
90
+ | `IsActive` | `bool` |
91
+ | `Retention` | `Enums.RetentionMode` |
92
+ | `StartedUtc` | `DateTime` |
93
+ | `EndedUtc` | `DateTime?` |
94
+ | `LastIntentionState` | `IntentionState` |
95
+ | `AuditLog` | `List<string>` |
96
+
97
+ **Example**
98
+
99
+ ```js
100
+ const { isError, message, result } = await web7.symbiosis.getSession({
101
+ sessionId: '<sessionId>'
102
+ });
103
+ if (isError) throw new Error(message);
104
+ console.log(result);
105
+ ```
106
+
107
+ Example response:
108
+
109
+ ```json
110
+ {
111
+ "isError": false,
112
+ "message": "",
113
+ "result": { "Id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "AvatarId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "ConsentGranted": true, "IsActive": true, "Retention": /* <Enums.RetentionMode> */, "StartedUtc": "2026-01-01T00:00:00Z", "EndedUtc": "2026-01-01T00:00:00Z", "LastIntentionState": { "Focus": 1.0, "EmotionalValence": 1.0, "Arousal": 1.0, "CognitiveLoad": 1.0, "Features": { "<string>": 1.0 }, "ComputedUtc": "2026-01-01T00:00:00Z" }, "AuditLog": ["example string"] }
114
+ }
115
+ ```
116
+
117
+ ---
118
+
119
+ ### `startSession`
120
+
121
+ Starts a new symbiosis session. ConsentGranted must be explicitly true.
122
+
123
+ **POST** `v1/symbiosis/sessions`
124
+
125
+ **Request**
126
+
127
+ Body fields:
128
+
129
+ | Field | Type |
130
+ | --- | --- |
131
+ | `consentGranted` | `bool` |
132
+ | `retention` | `RetentionMode (optional)` |
133
+
134
+ **Response**
135
+
136
+ Standard `OASISResult` envelope (see top of this page) with:
137
+
138
+ `result` type: `SymbiosisSession`
139
+
140
+ | Field | Type |
141
+ | --- | --- |
142
+ | `Id` | `Guid` |
143
+ | `AvatarId` | `Guid` |
144
+ | `ConsentGranted` | `bool` |
145
+ | `IsActive` | `bool` |
146
+ | `Retention` | `Enums.RetentionMode` |
147
+ | `StartedUtc` | `DateTime` |
148
+ | `EndedUtc` | `DateTime?` |
149
+ | `LastIntentionState` | `IntentionState` |
150
+ | `AuditLog` | `List<string>` |
151
+
152
+ **Example**
153
+
154
+ ```js
155
+ const { isError, message, result } = await web7.symbiosis.startSession({
156
+ consentGranted: true,
157
+ retention: '<retention>'
158
+ });
159
+ if (isError) throw new Error(message);
160
+ console.log(result);
161
+ ```
162
+
163
+ Example response:
164
+
165
+ ```json
166
+ {
167
+ "isError": false,
168
+ "message": "",
169
+ "result": { "Id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "AvatarId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "ConsentGranted": true, "IsActive": true, "Retention": /* <Enums.RetentionMode> */, "StartedUtc": "2026-01-01T00:00:00Z", "EndedUtc": "2026-01-01T00:00:00Z", "LastIntentionState": { "Focus": 1.0, "EmotionalValence": 1.0, "Arousal": 1.0, "CognitiveLoad": 1.0, "Features": { "<string>": 1.0 }, "ComputedUtc": "2026-01-01T00:00:00Z" }, "AuditLog": ["example string"] }
170
+ }
171
+ ```
172
+
173
+ ---
174
+
175
+ ### `submitSignals`
176
+
177
+ Submits a batch of raw bio-signal samples and returns the freshly computed intention state.
178
+
179
+ **POST** `v1/symbiosis/sessions/{sessionId}/signals`
180
+
181
+ Route parameters:
182
+
183
+ | Field | Type |
184
+ | --- | --- |
185
+ | `sessionId` | `Guid` |
186
+
187
+ **Request**
188
+
189
+ Body type: `BioSignalSample` (array)
190
+
191
+ | Field | Type |
192
+ | --- | --- |
193
+ | `SignalType` | `BioSignalType` |
194
+ | `Channel` | `string` |
195
+ | `SampleRateHz` | `double` |
196
+ | `Values` | `List<double>` |
197
+ | `CapturedUtc` | `DateTime` |
198
+
199
+ **Response**
200
+
201
+ Standard `OASISResult` envelope (see top of this page) with:
202
+
203
+ `result` type: `IntentionState`
204
+
205
+ | Field | Type |
206
+ | --- | --- |
207
+ | `Focus` | `double` |
208
+ | `EmotionalValence` | `double` |
209
+ | `Arousal` | `double` |
210
+ | `CognitiveLoad` | `double` |
211
+ | `Features` | `Dictionary<string, double>` |
212
+ | `ComputedUtc` | `DateTime` |
213
+
214
+ **Example**
215
+
216
+ ```js
217
+ const { isError, message, result } = await web7.symbiosis.submitSignals({
218
+ sessionId: '<sessionId>',
219
+ signalType: { },
220
+ channel: "example string",
221
+ sampleRateHz: 1.0,
222
+ values: [1.0],
223
+ capturedUtc: "2026-01-01T00:00:00Z"
224
+ });
225
+ if (isError) throw new Error(message);
226
+ console.log(result);
227
+ ```
228
+
229
+ Example response:
230
+
231
+ ```json
232
+ {
233
+ "isError": false,
234
+ "message": "",
235
+ "result": { "Focus": 1.0, "EmotionalValence": 1.0, "Arousal": 1.0, "CognitiveLoad": 1.0, "Features": { "<string>": 1.0 }, "ComputedUtc": "2026-01-01T00:00:00Z" }
236
+ }
237
+ ```
238
+
package/index.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ // AUTO-GENERATED by scripts/generate-types.js - do not hand-edit.
2
+ import type { OASISResponse, OASISSession } from './src/core/types';
3
+ import type { CollectiveConsciousnessModule } from './src/modules/CollectiveConsciousness';
4
+ import type { SymbiosisModule } from './src/modules/Symbiosis';
5
+
6
+ export type { OASISResponse, OASISSession };
7
+
8
+ export interface Web7ClientOptions {
9
+ baseUrl?: string;
10
+ persistSession?: boolean;
11
+ fetchImpl?: typeof fetch;
12
+ }
13
+
14
+ export declare class HttpClient {
15
+ constructor(options?: { baseUrl?: string; tokenStore?: unknown; fetchImpl?: typeof fetch });
16
+ setBaseUrl(baseUrl: string): void;
17
+ request(verb: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, options?: Record<string, any>): Promise<OASISResponse>;
18
+ get(path: string, options?: Record<string, any>): Promise<OASISResponse>;
19
+ post(path: string, options?: Record<string, any>): Promise<OASISResponse>;
20
+ put(path: string, options?: Record<string, any>): Promise<OASISResponse>;
21
+ delete(path: string, options?: Record<string, any>): Promise<OASISResponse>;
22
+ }
23
+
24
+ export declare class TokenStore {
25
+ constructor(options?: { persist?: boolean });
26
+ getSession(): OASISSession | null;
27
+ getToken(): string | null;
28
+ setSession(session: OASISSession | null): void;
29
+ clear(): void;
30
+ }
31
+
32
+ export declare const DEFAULT_BASE_URL: string;
33
+
34
+ export declare class Web7Client {
35
+ constructor(options?: Web7ClientOptions);
36
+ readonly http: HttpClient;
37
+ readonly tokenStore: TokenStore;
38
+ readonly collectiveConsciousness: CollectiveConsciousnessModule;
39
+ readonly symbiosis: SymbiosisModule;
40
+ setBaseUrl(baseUrl: string): void;
41
+ setToken(jwtToken: string, sessionExtras?: Partial<OASISSession>): void;
42
+ }
43
+
44
+ export default Web7Client;
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('./src/index');
package/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import cjs from './index.js';
2
+
3
+ export const { Web7Client, HttpClient, TokenStore, DEFAULT_BASE_URL } = cjs;
4
+ export default Web7Client;
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@oasisomniverse/web7-api",
3
+ "version": "1.0.0",
4
+ "publishConfig": { "access": "public" },
5
+ "description": "Isomorphic (Node + browser) JavaScript/TypeScript-friendly client for the WEB7 OASIS Symbiosis API - consenting bio-signal symbiosis sessions and shared collective-consciousness fields built on the OASIS2 WEB7 WebAPI.",
6
+ "main": "index.js",
7
+ "module": "index.mjs",
8
+ "types": "index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./index.d.ts",
12
+ "import": "./index.mjs",
13
+ "require": "./index.js"
14
+ }
15
+ },
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "files": [
20
+ "index.js",
21
+ "index.mjs",
22
+ "index.d.ts",
23
+ "src",
24
+ "docs"
25
+ ],
26
+ "scripts": {
27
+ "generate": "node scripts/generate-modules.js",
28
+ "docs": "node scripts/generate-docs.js",
29
+ "types": "node scripts/generate-types.js",
30
+ "test": "node --test test"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/NextGenSoftwareUK/OASIS-API-Javascript-Package-WEB7.git"
35
+ },
36
+ "author": "NextGen Software Ltd",
37
+ "license": "MIT",
38
+ "keywords": [
39
+ "WEB7 Symbiosis API",
40
+ "WEB7 WebAPI",
41
+ "OASIS Symbiosis",
42
+ "Bio-Signal Processing",
43
+ "Intention Engine",
44
+ "Collective Consciousness",
45
+ "Consent-Based Sessions",
46
+ "OASIS API",
47
+ "WEB 4",
48
+ "WEB 5",
49
+ "WEB 6",
50
+ "WEB 7",
51
+ "Blockchain",
52
+ "Interoperable",
53
+ "Metaverse",
54
+ "Aggregation",
55
+ "HOT-Swappable-Architecture",
56
+ "Decentralised",
57
+ "Distributed",
58
+ "Abstraction-Layer",
59
+ "Multi-Network",
60
+ "SSO",
61
+ "Agent-Centric",
62
+ "GOD-Protocol/API",
63
+ "More Coming..."
64
+ ]
65
+ }
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ const DEFAULT_BASE_URL = 'https://api.web7.oasisomniverse.one';
4
+
5
+ function buildQueryString(query) {
6
+ const entries = Object.entries(query || {}).filter(([, v]) => v !== undefined && v !== null);
7
+ if (!entries.length) return '';
8
+ const params = new URLSearchParams();
9
+ for (const [key, value] of entries) {
10
+ params.set(key, typeof value === 'object' ? JSON.stringify(value) : String(value));
11
+ }
12
+ return `?${params.toString()}`;
13
+ }
14
+
15
+ /**
16
+ * Thin isomorphic HTTP client around the global fetch API (Node 18+, all modern browsers).
17
+ * Every WEB7 Symbiosis & Collective Consciousness API call ultimately goes through `request()` below - there are no mocked
18
+ * or stubbed responses anywhere in this SDK.
19
+ */
20
+ class HttpClient {
21
+ constructor({ baseUrl = DEFAULT_BASE_URL, tokenStore, fetchImpl = globalThis.fetch } = {}) {
22
+ if (!fetchImpl) {
23
+ throw new Error(
24
+ 'No global fetch implementation found. Use Node 18+, a modern browser, or pass { fetchImpl } explicitly.'
25
+ );
26
+ }
27
+ this.baseUrl = baseUrl.replace(/\/+$/, '');
28
+ this.tokenStore = tokenStore;
29
+ this.fetchImpl = fetchImpl;
30
+ }
31
+
32
+ setBaseUrl(baseUrl) {
33
+ this.baseUrl = baseUrl.replace(/\/+$/, '');
34
+ }
35
+
36
+ /**
37
+ * @param {string} verb GET | POST | PUT | DELETE
38
+ * @param {string} path e.g. "v1/complete"
39
+ * @param {object} [options]
40
+ * @param {object} [options.query] query string params (GET/DELETE)
41
+ * @param {object} [options.body] JSON body (POST/PUT/DELETE)
42
+ * @param {boolean} [options.auth] attach Authorization: Bearer <token> (default true)
43
+ * @param {string} [options.token] override token for this single request
44
+ */
45
+ async request(verb, path, { query, body, auth = true, token } = {}) {
46
+ const url = `${this.baseUrl}/${path.replace(/^\/+/, '')}${buildQueryString(query)}`;
47
+ const headers = {
48
+ 'Content-Type': 'application/json',
49
+ Accept: 'application/json'
50
+ };
51
+
52
+ const bearer = token || (auth ? this.tokenStore?.getToken() : null);
53
+ if (bearer) headers.Authorization = `Bearer ${bearer}`;
54
+
55
+ const init = { method: verb, headers };
56
+ if (body !== undefined && verb !== 'GET') init.body = JSON.stringify(body);
57
+
58
+ let res;
59
+ try {
60
+ res = await this.fetchImpl(url, init);
61
+ } catch (err) {
62
+ return { isError: true, message: `Network error calling ${url}: ${err.message}`, exception: err };
63
+ }
64
+
65
+ const text = await res.text();
66
+ let json;
67
+ try {
68
+ json = text ? JSON.parse(text) : null;
69
+ } catch {
70
+ json = null;
71
+ }
72
+
73
+ if (!res.ok) {
74
+ const message =
75
+ json?.result?.message || json?.message || json?.title || `Request failed with status ${res.status}`;
76
+ return { isError: true, message, statusCode: res.status, raw: json };
77
+ }
78
+
79
+ // OASIS responses are typically { isError, message, result: { isError, message, result: <payload> } }.
80
+ // We surface the innermost payload as `.result` while keeping the full envelope available as `.raw`.
81
+ const inner = json?.result !== undefined ? json.result : json;
82
+ const payload = inner?.result !== undefined ? inner.result : inner;
83
+
84
+ return {
85
+ isError: Boolean(inner?.isError || json?.isError),
86
+ message: inner?.message || json?.message || null,
87
+ result: payload,
88
+ raw: json,
89
+ statusCode: res.status
90
+ };
91
+ }
92
+
93
+ get(path, options) {
94
+ return this.request('GET', path, options);
95
+ }
96
+
97
+ post(path, options) {
98
+ return this.request('POST', path, options);
99
+ }
100
+
101
+ put(path, options) {
102
+ return this.request('PUT', path, options);
103
+ }
104
+
105
+ delete(path, options) {
106
+ return this.request('DELETE', path, options);
107
+ }
108
+ }
109
+
110
+ module.exports = { HttpClient, DEFAULT_BASE_URL };
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ const TOKEN_PATTERN = /\{(\w+)(?::\w+)?\}/g;
4
+
5
+ /**
6
+ * Resolves a route template like "get-by-id/{id}" against an args object,
7
+ * substituting path tokens and returning the resolved path plus whatever
8
+ * args were *not* consumed as path tokens (these become the query/body).
9
+ */
10
+ function resolveRoute(routeTemplate, args = {}) {
11
+ const consumed = new Set();
12
+ const path = routeTemplate.replace(TOKEN_PATTERN, (match, name) => {
13
+ const key = Object.keys(args).find((k) => k.toLowerCase() === name.toLowerCase());
14
+ consumed.add(key);
15
+ const value = key !== undefined ? args[key] : undefined;
16
+ if (value === undefined) {
17
+ throw new Error(`Missing required route parameter "${name}" for route "${routeTemplate}"`);
18
+ }
19
+ return encodeURIComponent(value);
20
+ });
21
+
22
+ const rest = {};
23
+ for (const [key, value] of Object.entries(args)) {
24
+ if (!consumed.has(key)) rest[key] = value;
25
+ }
26
+
27
+ return { path, rest };
28
+ }
29
+
30
+ function takeKey(obj, name) {
31
+ const matchKey = Object.keys(obj).find((k) => k.toLowerCase() === name.toLowerCase());
32
+ if (matchKey === undefined) return { found: false, value: undefined };
33
+ const value = obj[matchKey];
34
+ delete obj[matchKey];
35
+ return { found: true, value };
36
+ }
37
+
38
+ /**
39
+ * Builds a bound method for a single WEB7 endpoint operation.
40
+ * @param {import('./httpClient').HttpClient} http
41
+ * @param {string} routePrefix e.g. "api/avatar"
42
+ * @param {string} verb GET | POST | PUT | DELETE
43
+ * @param {string} route route template relative to routePrefix, e.g. "get-by-id/{id}"
44
+ * @param {object} [opts]
45
+ * @param {string[]} [opts.query] arg names that ASP.NET binds from the query
46
+ * string on this action regardless of HTTP verb (e.g. `[FromQuery]` flags
47
+ * mixed into an otherwise-body-bound POST/PUT action). Always sent as query.
48
+ * @param {string} [opts.bodyParam] when the action's entire request body is a
49
+ * single `[FromBody]` parameter (primitive or object), the JSON body is
50
+ * that arg's value directly rather than the leftover-args object wrapped
51
+ * around it.
52
+ */
53
+ function makeOperation(http, routePrefix, verb, route, opts = {}) {
54
+ const declaredQueryKeys = opts.query || [];
55
+ const bodyParam = opts.bodyParam;
56
+
57
+ return async function operation(args = {}) {
58
+ const { path, rest } = resolveRoute(route, args);
59
+ const fullPath = path ? `${routePrefix}/${path}` : routePrefix;
60
+
61
+ const query = {};
62
+ for (const key of declaredQueryKeys) {
63
+ const { found, value } = takeKey(rest, key);
64
+ if (found) query[key] = value;
65
+ }
66
+
67
+ let body;
68
+ if (bodyParam) {
69
+ const { found, value } = takeKey(rest, bodyParam);
70
+ if (found) body = value;
71
+ // Any args left over that we don't recognize still get sent (as query)
72
+ // rather than silently dropped.
73
+ Object.assign(query, rest);
74
+ } else if (verb === 'GET' || verb === 'DELETE') {
75
+ Object.assign(query, rest);
76
+ } else {
77
+ body = Object.keys(rest).length ? rest : undefined;
78
+ }
79
+
80
+ const hasQuery = Object.keys(query).length > 0;
81
+ return http.request(verb, fullPath, { query: hasQuery ? query : undefined, body });
82
+ };
83
+ }
84
+
85
+ module.exports = { resolveRoute, makeOperation };
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ const hasLocalStorage = typeof globalThis.localStorage !== 'undefined';
4
+ const STORAGE_KEY = 'oasis_session';
5
+
6
+ /**
7
+ * Holds the current JWT/avatar session for the SDK.
8
+ * In the browser it persists to localStorage by default; in Node (or when
9
+ * persistence is disabled) it simply lives in memory for the lifetime of
10
+ * the client instance. Callers can always set/get/clear explicitly.
11
+ */
12
+ class TokenStore {
13
+ constructor({ persist = hasLocalStorage } = {}) {
14
+ this.persist = persist;
15
+ this._session = null;
16
+
17
+ if (this.persist) {
18
+ try {
19
+ const raw = globalThis.localStorage.getItem(STORAGE_KEY);
20
+ if (raw) this._session = JSON.parse(raw);
21
+ } catch {
22
+ this._session = null;
23
+ }
24
+ }
25
+ }
26
+
27
+ getSession() {
28
+ return this._session;
29
+ }
30
+
31
+ getToken() {
32
+ return this._session?.jwtToken || this._session?.token || null;
33
+ }
34
+
35
+ setSession(session) {
36
+ this._session = session || null;
37
+ if (this.persist) {
38
+ try {
39
+ if (session) globalThis.localStorage.setItem(STORAGE_KEY, JSON.stringify(session));
40
+ else globalThis.localStorage.removeItem(STORAGE_KEY);
41
+ } catch {
42
+ // Storage unavailable (e.g. private browsing) - in-memory session still works.
43
+ }
44
+ }
45
+ }
46
+
47
+ clear() {
48
+ this.setSession(null);
49
+ }
50
+ }
51
+
52
+ module.exports = { TokenStore };
@@ -0,0 +1,18 @@
1
+ // AUTO-GENERATED by scripts/generate-types.js - do not hand-edit.
2
+ export interface OASISResponse<T = any> {
3
+ isError: boolean;
4
+ message: string | null;
5
+ result: T;
6
+ raw: any;
7
+ statusCode: number;
8
+ }
9
+
10
+ export interface OASISSession {
11
+ avatarId: string;
12
+ username: string;
13
+ email: string;
14
+ firstName?: string;
15
+ lastName?: string;
16
+ jwtToken: string;
17
+ refreshToken?: string;
18
+ }
package/src/index.js ADDED
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ const { HttpClient, DEFAULT_BASE_URL } = require('./core/httpClient');
4
+ const { TokenStore } = require('./core/tokenStore');
5
+ const { attachGeneratedModules } = require('./modules/index');
6
+
7
+ /**
8
+ * Main SDK entry point. Works in Node 18+ and any modern browser.
9
+ *
10
+ * const { Web7Client } = require('@oasisomniverse/web7-api');
11
+ * const web7 = new Web7Client({ baseUrl: 'https://api.web7.oasisomniverse.one' });
12
+ * web7.setToken(jwtToken); // reuse a WEB4 OASIS JWT - WEB7 has no auth of its own
13
+ * const session = await web7.symbiosis.startSession({ avatarId, consentGranted: true });
14
+ *
15
+ * Every controller on the WEB7 Symbiosis WebAPI is reachable as a lowerCamel
16
+ * property (web7.symbiosis, web7.collectiveConsciousness). Generated methods
17
+ * take a single args object; route template tokens (e.g. {sessionId}) are
18
+ * consumed from it automatically, remaining keys become the query string
19
+ * (GET/DELETE) or JSON body (POST/PUT).
20
+ */
21
+ class Web7Client {
22
+ constructor({ baseUrl = DEFAULT_BASE_URL, persistSession, fetchImpl } = {}) {
23
+ this.tokenStore = new TokenStore({ persist: persistSession });
24
+ this.http = new HttpClient({ baseUrl, tokenStore: this.tokenStore, fetchImpl });
25
+
26
+ attachGeneratedModules(this, this.http);
27
+ }
28
+
29
+ setBaseUrl(baseUrl) {
30
+ this.http.setBaseUrl(baseUrl);
31
+ }
32
+
33
+ /**
34
+ * WEB7 is an internal bio-symbiosis layer sitting behind the same OASIS
35
+ * identity as WEB4/WEB5/WEB6 - it has no avatar/auth endpoints of its own.
36
+ * Reuse a JWT you already obtained from the WEB4 OASIS API (or your own
37
+ * backend) here.
38
+ */
39
+ setToken(jwtToken, sessionExtras = {}) {
40
+ this.tokenStore.setSession({ ...sessionExtras, jwtToken });
41
+ }
42
+ }
43
+
44
+ module.exports = { Web7Client, HttpClient, TokenStore, DEFAULT_BASE_URL };
45
+ module.exports.default = Web7Client;
@@ -0,0 +1,15 @@
1
+ // AUTO-GENERATED by scripts/generate-types.js - do not hand-edit.
2
+ import type { OASISResponse } from '../core/types';
3
+
4
+ export declare class CollectiveConsciousnessModule {
5
+ constructor(http: unknown);
6
+
7
+ /** POST v1/collective-consciousness/spaces (query: name) */
8
+ createSpace(args?: Record<string, any>): Promise<OASISResponse>;
9
+
10
+ /** GET v1/collective-consciousness/spaces/{spaceId}/field */
11
+ getAggregateField(args?: Record<string, any>): Promise<OASISResponse>;
12
+
13
+ /** POST v1/collective-consciousness/spaces/{spaceId}/join/{sessionId} */
14
+ joinSpace(args?: Record<string, any>): Promise<OASISResponse>;
15
+ }
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ // AUTO-GENERATED by scripts/generate-modules.js from endpoints.json - do not hand-edit.
4
+ // Regenerate with: node scripts/generate-modules.js
5
+
6
+ const { makeOperation } = require('../core/routeHelper');
7
+
8
+ /**
9
+ * Generated wrapper for v1/collective-consciousness (source: WEB7 Symbiosis WebAPI CollectiveConsciousnessController.cs).
10
+ * Every method takes a single args object: path-template tokens (e.g. {id})
11
+ * are consumed from it automatically; any remaining keys are sent as the
12
+ * query string (GET/DELETE) or JSON body (POST/PUT).
13
+ */
14
+ class CollectiveConsciousnessModule {
15
+ constructor(http) {
16
+ this._http = http;
17
+
18
+ // POST v1/collective-consciousness/spaces (query: name)
19
+ this.createSpace = makeOperation(http, "v1/collective-consciousness", "POST", "spaces", {"query":["name"]});
20
+ // GET v1/collective-consciousness/spaces/{spaceId}/field
21
+ this.getAggregateField = makeOperation(http, "v1/collective-consciousness", "GET", "spaces/{spaceId}/field");
22
+ // POST v1/collective-consciousness/spaces/{spaceId}/join/{sessionId}
23
+ this.joinSpace = makeOperation(http, "v1/collective-consciousness", "POST", "spaces/{spaceId}/join/{sessionId}");
24
+ }
25
+ }
26
+
27
+ module.exports = { CollectiveConsciousnessModule };
@@ -0,0 +1,18 @@
1
+ // AUTO-GENERATED by scripts/generate-types.js - do not hand-edit.
2
+ import type { OASISResponse } from '../core/types';
3
+
4
+ export declare class SymbiosisModule {
5
+ constructor(http: unknown);
6
+
7
+ /** POST v1/symbiosis/sessions/{sessionId}/end */
8
+ endSession(args?: Record<string, any>): Promise<OASISResponse>;
9
+
10
+ /** GET v1/symbiosis/sessions/{sessionId} */
11
+ getSession(args?: Record<string, any>): Promise<OASISResponse>;
12
+
13
+ /** POST v1/symbiosis/sessions (query: consentGranted, retention) */
14
+ startSession(args?: Record<string, any>): Promise<OASISResponse>;
15
+
16
+ /** POST v1/symbiosis/sessions/{sessionId}/signals */
17
+ submitSignals(args?: Record<string, any>): Promise<OASISResponse>;
18
+ }
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ // AUTO-GENERATED by scripts/generate-modules.js from endpoints.json - do not hand-edit.
4
+ // Regenerate with: node scripts/generate-modules.js
5
+
6
+ const { makeOperation } = require('../core/routeHelper');
7
+
8
+ /**
9
+ * Generated wrapper for v1/symbiosis (source: WEB7 Symbiosis WebAPI SymbiosisController.cs).
10
+ * Every method takes a single args object: path-template tokens (e.g. {id})
11
+ * are consumed from it automatically; any remaining keys are sent as the
12
+ * query string (GET/DELETE) or JSON body (POST/PUT).
13
+ */
14
+ class SymbiosisModule {
15
+ constructor(http) {
16
+ this._http = http;
17
+
18
+ // POST v1/symbiosis/sessions/{sessionId}/end
19
+ this.endSession = makeOperation(http, "v1/symbiosis", "POST", "sessions/{sessionId}/end");
20
+ // GET v1/symbiosis/sessions/{sessionId}
21
+ this.getSession = makeOperation(http, "v1/symbiosis", "GET", "sessions/{sessionId}");
22
+ // POST v1/symbiosis/sessions (query: consentGranted, retention)
23
+ this.startSession = makeOperation(http, "v1/symbiosis", "POST", "sessions", {"query":["consentGranted","retention"]});
24
+ // POST v1/symbiosis/sessions/{sessionId}/signals
25
+ this.submitSignals = makeOperation(http, "v1/symbiosis", "POST", "sessions/{sessionId}/signals");
26
+ }
27
+ }
28
+
29
+ module.exports = { SymbiosisModule };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ // AUTO-GENERATED by scripts/generate-modules.js - do not hand-edit.
4
+ const { CollectiveConsciousnessModule } = require('./CollectiveConsciousness');
5
+ const { SymbiosisModule } = require('./Symbiosis');
6
+
7
+ /**
8
+ * Attaches every generated module to the client under its lowerCamel controller
9
+ * name (e.g. client.completion, client.images, client.holonicMemory).
10
+ */
11
+ function attachGeneratedModules(client, http) {
12
+ client.collectiveConsciousness = client.collectiveConsciousness || new CollectiveConsciousnessModule(http);
13
+ client.symbiosis = client.symbiosis || new SymbiosisModule(http);
14
+ return client;
15
+ }
16
+
17
+ module.exports = { attachGeneratedModules };