@slates/provider 1.0.0-rc.17 → 1.0.0-rc.18
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/index.cjs +244 -17
- package/dist/index.d.cts +108 -29
- package/dist/index.d.ts +108 -29
- package/dist/index.module.js +237 -17
- package/package.json +2 -2
- package/src/action/action.ts +19 -1
- package/src/action/builder.test.ts +136 -0
- package/src/action/builder.ts +68 -11
- package/src/action/index.ts +2 -1
- package/src/action/publicTool.ts +36 -0
- package/src/action/tool.ts +15 -3
- package/src/adapter/adapter.ts +38 -0
- package/src/adapter/index.test.ts +322 -0
- package/src/adapter/index.ts +2 -0
- package/src/adapter/spec.ts +154 -0
- package/src/axios/trace.ts +3 -3
- package/src/context/context.ts +31 -16
- package/src/context/hook.ts +5 -10
- package/src/index.ts +1 -0
- package/src/specification/slate.ts +38 -2
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type SlateActionParameters,
|
|
3
|
+
SlatePublicTool,
|
|
4
|
+
SlateTool,
|
|
5
|
+
SlateTrigger
|
|
6
|
+
} from '../action';
|
|
7
|
+
import { SlateDeclarationError } from '../error';
|
|
8
|
+
import type { SlateSpecification } from '../specification/specification';
|
|
9
|
+
import { SlateAdapter } from './adapter';
|
|
10
|
+
|
|
11
|
+
export interface SlateAdapterCapability {
|
|
12
|
+
id: string;
|
|
13
|
+
value: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SlateAdapterSpecParameters {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
capabilities?: SlateAdapterCapability[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class SlateAdapterSpec {
|
|
23
|
+
private constructor(
|
|
24
|
+
private readonly _params: {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
capabilities: SlateAdapterCapability[];
|
|
28
|
+
}
|
|
29
|
+
) {}
|
|
30
|
+
|
|
31
|
+
static create(params: SlateAdapterSpecParameters): SlateAdapterSpec {
|
|
32
|
+
let id = params.id?.trim();
|
|
33
|
+
let name = params.name?.trim();
|
|
34
|
+
|
|
35
|
+
if (!id) {
|
|
36
|
+
throw new SlateDeclarationError('Adapter id must be a non-empty string');
|
|
37
|
+
}
|
|
38
|
+
if (!name) {
|
|
39
|
+
throw new SlateDeclarationError('Adapter name must be a non-empty string');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new SlateAdapterSpec({
|
|
43
|
+
id,
|
|
44
|
+
name,
|
|
45
|
+
capabilities: validateCapabilities(params.capabilities ?? [])
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get id() {
|
|
50
|
+
return this._params.id;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get name() {
|
|
54
|
+
return this._params.name;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get capabilities() {
|
|
58
|
+
return this._params.capabilities;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get parameters() {
|
|
62
|
+
return this._params;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
tool<ConfigType extends {}, AuthType extends {}>(
|
|
66
|
+
spec: SlateSpecification<ConfigType, AuthType>,
|
|
67
|
+
params: SlateActionParameters
|
|
68
|
+
) {
|
|
69
|
+
return SlateTool.create(spec, this.linkAction(params));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
publicTool<ConfigType extends {}, AuthType extends {}>(
|
|
73
|
+
spec: SlateSpecification<ConfigType, AuthType>,
|
|
74
|
+
params: SlateActionParameters
|
|
75
|
+
) {
|
|
76
|
+
return SlatePublicTool.create(spec, this.linkAction(params));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
trigger<ConfigType extends {}, AuthType extends {}>(
|
|
80
|
+
spec: SlateSpecification<ConfigType, AuthType>,
|
|
81
|
+
params: SlateActionParameters
|
|
82
|
+
) {
|
|
83
|
+
return SlateTrigger.create(spec, this.linkAction(params));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
register<ConfigType extends {}, AuthType extends {}>(params: {
|
|
87
|
+
tools: SlateTool<ConfigType, AuthType, any, any>[];
|
|
88
|
+
triggers: SlateTrigger<ConfigType, AuthType, any, any>[];
|
|
89
|
+
}): SlateAdapter<ConfigType, AuthType> {
|
|
90
|
+
let actions = [...params.tools, ...params.triggers];
|
|
91
|
+
let seenKeys = new Set<string>();
|
|
92
|
+
|
|
93
|
+
for (let action of actions) {
|
|
94
|
+
if (action.adapter && action.adapter !== this.id) {
|
|
95
|
+
throw new SlateDeclarationError(
|
|
96
|
+
`Action "${action.key}" is linked to adapter "${action.adapter}", not "${this.id}"`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!action.adapter) {
|
|
101
|
+
throw new SlateDeclarationError(
|
|
102
|
+
`Action "${action.key}" must be created with this adapter's tool(), publicTool(), or trigger() helpers`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (seenKeys.has(action.key)) {
|
|
107
|
+
throw new SlateDeclarationError(
|
|
108
|
+
`Adapter "${this.id}" already has an action with key "${action.key}"`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
seenKeys.add(action.key);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return new SlateAdapter(this, params.tools, params.triggers);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private linkAction(params: SlateActionParameters): SlateActionParameters {
|
|
119
|
+
if (params.adapter != null && params.adapter !== this.id) {
|
|
120
|
+
throw new SlateDeclarationError(
|
|
121
|
+
`Action "${params.key}" cannot be linked to adapter "${this.id}" because it is already linked to "${params.adapter}"`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
...params,
|
|
127
|
+
adapter: this.id
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export let adapterSpec = (params: SlateAdapterSpecParameters) =>
|
|
133
|
+
SlateAdapterSpec.create(params);
|
|
134
|
+
|
|
135
|
+
let validateCapabilities = (capabilities: SlateAdapterCapability[]) => {
|
|
136
|
+
let seenIds = new Set<string>();
|
|
137
|
+
|
|
138
|
+
return capabilities.map(capability => {
|
|
139
|
+
let id = capability.id?.trim();
|
|
140
|
+
if (!id) {
|
|
141
|
+
throw new SlateDeclarationError('Adapter capability ids must be non-empty strings');
|
|
142
|
+
}
|
|
143
|
+
if (seenIds.has(id)) {
|
|
144
|
+
throw new SlateDeclarationError(`Adapter capability "${id}" is defined more than once`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
seenIds.add(id);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
id,
|
|
151
|
+
value: capability.value
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
};
|
package/src/axios/trace.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SlatePublicContext } from '../context';
|
|
3
3
|
|
|
4
4
|
export interface SlateHttpTraceTextBody {
|
|
5
5
|
contentType?: string;
|
|
@@ -29,7 +29,7 @@ export interface SlateHttpTrace {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
interface SlateHttpTraceDraft {
|
|
32
|
-
context:
|
|
32
|
+
context: SlatePublicContext<any>;
|
|
33
33
|
startedAt: string;
|
|
34
34
|
startedAtMs: number;
|
|
35
35
|
request: SlateHttpTrace['request'];
|
|
@@ -664,7 +664,7 @@ let clearTraceDraft = (
|
|
|
664
664
|
|
|
665
665
|
export let attachHttpTraceDraft = (
|
|
666
666
|
config: InternalAxiosRequestConfig,
|
|
667
|
-
context:
|
|
667
|
+
context: SlatePublicContext<any>
|
|
668
668
|
) => {
|
|
669
669
|
let traceAwareConfig = config as TraceAwareAxiosRequestConfig;
|
|
670
670
|
let contentType = getContentType(config.headers);
|
package/src/context/context.ts
CHANGED
|
@@ -2,32 +2,22 @@ import type { SlateHttpTrace } from '../axios/trace';
|
|
|
2
2
|
import type { SlateLogger, SlateLogMessageInput } from '../logger';
|
|
3
3
|
import type { SlateSpecification } from '../specification/specification';
|
|
4
4
|
|
|
5
|
-
export class
|
|
6
|
-
#config: ConfigType;
|
|
5
|
+
export class SlatePublicContext<InputType extends {}> {
|
|
7
6
|
#input: InputType;
|
|
8
|
-
#auth: AuthType;
|
|
9
7
|
#httpTraces: SlateHttpTrace[] = [];
|
|
10
8
|
|
|
11
9
|
constructor(
|
|
12
|
-
config: ConfigType,
|
|
13
10
|
input: InputType,
|
|
14
|
-
|
|
15
|
-
private readonly spec: SlateSpecification<ConfigType, AuthType>,
|
|
11
|
+
private readonly spec: SlateSpecification<any, any>,
|
|
16
12
|
private readonly logger: SlateLogger
|
|
17
13
|
) {
|
|
18
|
-
this.#config = config;
|
|
19
14
|
this.#input = input;
|
|
20
|
-
this.#auth = auth;
|
|
21
15
|
}
|
|
22
16
|
|
|
23
17
|
get specification() {
|
|
24
18
|
return this.spec;
|
|
25
19
|
}
|
|
26
20
|
|
|
27
|
-
get config() {
|
|
28
|
-
return Object.freeze(this.#config);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
21
|
get input() {
|
|
32
22
|
return Object.freeze(this.#input);
|
|
33
23
|
}
|
|
@@ -56,10 +46,6 @@ export class SlateContext<ConfigType extends {}, AuthType extends {}, InputType
|
|
|
56
46
|
: never;
|
|
57
47
|
}
|
|
58
48
|
|
|
59
|
-
get auth() {
|
|
60
|
-
return Object.freeze(this.#auth);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
49
|
recordHttpTrace(trace: SlateHttpTrace) {
|
|
64
50
|
this.#httpTraces.push(trace);
|
|
65
51
|
}
|
|
@@ -101,3 +87,32 @@ export class SlateContext<ConfigType extends {}, AuthType extends {}, InputType
|
|
|
101
87
|
this.logger.progress(message);
|
|
102
88
|
}
|
|
103
89
|
}
|
|
90
|
+
|
|
91
|
+
export class SlateContext<
|
|
92
|
+
ConfigType extends {},
|
|
93
|
+
AuthType extends {},
|
|
94
|
+
InputType extends {}
|
|
95
|
+
> extends SlatePublicContext<InputType> {
|
|
96
|
+
#config: ConfigType;
|
|
97
|
+
#auth: AuthType;
|
|
98
|
+
|
|
99
|
+
constructor(
|
|
100
|
+
config: ConfigType,
|
|
101
|
+
input: InputType,
|
|
102
|
+
auth: AuthType,
|
|
103
|
+
spec: SlateSpecification<ConfigType, AuthType>,
|
|
104
|
+
logger: SlateLogger
|
|
105
|
+
) {
|
|
106
|
+
super(input, spec, logger);
|
|
107
|
+
this.#config = config;
|
|
108
|
+
this.#auth = auth;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
get config() {
|
|
112
|
+
return Object.freeze(this.#config);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get auth() {
|
|
116
|
+
return Object.freeze(this.#auth);
|
|
117
|
+
}
|
|
118
|
+
}
|
package/src/context/hook.ts
CHANGED
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
2
|
-
import type { SlateContext } from './context';
|
|
2
|
+
import type { SlateContext, SlatePublicContext } from './context';
|
|
3
3
|
|
|
4
4
|
let slateContextStorageKey = Symbol.for('slates.provider.context.asyncLocalStorage');
|
|
5
5
|
let globalWithSlateContext = globalThis as typeof globalThis & {
|
|
6
|
-
[key: symbol]: AsyncLocalStorage<
|
|
6
|
+
[key: symbol]: AsyncLocalStorage<SlatePublicContext<any>> | undefined;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
let asyncLocalStorage =
|
|
10
10
|
globalWithSlateContext[slateContextStorageKey] ??
|
|
11
|
-
new AsyncLocalStorage<
|
|
11
|
+
new AsyncLocalStorage<SlatePublicContext<any>>();
|
|
12
12
|
|
|
13
13
|
globalWithSlateContext[slateContextStorageKey] = asyncLocalStorage;
|
|
14
14
|
|
|
15
|
-
export let runWithContext = <
|
|
16
|
-
|
|
17
|
-
AuthType extends {},
|
|
18
|
-
InputType extends {},
|
|
19
|
-
RV
|
|
20
|
-
>(
|
|
21
|
-
context: SlateContext<ConfigType, AuthType, InputType>,
|
|
15
|
+
export let runWithContext = <InputType extends {}, RV>(
|
|
16
|
+
context: SlatePublicContext<InputType>,
|
|
22
17
|
fn: () => Promise<RV>
|
|
23
18
|
): Promise<RV> => {
|
|
24
19
|
return asyncLocalStorage.run(context, fn);
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { SlateTool, SlateTrigger } from '../action';
|
|
2
|
+
import type { SlateAdapter } from '../adapter';
|
|
3
|
+
import { SlateDeclarationError } from '../error';
|
|
2
4
|
import type { SlateSpecification } from './specification';
|
|
3
5
|
|
|
4
6
|
export class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
@@ -7,15 +9,45 @@ export class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
7
9
|
private readonly _actions: (
|
|
8
10
|
| SlateTrigger<ConfigType, AuthType, any, any>
|
|
9
11
|
| SlateTool<ConfigType, AuthType, any, any>
|
|
10
|
-
)[]
|
|
12
|
+
)[],
|
|
13
|
+
private readonly _adapters: SlateAdapter<ConfigType, AuthType>[]
|
|
11
14
|
) {}
|
|
12
15
|
|
|
13
16
|
static create<ConfigType extends {}, AuthType extends {}>(params: {
|
|
14
17
|
spec: SlateSpecification<ConfigType, AuthType>;
|
|
15
18
|
triggers: SlateTrigger<ConfigType, AuthType, any, any>[];
|
|
16
19
|
tools: SlateTool<ConfigType, AuthType, any, any>[];
|
|
20
|
+
adapters?: SlateAdapter<ConfigType, AuthType>[];
|
|
17
21
|
}) {
|
|
18
|
-
|
|
22
|
+
let adapters = params.adapters ?? [];
|
|
23
|
+
let actions = [...params.triggers, ...params.tools];
|
|
24
|
+
let seenAdapterIds = new Set<string>();
|
|
25
|
+
let seenActionKeys = new Map(actions.map(action => [action.key, action]));
|
|
26
|
+
|
|
27
|
+
for (let adapter of adapters) {
|
|
28
|
+
if (seenAdapterIds.has(adapter.id)) {
|
|
29
|
+
throw new SlateDeclarationError(
|
|
30
|
+
`Adapter "${adapter.id}" is registered more than once`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
seenAdapterIds.add(adapter.id);
|
|
34
|
+
|
|
35
|
+
for (let action of adapter.actions) {
|
|
36
|
+
let existing = seenActionKeys.get(action.key);
|
|
37
|
+
if (existing && existing !== action) {
|
|
38
|
+
throw new SlateDeclarationError(
|
|
39
|
+
`Adapter "${adapter.id}" action "${action.key}" conflicts with another action`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!existing) {
|
|
44
|
+
actions.push(action);
|
|
45
|
+
seenActionKeys.set(action.key, action);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return new Slate(params.spec, actions, adapters);
|
|
19
51
|
}
|
|
20
52
|
|
|
21
53
|
get spec() {
|
|
@@ -25,4 +57,8 @@ export class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
25
57
|
get actions() {
|
|
26
58
|
return this._actions;
|
|
27
59
|
}
|
|
60
|
+
|
|
61
|
+
get adapters() {
|
|
62
|
+
return this._adapters;
|
|
63
|
+
}
|
|
28
64
|
}
|