@ibgib/space-gib 0.0.9 → 0.0.13

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +1 -0
  3. package/dist/client/bootstrap.mjs +33 -33
  4. package/dist/client/bootstrap.mjs.map +3 -3
  5. package/dist/client/chunk-ROJZUPPE.mjs +19 -0
  6. package/dist/client/chunk-ROJZUPPE.mjs.map +7 -0
  7. package/dist/client/chunk-WJHRARK6.mjs +2329 -0
  8. package/dist/client/chunk-WJHRARK6.mjs.map +7 -0
  9. package/dist/client/index.mjs +22 -1
  10. package/dist/client/index.mjs.map +4 -4
  11. package/dist/client/script.mjs +1 -1
  12. package/dist/server/server.mjs +19147 -18210
  13. package/dist/server/server.mjs.map +4 -4
  14. package/package.json +4 -4
  15. package/space-gib.localhost-1785337158142.log +75 -0
  16. package/src/client/AUTO-GENERATED-version.mts +1 -1
  17. package/src/client/README.md +1 -1
  18. package/src/client/api/space-gib-api-bridge.mts +8 -224
  19. package/src/client/ui/shell/space-gib-shell-service.mts +68 -18
  20. package/src/common/keystone-policies.mts +1 -1
  21. package/src/server/README.md +3 -2
  22. package/src/server/server.mts +13 -32
  23. package/src/server/test.json +0 -0
  24. package/dist/client/chunk-ACIGPCQW.mjs +0 -2407
  25. package/dist/client/chunk-ACIGPCQW.mjs.map +0 -7
  26. package/dist/client/chunk-QRMTJE6M.mjs +0 -42
  27. package/dist/client/chunk-QRMTJE6M.mjs.map +0 -7
  28. package/space-gib.localhost-1783713259760.log +0 -45
  29. package/src/client/components/identity-header/IMPLEMENTATION.md +0 -45
  30. package/src/client/components/identity-header/identity-header.css +0 -112
  31. package/src/client/components/identity-header/identity-header.html +0 -11
  32. package/src/client/components/identity-header/identity-header.mts +0 -439
  33. package/src/client/components/identity-manager/IMPLEMENTATION.md +0 -100
  34. package/src/client/components/identity-manager/identity-manager.css +0 -171
  35. package/src/client/components/identity-manager/identity-manager.html +0 -19
  36. package/src/client/components/identity-manager/identity-manager.mts +0 -639
  37. package/src/client/components/keystone-creator/keystone-creator.css +0 -65
  38. package/src/client/components/keystone-creator/keystone-creator.html +0 -41
  39. package/src/client/components/keystone-creator/keystone-creator.mts +0 -443
  40. package/src/client/components/keystone-details/keystone-details.css +0 -611
  41. package/src/client/components/keystone-details/keystone-details.html +0 -151
  42. package/src/client/components/keystone-details/keystone-details.mts +0 -1213
  43. package/src/client/components/keystone-scrubber/SCRUBBER_IMPLEMENTATION.md +0 -33
  44. package/src/client/components/keystone-scrubber/keystone-scrubber.css +0 -46
  45. package/src/client/components/keystone-scrubber/keystone-scrubber.html +0 -15
  46. package/src/client/components/keystone-scrubber/keystone-scrubber.mts +0 -356
  47. package/src/server/bootstrap-helper.mts +0 -141
  48. package/src/server/bootstrap-helper.respec.mts +0 -100
  49. package/src/server/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts +0 -85
  50. package/src/server/path-constants.mts +0 -101
  51. package/src/server/path-helper.mts +0 -101
  52. package/src/server/path-helper.respec.mts +0 -99
  53. package/src/server/serve-gib/CHANGELOG.md +0 -29
  54. package/src/server/serve-gib/README.md +0 -43
  55. package/src/server/serve-gib/constants.mts +0 -1
  56. package/src/server/serve-gib/handlers/api/debug/ws-echo.handler.mts +0 -105
  57. package/src/server/serve-gib/handlers/api/health.handler.mts +0 -23
  58. package/src/server/serve-gib/handlers/api/health.respec.mts +0 -51
  59. package/src/server/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts +0 -49
  60. package/src/server/serve-gib/handlers/api/ibgib/ibgib.handler.mts +0 -176
  61. package/src/server/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts +0 -150
  62. package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +0 -146
  63. package/src/server/serve-gib/handlers/api/keystone/keystone-get.handler.mts +0 -198
  64. package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +0 -107
  65. package/src/server/serve-gib/handlers/api/keystone/keystone-handler-types.mts +0 -29
  66. package/src/server/serve-gib/handlers/api/keystone/keystone-post.handler.mts +0 -55
  67. package/src/server/serve-gib/handlers/api/keystone/keystone-post.respec.mts +0 -130
  68. package/src/server/serve-gib/handlers/api/keystone/sso-config.handler.mts +0 -66
  69. package/src/server/serve-gib/handlers/api/keystone/sso-link.handler.mts +0 -140
  70. package/src/server/serve-gib/handlers/api/keystone/sso-login.handler.mts +0 -190
  71. package/src/server/serve-gib/handlers/error-handler.mts +0 -36
  72. package/src/server/serve-gib/handlers/handler-base.mts +0 -383
  73. package/src/server/serve-gib/handlers/static-handler.mts +0 -82
  74. package/src/server/serve-gib/handlers/ws/sync-upgrade-handler-base.mts +0 -233
  75. package/src/server/serve-gib/handlers/ws/sync-upgrade.handler.mts +0 -24
  76. package/src/server/serve-gib/handlers/ws/ws-helper.mts +0 -216
  77. package/src/server/serve-gib/handlers/ws/ws-types.mts +0 -53
  78. package/src/server/serve-gib/serve-gib-helpers.mts +0 -32
  79. package/src/server/serve-gib/serve-gib-v1.mts +0 -172
  80. package/src/server/serve-gib/serve-gib.respec.mts +0 -90
  81. package/src/server/serve-gib/types.mts +0 -102
  82. package/src/server/server-constants.mts +0 -2
@@ -1,172 +0,0 @@
1
- /**
2
- * @module serve-gib/serve-gib-v1
3
- *
4
- * The main entry point for processing incoming requests in the serve-gib
5
- * framework.
6
- */
7
-
8
- import { IncomingMessage, ServerResponse } from 'node:http';
9
-
10
- import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
11
-
12
- import { GLOBAL_LOG_A_LOT } from './constants.mjs';
13
- import { RequestContext, ResponseResult, ServeGibHandler, ServeGibHttpMethod } from './types.mjs';
14
-
15
- const logalot = GLOBAL_LOG_A_LOT;
16
-
17
- export interface ServeGibOptions {
18
- /** Pipeline of handlers to check in order. */
19
- handlers: ServeGibHandler<any, any>[];
20
- /** Dedicated handler for errors (404, 500, etc.). */
21
- errorHandler: ServeGibHandler<any, any>;
22
- /** Port the server is listening on. */
23
- port: number;
24
- /**
25
- * Root data directory for the server. We will use this as the root dir for
26
- * all spaces that house multitenant ibgib data.
27
- */
28
- dataDir: string;
29
- }
30
-
31
- export class ServeGib_V1 {
32
- private lc = `[${ServeGib_V1.name}]`;
33
-
34
- constructor(private options: ServeGibOptions) { }
35
-
36
- /**
37
- * Entry point for all incoming HTTP requests.
38
- */
39
- async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {
40
- const lc = `${this.lc}[${this.handleRequest.name}]`;
41
- const start = Date.now();
42
- let reqCtx: RequestContext | undefined;
43
-
44
- try {
45
- // Contextualize the request
46
- reqCtx = await this.prepareContext(req);
47
- if (!reqCtx) { throw new Error(`(UNEXPECTED) reqCtx falsy? couldn't prepare context? (E: 401888c0f649dfdf0e2d21f86b3ff826)`); }
48
-
49
- // Execute pipeline
50
- let result: ResponseResult | undefined;
51
- for (const handler of this.options.handlers) {
52
- result = await handler.handleRoute(reqCtx);
53
- if (result) { break; }
54
- }
55
-
56
- // Fallback if no handler matched
57
- if (!result) {
58
- result = await this.options.errorHandler.handleRoute(reqCtx);
59
- }
60
-
61
- // Final output
62
- if (result) {
63
- this.sendResponse(res, result);
64
- } else {
65
- // If even the error handler didn't produce a result
66
- this.sendResponse(res, { status: 404, body: 'Not Found' });
67
- }
68
-
69
- } catch (error) {
70
- console.error(`${lc} Fatal error handling ${req.method} ${req.url}: ${extractErrorMsg(error)}`);
71
- try {
72
- // Try to use the error handler for the fatal error
73
- if (reqCtx) {
74
- const errorResult = await this.options.errorHandler.handleRoute(reqCtx);
75
- this.sendResponse(res, errorResult ?? { status: 500, body: 'Internal Server Error' });
76
- } else {
77
- throw new Error(`errored before reqCtx could be set. (E: d77ab84b4f8874e188cfa8e9895f1226)`);
78
- }
79
- } catch (innerError) {
80
- // Total collapse fallback
81
- console.error(`${lc} Collapse in error handler: ${extractErrorMsg(innerError)}`);
82
- res.writeHead(500);
83
- res.end('Critical Server Error');
84
- }
85
- } finally {
86
- const duration = Date.now() - start;
87
- // Standard access logging
88
- console.log(`${lc} ${req.method} ${req.url} -> ${res.statusCode} (${duration}ms)`);
89
- }
90
- }
91
-
92
- /**
93
- * Builds request context (e.g. extracting/decoding URL, path segments, body
94
- * content, etc.), and initializes the request's metaspace if applicable.
95
- */
96
- public async prepareContext(req: IncomingMessage): Promise<RequestContext> {
97
- const lc = `${this.lc}[${this.prepareContext.name}]`;
98
- try {
99
- if (logalot) { console.log(`${lc} starting... (I: ad9e9c678d0538c2d1e16ca8063d4426)`); }
100
-
101
- /**
102
- * These are NOT all of the validation we do on the context, rather,
103
- * it is just simple initial validation.
104
- */
105
- const initialValidationErrors: string[] = [];
106
-
107
- const rawUrl = req.url ?? '/';
108
- const protocol = (req.headers['x-forwarded-proto'] as string) || 'http'; // todo: who owns the req.headers? Can an attacker manipulate this?
109
- const url = new URL(rawUrl, `${protocol}://localhost:${this.options.port}`); // todo: wth?? Why are we hard-coding localhost? in the URL object?
110
-
111
- const pathname = url.pathname;
112
- const rawPathSegments = pathname.split('/');
113
- const decodedPathSegments = rawPathSegments.map(s => decodeURIComponent(s));
114
-
115
- const body = await this.readBody(req);
116
-
117
- const reqCtx: RequestContext = {
118
- rawUrl,
119
- pathname,
120
- method: req.method?.toUpperCase() as ServeGibHttpMethod ?? 'GET',
121
- protocol,
122
- body,
123
- rawPathSegments,
124
- decodedPathSegments,
125
- url,
126
- dataDir: this.options.dataDir,
127
- headers: req.headers,
128
- }
129
-
130
- return reqCtx;
131
- } catch (error) {
132
- console.error(`${lc} ${extractErrorMsg(error)}`);
133
- throw error;
134
- } finally {
135
- if (logalot) { console.log(`${lc} complete.`); }
136
- }
137
- }
138
-
139
- /** Reads the full request body as UTF-8. */
140
- private readBody(req: IncomingMessage): Promise<string> {
141
- return new Promise((resolve, reject) => {
142
- const chunks: Buffer[] = [];
143
- req.on('data', (chunk: Buffer) => chunks.push(chunk));
144
- req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
145
- req.on('error', reject);
146
- });
147
- }
148
-
149
- /** Sends the response result to the client. */
150
- private sendResponse(res: ServerResponse, result: ResponseResult): void {
151
- const lc = `${this.lc}[${this.sendResponse.name}]`;
152
- try {
153
- if (logalot) { console.log(`${lc} starting... (I: 37369cf120c14780e8652bf27ada1726)`); }
154
-
155
- const { status, headers = {}, body, isJson = false } = result;
156
-
157
- let payload: any = body;
158
- if (isJson) {
159
- headers['Content-Type'] = 'application/json; charset=utf-8';
160
- payload = JSON.stringify(body);
161
- }
162
-
163
- res.writeHead(status, headers);
164
- res.end(payload);
165
- } catch (error) {
166
- console.error(`${lc} ${extractErrorMsg(error)}`);
167
- throw error;
168
- } finally {
169
- if (logalot) { console.log(`${lc} complete.`); }
170
- }
171
- }
172
- }
@@ -1,90 +0,0 @@
1
- import { respecfully, iReckon, ifWe } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
2
- import { ServeGib_V1 } from './serve-gib-v1.mjs';
3
- import { HealthHandler } from './handlers/api/health.handler.mjs';
4
- import { ErrorHandler } from './handlers/error-handler.mjs';
5
-
6
- const sir = `[${import.meta.url}]`;
7
-
8
- await respecfully(sir, 'ServeGib ServeGib_V1', async () => {
9
-
10
- await ifWe(sir, 'construct a RouteInfo object', async () => {
11
- const serveGib = new ServeGib_V1({
12
- port: 3000,
13
- dataDir: './test-data',
14
- handlers: [],
15
- errorHandler: new ErrorHandler()
16
- });
17
-
18
- // Mock request
19
- const req: any = {
20
- url: '/api/health?foo=bar',
21
- method: 'GET',
22
- headers: { 'x-forwarded-proto': 'https' },
23
- on: (event: string, cb: any) => {
24
- if (event === 'end') { cb(); }
25
- } // immediate end for readBody
26
- };
27
-
28
- const info = await (serveGib as any).buildRouteInfo(req);
29
-
30
- iReckon(sir, info.pathname).isGonnaBe('/api/health');
31
- iReckon(sir, info.method).isGonnaBe('GET');
32
- iReckon(sir, info.protocol).isGonnaBe('https');
33
- iReckon(sir, info.pathSegments).includes('api');
34
- iReckon(sir, info.pathSegments).includes('health');
35
- });
36
-
37
- await ifWe(sir, 'execute a handler in the pipeline', async () => {
38
- const health = new HealthHandler();
39
- const serveGib = new ServeGib_V1({
40
- port: 3000,
41
- dataDir: './test-data',
42
- handlers: [health],
43
- errorHandler: new ErrorHandler()
44
- });
45
-
46
- // Mock objects
47
- const req: any = {
48
- url: '/api/health',
49
- method: 'GET',
50
- headers: {},
51
- on: (event: string, cb: any) => {
52
- if (event === 'end') { cb(); }
53
- }
54
- };
55
- const res: any = {
56
- writeHead: () => { },
57
- end: () => { },
58
- statusCode: 200
59
- };
60
-
61
- await serveGib.handleRequest(req, res);
62
- iReckon(sir, res.statusCode).isGonnaBe(200);
63
- });
64
-
65
- await ifWe(sir, 'fall back to error handler when no handler matches', async () => {
66
- const serveGib = new ServeGib_V1({
67
- port: 3000,
68
- dataDir: './test-data',
69
- handlers: [],
70
- errorHandler: new ErrorHandler()
71
- });
72
-
73
- const req: any = {
74
- url: '/not/found',
75
- method: 'GET',
76
- headers: {},
77
- on: (event: string, cb: any) => {
78
- if (event === 'end') { cb(); }
79
- }
80
- };
81
- const res: any = {
82
- writeHead: () => { },
83
- end: () => { },
84
- statusCode: 404
85
- };
86
-
87
- await serveGib.handleRequest(req, res);
88
- iReckon(sir, res.statusCode).isGonnaBe(404);
89
- });
90
- });
@@ -1,102 +0,0 @@
1
- /**
2
- * @module serve-gib/types
3
- *
4
- * Foundational types for the serve-gib microframework.
5
- */
6
-
7
- import { Gib, Ib, IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
8
- import { GibInfo } from '@ibgib/ts-gib/dist/V1/types.mjs';
9
- import { MetaspaceService } from '@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs';
10
-
11
- /**
12
- * Standard HTTP methods supported by the serve-gib framework, plus 'ALL' for catch-all handlers.
13
- */
14
- export type ServeGibHttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'ALL';
15
-
16
- /**
17
- * @see {@link RequestContext.domainInfo}
18
- */
19
- export interface DomainInfo {
20
- ib: Ib;
21
- gib: Gib;
22
- addr: IbGibAddr;
23
- gibInfo: GibInfo;
24
- /** The physical root directory for the current domain. */
25
- // rootPath?: string;
26
- }
27
-
28
- export interface ParamsWithDomain {
29
- domainInfo: DomainInfo;
30
- }
31
-
32
- /**
33
- * Encapsulates the context of an incoming HTTP request.
34
- */
35
- export interface RequestContext<TParams = any, TQueryParams = any> {
36
- /** The native Node.js/Web URL object. */
37
- url: URL;
38
- /** The root data directory for spaces. */
39
- dataDir: string;
40
- /** The original request URL string. */
41
- rawUrl: string;
42
- /** The pathname part of the URL (e.g. /api/health). */
43
- pathname: string;
44
- /** HTTP method (GET, POST, etc.). */
45
- method: ServeGibHttpMethod;
46
- /** Request protocol (http or https). */
47
- protocol: string;
48
- /** The raw request body as a string. */
49
- body: string;
50
- /** Array of raw path segments split by '/'. */
51
- rawPathSegments: string[];
52
- /**
53
- * Same as {@link rawPathSegments}, but with any ibgib addr(s) URL decoded.
54
- */
55
- decodedPathSegments: string[];
56
- params?: TParams;
57
- /** Parsed query parameters. */
58
- queryParams?: TQueryParams;
59
- /** Request headers. */
60
- headers: Record<string, string | string[] | undefined>;
61
- /**
62
- * The bootstrapped MetaspaceService for the current domain.
63
- *
64
- * Note that not all routes require this, hence it's optional.
65
- */
66
- metaspace?: MetaspaceService;
67
- /**
68
- * keystones define "domains" to enable multitenancy. This is info about the
69
- * keystone domain.
70
- *
71
- * ## notes
72
- *
73
- * I would call this "KeystoneInfo", and right now, this is only one keystone's
74
- * info. but ultimately I _think_ that we will have nested domains.
75
- */
76
- domainInfo?: DomainInfo;
77
- }
78
-
79
- /**
80
- * Standardized response shape returned by handlers.
81
- */
82
- export interface ResponseResult {
83
- /** HTTP status code (200, 404, etc.). */
84
- status: number;
85
- /** Optional response headers. */
86
- headers?: Record<string, string>;
87
- /** Response body content. */
88
- body: any;
89
- /** If true, body will be stringified as JSON and Content-Type set accordingly. */
90
- isJson?: boolean;
91
- }
92
-
93
- /**
94
- * Interface for a serve-gib route handler.
95
- */
96
- export interface ServeGibHandler<TParams, TQueryParams> {
97
- /**
98
- * Attempts to handle the request.
99
- * @returns A ResponseResult if handled, or undefined to pass to the next handler.
100
- */
101
- handleRoute(reqCtx: RequestContext<TParams, TQueryParams>): Promise<ResponseResult | undefined>;
102
- }
@@ -1,2 +0,0 @@
1
- export const GLOBAL_LOG_A_LOT = false;
2
- export const GLOBAL_TIMER_NAME = '[space^gib server timer]';