@feasibleone/blong-gogo 1.11.2 → 1.12.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -1
  3. package/src/ApiSchema.ts +45 -10
  4. package/src/ErrorFactory.ts +2 -2
  5. package/src/Gateway.ts +2 -2
  6. package/src/GatewayClient.ts +1 -1
  7. package/src/GatewayCodec.ts +1 -1
  8. package/src/Local.ts +1 -1
  9. package/src/Log.ts +1 -1
  10. package/src/Port.ts +1 -1
  11. package/src/Realm.ts +2 -2
  12. package/src/Registry.ts +2 -2
  13. package/src/Remote.ts +2 -2
  14. package/src/ResolutionDiscovery.ts +1 -1
  15. package/src/ResolutionLocal.ts +1 -1
  16. package/src/RpcClient.ts +1 -1
  17. package/src/RpcServer.ts +1 -1
  18. package/src/Watch.ts +1 -1
  19. package/src/adapter/browser/http.ts +2 -2
  20. package/src/adapter/browser.ts +1 -1
  21. package/src/adapter/server/github.ts +1 -1
  22. package/src/adapter/server/http.ts +2 -2
  23. package/src/adapter/server/k8s.ts +1 -1
  24. package/src/adapter/server/kafka.ts +1 -1
  25. package/src/adapter/server/keycloak.ts +1 -1
  26. package/src/adapter/server/knex.ts +1 -1
  27. package/src/adapter/server/mongodb.ts +1 -1
  28. package/src/adapter/server/s3.ts +1 -1
  29. package/src/adapter/server/slack.ts +1 -1
  30. package/src/adapter/server/tcp.ts +1 -1
  31. package/src/adapter/server/vault.ts +1 -1
  32. package/src/adapter/server/webhook.ts +1 -1
  33. package/src/adapter/server.ts +1 -1
  34. package/src/adapter.ts +1 -1
  35. package/src/codec/adapter/jsonrpc/errors.ts +1 -1
  36. package/src/codec/adapter/jsonrpc/receive.ts +1 -1
  37. package/src/codec/adapter/jsonrpc/send.ts +2 -2
  38. package/src/codec/adapter/mle/ready.ts +1 -1
  39. package/src/codec/adapter/openapi/errors.ts +1 -1
  40. package/src/codec/adapter/openapi/load.ts +1 -1
  41. package/src/codec/adapter/openapi/ready.ts +1 -1
  42. package/src/codec/adapter/openapi/request.ts +1 -1
  43. package/src/codec/browser.ts +1 -1
  44. package/src/codec/server.ts +1 -1
  45. package/src/codec/test/test/testCodecMle.ts +1 -1
  46. package/src/codec/test/test/testLoginTokenCreate.ts +1 -1
  47. package/src/error.ts +1 -1
  48. package/src/handler.name.test.ts +25 -13
  49. package/src/jwt.ts +1 -1
  50. package/src/layerProxy.ts +1 -1
  51. package/src/load.ts +15 -15
  52. package/src/loop.ts +1 -1
  53. package/src/orchestrator/common/dispatch.ts +1 -1
  54. package/src/orchestrator/common/openapi.ts +1 -1
  55. package/src/orchestrator/index.ts +1 -1
  56. package/src/scan.ts +12 -0
  57. package/src/timeout.ts +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.12.0](https://github.com/feasibleone/blong/compare/blong-gogo-v1.11.2...blong-gogo-v1.12.0) (2026-03-15)
4
+
5
+
6
+ ### Features
7
+
8
+ * improve api loading ([2008fa3](https://github.com/feasibleone/blong/commit/2008fa38272252682f259e22632f10e8c33d64f5))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * imports ([c179b6d](https://github.com/feasibleone/blong/commit/c179b6d2d0709f548560e13a99dc2e62facad645))
14
+
3
15
  ## [1.11.2](https://github.com/feasibleone/blong/compare/blong-gogo-v1.11.1...blong-gogo-v1.11.2) (2026-03-15)
4
16
 
5
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feasibleone/blong-gogo",
3
- "version": "1.11.2",
3
+ "version": "1.12.0",
4
4
  "repository": {
5
5
  "url": "git+https://github.com/feasibleone/blong.git"
6
6
  },
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
- def: {
47
- namespace: Record<string, string | string[]>;
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(def.namespace)) {
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
- this.#loaded[`${namespace}${method}`.toLowerCase()] = result[
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: {
@@ -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';
@@ -1,4 +1,4 @@
1
- import type {Errors, IErrorFactory, IErrorMap, ILocal, ILog, IMeta} from '@feasibleone/blong';
1
+ import type {Errors, IErrorFactory, IErrorMap, ILocal, ILog, IMeta} from '@feasibleone/blong/types';
2
2
  import ky from 'ky';
3
3
  import {spare} from 'ut-function.timing';
4
4
 
@@ -1,4 +1,4 @@
1
- import type {IMeta} from '@feasibleone/blong';
1
+ import type {IMeta} from '@feasibleone/blong/types';
2
2
  import got, {type HTTPAlias, type Headers} from 'got';
3
3
  import type {JWTPayload} from 'jose';
4
4
  import busGateway from 'ut-bus/gateway.js';
package/src/Local.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {type ILocal, Internal} from '@feasibleone/blong';
1
+ import {type ILocal, Internal} from '@feasibleone/blong/types';
2
2
 
3
3
  export default class Local extends Internal implements ILocal {
4
4
  #mapLocal: object = {};
package/src/Log.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {Internal, type ILog} from '@feasibleone/blong';
1
+ import {Internal, type ILog} from '@feasibleone/blong/types';
2
2
  import {pino, type Logger, type LoggerOptions} from 'pino';
3
3
 
4
4
  // echo -e "\u001B]8;;https://google.com\u001B\\Кликни тук\u001B]8;;\e\\"
package/src/Port.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {Internal, type IAdapterFactory} from '@feasibleone/blong';
1
+ import {Internal, type IAdapterFactory} from '@feasibleone/blong/types';
2
2
  import {Port as UtPort} from 'ut-port';
3
3
 
4
4
  export interface IPort {
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';
@@ -1,4 +1,4 @@
1
- import {Internal} from '@feasibleone/blong';
1
+ import {Internal} from '@feasibleone/blong/types';
2
2
 
3
3
  import type {IResolution} from './Resolution.ts';
4
4
 
package/src/RpcClient.ts CHANGED
@@ -6,7 +6,7 @@ import type {
6
6
  ILog,
7
7
  IMeta,
8
8
  IRemote,
9
- } from '@feasibleone/blong';
9
+ } from '@feasibleone/blong/types';
10
10
  import got, {type HttpsOptions} from 'got';
11
11
  import timing from 'ut-function.timing';
12
12
 
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';
@@ -1,4 +1,4 @@
1
- import {realm} from '@feasibleone/blong';
1
+ import {realm} from '@feasibleone/blong/types';
2
2
 
3
3
  export default realm(blong => ({
4
4
  url: import.meta.url,
@@ -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 {Octokit} from '@octokit/rest';
3
3
 
4
4
  export interface IConfig {
@@ -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 * as k8s from '@kubernetes/client-node';
3
3
 
4
4
  export interface IConfig {
@@ -1,4 +1,4 @@
1
- import {adapter} from '@feasibleone/blong';
1
+ import {adapter} from '@feasibleone/blong/types';
2
2
  import Kafka from 'node-rdkafka';
3
3
  import {Duplex} from 'stream';
4
4
 
@@ -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 KcAdminClient from '@keycloak/keycloak-admin-client';
3
3
  import got from 'got';
4
4
 
@@ -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 Knex from 'knex';
3
3
 
4
4
  export interface IConfig {
@@ -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
 
@@ -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 {IncomingWebhook} from '@slack/webhook';
3
3
 
4
4
  export interface IConfig {
@@ -1,4 +1,4 @@
1
- import {adapter, type ITypedError} from '@feasibleone/blong';
1
+ import {adapter, type ITypedError} from '@feasibleone/blong/types';
2
2
  import {Socket} from 'net';
3
3
  import createReconnect from 'reconnect-core';
4
4
  import bitSyntax from 'ut-bitsyntax';
@@ -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 vault from 'node-vault';
3
3
 
4
4
  export interface IConfig {
@@ -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
 
@@ -1,4 +1,4 @@
1
- import {realm} from '@feasibleone/blong';
1
+ import {realm} from '@feasibleone/blong/types';
2
2
 
3
3
  export default realm(blong => ({
4
4
  url: import.meta.url,
package/src/adapter.ts CHANGED
@@ -6,7 +6,7 @@ import type {
6
6
  IErrorMap,
7
7
  IMeta,
8
8
  ITypedError,
9
- } from '@feasibleone/blong';
9
+ } from '@feasibleone/blong/types';
10
10
  import type net from 'node:net';
11
11
  import PQueue from 'p-queue';
12
12
  import merge from 'ut-function.merge';
@@ -1,4 +1,4 @@
1
- import {library} from '@feasibleone/blong';
1
+ import {library} from '@feasibleone/blong/types';
2
2
 
3
3
  export default library(({lib: {error}}) => ({
4
4
  errors: error({
@@ -1,4 +1,4 @@
1
- import {handler, type ITypedError} from '@feasibleone/blong';
1
+ import {handler, type ITypedError} from '@feasibleone/blong/types';
2
2
  import {type Response} from 'got';
3
3
 
4
4
  export default handler(({errors}) => ({
@@ -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;
@@ -1,4 +1,4 @@
1
- import {handler} from '@feasibleone/blong';
1
+ import {handler} from '@feasibleone/blong/types';
2
2
  import {type Response} from 'got';
3
3
  import {exportJWK, generateKeyPair} from 'jose';
4
4
  import joseFactory from 'ut-bus/jose.js';
@@ -1,4 +1,4 @@
1
- import {library} from '@feasibleone/blong';
1
+ import {library} from '@feasibleone/blong/types';
2
2
 
3
3
  export default library(({lib: {error}}) => {
4
4
  error({
@@ -1,4 +1,4 @@
1
- import {library} from '@feasibleone/blong';
1
+ import {library} from '@feasibleone/blong/types';
2
2
 
3
3
  import loadApi from '../../../loadApi.ts';
4
4
 
@@ -1,4 +1,4 @@
1
- import {handler, type IMeta} from '@feasibleone/blong';
1
+ import {handler, type IMeta} from '@feasibleone/blong/types';
2
2
 
3
3
  import {methodId} from '../../../lib.ts';
4
4
 
@@ -1,4 +1,4 @@
1
- import {library} from '@feasibleone/blong';
1
+ import {library} from '@feasibleone/blong/types';
2
2
  import {type OpenAPIV2} from 'openapi-types';
3
3
  import interpolate from 'ut-function.interpolate';
4
4
 
@@ -1,4 +1,4 @@
1
- import {realm} from '@feasibleone/blong';
1
+ import {realm} from '@feasibleone/blong/types';
2
2
 
3
3
  export default realm(blong => ({
4
4
  url: import.meta.url,
@@ -1,4 +1,4 @@
1
- import {realm} from '@feasibleone/blong';
1
+ import {realm} from '@feasibleone/blong/types';
2
2
 
3
3
  export default realm(blong => ({
4
4
  url: import.meta.url,
@@ -1,4 +1,4 @@
1
- import {handler, type IMeta} from '@feasibleone/blong';
1
+ import {handler, type IMeta} from '@feasibleone/blong/types';
2
2
  import type Assert from 'node:assert';
3
3
 
4
4
  const DAY = 24 * 60 * 60 * 1000;
@@ -1,4 +1,4 @@
1
- import {handler, type IMeta} from '@feasibleone/blong';
1
+ import {handler, type IMeta} from '@feasibleone/blong/types';
2
2
 
3
3
  export default handler(({lib: {group}, handler: {loginTokenCreate}}) => ({
4
4
  testLoginTokenCreate: ({name = 'login token'}: {name?: string}) =>
package/src/error.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type {IErrorFactory, IMeta, ITypedError} from '@feasibleone/blong';
1
+ import type {IErrorFactory, IMeta, ITypedError} from '@feasibleone/blong/types';
2
2
 
3
3
  const typeRegex: RegExp = /^[$a-z]\w*(\.!?\w+)*$/;
4
4
  const paramsRegex: RegExp = /\{([^}]*)\}/g;
@@ -2,45 +2,57 @@
2
2
  * Test to verify that handlers get unique names matching their filenames
3
3
  */
4
4
 
5
- import {describe, it} from 'node:test';
5
+ import {handler} from '@feasibleone/blong/types';
6
6
  import assert from 'node:assert';
7
- import {handler} from '@feasibleone/blong';
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((namedHandler as Function).name, 'myHandler', 'Named handler should preserve its name');
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((anonymousHandler as Function).name, 'send', 'Handler name should be settable');
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((handler1 as Function).name, (handler2 as Function).name, 'Handlers should have unique names');
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
@@ -4,7 +4,7 @@ import {
4
4
  type IApiSchema,
5
5
  type IErrorFactory,
6
6
  type IModuleConfig,
7
- } from '@feasibleone/blong';
7
+ } from '@feasibleone/blong/types';
8
8
  import merge from 'ut-function.merge';
9
9
 
10
10
  import createPort from './adapter.ts';
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<Map<string, object>> {
52
- const result = new Map<string, object>();
53
- let entries: Dirent[];
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.set(name, activation);
67
+ result.push([name, activation]);
69
68
  } else if (name in WELL_KNOWN_LAYERS && WELL_KNOWN_LAYERS[name][kind_]) {
70
- result.set(name, WELL_KNOWN_LAYERS[name][kind_]);
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)) merge(mergedConfig, {[folderName]: activation});
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
@@ -1,4 +1,4 @@
1
- import type {IAdapterFactory, IMeta, ITypedError} from '@feasibleone/blong';
1
+ import type {IAdapterFactory, IMeta, ITypedError} from '@feasibleone/blong/types';
2
2
  import type net from 'node:net';
3
3
  import {v4} from 'uuid';
4
4
 
@@ -1,4 +1,4 @@
1
- import {orchestrator, type IMeta} from '@feasibleone/blong';
1
+ import {orchestrator, type IMeta} from '@feasibleone/blong/types';
2
2
 
3
3
  export default orchestrator<{destination?: string}>(({remote}) => ({
4
4
  activation: {
@@ -1,4 +1,4 @@
1
- import {orchestrator} from '@feasibleone/blong';
1
+ import {orchestrator} from '@feasibleone/blong/types';
2
2
 
3
3
  export default orchestrator<{api?: {namespace: Record<string, string | string[]>}}>(
4
4
  ({remote, registry}) => ({
@@ -1,4 +1,4 @@
1
- import {realm} from '@feasibleone/blong';
1
+ import {realm} from '@feasibleone/blong/types';
2
2
 
3
3
  export default realm(blong => ({
4
4
  url: import.meta.url,
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)