@nmtjs/contract 0.16.1 → 0.17.0-beta.2
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/LICENSE.md +1 -1
- package/README.md +41 -1
- package/dist/index.d.ts +5 -15
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/schemas/event.d.ts +5 -9
- package/dist/schemas/event.js +1 -3
- package/dist/schemas/event.js.map +1 -1
- package/dist/schemas/subscription.d.ts +40 -15
- package/dist/schemas/subscription.js +21 -19
- package/dist/schemas/subscription.js.map +1 -1
- package/dist/types/blob.js +5 -5
- package/dist/types/blob.js.map +1 -1
- package/package.json +3 -6
- package/src/index.ts +2 -2
- package/src/schemas/event.ts +7 -26
- package/src/schemas/subscription.ts +127 -52
- package/src/types/blob.ts +5 -5
package/LICENSE.md
CHANGED
|
@@ -4,4 +4,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
4
4
|
|
|
5
5
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
6
|
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,9 +1,49 @@
|
|
|
1
1
|
# NeemataJS - RPC application server for real-time applications (proof of concept)
|
|
2
2
|
|
|
3
3
|
### Built with following in mind:
|
|
4
|
+
|
|
4
5
|
- transport-agnostic (like WebSockets, WebTransport, .etc)
|
|
5
6
|
- format-agnostic (like JSON, MessagePack, BSON, .etc)
|
|
6
7
|
- binary data streaming and event subscriptions
|
|
7
8
|
- contract-based API
|
|
8
9
|
- end-to-end type safety
|
|
9
|
-
- CPU-intensive task execution on separate workers
|
|
10
|
+
- CPU-intensive task execution on separate workers
|
|
11
|
+
|
|
12
|
+
## Neem CLI draft
|
|
13
|
+
|
|
14
|
+
`neem build` compiles config, app entries, plugin entries, and plugin-declared
|
|
15
|
+
artifacts into `dist` by default. It writes an internal `neem.manifest.json`
|
|
16
|
+
with relative artifact paths.
|
|
17
|
+
|
|
18
|
+
`neem start` consumes an existing built output directory. It reads the manifest
|
|
19
|
+
for executable artifacts and serialized runtime config, registers built plugin
|
|
20
|
+
hooks, and starts app workers in production mode.
|
|
21
|
+
|
|
22
|
+
`neem dev` uses `.neem` by default as a build-like watched output directory. It
|
|
23
|
+
uses the same manifest shape as `start`, restarts app workers after successful
|
|
24
|
+
config/app rebuilds, reloads plugin hooks after plugin entry rebuilds, and keeps
|
|
25
|
+
existing workers alive on rebuild errors.
|
|
26
|
+
|
|
27
|
+
## Service integration tests
|
|
28
|
+
|
|
29
|
+
Service-backed package integration tests live beside package owners under
|
|
30
|
+
`packages/*/tests/integration`.
|
|
31
|
+
|
|
32
|
+
Local services:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
docker compose up -d --wait redis valkey kafka
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Run required service tests:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
NMTJS_REQUIRE_SERVICE_TESTS=1 \
|
|
42
|
+
REDIS_URL=redis://localhost:6379 \
|
|
43
|
+
VALKEY_URL=redis://localhost:6380 \
|
|
44
|
+
KAFKA_BROKERS=localhost:9092 \
|
|
45
|
+
pnpm run test:integration:services
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Without service env, these tests skip in normal package/root test runs. In CI,
|
|
49
|
+
`NMTJS_REQUIRE_SERVICE_TESTS=1` makes missing service env fail instead of skip.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SubscriptionContract } from './schemas/subscription.ts';
|
|
1
2
|
export * from './schemas/event.ts';
|
|
2
3
|
export * from './schemas/procedure.ts';
|
|
3
4
|
export * from './schemas/router.ts';
|
|
@@ -11,29 +12,18 @@ export declare namespace contract {
|
|
|
11
12
|
schemaOptions?: import("./utils.ts").ContractSchemaOptions;
|
|
12
13
|
name?: string;
|
|
13
14
|
}>(options: Options) => import("./schemas/procedure.ts").TProcedureContract<Options['input'] extends import("@nmtjs/type").BaseType ? Options['input'] : import("@nmtjs/type/never").NeverType, Options['output'] extends import("@nmtjs/type").BaseType ? Options['output'] : import("@nmtjs/type/never").NeverType, Options['stream'] extends true ? true : undefined, Options['name'] extends string ? Options['name'] : undefined>;
|
|
14
|
-
const event: <Payload extends import("@nmtjs/type").BaseType
|
|
15
|
+
const event: <Payload extends import("@nmtjs/type").BaseType = import("@nmtjs/type/never").NeverType>(options?: {
|
|
15
16
|
payload?: Payload;
|
|
16
17
|
schemaOptions?: import("./utils.ts").ContractSchemaOptions;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const subscription: (<const Options extends {
|
|
20
|
-
events: Record<string, import("./schemas/event.ts").TAnyEventContract>;
|
|
21
|
-
name?: string;
|
|
22
|
-
schemaOptions?: import("./utils.ts").ContractSchemaOptions;
|
|
23
|
-
}, SubOpt extends import("./schemas/subscription.ts").SubcriptionOptions = null>(options: Options) => import("./schemas/subscription.ts").TSubscriptionContract<SubOpt, Options["events"], Options["name"]>) & {
|
|
24
|
-
withOptions: <Options extends import("./schemas/subscription.ts").SubcriptionOptions>() => <T extends {
|
|
25
|
-
events: Record<string, import("./schemas/event.ts").TAnyEventContract>;
|
|
26
|
-
name?: string;
|
|
27
|
-
schemaOptions?: import("./utils.ts").ContractSchemaOptions;
|
|
28
|
-
}>(options: T) => import("./schemas/subscription.ts").TSubscriptionContract<Options, T["events"], T["name"]>;
|
|
29
|
-
};
|
|
18
|
+
}) => import("./schemas/event.ts").TEventContract<Payload>;
|
|
19
|
+
const subscription: typeof SubscriptionContract;
|
|
30
20
|
const router: <const Options extends {
|
|
31
21
|
routes: Record<string, import("./schemas/router.ts").TRouteContract>;
|
|
32
22
|
name?: string;
|
|
33
23
|
timeout?: number;
|
|
34
24
|
schemaOptions?: import("./utils.ts").ContractSchemaOptions;
|
|
35
25
|
}>(options: Options) => import("./schemas/router.ts").TRouterContract<Options["routes"], Options["name"] extends string ? Options["name"] : undefined>;
|
|
36
|
-
const blob: (options?: import("./types/blob.ts").BlobOptions) => import("@nmtjs/type/custom").CustomType<import("@nmtjs/protocol").ProtocolBlobInterface>;
|
|
37
26
|
}
|
|
27
|
+
export { BlobType as blobType } from './types/blob.ts';
|
|
38
28
|
export { contract as c };
|
|
39
29
|
export default contract;
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import { EventContract } from './schemas/event.js';
|
|
|
2
2
|
import { ProcedureContract } from './schemas/procedure.js';
|
|
3
3
|
import { RouterContract } from './schemas/router.js';
|
|
4
4
|
import { SubscriptionContract } from './schemas/subscription.js';
|
|
5
|
-
import { BlobType } from './types/blob.js';
|
|
6
5
|
export * from './schemas/event.js';
|
|
7
6
|
export * from './schemas/procedure.js';
|
|
8
7
|
export * from './schemas/router.js';
|
|
@@ -13,8 +12,8 @@ export var contract;
|
|
|
13
12
|
contract.event = EventContract;
|
|
14
13
|
contract.subscription = SubscriptionContract;
|
|
15
14
|
contract.router = RouterContract;
|
|
16
|
-
contract.blob = BlobType;
|
|
17
15
|
})(contract || (contract = {}));
|
|
16
|
+
export { BlobType as blobType } from './types/blob.js';
|
|
18
17
|
export { contract as c };
|
|
19
18
|
export default contract;
|
|
20
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAEhE,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,2BAA2B,CAAA;AAEzC,MAAM,KAAW,QAAQ,CAKxB;AALD,WAAiB,QAAQ;IACV,kBAAS,GAAG,iBAAiB,CAAA;IAC7B,cAAK,GAAG,aAAa,CAAA;IACrB,qBAAY,GAAG,oBAAoB,CAAA;IACnC,eAAM,GAAG,cAAc,CAAA;AACtC,CAAC,EALgB,QAAQ,KAAR,QAAQ,QAKxB;AAED,OAAO,EAAE,QAAQ,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAEtD,OAAO,EAAE,QAAQ,IAAI,CAAC,EAAE,CAAA;AAExB,eAAe,QAAQ,CAAA"}
|
package/dist/schemas/event.d.ts
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import type { BaseType } from '@nmtjs/type';
|
|
1
|
+
import type { BaseType, BaseTypeAny } from '@nmtjs/type';
|
|
2
2
|
import { t } from '@nmtjs/type';
|
|
3
3
|
import type { ContractSchemaOptions } from '../utils.ts';
|
|
4
|
-
import type { SubcriptionOptions } from './subscription.ts';
|
|
5
4
|
import { Kind } from '../constants.ts';
|
|
6
5
|
export declare const EventKind: unique symbol;
|
|
7
|
-
export type TAnyEventContract = TEventContract<
|
|
8
|
-
export interface TEventContract<Payload extends BaseType = t.NeverType
|
|
6
|
+
export type TAnyEventContract = TEventContract<BaseTypeAny>;
|
|
7
|
+
export interface TEventContract<Payload extends BaseType = t.NeverType> {
|
|
9
8
|
readonly [Kind]: typeof EventKind;
|
|
10
9
|
readonly type: 'neemata:event';
|
|
11
|
-
readonly name: Name;
|
|
12
10
|
readonly payload: Payload;
|
|
13
|
-
readonly options: Options;
|
|
14
11
|
}
|
|
15
|
-
export declare const EventContract: <Payload extends BaseType
|
|
12
|
+
export declare const EventContract: <Payload extends BaseType = t.NeverType>(options?: {
|
|
16
13
|
payload?: Payload;
|
|
17
14
|
schemaOptions?: ContractSchemaOptions;
|
|
18
|
-
|
|
19
|
-
}) => TEventContract<Payload, Name, Options>;
|
|
15
|
+
}) => TEventContract<Payload>;
|
|
20
16
|
export declare function IsEventContract(value: any): value is TAnyEventContract;
|
package/dist/schemas/event.js
CHANGED
|
@@ -3,14 +3,12 @@ import { Kind } from '../constants.js';
|
|
|
3
3
|
import { createSchema } from '../utils.js';
|
|
4
4
|
export const EventKind = Symbol('NeemataEvent');
|
|
5
5
|
export const EventContract = (options) => {
|
|
6
|
-
const { payload = t.never(), schemaOptions = {}
|
|
6
|
+
const { payload = t.never(), schemaOptions = {} } = options ?? {};
|
|
7
7
|
return createSchema({
|
|
8
8
|
...schemaOptions,
|
|
9
9
|
[Kind]: EventKind,
|
|
10
10
|
type: 'neemata:event',
|
|
11
11
|
payload,
|
|
12
|
-
name,
|
|
13
|
-
options: undefined,
|
|
14
12
|
});
|
|
15
13
|
};
|
|
16
14
|
export function IsEventContract(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.js","sourceRoot":"","sources":["../../src/schemas/event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"event.js","sourceRoot":"","sources":["../../src/schemas/event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,aAAa,CAAA;AAG/B,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,CAAA;AAU/C,MAAM,CAAC,MAAM,aAAa,GAAG,CAE3B,OAGD,EAAE,EAAE;IACH,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,EAAwB,EAAE,aAAa,GAAG,EAAE,EAAE,GACrE,OAAO,IAAI,EAAE,CAAA;IACf,OAAO,YAAY,CAA0B;QAC3C,GAAG,aAAa;QAChB,CAAC,IAAI,CAAC,EAAE,SAAS;QACjB,IAAI,EAAE,eAAe;QACrB,OAAO;KACR,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,UAAU,eAAe,CAAC,KAAU;IACxC,OAAO,IAAI,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAA;AACnD,CAAC"}
|
|
@@ -1,27 +1,52 @@
|
|
|
1
|
+
import type { AnyCompatibleType, BaseType, BaseTypeAny, t } from '@nmtjs/type';
|
|
1
2
|
import type { ContractSchemaOptions } from '../utils.ts';
|
|
2
3
|
import type { TAnyEventContract, TEventContract } from './event.ts';
|
|
3
4
|
import { Kind } from '../constants.ts';
|
|
4
5
|
export declare const SubscriptionKind: unique symbol;
|
|
5
|
-
export type
|
|
6
|
-
export type
|
|
7
|
-
export
|
|
6
|
+
export type SubscriptionParamsType = AnyCompatibleType<Record<string, string | number | boolean | null>>;
|
|
7
|
+
export type SubscriptionKey<Params extends BaseType> = Params extends t.NeverType ? undefined : (params: t.infer.decode.output<Params>) => string;
|
|
8
|
+
export type TAnySubscriptionContract = TSubscriptionContract<any, Record<string, TAnyEventContract>, string>;
|
|
9
|
+
export type TAnySubscriptionEventContract = TSubscriptionEventContract<BaseTypeAny, string, TAnySubscriptionContract>;
|
|
10
|
+
export type SubscriptionParams<Contract extends TAnySubscriptionContract> = t.infer.decode.output<Contract['params']>;
|
|
11
|
+
export type SubscriptionEventMessage<E extends TAnySubscriptionEventContract> = {
|
|
12
|
+
event: E['event'];
|
|
13
|
+
payload: t.infer.decode.output<E['payload']>;
|
|
14
|
+
};
|
|
15
|
+
export type SubscriptionPublishInput<E extends TAnySubscriptionEventContract> = t.infer.encode.input<E['payload']>;
|
|
16
|
+
export type SubscriptionEventUnion<Events extends Record<string, TAnySubscriptionEventContract>> = {
|
|
17
|
+
[K in keyof Events]: SubscriptionEventMessage<Events[K]>;
|
|
18
|
+
}[keyof Events];
|
|
19
|
+
export type SubscriptionSelectedEventUnion<Contract extends TAnySubscriptionContract, Events extends Partial<Record<keyof Contract['events'], true>>> = {} extends Events ? SubscriptionEventUnion<Contract['events']> : {
|
|
20
|
+
[K in keyof Events]: K extends keyof Contract['events'] ? SubscriptionEventMessage<Contract['events'][K]> : never;
|
|
21
|
+
}[keyof Events];
|
|
22
|
+
export interface TSubscriptionEventContract<Payload extends BaseType = BaseTypeAny, Event extends string = string, Subscription = TAnySubscriptionContract> extends TEventContract<Payload> {
|
|
23
|
+
readonly event: Event;
|
|
24
|
+
readonly subscription: Subscription;
|
|
25
|
+
}
|
|
26
|
+
export interface TSubscriptionContract<Params extends BaseType = t.NeverType, Events extends Record<string, unknown> = {}, Namespace extends string = string> {
|
|
8
27
|
readonly [Kind]: typeof SubscriptionKind;
|
|
9
28
|
readonly type: 'neemata:subscription';
|
|
10
|
-
readonly
|
|
11
|
-
readonly
|
|
29
|
+
readonly namespace: Namespace;
|
|
30
|
+
readonly params: Params;
|
|
31
|
+
readonly key: SubscriptionKey<Params>;
|
|
12
32
|
readonly events: {
|
|
13
|
-
[K in keyof Events]: Events[K] extends TAnyEventContract ?
|
|
33
|
+
[K in keyof Events]: Events[K] extends TAnyEventContract ? TSubscriptionEventContract<Events[K]['payload'], Extract<K, string>, TSubscriptionContract<Params, Events, Namespace>> : never;
|
|
14
34
|
};
|
|
15
35
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
36
|
+
type SubscriptionContractBaseOptions<Namespace extends string, Events extends Record<string, TAnyEventContract>> = {
|
|
37
|
+
namespace: Namespace;
|
|
38
|
+
events: Events;
|
|
19
39
|
schemaOptions?: ContractSchemaOptions;
|
|
20
|
-
}, SubOpt extends SubcriptionOptions = null>(options: Options) => TSubscriptionContract<SubOpt, Options["events"], Options["name"]>) & {
|
|
21
|
-
withOptions: <Options extends SubcriptionOptions>() => <T extends {
|
|
22
|
-
events: Record<string, TAnyEventContract>;
|
|
23
|
-
name?: string;
|
|
24
|
-
schemaOptions?: ContractSchemaOptions;
|
|
25
|
-
}>(options: T) => TSubscriptionContract<Options, T["events"], T["name"]>;
|
|
26
40
|
};
|
|
41
|
+
type SubscriptionContractNoParamsOptions<Namespace extends string, Events extends Record<string, TAnyEventContract>> = SubscriptionContractBaseOptions<Namespace, Events> & {
|
|
42
|
+
params?: undefined;
|
|
43
|
+
key?: undefined;
|
|
44
|
+
};
|
|
45
|
+
type SubscriptionContractWithParamsOptions<Namespace extends string, Params extends SubscriptionParamsType, Events extends Record<string, TAnyEventContract>> = SubscriptionContractBaseOptions<Namespace, Events> & {
|
|
46
|
+
params: Params;
|
|
47
|
+
key: (params: t.infer.decode.output<Params>) => string;
|
|
48
|
+
};
|
|
49
|
+
export declare function SubscriptionContract<const Namespace extends string, const Events extends Record<string, TAnyEventContract>>(options: SubscriptionContractNoParamsOptions<Namespace, Events>): TSubscriptionContract<t.NeverType, Events, Namespace>;
|
|
50
|
+
export declare function SubscriptionContract<const Namespace extends string, const Params extends SubscriptionParamsType, const Events extends Record<string, TAnyEventContract>>(options: SubscriptionContractWithParamsOptions<Namespace, Params, Events>): TSubscriptionContract<Params, Events, Namespace>;
|
|
27
51
|
export declare function IsSubscriptionContract(contract: any): contract is TAnySubscriptionContract;
|
|
52
|
+
export {};
|
|
@@ -1,28 +1,30 @@
|
|
|
1
|
+
import { t as types } from '@nmtjs/type';
|
|
1
2
|
import { Kind } from '../constants.js';
|
|
2
|
-
import {
|
|
3
|
+
import { createSchema } from '../utils.js';
|
|
3
4
|
export const SubscriptionKind = Symbol('NeemataSubscription');
|
|
4
|
-
|
|
5
|
-
const { schemaOptions = {}
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const fullName = concatFullName(name, key);
|
|
10
|
-
_events[key] = createSchema({ ...event, name: fullName });
|
|
11
|
-
}
|
|
12
|
-
return createSchema({
|
|
5
|
+
export function SubscriptionContract(options) {
|
|
6
|
+
const { schemaOptions = {} } = options;
|
|
7
|
+
const params = options.params ?? types.never();
|
|
8
|
+
const events = {};
|
|
9
|
+
const subscription = createSchema({
|
|
13
10
|
...schemaOptions,
|
|
14
11
|
[Kind]: SubscriptionKind,
|
|
15
12
|
type: 'neemata:subscription',
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
namespace: options.namespace,
|
|
14
|
+
params,
|
|
15
|
+
key: options.key,
|
|
16
|
+
events,
|
|
19
17
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
for (const eventName in options.events) {
|
|
19
|
+
const event = options.events[eventName];
|
|
20
|
+
events[eventName] = createSchema({
|
|
21
|
+
...event,
|
|
22
|
+
event: eventName,
|
|
23
|
+
subscription,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return subscription;
|
|
27
|
+
}
|
|
26
28
|
export function IsSubscriptionContract(contract) {
|
|
27
29
|
return Kind in contract && contract[Kind] === SubscriptionKind;
|
|
28
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/schemas/subscription.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/schemas/subscription.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,IAAI,KAAK,EAAE,MAAM,aAAa,CAAA;AAIxC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAA;AAsH7D,MAAM,UAAU,oBAAoB,CAAC,OAMpC;IACC,MAAM,EAAE,aAAa,GAAG,EAAE,EAAE,GAAG,OAAO,CAAA;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,EAAmD,CAAA;IAClE,MAAM,YAAY,GAAG,YAAY,CAAM;QACrC,GAAG,aAAa;QAChB,CAAC,IAAI,CAAC,EAAE,gBAAgB;QACxB,IAAI,EAAE,sBAAsB;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM;QACN,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,MAAM;KACP,CAAC,CAAA;IAEF,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACvC,MAAM,CAAC,SAAS,CAAC,GAAG,YAAY,CAAgC;YAC9D,GAAG,KAAK;YACR,KAAK,EAAE,SAAS;YAChB,YAAY;SACb,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,QAAa;IAEb,OAAO,IAAI,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,gBAAgB,CAAA;AAChE,CAAC"}
|
package/dist/types/blob.js
CHANGED
|
@@ -4,12 +4,12 @@ export const BlobType = (options = {}) => CustomType.factory({
|
|
|
4
4
|
decode: (value) => value,
|
|
5
5
|
encode: (value) => value,
|
|
6
6
|
validation: {
|
|
7
|
-
decode(value,
|
|
7
|
+
decode(value, payload) {
|
|
8
8
|
if (isBlobInterface(value)) {
|
|
9
9
|
if (options.maxSize) {
|
|
10
10
|
const size = value.metadata.size;
|
|
11
11
|
if (typeof size !== 'undefined' && size > options.maxSize) {
|
|
12
|
-
addIssue({
|
|
12
|
+
payload.addIssue({
|
|
13
13
|
code: 'custom',
|
|
14
14
|
message: `Blob size unknown or exceeds maximum allowed size of ${options.maxSize} bytes`,
|
|
15
15
|
});
|
|
@@ -17,15 +17,15 @@ export const BlobType = (options = {}) => CustomType.factory({
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
|
-
addIssue({
|
|
20
|
+
payload.addIssue({
|
|
21
21
|
code: 'custom',
|
|
22
22
|
message: 'Value is not a Neemata Blob. Make sure to use transport that supports encoded streams.',
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
|
-
encode(value,
|
|
26
|
+
encode(value, payload) {
|
|
27
27
|
if (!isBlobInterface(value)) {
|
|
28
|
-
addIssue({
|
|
28
|
+
payload.addIssue({
|
|
29
29
|
code: 'custom',
|
|
30
30
|
message: 'Value is not a Neemata Blob. Make sure to use transport that supports encoded streams.',
|
|
31
31
|
});
|
package/dist/types/blob.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blob.js","sourceRoot":"","sources":["../../src/types/blob.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAO/C,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,OAAO,GAAgB,EAAE,EACU,EAAE,CACrC,UAAU,CAAC,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;IACxB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;IACxB,UAAU,EAAE;QACV,MAAM,CAAC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"blob.js","sourceRoot":"","sources":["../../src/types/blob.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAO/C,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,OAAO,GAAgB,EAAE,EACU,EAAE,CACrC,UAAU,CAAC,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;IACxB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;IACxB,UAAU,EAAE;QACV,MAAM,CAAC,KAAK,EAAE,OAAO;YACnB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAA;oBAChC,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;wBAC1D,OAAO,CAAC,QAAQ,CAAC;4BACf,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,wDAAwD,OAAO,CAAC,OAAO,QAAQ;yBACzF,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,QAAQ,CAAC;oBACf,IAAI,EAAE,QAAQ;oBACd,OAAO,EACL,wFAAwF;iBAC3F,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,OAAO;YACnB,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO,CAAC,QAAQ,CAAC;oBACf,IAAI,EAAE,QAAQ;oBACd,OAAO,EACL,wFAAwF;iBAC3F,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;KACF;CACF,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@nmtjs/protocol": "0.
|
|
14
|
-
"@nmtjs/type": "0.
|
|
13
|
+
"@nmtjs/protocol": "0.17.0-beta.2",
|
|
14
|
+
"@nmtjs/type": "0.17.0-beta.2"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"zod": "^4.0.0"
|
|
@@ -22,12 +22,9 @@
|
|
|
22
22
|
"LICENSE.md",
|
|
23
23
|
"README.md"
|
|
24
24
|
],
|
|
25
|
-
"version": "0.
|
|
25
|
+
"version": "0.17.0-beta.2",
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
28
|
"url": "https://github.com/neematajs/neemata"
|
|
29
|
-
},
|
|
30
|
-
"scripts": {
|
|
31
|
-
"clean-build": "rm -rf ./dist"
|
|
32
29
|
}
|
|
33
30
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { EventContract } from './schemas/event.ts'
|
|
|
2
2
|
import { ProcedureContract } from './schemas/procedure.ts'
|
|
3
3
|
import { RouterContract } from './schemas/router.ts'
|
|
4
4
|
import { SubscriptionContract } from './schemas/subscription.ts'
|
|
5
|
-
import { BlobType } from './types/blob.ts'
|
|
6
5
|
|
|
7
6
|
export * from './schemas/event.ts'
|
|
8
7
|
export * from './schemas/procedure.ts'
|
|
@@ -14,9 +13,10 @@ export namespace contract {
|
|
|
14
13
|
export const event = EventContract
|
|
15
14
|
export const subscription = SubscriptionContract
|
|
16
15
|
export const router = RouterContract
|
|
17
|
-
export const blob = BlobType
|
|
18
16
|
}
|
|
19
17
|
|
|
18
|
+
export { BlobType as blobType } from './types/blob.ts'
|
|
19
|
+
|
|
20
20
|
export { contract as c }
|
|
21
21
|
|
|
22
22
|
export default contract
|
package/src/schemas/event.ts
CHANGED
|
@@ -1,52 +1,33 @@
|
|
|
1
|
-
import type { BaseType } from '@nmtjs/type'
|
|
1
|
+
import type { BaseType, BaseTypeAny } from '@nmtjs/type'
|
|
2
2
|
import { t } from '@nmtjs/type'
|
|
3
3
|
|
|
4
4
|
import type { ContractSchemaOptions } from '../utils.ts'
|
|
5
|
-
import type { SubcriptionOptions } from './subscription.ts'
|
|
6
5
|
import { Kind } from '../constants.ts'
|
|
7
6
|
import { createSchema } from '../utils.ts'
|
|
8
7
|
|
|
9
8
|
export const EventKind = Symbol('NeemataEvent')
|
|
10
9
|
|
|
11
|
-
export type TAnyEventContract = TEventContract<
|
|
12
|
-
BaseType,
|
|
13
|
-
string | undefined,
|
|
14
|
-
SubcriptionOptions | undefined
|
|
15
|
-
>
|
|
10
|
+
export type TAnyEventContract = TEventContract<BaseTypeAny>
|
|
16
11
|
|
|
17
|
-
export interface TEventContract<
|
|
18
|
-
Payload extends BaseType = t.NeverType,
|
|
19
|
-
Name extends string | undefined = undefined,
|
|
20
|
-
Options extends SubcriptionOptions | undefined = undefined,
|
|
21
|
-
> {
|
|
12
|
+
export interface TEventContract<Payload extends BaseType = t.NeverType> {
|
|
22
13
|
readonly [Kind]: typeof EventKind
|
|
23
14
|
readonly type: 'neemata:event'
|
|
24
|
-
readonly name: Name
|
|
25
15
|
readonly payload: Payload
|
|
26
|
-
readonly options: Options
|
|
27
16
|
}
|
|
28
17
|
|
|
29
18
|
export const EventContract = <
|
|
30
|
-
Payload extends BaseType,
|
|
31
|
-
Name extends string | undefined = undefined,
|
|
32
|
-
Options extends SubcriptionOptions | undefined = undefined,
|
|
19
|
+
Payload extends BaseType = t.NeverType,
|
|
33
20
|
>(options?: {
|
|
34
21
|
payload?: Payload
|
|
35
22
|
schemaOptions?: ContractSchemaOptions
|
|
36
|
-
name?: Name
|
|
37
23
|
}) => {
|
|
38
|
-
const {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
name = undefined as any,
|
|
42
|
-
} = options ?? {}
|
|
43
|
-
return createSchema<TEventContract<Payload, Name, Options>>({
|
|
24
|
+
const { payload = t.never() as unknown as Payload, schemaOptions = {} } =
|
|
25
|
+
options ?? {}
|
|
26
|
+
return createSchema<TEventContract<Payload>>({
|
|
44
27
|
...schemaOptions,
|
|
45
28
|
[Kind]: EventKind,
|
|
46
29
|
type: 'neemata:event',
|
|
47
30
|
payload,
|
|
48
|
-
name,
|
|
49
|
-
options: undefined as Options,
|
|
50
31
|
})
|
|
51
32
|
}
|
|
52
33
|
|
|
@@ -1,85 +1,160 @@
|
|
|
1
|
+
import type { AnyCompatibleType, BaseType, BaseTypeAny, t } from '@nmtjs/type'
|
|
2
|
+
import { t as types } from '@nmtjs/type'
|
|
3
|
+
|
|
1
4
|
import type { ContractSchemaOptions } from '../utils.ts'
|
|
2
5
|
import type { TAnyEventContract, TEventContract } from './event.ts'
|
|
3
6
|
import { Kind } from '../constants.ts'
|
|
4
|
-
import {
|
|
7
|
+
import { createSchema } from '../utils.ts'
|
|
5
8
|
|
|
6
9
|
export const SubscriptionKind = Symbol('NeemataSubscription')
|
|
7
10
|
|
|
8
|
-
export type
|
|
9
|
-
string,
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
export type SubscriptionParamsType = AnyCompatibleType<
|
|
12
|
+
Record<string, string | number | boolean | null>
|
|
13
|
+
>
|
|
14
|
+
|
|
15
|
+
export type SubscriptionKey<Params extends BaseType> =
|
|
16
|
+
Params extends t.NeverType
|
|
17
|
+
? undefined
|
|
18
|
+
: (params: t.infer.decode.output<Params>) => string
|
|
12
19
|
|
|
13
20
|
export type TAnySubscriptionContract = TSubscriptionContract<
|
|
14
|
-
|
|
21
|
+
any,
|
|
15
22
|
Record<string, TAnyEventContract>,
|
|
16
|
-
string
|
|
23
|
+
string
|
|
24
|
+
>
|
|
25
|
+
|
|
26
|
+
export type TAnySubscriptionEventContract = TSubscriptionEventContract<
|
|
27
|
+
BaseTypeAny,
|
|
28
|
+
string,
|
|
29
|
+
TAnySubscriptionContract
|
|
17
30
|
>
|
|
18
31
|
|
|
32
|
+
export type SubscriptionParams<Contract extends TAnySubscriptionContract> =
|
|
33
|
+
t.infer.decode.output<Contract['params']>
|
|
34
|
+
|
|
35
|
+
export type SubscriptionEventMessage<E extends TAnySubscriptionEventContract> =
|
|
36
|
+
{ event: E['event']; payload: t.infer.decode.output<E['payload']> }
|
|
37
|
+
|
|
38
|
+
export type SubscriptionPublishInput<E extends TAnySubscriptionEventContract> =
|
|
39
|
+
t.infer.encode.input<E['payload']>
|
|
40
|
+
|
|
41
|
+
export type SubscriptionEventUnion<
|
|
42
|
+
Events extends Record<string, TAnySubscriptionEventContract>,
|
|
43
|
+
> = {
|
|
44
|
+
[K in keyof Events]: SubscriptionEventMessage<Events[K]>
|
|
45
|
+
}[keyof Events]
|
|
46
|
+
|
|
47
|
+
export type SubscriptionSelectedEventUnion<
|
|
48
|
+
Contract extends TAnySubscriptionContract,
|
|
49
|
+
Events extends Partial<Record<keyof Contract['events'], true>>,
|
|
50
|
+
> = {} extends Events
|
|
51
|
+
? SubscriptionEventUnion<Contract['events']>
|
|
52
|
+
: {
|
|
53
|
+
[K in keyof Events]: K extends keyof Contract['events']
|
|
54
|
+
? SubscriptionEventMessage<Contract['events'][K]>
|
|
55
|
+
: never
|
|
56
|
+
}[keyof Events]
|
|
57
|
+
|
|
58
|
+
export interface TSubscriptionEventContract<
|
|
59
|
+
Payload extends BaseType = BaseTypeAny,
|
|
60
|
+
Event extends string = string,
|
|
61
|
+
Subscription = TAnySubscriptionContract,
|
|
62
|
+
> extends TEventContract<Payload> {
|
|
63
|
+
readonly event: Event
|
|
64
|
+
readonly subscription: Subscription
|
|
65
|
+
}
|
|
66
|
+
|
|
19
67
|
export interface TSubscriptionContract<
|
|
20
|
-
|
|
68
|
+
Params extends BaseType = t.NeverType,
|
|
21
69
|
Events extends Record<string, unknown> = {},
|
|
22
|
-
|
|
70
|
+
Namespace extends string = string,
|
|
23
71
|
> {
|
|
24
72
|
readonly [Kind]: typeof SubscriptionKind
|
|
25
73
|
readonly type: 'neemata:subscription'
|
|
26
|
-
readonly
|
|
27
|
-
readonly
|
|
74
|
+
readonly namespace: Namespace
|
|
75
|
+
readonly params: Params
|
|
76
|
+
readonly key: SubscriptionKey<Params>
|
|
28
77
|
readonly events: {
|
|
29
78
|
[K in keyof Events]: Events[K] extends TAnyEventContract
|
|
30
|
-
?
|
|
79
|
+
? TSubscriptionEventContract<
|
|
31
80
|
Events[K]['payload'],
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
: Extract<K, string>,
|
|
35
|
-
Options
|
|
81
|
+
Extract<K, string>,
|
|
82
|
+
TSubscriptionContract<Params, Events, Namespace>
|
|
36
83
|
>
|
|
37
84
|
: never
|
|
38
85
|
}
|
|
39
86
|
}
|
|
40
87
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
88
|
+
type SubscriptionContractBaseOptions<
|
|
89
|
+
Namespace extends string,
|
|
90
|
+
Events extends Record<string, TAnyEventContract>,
|
|
91
|
+
> = {
|
|
92
|
+
namespace: Namespace
|
|
93
|
+
events: Events
|
|
94
|
+
schemaOptions?: ContractSchemaOptions
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
type SubscriptionContractNoParamsOptions<
|
|
98
|
+
Namespace extends string,
|
|
99
|
+
Events extends Record<string, TAnyEventContract>,
|
|
100
|
+
> = SubscriptionContractBaseOptions<Namespace, Events> & {
|
|
101
|
+
params?: undefined
|
|
102
|
+
key?: undefined
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
type SubscriptionContractWithParamsOptions<
|
|
106
|
+
Namespace extends string,
|
|
107
|
+
Params extends SubscriptionParamsType,
|
|
108
|
+
Events extends Record<string, TAnyEventContract>,
|
|
109
|
+
> = SubscriptionContractBaseOptions<Namespace, Events> & {
|
|
110
|
+
params: Params
|
|
111
|
+
key: (params: t.infer.decode.output<Params>) => string
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function SubscriptionContract<
|
|
115
|
+
const Namespace extends string,
|
|
116
|
+
const Events extends Record<string, TAnyEventContract>,
|
|
48
117
|
>(
|
|
49
|
-
options:
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
>
|
|
118
|
+
options: SubscriptionContractNoParamsOptions<Namespace, Events>,
|
|
119
|
+
): TSubscriptionContract<t.NeverType, Events, Namespace>
|
|
120
|
+
export function SubscriptionContract<
|
|
121
|
+
const Namespace extends string,
|
|
122
|
+
const Params extends SubscriptionParamsType,
|
|
123
|
+
const Events extends Record<string, TAnyEventContract>,
|
|
124
|
+
>(
|
|
125
|
+
options: SubscriptionContractWithParamsOptions<Namespace, Params, Events>,
|
|
126
|
+
): TSubscriptionContract<Params, Events, Namespace>
|
|
127
|
+
export function SubscriptionContract(options: {
|
|
128
|
+
namespace: string
|
|
129
|
+
events: Record<string, TAnyEventContract>
|
|
130
|
+
params?: BaseType
|
|
131
|
+
key?: (params: any) => string
|
|
132
|
+
schemaOptions?: ContractSchemaOptions
|
|
133
|
+
}) {
|
|
134
|
+
const { schemaOptions = {} } = options
|
|
135
|
+
const params = options.params ?? types.never()
|
|
136
|
+
const events = {} as Record<string, TAnySubscriptionEventContract>
|
|
137
|
+
const subscription = createSchema<any>({
|
|
61
138
|
...schemaOptions,
|
|
62
139
|
[Kind]: SubscriptionKind,
|
|
63
140
|
type: 'neemata:subscription',
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
141
|
+
namespace: options.namespace,
|
|
142
|
+
params,
|
|
143
|
+
key: options.key,
|
|
144
|
+
events,
|
|
67
145
|
})
|
|
68
|
-
}
|
|
69
146
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
},
|
|
82
|
-
})
|
|
147
|
+
for (const eventName in options.events) {
|
|
148
|
+
const event = options.events[eventName]
|
|
149
|
+
events[eventName] = createSchema<TAnySubscriptionEventContract>({
|
|
150
|
+
...event,
|
|
151
|
+
event: eventName,
|
|
152
|
+
subscription,
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return subscription
|
|
157
|
+
}
|
|
83
158
|
|
|
84
159
|
export function IsSubscriptionContract(
|
|
85
160
|
contract: any,
|
package/src/types/blob.ts
CHANGED
|
@@ -14,28 +14,28 @@ export const BlobType = (
|
|
|
14
14
|
decode: (value) => value,
|
|
15
15
|
encode: (value) => value,
|
|
16
16
|
validation: {
|
|
17
|
-
decode(value,
|
|
17
|
+
decode(value, payload) {
|
|
18
18
|
if (isBlobInterface(value)) {
|
|
19
19
|
if (options.maxSize) {
|
|
20
20
|
const size = value.metadata.size
|
|
21
21
|
if (typeof size !== 'undefined' && size > options.maxSize) {
|
|
22
|
-
addIssue({
|
|
22
|
+
payload.addIssue({
|
|
23
23
|
code: 'custom',
|
|
24
24
|
message: `Blob size unknown or exceeds maximum allowed size of ${options.maxSize} bytes`,
|
|
25
25
|
})
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
} else {
|
|
29
|
-
addIssue({
|
|
29
|
+
payload.addIssue({
|
|
30
30
|
code: 'custom',
|
|
31
31
|
message:
|
|
32
32
|
'Value is not a Neemata Blob. Make sure to use transport that supports encoded streams.',
|
|
33
33
|
})
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
-
encode(value,
|
|
36
|
+
encode(value, payload) {
|
|
37
37
|
if (!isBlobInterface(value)) {
|
|
38
|
-
addIssue({
|
|
38
|
+
payload.addIssue({
|
|
39
39
|
code: 'custom',
|
|
40
40
|
message:
|
|
41
41
|
'Value is not a Neemata Blob. Make sure to use transport that supports encoded streams.',
|