@ibgib/space-gib 0.0.1
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/CHANGELOG.md +31 -0
- package/Dockerfile +14 -0
- package/IMPLEMENTATION.md +484 -0
- package/README.md +46 -0
- package/dist/client/bootstrap.mjs +58 -0
- package/dist/client/bootstrap.mjs.map +7 -0
- package/dist/client/chunk-CT47Z5WU.mjs +21 -0
- package/dist/client/chunk-CT47Z5WU.mjs.map +7 -0
- package/dist/client/chunk-RHEDTRKF.mjs +235 -0
- package/dist/client/chunk-RHEDTRKF.mjs.map +7 -0
- package/dist/client/index.html +147 -0
- package/dist/client/index.mjs +2 -0
- package/dist/client/index.mjs.map +7 -0
- package/dist/client/script.mjs +2 -0
- package/dist/client/script.mjs.map +7 -0
- package/dist/client/style.css +605 -0
- package/dist/respec-gib.node.mjs +5 -0
- package/dist/server/server.mjs +20157 -0
- package/dist/server/server.mjs.map +7 -0
- package/generate-version-file.js +35 -0
- package/package.json +27 -0
- package/src/client/AUTO-GENERATED-version.mts +11 -0
- package/src/client/README.md +19 -0
- package/src/client/api/function-infos.web.mts +38 -0
- package/src/client/api/space-gib-api-bridge.mts +85 -0
- package/src/client/bootstrap.mts +49 -0
- package/src/client/components/keystone-creator/keystone-creator.css +139 -0
- package/src/client/components/keystone-creator/keystone-creator.html +26 -0
- package/src/client/components/keystone-creator/keystone-creator.mts +229 -0
- package/src/client/constants.mts +76 -0
- package/src/client/custom.d.ts +11 -0
- package/src/client/dev-tools.mts +540 -0
- package/src/client/helpers.web.mts +178 -0
- package/src/client/index.html +147 -0
- package/src/client/index.mts +59 -0
- package/src/client/script.mts +13 -0
- package/src/client/style.css +605 -0
- package/src/client/types.mts +85 -0
- package/src/client/ui/shell/space-gib-shell-constants.mts +24 -0
- package/src/client/ui/shell/space-gib-shell-service.mts +233 -0
- package/src/client/ui/shell/space-gib-shell-types.mts +5 -0
- package/src/client/witness/app/space-gib/space-gib-app-v1.mts +160 -0
- package/src/client/witness/app/space-gib/space-gib-constants.mts +38 -0
- package/src/client/witness/app/space-gib/space-gib-helper.mts +72 -0
- package/src/client/witness/app/space-gib/space-gib-types.mts +47 -0
- package/src/common/keystone-policies.mts +159 -0
- package/src/respec-gib.node.mts +6 -0
- package/src/server/README.md +18 -0
- package/src/server/bootstrap-helper.mts +141 -0
- package/src/server/bootstrap-helper.respec.mts +100 -0
- package/src/server/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts +85 -0
- package/src/server/path-constants.mts +89 -0
- package/src/server/path-helper.mts +101 -0
- package/src/server/path-helper.respec.mts +94 -0
- package/src/server/serve-gib/CHANGELOG.md +29 -0
- package/src/server/serve-gib/README.md +34 -0
- package/src/server/serve-gib/constants.mts +1 -0
- package/src/server/serve-gib/handlers/api/debug/ws-echo.handler.mts +104 -0
- package/src/server/serve-gib/handlers/api/health.handler.mts +23 -0
- package/src/server/serve-gib/handlers/api/health.respec.mts +51 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts +49 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib.handler.mts +176 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts +261 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +146 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.handler.mts +198 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +107 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-handler-types.mts +29 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.handler.mts +70 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.respec.mts +130 -0
- package/src/server/serve-gib/handlers/error-handler.mts +36 -0
- package/src/server/serve-gib/handlers/handler-base.mts +383 -0
- package/src/server/serve-gib/handlers/static-handler.mts +82 -0
- package/src/server/serve-gib/handlers/ws/sync-upgrade.handler.mts +498 -0
- package/src/server/serve-gib/handlers/ws/ws-helper.mts +111 -0
- package/src/server/serve-gib/handlers/ws/ws-types.mts +53 -0
- package/src/server/serve-gib/serve-gib-helpers.mts +32 -0
- package/src/server/serve-gib/serve-gib-v1.mts +172 -0
- package/src/server/serve-gib/serve-gib.respec.mts +90 -0
- package/src/server/serve-gib/types.mts +102 -0
- package/src/server/server-constants.mts +2 -0
- package/src/server/server.mts +96 -0
- package/tsconfig.json +29 -0
- package/tsconfig.server.json +29 -0
- package/tsconfig.test.json +27 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { existsSync, rmSync, mkdirSync } from 'node:fs';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
respecfully, iReckon, ifWe, ifWeMight
|
|
6
|
+
} from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
|
|
7
|
+
const sir = `[${import.meta.url}]`;
|
|
8
|
+
|
|
9
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
10
|
+
import { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';
|
|
11
|
+
import { createStandardPoolConfig } from '@ibgib/core-gib/dist/keystone/keystone-config-builder.mjs';
|
|
12
|
+
import { POOL_ID_DEFAULT } from '@ibgib/core-gib/dist/keystone/keystone-constants.mjs';
|
|
13
|
+
|
|
14
|
+
import { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';
|
|
15
|
+
import { ServeGib_V1 } from '../../../serve-gib-v1.mjs';
|
|
16
|
+
import { KeystonePostHandler } from './keystone-post.handler.mjs';
|
|
17
|
+
import { KeystoneGetHandler } from './keystone-get.handler.mjs';
|
|
18
|
+
import { ErrorHandler } from '../../error-handler.mjs';
|
|
19
|
+
|
|
20
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
21
|
+
|
|
22
|
+
class MockMetaspace {
|
|
23
|
+
async getLocalUserSpace() { return new MockSpace(); }
|
|
24
|
+
async put() { }
|
|
25
|
+
async registerNewIbGib() { }
|
|
26
|
+
}
|
|
27
|
+
class MockSpace {
|
|
28
|
+
async witness() { return { data: { success: true } }; }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await respecfully(sir, 'Keystone GET Integration', async () => {
|
|
32
|
+
const testDataDir = './test-data-get';
|
|
33
|
+
const port = 3003;
|
|
34
|
+
|
|
35
|
+
// Clean test data
|
|
36
|
+
if (existsSync(testDataDir)) {
|
|
37
|
+
rmSync(testDataDir, { recursive: true, force: true });
|
|
38
|
+
}
|
|
39
|
+
mkdirSync(testDataDir, { recursive: true });
|
|
40
|
+
|
|
41
|
+
await ifWeMight(sir, 'retrieve a keystone chain via GET /api/keystone/:addr', async () => {
|
|
42
|
+
const keystoneService = new KeystoneService_V1();
|
|
43
|
+
const config = createStandardPoolConfig({ id: POOL_ID_DEFAULT, salt: POOL_ID_DEFAULT });
|
|
44
|
+
|
|
45
|
+
// 1. Setup ServeGib_V1 with both POST and GET handlers
|
|
46
|
+
const serveGib = new ServeGib_V1({
|
|
47
|
+
port,
|
|
48
|
+
dataDir: testDataDir,
|
|
49
|
+
handlers: [
|
|
50
|
+
new KeystonePostHandler(),
|
|
51
|
+
new KeystoneGetHandler(),
|
|
52
|
+
],
|
|
53
|
+
errorHandler: new ErrorHandler()
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// 2. Generate and POST genesis
|
|
57
|
+
const genesis = await keystoneService.genesis({
|
|
58
|
+
masterSecret: 'AliceSecret',
|
|
59
|
+
configs: [config],
|
|
60
|
+
metaspace: new MockMetaspace() as any,
|
|
61
|
+
space: new MockSpace() as any,
|
|
62
|
+
});
|
|
63
|
+
const addr = getIbGibAddr({ ibGib: genesis });
|
|
64
|
+
|
|
65
|
+
const postReq: any = {
|
|
66
|
+
url: '/api/keystone',
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: { 'ibgib-domain': addr, 'content-type': 'application/json' },
|
|
69
|
+
on: (event: string, cb: any) => {
|
|
70
|
+
if (event === 'data') cb(Buffer.from(JSON.stringify({ ibGibs: [genesis] })));
|
|
71
|
+
if (event === 'end') cb();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const postRes: any = {
|
|
75
|
+
writeHead: () => { },
|
|
76
|
+
end: () => { },
|
|
77
|
+
};
|
|
78
|
+
await serveGib.handleRequest(postReq, postRes);
|
|
79
|
+
|
|
80
|
+
// 3. Mock GET Request
|
|
81
|
+
const getReq: any = {
|
|
82
|
+
url: `/api/keystone/${encodeURIComponent(addr)}`,
|
|
83
|
+
method: 'GET',
|
|
84
|
+
headers: { 'ibgib-domain': addr },
|
|
85
|
+
on: (event: string, cb: any) => {
|
|
86
|
+
if (event === 'end') cb();
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
let capturedStatus: number = 0;
|
|
91
|
+
let capturedBody: any = null;
|
|
92
|
+
const getRes: any = {
|
|
93
|
+
writeHead: (status: number) => { capturedStatus = status; },
|
|
94
|
+
end: (body: string) => { capturedBody = JSON.parse(body); },
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// 4. Handle GET
|
|
98
|
+
await serveGib.handleRequest(getReq, getRes);
|
|
99
|
+
|
|
100
|
+
// 5. Verify
|
|
101
|
+
iReckon(sir, capturedStatus).asTo('captured status code').isGonnaBe(200);
|
|
102
|
+
iReckon(sir, capturedBody.chain).asTo('captured body chain').isGonnaBeTruthy();
|
|
103
|
+
iReckon(sir, Array.isArray(capturedBody.chain)).asTo('chain is array').isGonnaBe(true);
|
|
104
|
+
iReckon(sir, capturedBody.chain.length).asTo('chain length').isGonnaBe(1);
|
|
105
|
+
iReckon(sir, capturedBody.chain[0].gib).asTo('genesis gib matches').isGonnaBe(genesis.gib);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DomainInfo } from "../../../types.mjs";
|
|
2
|
+
|
|
3
|
+
export interface KeystoneParams {
|
|
4
|
+
domainInfo: DomainInfo;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// #region KeystoneGetQueryParams
|
|
8
|
+
export const DEFAULT_QUERY_PARAMS_GET_KEYSTONE = {
|
|
9
|
+
/**
|
|
10
|
+
* If true, will get the latest keystone frame.
|
|
11
|
+
*/
|
|
12
|
+
getLatest: true,
|
|
13
|
+
/**
|
|
14
|
+
* If true, will get the keystone's entire dependency graph
|
|
15
|
+
*/
|
|
16
|
+
getGraph: true,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* @see {@link DEFAULT_QUERY_PARAMS_GET_KEYSTONE} key/values for jsdocs
|
|
20
|
+
*/
|
|
21
|
+
export type KeystoneGetQueryParams = Partial<typeof DEFAULT_QUERY_PARAMS_GET_KEYSTONE>;
|
|
22
|
+
export type KNOWN_QUERY_PARAMS_KEYSTONE_GET = keyof KeystoneGetQueryParams;
|
|
23
|
+
export const KNOWN_QUERY_PARAMS_KEYSTONE_GET = Object.keys(DEFAULT_QUERY_PARAMS_GET_KEYSTONE) as KNOWN_QUERY_PARAMS_KEYSTONE_GET[];
|
|
24
|
+
export function isKnownQueryParamsKey_KeystoneGet(key: any): key is KNOWN_QUERY_PARAMS_KEYSTONE_GET {
|
|
25
|
+
return !!key && typeof key === 'string' ?
|
|
26
|
+
KNOWN_QUERY_PARAMS_KEYSTONE_GET.includes(key as any) :
|
|
27
|
+
false;
|
|
28
|
+
}
|
|
29
|
+
// #endregion KeystoneGetQueryParams
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module serve-gib/handlers/api/keystone
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
6
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
7
|
+
import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
|
|
8
|
+
|
|
9
|
+
import { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';
|
|
10
|
+
import { ServeGibHandlerBase } from '../../handler-base.mjs';
|
|
11
|
+
import { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../types.mjs';
|
|
12
|
+
import { API_PATH_REGEXES } from '../../../../path-constants.mjs';
|
|
13
|
+
import { KeystoneParams } from './keystone-handler-types.mjs';
|
|
14
|
+
|
|
15
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* POST /api/keystone
|
|
19
|
+
*/
|
|
20
|
+
export class KeystonePostHandler extends ServeGibHandlerBase<KeystoneParams, any> { // todo: keystone post query params if needed?
|
|
21
|
+
protected override lc: string = `[${KeystonePostHandler.name}]`;
|
|
22
|
+
protected override method: ServeGibHttpMethod = 'POST';
|
|
23
|
+
protected override regex = API_PATH_REGEXES.KEYSTONE;
|
|
24
|
+
|
|
25
|
+
protected async handleRouteImpl(reqCtx: RequestContext<KeystoneParams, any>): Promise<ResponseResult | undefined> {
|
|
26
|
+
const lc = `[${this.handleRouteImpl.name}]`;
|
|
27
|
+
try {
|
|
28
|
+
if (logalot) { console.log(`${lc} starting... (I: 63bab8214834cb6e383e0fc364ee8826)`); }
|
|
29
|
+
|
|
30
|
+
const { metaspace } = reqCtx;
|
|
31
|
+
if (!metaspace) { throw new Error(`(UNEXPECTED) reqCtx.metaspace falsy? (E: 3d03027ea7f6f237980e511801255826)`); }
|
|
32
|
+
|
|
33
|
+
const { ibGibs } = JSON.parse(reqCtx.body) as { ibGibs: any[] };
|
|
34
|
+
if (!Array.isArray(ibGibs)) return this.error(400, 'ibGibs array required');
|
|
35
|
+
|
|
36
|
+
// 1. Intrinsic Validation
|
|
37
|
+
for (const ibGib of ibGibs) {
|
|
38
|
+
const errors = await validateIbGibIntrinsically({ ibGib });
|
|
39
|
+
if (errors) {
|
|
40
|
+
return this.error(422, 'Intrinsic validation failed', { failedAddr: getIbGibAddr({ ibGib }), errors });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 2. Keystone-specific checks
|
|
45
|
+
for (const ibGib of ibGibs) {
|
|
46
|
+
if (ibGib.ib?.startsWith('keystone')) {
|
|
47
|
+
if (!reqCtx.metaspace) { return this.error(500, 'Metaspace not initialized'); }
|
|
48
|
+
// Registration handles genesis vs evolution internally via metastones
|
|
49
|
+
await reqCtx.metaspace.registerNewIbGib({
|
|
50
|
+
ibGib,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 3. Persistence
|
|
56
|
+
console.log(`[KeystoneHandler] Persisting ${ibGibs.length} ibGibs...`);
|
|
57
|
+
await metaspace.put({ ibGibs })
|
|
58
|
+
// await spaceSvc.putIbGibGraph(ibGibs);
|
|
59
|
+
console.log(`[KeystoneHandler] Persistence successful.`);
|
|
60
|
+
return { status: 201, body: { success: true }, isJson: true };
|
|
61
|
+
|
|
62
|
+
} catch (error) {
|
|
63
|
+
const emsg = `${lc} ${extractErrorMsg(error)}`;
|
|
64
|
+
console.error(emsg);
|
|
65
|
+
return this.error(500, emsg);
|
|
66
|
+
} finally {
|
|
67
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { existsSync, rmSync, mkdirSync, readdirSync } from 'node:fs';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
respecfully, iReckon, ifWe, ifWeMight
|
|
6
|
+
} from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
|
|
7
|
+
const sir = `[${import.meta.url}]`;
|
|
8
|
+
|
|
9
|
+
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
10
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
11
|
+
import { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';
|
|
12
|
+
import { createStandardPoolConfig } from '@ibgib/core-gib/dist/keystone/keystone-config-builder.mjs';
|
|
13
|
+
import { POOL_ID_DEFAULT } from '@ibgib/core-gib/dist/keystone/keystone-constants.mjs';
|
|
14
|
+
|
|
15
|
+
import { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';
|
|
16
|
+
import { ServeGib_V1 } from '../../../serve-gib-v1.mjs';
|
|
17
|
+
import { KeystonePostHandler } from './keystone-post.handler.mjs';
|
|
18
|
+
import { ErrorHandler } from '../../error-handler.mjs';
|
|
19
|
+
import { getDomainRootPath } from '../../../../bootstrap-helper.mjs';
|
|
20
|
+
|
|
21
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
22
|
+
if (logalot) { console.log(`[test] keystone-post.respec.mts top-level entry`); }
|
|
23
|
+
|
|
24
|
+
class MockMetaspace {
|
|
25
|
+
async getLocalUserSpace() { return new MockSpace(); }
|
|
26
|
+
async put() { }
|
|
27
|
+
async registerNewIbGib() { }
|
|
28
|
+
}
|
|
29
|
+
class MockSpace {
|
|
30
|
+
async witness() { return { data: { success: true } }; }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await respecfully(sir, 'Keystone POST Integration', async () => {
|
|
34
|
+
const testDataDir = './test-data-post';
|
|
35
|
+
const port = 3001;
|
|
36
|
+
|
|
37
|
+
// Clean test data
|
|
38
|
+
if (existsSync(testDataDir)) {
|
|
39
|
+
rmSync(testDataDir, { recursive: true, force: true });
|
|
40
|
+
}
|
|
41
|
+
mkdirSync(testDataDir, { recursive: true });
|
|
42
|
+
|
|
43
|
+
await ifWe(sir, 'bootstrap a new domain via POST /api/keystone', async () => {
|
|
44
|
+
const keystoneService = new KeystoneService_V1();
|
|
45
|
+
const config = createStandardPoolConfig({ id: POOL_ID_DEFAULT, salt: POOL_ID_DEFAULT });
|
|
46
|
+
|
|
47
|
+
// 1. Generate real genesis
|
|
48
|
+
const genesis = await keystoneService.genesis({
|
|
49
|
+
masterSecret: 'AliceSecret',
|
|
50
|
+
configs: [config],
|
|
51
|
+
metaspace: new MockMetaspace() as any,
|
|
52
|
+
space: new MockSpace() as any,
|
|
53
|
+
});
|
|
54
|
+
const addr = getIbGibAddr({ ibGib: genesis });
|
|
55
|
+
|
|
56
|
+
if (logalot) { console.log(`[test] Generated genesis: ${addr}`); }
|
|
57
|
+
|
|
58
|
+
// 2. Setup ServeGib_V1
|
|
59
|
+
const serveGib = new ServeGib_V1({
|
|
60
|
+
port,
|
|
61
|
+
dataDir: testDataDir,
|
|
62
|
+
handlers: [new KeystonePostHandler()],
|
|
63
|
+
errorHandler: new ErrorHandler()
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (logalot) { console.log(`[test] ServeGib_V1 setup. Posting to /api/keystone...`); }
|
|
67
|
+
|
|
68
|
+
// 3. Mock POST Request
|
|
69
|
+
const req: any = {
|
|
70
|
+
url: '/api/keystone',
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: {
|
|
73
|
+
'ibgib-domain': addr,
|
|
74
|
+
'content-type': 'application/json'
|
|
75
|
+
},
|
|
76
|
+
on: (event: string, cb: any) => {
|
|
77
|
+
if (event === 'data') {
|
|
78
|
+
if (logalot) { console.log(`[test] sending data chunk...`); }
|
|
79
|
+
cb(Buffer.from(JSON.stringify({ ibGibs: [genesis] })));
|
|
80
|
+
}
|
|
81
|
+
if (event === 'end') {
|
|
82
|
+
if (logalot) { console.log(`[test] end of request.`); }
|
|
83
|
+
cb();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
let capturedStatus: number = 0;
|
|
89
|
+
let capturedBody: any = null;
|
|
90
|
+
const res: any = {
|
|
91
|
+
writeHead: (status: number) => {
|
|
92
|
+
if (logalot) { console.log(`[test] writeHead: ${status}`); }
|
|
93
|
+
capturedStatus = status;
|
|
94
|
+
},
|
|
95
|
+
end: (body: string) => {
|
|
96
|
+
if (logalot) { console.log(`[test] res.end called with body length: ${body?.length}`); }
|
|
97
|
+
capturedBody = JSON.parse(body);
|
|
98
|
+
},
|
|
99
|
+
statusCode: 0
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// 4. Handle
|
|
103
|
+
if (logalot) { console.log(`[test] Calling handleRequest...`); }
|
|
104
|
+
await serveGib.handleRequest(req, res);
|
|
105
|
+
if (logalot) { console.log(`[test] handleRequest completed.`); }
|
|
106
|
+
|
|
107
|
+
// 5. Verify
|
|
108
|
+
iReckon(sir, capturedStatus).asTo('captured status code').isGonnaBe(201);
|
|
109
|
+
iReckon(sir, capturedBody.success).asTo(`Handler failed: ${capturedBody.message || 'no message'}`).isGonnaBe(true);
|
|
110
|
+
|
|
111
|
+
const domainPath = getDomainRootPath(genesis.gib!, testDataDir);
|
|
112
|
+
iReckon(sir, existsSync(domainPath)).asTo('domain path exists').isGonnaBe(true);
|
|
113
|
+
|
|
114
|
+
// Verify the ibgib actually exists in the new domain's storage
|
|
115
|
+
// With indexed storage, it's in a bucketed subpath: ibgib/default/ibgibs/B1/B2/
|
|
116
|
+
const bucket1 = genesis.gib!.substring(0, 3).toUpperCase();
|
|
117
|
+
const bucket2 = genesis.gib!.substring(3, 6).toUpperCase();
|
|
118
|
+
const bucketPath = join(domainPath, 'ibgib', 'default', 'ibgibs', bucket1, bucket2);
|
|
119
|
+
|
|
120
|
+
iReckon(sir, existsSync(bucketPath)).asTo(`Bucket path does not exist: ${bucketPath}`).isGonnaBe(true);
|
|
121
|
+
|
|
122
|
+
// We don't know the random filename, but we know it's a .json file in that bucket
|
|
123
|
+
try {
|
|
124
|
+
const files = readdirSync(bucketPath).filter(f => f.endsWith('.json'));
|
|
125
|
+
iReckon(sir, files.length > 0).asTo(`No .json files found in bucket: ${bucketPath}`).isGonnaBe(true);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
iReckon(sir, true).asTo(`error trying to readdir ${bucketPath}: ${extractErrorMsg(error)}`).isGonnaBe(true);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module serve-gib/handlers/error-handler
|
|
3
|
+
*
|
|
4
|
+
* Default error handler for serve-gib.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
8
|
+
|
|
9
|
+
import { GLOBAL_LOG_A_LOT } from '../constants.mjs';
|
|
10
|
+
import { ServeGibHandlerBase } from './handler-base.mjs';
|
|
11
|
+
import { RequestContext, ResponseResult, ServeGibHttpMethod } from '../types.mjs';
|
|
12
|
+
|
|
13
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
14
|
+
|
|
15
|
+
export class ErrorHandler extends ServeGibHandlerBase {
|
|
16
|
+
protected override lc: string = `[${ErrorHandler.name}]`;
|
|
17
|
+
protected override method: ServeGibHttpMethod = 'ALL';
|
|
18
|
+
protected override regex = /.*/;
|
|
19
|
+
|
|
20
|
+
async handleRouteImpl(reqCtx: RequestContext): Promise<ResponseResult | undefined> {
|
|
21
|
+
const lc = `${this.lc}[${this.handleRouteImpl.name}]`;
|
|
22
|
+
try {
|
|
23
|
+
if (logalot) { console.log(`${lc} starting...`); }
|
|
24
|
+
|
|
25
|
+
const { rawUrl, pathname, method, } = reqCtx;
|
|
26
|
+
|
|
27
|
+
// This is the fallback handler
|
|
28
|
+
return this.error(404, 'Not Found', { method, rawUrl, pathname });
|
|
29
|
+
} catch (error: any) {
|
|
30
|
+
console.log(`${lc} ${extractErrorMsg(error)}`);
|
|
31
|
+
throw error;
|
|
32
|
+
} finally {
|
|
33
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|