@feasibleone/blong-gogo 1.11.2 → 1.12.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 +19 -0
- package/package.json +1 -1
- package/src/ApiSchema.ts +45 -10
- package/src/ErrorFactory.ts +2 -2
- package/src/Gateway.ts +2 -2
- package/src/GatewayClient.ts +1 -1
- package/src/GatewayCodec.ts +1 -1
- package/src/Local.ts +1 -1
- package/src/Log.ts +1 -1
- package/src/Port.ts +1 -1
- package/src/Realm.ts +2 -2
- package/src/Registry.ts +2 -2
- package/src/Remote.ts +2 -2
- package/src/ResolutionDiscovery.ts +1 -1
- package/src/ResolutionLocal.ts +1 -1
- package/src/RpcClient.ts +1 -1
- package/src/RpcServer.ts +1 -1
- package/src/Watch.ts +1 -1
- package/src/adapter/browser/http.ts +2 -2
- package/src/adapter/browser.ts +1 -1
- package/src/adapter/server/github.ts +1 -1
- package/src/adapter/server/http.ts +2 -2
- package/src/adapter/server/k8s.ts +1 -1
- package/src/adapter/server/kafka.ts +1 -1
- package/src/adapter/server/keycloak.ts +1 -1
- package/src/adapter/server/knex.ts +1 -1
- package/src/adapter/server/mongodb.ts +1 -1
- package/src/adapter/server/s3.ts +1 -1
- package/src/adapter/server/slack.ts +1 -1
- package/src/adapter/server/tcp.ts +1 -1
- package/src/adapter/server/vault.ts +1 -1
- package/src/adapter/server/webhook.ts +1 -1
- package/src/adapter/server.ts +1 -1
- package/src/adapter.ts +1 -1
- package/src/codec/adapter/jsonrpc/errors.ts +1 -1
- package/src/codec/adapter/jsonrpc/receive.ts +1 -1
- package/src/codec/adapter/jsonrpc/send.ts +2 -2
- package/src/codec/adapter/mle/ready.ts +1 -1
- package/src/codec/adapter/openapi/errors.ts +1 -1
- package/src/codec/adapter/openapi/load.ts +1 -1
- package/src/codec/adapter/openapi/ready.ts +1 -1
- package/src/codec/adapter/openapi/request.ts +1 -1
- package/src/codec/browser.ts +1 -1
- package/src/codec/server.ts +1 -1
- package/src/codec/test/test/testCodecMle.ts +1 -1
- package/src/codec/test/test/testLoginTokenCreate.ts +1 -1
- package/src/error.ts +1 -1
- package/src/handler.name.test.ts +25 -13
- package/src/jwt.ts +1 -1
- package/src/layerProxy.ts +1 -1
- package/src/load.ts +15 -15
- package/src/loop.ts +1 -1
- package/src/orchestrator/common/dispatch.ts +1 -1
- package/src/orchestrator/common/openapi.ts +1 -1
- package/src/orchestrator/index.ts +1 -1
- package/src/scan.ts +12 -0
- package/src/timeout.ts +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.12.1](https://github.com/feasibleone/blong/compare/blong-gogo-v1.12.0...blong-gogo-v1.12.1) (2026-03-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* build ([3d35ac3](https://github.com/feasibleone/blong/commit/3d35ac3058279a941eeacbc02888bf5cd74ce93a))
|
|
9
|
+
|
|
10
|
+
## [1.12.0](https://github.com/feasibleone/blong/compare/blong-gogo-v1.11.2...blong-gogo-v1.12.0) (2026-03-15)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* improve api loading ([2008fa3](https://github.com/feasibleone/blong/commit/2008fa38272252682f259e22632f10e8c33d64f5))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* imports ([c179b6d](https://github.com/feasibleone/blong/commit/c179b6d2d0709f548560e13a99dc2e62facad645))
|
|
21
|
+
|
|
3
22
|
## [1.11.2](https://github.com/feasibleone/blong/compare/blong-gogo-v1.11.1...blong-gogo-v1.11.2) (2026-03-15)
|
|
4
23
|
|
|
5
24
|
|
package/package.json
CHANGED
package/src/ApiSchema.ts
CHANGED
|
@@ -4,13 +4,15 @@ import type {
|
|
|
4
4
|
ILog,
|
|
5
5
|
PathItemObject,
|
|
6
6
|
SchemaObject,
|
|
7
|
-
} from '@feasibleone/blong';
|
|
8
|
-
import {Internal} from '@feasibleone/blong';
|
|
7
|
+
} from '@feasibleone/blong/types';
|
|
8
|
+
import {Internal} from '@feasibleone/blong/types';
|
|
9
9
|
import {createReadStream, statSync, writeFileSync, type Dirent} from 'node:fs';
|
|
10
|
-
import path, {basename, extname} from 'node:path';
|
|
10
|
+
import path, {basename, dirname, extname} from 'node:path';
|
|
11
11
|
|
|
12
|
+
import {join} from 'path';
|
|
12
13
|
import {identifier} from './lib.ts';
|
|
13
14
|
import loadApi from './loadApi.ts';
|
|
15
|
+
import scan from './scan.ts';
|
|
14
16
|
|
|
15
17
|
interface IConfig {
|
|
16
18
|
logLevel?: Parameters<ILog['logger']>[0];
|
|
@@ -24,6 +26,7 @@ export default class ApiSchema extends Internal implements IApiSchema {
|
|
|
24
26
|
};
|
|
25
27
|
|
|
26
28
|
#loaded: Record<string, GatewaySchema> = {};
|
|
29
|
+
#namespace: Record<string, Record<string, GatewaySchema>> = {};
|
|
27
30
|
#generateFile: Set<string> = new Set();
|
|
28
31
|
#generateDir: Record<
|
|
29
32
|
string,
|
|
@@ -43,16 +46,46 @@ export default class ApiSchema extends Internal implements IApiSchema {
|
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
public async schema(
|
|
46
|
-
|
|
47
|
-
namespace
|
|
49
|
+
{
|
|
50
|
+
namespace,
|
|
51
|
+
url,
|
|
52
|
+
}: {
|
|
53
|
+
namespace?: Record<string, string | string[]> | string[];
|
|
54
|
+
url?: string;
|
|
48
55
|
},
|
|
49
56
|
source: string,
|
|
50
57
|
): Promise<Record<string, GatewaySchema>> {
|
|
51
58
|
const result: Record<string, GatewaySchema> = {};
|
|
59
|
+
if (url) {
|
|
60
|
+
const dir = dirname(url.startsWith('file://') ? url.slice(7) : url);
|
|
61
|
+
const files = await scan(dir);
|
|
62
|
+
namespace = namespace || {};
|
|
63
|
+
for (const file of files) {
|
|
64
|
+
if (
|
|
65
|
+
file.isFile() &&
|
|
66
|
+
(file.name.endsWith('.yaml') ||
|
|
67
|
+
file.name.endsWith('.yml') ||
|
|
68
|
+
file.name.endsWith('.json'))
|
|
69
|
+
) {
|
|
70
|
+
const [name] = basename(file.name).split('.');
|
|
71
|
+
namespace[name] ||= [];
|
|
72
|
+
namespace[name].push(join(dir, file.name));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(namespace))
|
|
77
|
+
return namespace.reduce(
|
|
78
|
+
(acc, name) => ({
|
|
79
|
+
...acc,
|
|
80
|
+
...this.#namespace[name],
|
|
81
|
+
}),
|
|
82
|
+
{},
|
|
83
|
+
);
|
|
52
84
|
|
|
53
|
-
for (const [name, locations] of Object.entries(
|
|
85
|
+
for (const [name, locations] of Object.entries(namespace)) {
|
|
54
86
|
const bundle = await loadApi(locations, source);
|
|
55
87
|
const {namespace = name, destination} = bundle['x-blong'] ?? {};
|
|
88
|
+
this.#namespace[namespace] ||= {};
|
|
56
89
|
Object.entries(bundle.paths).forEach(([path, methods]: [string, PathItemObject]) => {
|
|
57
90
|
['get', 'post', 'put', 'delete'].forEach(
|
|
58
91
|
(httpMethod: 'get' | 'post' | 'put' | 'delete') => {
|
|
@@ -62,9 +95,7 @@ export default class ApiSchema extends Internal implements IApiSchema {
|
|
|
62
95
|
operation.parameters as {in?: string; schema: unknown}[]
|
|
63
96
|
)?.find?.(param => param?.in === 'body')?.schema;
|
|
64
97
|
const method = this.method(operation);
|
|
65
|
-
|
|
66
|
-
`${namespace}.${method}`.toLowerCase()
|
|
67
|
-
] = {
|
|
98
|
+
const definition: GatewaySchema = {
|
|
68
99
|
rpc: false,
|
|
69
100
|
auth: false,
|
|
70
101
|
...(bodyParam && {
|
|
@@ -88,6 +119,10 @@ export default class ApiSchema extends Internal implements IApiSchema {
|
|
|
88
119
|
operation,
|
|
89
120
|
path: path.replaceAll('{', ':').replaceAll('}', ''),
|
|
90
121
|
};
|
|
122
|
+
this.#loaded[`${namespace}${method}`.toLowerCase()] = definition;
|
|
123
|
+
this.#namespace[namespace][`${namespace}.${method}`.toLowerCase()] =
|
|
124
|
+
definition;
|
|
125
|
+
result[`${namespace}.${method}`.toLowerCase()] = definition;
|
|
91
126
|
},
|
|
92
127
|
);
|
|
93
128
|
});
|
|
@@ -110,7 +145,7 @@ export default class ApiSchema extends Internal implements IApiSchema {
|
|
|
110
145
|
writeFileSync(
|
|
111
146
|
filename,
|
|
112
147
|
`import unchanged from '@feasibleone/blong';
|
|
113
|
-
import {type IMeta, handler} from '@feasibleone/blong';
|
|
148
|
+
import {type IMeta, handler} from '@feasibleone/blong/types';
|
|
114
149
|
|
|
115
150
|
// #region API
|
|
116
151
|
type Handler = (params: {
|
package/src/ErrorFactory.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {IErrorFactory, ILog, IMeta, ITypedError} from '@feasibleone/blong';
|
|
2
|
-
import {Internal} from '@feasibleone/blong';
|
|
1
|
+
import type {IErrorFactory, ILog, IMeta, ITypedError} from '@feasibleone/blong/types';
|
|
2
|
+
import {Internal} from '@feasibleone/blong/types';
|
|
3
3
|
|
|
4
4
|
import Errors from './error.ts';
|
|
5
5
|
|
package/src/Gateway.ts
CHANGED
|
@@ -8,8 +8,8 @@ import type {
|
|
|
8
8
|
ILocal,
|
|
9
9
|
ILog,
|
|
10
10
|
IMeta,
|
|
11
|
-
} from '@feasibleone/blong';
|
|
12
|
-
import {Internal} from '@feasibleone/blong';
|
|
11
|
+
} from '@feasibleone/blong/types';
|
|
12
|
+
import {Internal} from '@feasibleone/blong/types';
|
|
13
13
|
import fastify, {type FastifyRequest, type RouteOptions} from 'fastify';
|
|
14
14
|
import os from 'os';
|
|
15
15
|
import type {LevelWithSilent} from 'pino';
|
package/src/GatewayClient.ts
CHANGED
package/src/GatewayCodec.ts
CHANGED
package/src/Local.ts
CHANGED
package/src/Log.ts
CHANGED
package/src/Port.ts
CHANGED
package/src/Realm.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {IAdapterFactory, ILog, IRegistry} from '@feasibleone/blong';
|
|
1
|
+
import type {IAdapterFactory, ILog, IRegistry} from '@feasibleone/blong/types';
|
|
2
2
|
|
|
3
3
|
export interface IRealm {
|
|
4
4
|
addModule: (name: string | symbol, mod: IRegistry) => void;
|
|
@@ -21,7 +21,7 @@ export default class RealmImpl implements IRealm {
|
|
|
21
21
|
name: string;
|
|
22
22
|
pkg: {name: string; version: string};
|
|
23
23
|
},
|
|
24
|
-
{log, registry}: {log?: ILog; registry?: IRegistry}
|
|
24
|
+
{log, registry}: {log?: ILog; registry?: IRegistry},
|
|
25
25
|
) {
|
|
26
26
|
this.#config = config;
|
|
27
27
|
this.#registry = registry;
|
package/src/Registry.ts
CHANGED
|
@@ -10,8 +10,8 @@ import type {
|
|
|
10
10
|
IRegistry,
|
|
11
11
|
IRemote,
|
|
12
12
|
IRpcServer,
|
|
13
|
-
} from '@feasibleone/blong';
|
|
14
|
-
import {Internal} from '@feasibleone/blong';
|
|
13
|
+
} from '@feasibleone/blong/types';
|
|
14
|
+
import {Internal} from '@feasibleone/blong/types';
|
|
15
15
|
import PQueue from 'p-queue';
|
|
16
16
|
import {Type} from 'typebox';
|
|
17
17
|
import {monotonicFactory} from 'ulidx';
|
package/src/Remote.ts
CHANGED
|
@@ -8,8 +8,8 @@ import type {
|
|
|
8
8
|
IRemote,
|
|
9
9
|
ITypedError,
|
|
10
10
|
RemoteMethod,
|
|
11
|
-
} from '@feasibleone/blong';
|
|
12
|
-
import {Internal} from '@feasibleone/blong';
|
|
11
|
+
} from '@feasibleone/blong/types';
|
|
12
|
+
import {Internal} from '@feasibleone/blong/types';
|
|
13
13
|
import hrtime from 'browser-process-hrtime';
|
|
14
14
|
|
|
15
15
|
const errorMap: IErrorMap = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Internal, type Errors, type IErrorFactory, type IErrorMap} from '@feasibleone/blong';
|
|
1
|
+
import {Internal, type Errors, type IErrorFactory, type IErrorMap} from '@feasibleone/blong/types';
|
|
2
2
|
import hrtime from 'browser-process-hrtime';
|
|
3
3
|
import {hostname} from 'os';
|
|
4
4
|
import multicastResolver from 'ut-bus/resolver.ts';
|
package/src/ResolutionLocal.ts
CHANGED
package/src/RpcClient.ts
CHANGED
package/src/RpcServer.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// import { DaprServer, CommunicationProtocolEnum } from '@dapr/dapr';
|
|
2
|
-
import {Internal, type ILog, type IRpcServer} from '@feasibleone/blong';
|
|
2
|
+
import {Internal, type ILog, type IRpcServer} from '@feasibleone/blong/types';
|
|
3
3
|
import fastify, {type FastifyReply, type FastifyRequest, type RouteOptions} from 'fastify';
|
|
4
4
|
|
|
5
5
|
import type {IResolution} from './Resolution.ts';
|
package/src/Watch.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type IModuleConfig,
|
|
8
8
|
type IRegistry,
|
|
9
9
|
type IRemote,
|
|
10
|
-
} from '@feasibleone/blong';
|
|
10
|
+
} from '@feasibleone/blong/types';
|
|
11
11
|
import {Formatter, TypeScriptToTypeBox} from '@sinclair/typebox-codegen';
|
|
12
12
|
import chokidar, {type FSWatcher} from 'chokidar';
|
|
13
13
|
import type {Dirent} from 'fs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {Errors, IErrorMap, IMeta} from '@feasibleone/blong';
|
|
2
|
-
import {adapter} from '@feasibleone/blong';
|
|
1
|
+
import type {Errors, IErrorMap, IMeta} from '@feasibleone/blong/types';
|
|
2
|
+
import {adapter} from '@feasibleone/blong/types';
|
|
3
3
|
import got, {type HttpsOptions, type Options} from 'got';
|
|
4
4
|
|
|
5
5
|
import tls from '../../tls.ts';
|
package/src/adapter/browser.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {IMeta} from '@feasibleone/blong';
|
|
2
|
-
import {adapter, type Errors, type IErrorMap} from '@feasibleone/blong';
|
|
1
|
+
import type {IMeta} from '@feasibleone/blong/types';
|
|
2
|
+
import {adapter, type Errors, type IErrorMap} from '@feasibleone/blong/types';
|
|
3
3
|
import got, {type HttpsOptions, type Options} from 'got';
|
|
4
4
|
|
|
5
5
|
import tls from '../../tls.ts';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {adapter, type Errors, type IErrorMap, type IMeta} from '@feasibleone/blong';
|
|
1
|
+
import {adapter, type Errors, type IErrorMap, type IMeta} from '@feasibleone/blong/types';
|
|
2
2
|
import mongoUriBuilder from 'mongo-uri-builder';
|
|
3
3
|
import {MongoClient, type Sort} from 'mongodb';
|
|
4
4
|
|
package/src/adapter/server/s3.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
PutObjectCommand,
|
|
8
8
|
S3Client,
|
|
9
9
|
} from '@aws-sdk/client-s3';
|
|
10
|
-
import {adapter, type Errors, type IErrorMap, type IMeta} from '@feasibleone/blong';
|
|
10
|
+
import {adapter, type Errors, type IErrorMap, type IMeta} from '@feasibleone/blong/types';
|
|
11
11
|
import {createReadStream, statSync} from 'fs';
|
|
12
12
|
import {Readable} from 'stream';
|
|
13
13
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {adapter, type Errors, type IErrorMap, type IMeta} from '@feasibleone/blong';
|
|
1
|
+
import {adapter, type Errors, type IErrorMap, type IMeta} from '@feasibleone/blong/types';
|
|
2
2
|
import got, {type HttpsOptions, type Options} from 'got';
|
|
3
3
|
import {Duplex, Readable, Writable} from 'stream';
|
|
4
4
|
|
package/src/adapter/server.ts
CHANGED
package/src/adapter.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {handler, type IMeta} from '@feasibleone/blong';
|
|
1
|
+
import {handler, type IMeta} from '@feasibleone/blong/types';
|
|
2
2
|
import timing from 'ut-function.timing';
|
|
3
3
|
|
|
4
4
|
export default handler(({config}) => {
|
|
@@ -7,7 +7,7 @@ export default handler(({config}) => {
|
|
|
7
7
|
send(
|
|
8
8
|
msg: {$http: {method?: string; headers?: unknown; path?: unknown}},
|
|
9
9
|
$meta: IMeta,
|
|
10
|
-
context: unknown
|
|
10
|
+
context: unknown,
|
|
11
11
|
) {
|
|
12
12
|
const params = (msg && !(msg instanceof Array) && Object.assign({}, msg)) || msg;
|
|
13
13
|
const $http = params?.$http;
|
package/src/codec/browser.ts
CHANGED
package/src/codec/server.ts
CHANGED
package/src/error.ts
CHANGED
package/src/handler.name.test.ts
CHANGED
|
@@ -2,45 +2,57 @@
|
|
|
2
2
|
* Test to verify that handlers get unique names matching their filenames
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {handler} from '@feasibleone/blong/types';
|
|
6
6
|
import assert from 'node:assert';
|
|
7
|
-
import {
|
|
7
|
+
import {describe, it} from 'node:test';
|
|
8
8
|
|
|
9
9
|
describe('Handler naming', () => {
|
|
10
10
|
it('should preserve explicit handler names when they match expected name', () => {
|
|
11
11
|
const namedHandler = handler(function myHandler({config}) {
|
|
12
12
|
return {send() {}};
|
|
13
13
|
});
|
|
14
|
-
|
|
15
|
-
assert.strictEqual(
|
|
14
|
+
|
|
15
|
+
assert.strictEqual(
|
|
16
|
+
(namedHandler as Function).name,
|
|
17
|
+
'myHandler',
|
|
18
|
+
'Named handler should preserve its name',
|
|
19
|
+
);
|
|
16
20
|
});
|
|
17
21
|
|
|
18
22
|
it('should allow setting name on anonymous handlers', () => {
|
|
19
23
|
const anonymousHandler = handler(({config}) => {
|
|
20
24
|
return {send() {}};
|
|
21
25
|
});
|
|
22
|
-
|
|
26
|
+
|
|
23
27
|
// Simulate what Watch.ts does when loading handlers
|
|
24
28
|
Object.defineProperty(anonymousHandler, 'name', {
|
|
25
29
|
value: 'send',
|
|
26
30
|
configurable: true,
|
|
27
31
|
enumerable: false,
|
|
28
32
|
});
|
|
29
|
-
|
|
30
|
-
assert.strictEqual(
|
|
33
|
+
|
|
34
|
+
assert.strictEqual(
|
|
35
|
+
(anonymousHandler as Function).name,
|
|
36
|
+
'send',
|
|
37
|
+
'Handler name should be settable',
|
|
38
|
+
);
|
|
31
39
|
});
|
|
32
40
|
|
|
33
41
|
it('should ensure names are unique per file', () => {
|
|
34
42
|
const handler1 = handler(({config}) => ({send() {}}));
|
|
35
43
|
const handler2 = handler(({config}) => ({receive() {}}));
|
|
36
|
-
|
|
44
|
+
|
|
37
45
|
// Simulate loading from different files
|
|
38
46
|
Object.defineProperty(handler1, 'name', {value: 'send', configurable: true});
|
|
39
47
|
Object.defineProperty(handler2, 'name', {value: 'receive', configurable: true});
|
|
40
|
-
|
|
48
|
+
|
|
41
49
|
assert.strictEqual((handler1 as Function).name, 'send');
|
|
42
50
|
assert.strictEqual((handler2 as Function).name, 'receive');
|
|
43
|
-
assert.notStrictEqual(
|
|
51
|
+
assert.notStrictEqual(
|
|
52
|
+
(handler1 as Function).name,
|
|
53
|
+
(handler2 as Function).name,
|
|
54
|
+
'Handlers should have unique names',
|
|
55
|
+
);
|
|
44
56
|
});
|
|
45
57
|
|
|
46
58
|
it('should detect mismatch between handler name and expected name', () => {
|
|
@@ -48,13 +60,13 @@ describe('Handler naming', () => {
|
|
|
48
60
|
const namedHandler = handler(function wrongName({config}) {
|
|
49
61
|
return {send() {}};
|
|
50
62
|
});
|
|
51
|
-
|
|
63
|
+
|
|
52
64
|
// In Watch.ts, this would trigger an error like:
|
|
53
65
|
// "Handler name mismatch in 'send.ts': function is named 'wrongName' but file is named 'send.ts'"
|
|
54
|
-
|
|
66
|
+
|
|
55
67
|
const actualName = (namedHandler as Function).name;
|
|
56
68
|
const expectedName = 'send';
|
|
57
|
-
|
|
69
|
+
|
|
58
70
|
assert.notStrictEqual(actualName, expectedName, 'Mismatch should be detectable');
|
|
59
71
|
assert.strictEqual(actualName, 'wrongName', 'Handler should preserve explicit name');
|
|
60
72
|
});
|
package/src/jwt.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import basic from '@fastify/basic-auth';
|
|
2
2
|
import bearer from '@fastify/bearer-auth';
|
|
3
3
|
import cookie from '@fastify/cookie';
|
|
4
|
-
import {type Errors} from '@feasibleone/blong';
|
|
4
|
+
import {type Errors} from '@feasibleone/blong/types';
|
|
5
5
|
import type {FastifyInstance, FastifyPluginOptions, FastifyReply, FastifyRequest} from 'fastify';
|
|
6
6
|
import fp from 'fastify-plugin';
|
|
7
7
|
import {LRUCache} from 'lru-cache';
|
package/src/layerProxy.ts
CHANGED
package/src/load.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
type Kind,
|
|
11
11
|
type Kinds,
|
|
12
12
|
type SolutionFactory,
|
|
13
|
-
} from '@feasibleone/blong';
|
|
13
|
+
} from '@feasibleone/blong/types';
|
|
14
14
|
import {existsSync} from 'fs';
|
|
15
15
|
import {readdir} from 'fs/promises';
|
|
16
16
|
import {createRequire} from 'node:module';
|
|
@@ -28,6 +28,9 @@ const LAYER_FILE = 'layer' as const;
|
|
|
28
28
|
|
|
29
29
|
/** Well-known layer folder names and their default activation per kind */
|
|
30
30
|
const WELL_KNOWN_LAYERS: Record<string, {server?: object; browser?: object}> = {
|
|
31
|
+
init: {server: {default: true}, browser: {default: true}},
|
|
32
|
+
'server/init': {server: {default: true}},
|
|
33
|
+
'browser/init': {browser: {default: true}},
|
|
31
34
|
error: {server: {default: true}},
|
|
32
35
|
sim: {server: {integration: true}},
|
|
33
36
|
adapter: {server: {default: true}},
|
|
@@ -37,6 +40,8 @@ const WELL_KNOWN_LAYERS: Record<string, {server?: object; browser?: object}> = {
|
|
|
37
40
|
backend: {browser: {default: true}},
|
|
38
41
|
component: {browser: {default: true}},
|
|
39
42
|
test: {browser: {integration: true}},
|
|
43
|
+
'server/test': {server: {integration: true}},
|
|
44
|
+
'browser/test': {browser: {integration: true}},
|
|
40
45
|
};
|
|
41
46
|
|
|
42
47
|
/**
|
|
@@ -48,26 +53,20 @@ async function discoverLayerFolders(
|
|
|
48
53
|
kind_: 'server' | 'browser',
|
|
49
54
|
explicitChildren: Set<string>,
|
|
50
55
|
configNames: string[],
|
|
51
|
-
): Promise<
|
|
52
|
-
const result
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
entries = (await readdir(base, {withFileTypes: true})) as Dirent[];
|
|
56
|
-
} catch {
|
|
57
|
-
return result;
|
|
58
|
-
}
|
|
59
|
-
for (const entry of entries) {
|
|
60
|
-
if (!entry.isDirectory()) continue;
|
|
61
|
-
const name = entry.name.toString();
|
|
56
|
+
): Promise<[string, object][]> {
|
|
57
|
+
const result: [string, object][] = [];
|
|
58
|
+
for (const name of Object.keys(WELL_KNOWN_LAYERS)) {
|
|
62
59
|
if (explicitChildren.has(name)) continue;
|
|
60
|
+
const layerFolder = join(base, name);
|
|
61
|
+
if (!existsSync(layerFolder)) continue;
|
|
63
62
|
const layerFile = join(base, name, `${LAYER_FILE}.${kind_}.ts`);
|
|
64
63
|
if (existsSync(layerFile)) {
|
|
65
64
|
// Read activation from layer.server.ts / layer.browser.ts
|
|
66
65
|
const mod = await import(layerFile).catch(() => null);
|
|
67
66
|
const activation = mod?.default ?? {default: true};
|
|
68
|
-
result.
|
|
67
|
+
result.push([name, activation]);
|
|
69
68
|
} else if (name in WELL_KNOWN_LAYERS && WELL_KNOWN_LAYERS[name][kind_]) {
|
|
70
|
-
result.
|
|
69
|
+
result.push([name, WELL_KNOWN_LAYERS[name][kind_]]);
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
return result;
|
|
@@ -253,7 +252,8 @@ export default async function loadRealm<T extends TSchema>(
|
|
|
253
252
|
configNames,
|
|
254
253
|
);
|
|
255
254
|
for (const [folderName, activation] of discoveredFolders) {
|
|
256
|
-
if (!(folderName in mergedConfig))
|
|
255
|
+
if (!(folderName in mergedConfig))
|
|
256
|
+
merge(mergedConfig, {[basename(folderName)]: activation});
|
|
257
257
|
extraChildren.push(`./${folderName}`);
|
|
258
258
|
}
|
|
259
259
|
}
|
package/src/loop.ts
CHANGED
package/src/scan.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type {Dirent} from 'fs';
|
|
2
|
+
import {readdir} from 'fs/promises';
|
|
3
|
+
import {join} from 'path';
|
|
4
|
+
|
|
5
|
+
export default async function scan(...path: string[]): Promise<Dirent[]> {
|
|
6
|
+
const dirName = join(...path);
|
|
7
|
+
return (
|
|
8
|
+
await readdir(dirName.startsWith('file://') ? dirName.slice(7) : dirName, {
|
|
9
|
+
withFileTypes: true,
|
|
10
|
+
})
|
|
11
|
+
).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
12
|
+
}
|
package/src/timeout.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {IMeta} from '@feasibleone/blong';
|
|
1
|
+
import type {IMeta} from '@feasibleone/blong/types';
|
|
2
2
|
import hrtime from 'browser-process-hrtime';
|
|
3
3
|
|
|
4
4
|
type HRTime = ReturnType<typeof hrtime>;
|
|
@@ -19,7 +19,7 @@ class Timeout {
|
|
|
19
19
|
|
|
20
20
|
protected clean(): void {
|
|
21
21
|
Array.from(this.#calls).forEach((end: {checkTimeout: (time: HRTime) => void}) =>
|
|
22
|
-
end.checkTimeout(now())
|
|
22
|
+
end.checkTimeout(now()),
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -27,7 +27,7 @@ class Timeout {
|
|
|
27
27
|
onTimeout: (error: Error) => void,
|
|
28
28
|
timeout: number,
|
|
29
29
|
createTimeoutError: () => Error,
|
|
30
|
-
set?: Set<IEnd
|
|
30
|
+
set?: Set<IEnd>,
|
|
31
31
|
): IEnd {
|
|
32
32
|
this.#interval = this.#interval || setInterval(this.clean.bind(this), 500);
|
|
33
33
|
const end: IEnd = (error?: Error) => {
|
|
@@ -54,7 +54,7 @@ class Timeout {
|
|
|
54
54
|
fn: (params: unknown) => Promise<unknown>,
|
|
55
55
|
$meta: IMeta,
|
|
56
56
|
error: () => Error,
|
|
57
|
-
set: Set<IEnd
|
|
57
|
+
set: Set<IEnd>,
|
|
58
58
|
): Promise<unknown> {
|
|
59
59
|
if (Array.isArray($meta && $meta.timeout)) {
|
|
60
60
|
return new Promise((resolve, reject) => {
|
|
@@ -70,7 +70,7 @@ class Timeout {
|
|
|
70
70
|
},
|
|
71
71
|
$meta.timeout,
|
|
72
72
|
error,
|
|
73
|
-
set
|
|
73
|
+
set,
|
|
74
74
|
);
|
|
75
75
|
Promise.resolve(params)
|
|
76
76
|
.then(fn)
|