@covenant-rpc/core 0.3.0 → 0.4.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.
- package/dist/channel.d.ts +75 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +44 -0
- package/dist/channel.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +61 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +21 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +2 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/logger.d.ts +15 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +4 -0
- package/dist/logger.js.map +1 -0
- package/dist/procedure.d.ts +69 -0
- package/dist/procedure.d.ts.map +1 -0
- package/dist/procedure.js +18 -0
- package/dist/procedure.js.map +1 -0
- package/dist/sidekick/protocol.d.ts +89 -0
- package/dist/sidekick/protocol.d.ts.map +1 -0
- package/dist/sidekick/protocol.js +68 -0
- package/dist/sidekick/protocol.js.map +1 -0
- package/dist/utils.d.ts +30 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +50 -0
- package/dist/utils.js.map +1 -0
- package/dist/validation.d.ts +20 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +85 -0
- package/dist/validation.js.map +1 -0
- package/package.json +10 -3
- package/channel.ts +0 -139
- package/errors.ts +0 -80
- package/index.ts +0 -112
- package/interfaces.ts +0 -28
- package/logger.ts +0 -18
- package/procedure.ts +0 -105
- package/sidekick/protocol.ts +0 -104
- package/utils.ts +0 -87
- package/validation.ts +0 -99
package/procedure.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
-
import type { ProcedureDeclaration, ProcedureType } from ".";
|
|
3
|
-
import type { MaybePromise } from "./utils";
|
|
4
|
-
import { v } from "./validation";
|
|
5
|
-
import type { Logger } from "./logger";
|
|
6
|
-
|
|
7
|
-
export interface ProcedureRequest {
|
|
8
|
-
headers: Headers;
|
|
9
|
-
input: unknown;
|
|
10
|
-
url: string;
|
|
11
|
-
procedure: string;
|
|
12
|
-
path: string;
|
|
13
|
-
req: Request;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ProcedureInputs<Inputs, Context, Derivation> {
|
|
17
|
-
inputs: Inputs,
|
|
18
|
-
ctx: Context,
|
|
19
|
-
derived: Derivation,
|
|
20
|
-
request: ProcedureRequest,
|
|
21
|
-
logger: Logger,
|
|
22
|
-
setHeader: (name: string, value: string) => void;
|
|
23
|
-
deleteHeader: (name: string) => void;
|
|
24
|
-
error: (message: string, code: number) => never;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ResourceInputs<Inputs, Context, Outputs> {
|
|
28
|
-
inputs: Inputs,
|
|
29
|
-
logger: Logger,
|
|
30
|
-
ctx: Context,
|
|
31
|
-
outputs: Outputs,
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type ProcedureDefinition<T, Context, Derivation> = T extends ProcedureDeclaration<
|
|
35
|
-
infer InputSchema,
|
|
36
|
-
infer OutputSchema,
|
|
37
|
-
ProcedureType> ? {
|
|
38
|
-
procedure: (i: ProcedureInputs<
|
|
39
|
-
StandardSchemaV1.InferOutput<InputSchema>,
|
|
40
|
-
Context,
|
|
41
|
-
Derivation
|
|
42
|
-
>) => MaybePromise<StandardSchemaV1.InferOutput<OutputSchema>>
|
|
43
|
-
resources: (i: ResourceInputs<
|
|
44
|
-
StandardSchemaV1.InferOutput<InputSchema>,
|
|
45
|
-
Context,
|
|
46
|
-
StandardSchemaV1.InferOutput<OutputSchema>
|
|
47
|
-
>) => MaybePromise<string[]>
|
|
48
|
-
} : never
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
export const procedureErrorSchema = v.obj({
|
|
52
|
-
message: v.string(),
|
|
53
|
-
code: v.number(),
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
export type ProcedureError = v.Infer<typeof procedureErrorSchema>;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
export const procedureResponseSchema = v.union(
|
|
60
|
-
v.obj({
|
|
61
|
-
status: v.literal("OK"),
|
|
62
|
-
data: v.unknown(),
|
|
63
|
-
resources: v.array(v.string()),
|
|
64
|
-
}),
|
|
65
|
-
v.obj({
|
|
66
|
-
status: v.literal("ERR"),
|
|
67
|
-
error: procedureErrorSchema,
|
|
68
|
-
}),
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
export type ProcedureResponse = v.Infer<typeof procedureResponseSchema>;
|
|
72
|
-
|
|
73
|
-
export const procedureRequestBodySchema = v.obj({
|
|
74
|
-
procedure: v.string(),
|
|
75
|
-
inputs: v.unknown(),
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
export type ProcedureRequestBody = v.Infer<typeof procedureRequestBodySchema>;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
export type InferProcedureInputs<P> = P extends ProcedureDeclaration<
|
|
82
|
-
infer InputSchema,
|
|
83
|
-
any,
|
|
84
|
-
any
|
|
85
|
-
> ? StandardSchemaV1.InferInput<InputSchema> : never;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
export type InferProcedureOutputs<P> = P extends ProcedureDeclaration<
|
|
89
|
-
any,
|
|
90
|
-
infer OutputSchema,
|
|
91
|
-
any
|
|
92
|
-
> ? StandardSchemaV1.InferOutput<OutputSchema> : never
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
export type InferProcedureResult<P> = {
|
|
96
|
-
success: true,
|
|
97
|
-
data: InferProcedureOutputs<P>,
|
|
98
|
-
resources: string[]
|
|
99
|
-
error: null,
|
|
100
|
-
} | {
|
|
101
|
-
success: false,
|
|
102
|
-
error: ProcedureError,
|
|
103
|
-
data: null,
|
|
104
|
-
resources: null,
|
|
105
|
-
}
|
package/sidekick/protocol.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { channelErrorSchema } from "../channel";
|
|
2
|
-
import { v } from "../validation";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// tokens are given to the server and the sidekick at the same time
|
|
7
|
-
export const subscribeMessageSchema = v.obj({
|
|
8
|
-
type: v.literal("subscribe"),
|
|
9
|
-
token: v.string(),
|
|
10
|
-
});
|
|
11
|
-
export type SubscribeMessage = v.Infer<typeof subscribeMessageSchema>;
|
|
12
|
-
|
|
13
|
-
export const unsubscribeMessageSchema = v.obj({
|
|
14
|
-
type: v.literal("unsubscribe"),
|
|
15
|
-
token: v.string(),
|
|
16
|
-
});
|
|
17
|
-
export type UnsubscribeMessage = v.Infer<typeof unsubscribeMessageSchema>;
|
|
18
|
-
|
|
19
|
-
export const sendMessageSchema = v.obj({
|
|
20
|
-
type: v.literal("send"),
|
|
21
|
-
token: v.string(),
|
|
22
|
-
channel: v.string(),
|
|
23
|
-
params: v.record(v.string(), v.string()),
|
|
24
|
-
data: v.unknown(),
|
|
25
|
-
});
|
|
26
|
-
export type SendMessage = v.Infer<typeof sendMessageSchema>;
|
|
27
|
-
|
|
28
|
-
export const listenMessageSchema = v.obj({
|
|
29
|
-
type: v.literal("listen"),
|
|
30
|
-
resources: v.array(v.string()),
|
|
31
|
-
});
|
|
32
|
-
export type ListenMessage = v.Infer<typeof listenMessageSchema>;
|
|
33
|
-
|
|
34
|
-
export const unlistenMessageSchema = v.obj({
|
|
35
|
-
type: v.literal("unlisten"),
|
|
36
|
-
resources: v.array(v.string()),
|
|
37
|
-
});
|
|
38
|
-
export type UnlistenMessage = v.Infer<typeof unlistenMessageSchema>;
|
|
39
|
-
|
|
40
|
-
export const sidekickIncomingMessageSchema = v.union(
|
|
41
|
-
subscribeMessageSchema,
|
|
42
|
-
unsubscribeMessageSchema,
|
|
43
|
-
sendMessageSchema,
|
|
44
|
-
listenMessageSchema,
|
|
45
|
-
unlistenMessageSchema,
|
|
46
|
-
);
|
|
47
|
-
export type SidekickIncomingMessage = v.Infer<typeof sidekickIncomingMessageSchema>;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
export const sidekickOutgoingMessageSchema = v.union(
|
|
51
|
-
v.obj({
|
|
52
|
-
type: v.literal("error"),
|
|
53
|
-
error: channelErrorSchema,
|
|
54
|
-
}),
|
|
55
|
-
v.obj({
|
|
56
|
-
type: v.literal("message"),
|
|
57
|
-
channel: v.string(),
|
|
58
|
-
params: v.record(v.string(), v.string()),
|
|
59
|
-
data: v.unknown(),
|
|
60
|
-
}),
|
|
61
|
-
v.obj({
|
|
62
|
-
type: v.literal("updated"),
|
|
63
|
-
resource: v.string(),
|
|
64
|
-
}),
|
|
65
|
-
v.obj({
|
|
66
|
-
type: v.literal("listening"),
|
|
67
|
-
resources: v.array(v.string()),
|
|
68
|
-
}),
|
|
69
|
-
v.obj({
|
|
70
|
-
type: v.literal("unlistening"),
|
|
71
|
-
resources: v.array(v.string()),
|
|
72
|
-
}),
|
|
73
|
-
v.obj({
|
|
74
|
-
type: v.literal("subscribed"),
|
|
75
|
-
channel: v.string(),
|
|
76
|
-
params: v.record(v.string(), v.string()),
|
|
77
|
-
}),
|
|
78
|
-
v.obj({
|
|
79
|
-
type: v.literal("unsubscribed"),
|
|
80
|
-
channel: v.string(),
|
|
81
|
-
params: v.record(v.string(), v.string()),
|
|
82
|
-
}),
|
|
83
|
-
v.obj({
|
|
84
|
-
type: v.literal("listening"),
|
|
85
|
-
channel: v.string(),
|
|
86
|
-
params: v.record(v.string(), v.string()),
|
|
87
|
-
}),
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
export type SidekickOutgoingMessage = v.Infer<typeof sidekickOutgoingMessageSchema>;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
export function getChannelTopicName(channel: string, params: Record<string, string>) {
|
|
94
|
-
const map = Object.keys(params).map(k => `${k}:${params[k]}`).join(",");
|
|
95
|
-
return `channel:${channel}/${map}`
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function getResourceTopicName(resource: string) {
|
|
99
|
-
return `resource:${resource}`;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function getMapId(wsId: string, topic: string) {
|
|
103
|
-
return `${wsId}@${topic}`;
|
|
104
|
-
}
|
package/utils.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
-
|
|
3
|
-
export type MaybePromise<T> = T | Promise<T>;
|
|
4
|
-
export type Flatten<T> = { [k in keyof T]: T[k] } & {};
|
|
5
|
-
export type ArrayToMap<T extends readonly string[]> = { [k in T[number]]: string };
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export type Result<T> = {
|
|
10
|
-
success: true;
|
|
11
|
-
data: T;
|
|
12
|
-
error: null;
|
|
13
|
-
} | {
|
|
14
|
-
success: false;
|
|
15
|
-
data: null;
|
|
16
|
-
error: Error
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type AsyncResult<T> = Promise<Result<T>>;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
export function ok<T>(t: T): Result<T> {
|
|
23
|
-
return {
|
|
24
|
-
data: t,
|
|
25
|
-
success: true,
|
|
26
|
-
error: null,
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function err(error: Error): Result<any> {
|
|
31
|
-
return {
|
|
32
|
-
data: null,
|
|
33
|
-
success: false,
|
|
34
|
-
error,
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function issuesToString(issues: readonly StandardSchemaV1.Issue[]): string {
|
|
39
|
-
const strs: string[] = []
|
|
40
|
-
|
|
41
|
-
for (const issue of issues) {
|
|
42
|
-
strs.push(`${issue.path}: ${issue.message}`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return strs.join(", ");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
export type PubsubListener<T> = (t: T) => MaybePromise<void>;
|
|
52
|
-
|
|
53
|
-
export class MultiTopicPubsub<T> {
|
|
54
|
-
private listenerMap: Map<string, PubsubListener<T>[]> = new Map();
|
|
55
|
-
|
|
56
|
-
subscribe(topic: string, listener: PubsubListener<T>) {
|
|
57
|
-
if (this.listenerMap.has(topic)) {
|
|
58
|
-
const newListeners = [...this.listenerMap.get(topic)!, listener];
|
|
59
|
-
this.listenerMap.set(topic, newListeners);
|
|
60
|
-
} else {
|
|
61
|
-
this.listenerMap.set(topic, [listener]);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
unsubscribe(topic: string, listener: PubsubListener<T>) {
|
|
66
|
-
if (this.listenerMap.has(topic)) {
|
|
67
|
-
const listeners = this.listenerMap.get(topic)!;
|
|
68
|
-
this.listenerMap.set(topic, listeners.filter(l => l !== listener));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async publish(topic: string, data: T) {
|
|
73
|
-
const listeners = this.listenerMap.get(topic) ?? [];
|
|
74
|
-
|
|
75
|
-
const promises = listeners.map(l => l(data));
|
|
76
|
-
await Promise.all(promises);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
export function isPromise(obj: unknown): obj is Promise<unknown> {
|
|
83
|
-
return obj != null &&
|
|
84
|
-
typeof obj === "object" &&
|
|
85
|
-
typeof (obj as any).then === "function";
|
|
86
|
-
}
|
|
87
|
-
|
package/validation.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// Covenant cannot have any dependencies, so I have to make a very tiny validation library for parsing requests. This does not implement standard schema, and should not be used
|
|
2
|
-
// outside of covenant code. If you are doing so, you are wrong
|
|
3
|
-
export namespace v {
|
|
4
|
-
export type Validator<T> = (o: unknown) => o is T;
|
|
5
|
-
export type Infer<K> = K extends Validator<infer T> ? T : never;
|
|
6
|
-
|
|
7
|
-
export const bool: () => Validator<boolean> = () => (o: unknown) => typeof o === "boolean";
|
|
8
|
-
export const number: () => Validator<number> = () => (o: unknown) => typeof o === "number"
|
|
9
|
-
export const string: () => Validator<string> = () => (o: unknown) => typeof o === "string";
|
|
10
|
-
export const unknown: () => Validator<unknown> = () => (o: unknown): o is unknown => true;
|
|
11
|
-
|
|
12
|
-
export function optional<T>(validator: Validator<T>): Validator<T | undefined> {
|
|
13
|
-
return (o: unknown) => validator(o) || o === undefined;
|
|
14
|
-
}
|
|
15
|
-
export function nullable<T>(validator: Validator<T>): Validator<T | null> {
|
|
16
|
-
return (o: unknown) => validator(o) || o === null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function union<T extends readonly Validator<any>[]>(...validators: T): Validator<Infer<T[number]>> {
|
|
20
|
-
return (o: unknown): o is Infer<T[number]> => {
|
|
21
|
-
return validators.some(validator => validator(o));
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function literal<T extends string | number | boolean | null | undefined>(value: T): Validator<T> {
|
|
26
|
-
return (o: unknown): o is T => o === value;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function obj<T extends Record<string, Validator<any>>>(obj: T): Validator<{ [K in keyof T]: Infer<T[K]> }> {
|
|
30
|
-
return (o: unknown): o is { [K in keyof T]: Infer<T[K]> } => {
|
|
31
|
-
if (typeof o !== "object" || o === null || o === undefined) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const target = o as Record<string, unknown>;
|
|
36
|
-
|
|
37
|
-
for (const key of Object.keys(obj)) {
|
|
38
|
-
const validator = obj[key]!;
|
|
39
|
-
const valid = validator(target[key]);
|
|
40
|
-
if (!valid) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function parse<T>(object: unknown, validator: Validator<T>): T {
|
|
50
|
-
const valid = validator(object);
|
|
51
|
-
|
|
52
|
-
if (!valid) {
|
|
53
|
-
throw new Error("Validation failed!");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return object;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function parseSafe<T>(object: unknown, validator: Validator<T>): T | null {
|
|
60
|
-
const valid = validator(object);
|
|
61
|
-
|
|
62
|
-
if (!valid) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return object;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function array<T>(elementValidator: Validator<T>): Validator<T[]> {
|
|
70
|
-
return (o: unknown): o is T[] => {
|
|
71
|
-
if (!Array.isArray(o)) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
return o.every(element => elementValidator(element));
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function record<K extends string | number | symbol, V>(
|
|
79
|
-
keyValidator: Validator<K>,
|
|
80
|
-
valueValidator: Validator<V>
|
|
81
|
-
): Validator<Record<K, V>> {
|
|
82
|
-
return (o: unknown): o is Record<K, V> => {
|
|
83
|
-
if (typeof o !== "object" || o === null || o === undefined) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const target = o as Record<string | number | symbol, unknown>;
|
|
88
|
-
|
|
89
|
-
for (const [key, value] of Object.entries(target)) {
|
|
90
|
-
if (!keyValidator(key) || !valueValidator(value)) {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return true;
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|