@valon-technologies/gestalt 0.0.1-alpha.1 → 0.0.1-alpha.11
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/README.md +8 -26
- package/gen/v1/{auth_pb.ts → authentication_pb.ts} +51 -17
- package/gen/v1/authorization_pb.ts +857 -0
- package/gen/v1/cache_pb.ts +32 -0
- package/gen/v1/datastore_pb.ts +62 -0
- package/gen/v1/plugin_pb.ts +279 -18
- package/gen/v1/runtime_pb.ts +27 -3
- package/gen/v1/s3_pb.ts +39 -0
- package/gen/v1/secrets_pb.ts +6 -0
- package/gen/v1/workflow_pb.ts +1372 -0
- package/package.json +12 -10
- package/src/api.ts +56 -0
- package/src/auth.ts +67 -16
- package/src/build.ts +37 -21
- package/src/cache.ts +32 -0
- package/src/catalog.ts +27 -0
- package/src/index.ts +105 -18
- package/src/indexeddb.ts +166 -0
- package/src/invoker.ts +160 -0
- package/src/manifest-metadata.ts +101 -0
- package/src/plugin.ts +255 -38
- package/src/provider-kind.ts +107 -0
- package/src/provider.ts +32 -1
- package/src/runtime.ts +245 -219
- package/src/s3.ts +135 -20
- package/src/schema.ts +46 -0
- package/src/secrets.ts +12 -0
- package/src/target.ts +58 -60
- package/src/workflow-manager.ts +131 -0
- package/src/workflow.ts +479 -0
- package/tsconfig.json +1 -0
package/src/runtime.ts
CHANGED
|
@@ -4,17 +4,22 @@ import { dirname, resolve } from "node:path";
|
|
|
4
4
|
|
|
5
5
|
import { create } from "@bufbuild/protobuf";
|
|
6
6
|
import { EmptySchema } from "@bufbuild/protobuf/wkt";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Code,
|
|
9
|
+
ConnectError,
|
|
10
|
+
type ConnectRouter,
|
|
11
|
+
type ServiceImpl,
|
|
12
|
+
} from "@connectrpc/connect";
|
|
8
13
|
import { connectNodeAdapter } from "@connectrpc/connect-node";
|
|
9
14
|
|
|
10
15
|
import {
|
|
11
|
-
|
|
16
|
+
AuthenticationProvider as AuthenticationProviderService,
|
|
12
17
|
AuthSessionSettingsSchema,
|
|
13
18
|
AuthenticatedUserSchema,
|
|
14
19
|
BeginLoginResponseSchema,
|
|
15
20
|
type CompleteLoginRequest as AuthCompleteLoginRequest,
|
|
16
21
|
type ValidateExternalTokenRequest,
|
|
17
|
-
} from "../gen/v1/
|
|
22
|
+
} from "../gen/v1/authentication_pb.ts";
|
|
18
23
|
import {
|
|
19
24
|
Cache as CacheService,
|
|
20
25
|
CacheDeleteManyResponseSchema,
|
|
@@ -53,23 +58,33 @@ import {
|
|
|
53
58
|
type ConfigureProviderRequest,
|
|
54
59
|
} from "../gen/v1/runtime_pb.ts";
|
|
55
60
|
import { S3 as S3Service } from "../gen/v1/s3_pb.ts";
|
|
61
|
+
import { WorkflowProvider as WorkflowProviderService } from "../gen/v1/workflow_pb.ts";
|
|
56
62
|
import { errorMessage, type Request } from "./api.ts";
|
|
57
63
|
import {
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
AuthenticationProvider,
|
|
65
|
+
isAuthenticationProvider,
|
|
60
66
|
type AuthenticatedUser,
|
|
61
67
|
} from "./auth.ts";
|
|
62
68
|
import { CacheProvider, isCacheProvider } from "./cache.ts";
|
|
63
69
|
import { SecretsProvider, isSecretsProvider } from "./secrets.ts";
|
|
64
70
|
import { catalogToYaml, type Catalog } from "./catalog.ts";
|
|
65
71
|
import {
|
|
66
|
-
|
|
72
|
+
PluginProvider,
|
|
67
73
|
connectionModeToProtoValue,
|
|
68
74
|
connectionParamToProto,
|
|
69
|
-
|
|
75
|
+
isPluginProvider,
|
|
70
76
|
} from "./plugin.ts";
|
|
77
|
+
import {
|
|
78
|
+
providerKindLabel,
|
|
79
|
+
resolveDefaultProviderExport,
|
|
80
|
+
} from "./provider-kind.ts";
|
|
71
81
|
import { type ProviderKind, slugName } from "./provider.ts";
|
|
72
82
|
import { S3Provider, createS3Service, isS3Provider } from "./s3.ts";
|
|
83
|
+
import {
|
|
84
|
+
WorkflowProvider,
|
|
85
|
+
createWorkflowProviderService,
|
|
86
|
+
isWorkflowProvider,
|
|
87
|
+
} from "./workflow.ts";
|
|
73
88
|
import {
|
|
74
89
|
defaultProviderName,
|
|
75
90
|
formatProviderTarget,
|
|
@@ -79,24 +94,134 @@ import {
|
|
|
79
94
|
resolveProviderImportUrl,
|
|
80
95
|
} from "./target.ts";
|
|
81
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Environment variable containing the Unix socket path for a running provider.
|
|
99
|
+
*/
|
|
82
100
|
export const ENV_PROVIDER_SOCKET = "GESTALT_PLUGIN_SOCKET";
|
|
101
|
+
/**
|
|
102
|
+
* Environment variable containing the parent process ID supplied by the host.
|
|
103
|
+
*/
|
|
83
104
|
export const ENV_PROVIDER_PARENT_PID = "GESTALT_PLUGIN_PARENT_PID";
|
|
105
|
+
/**
|
|
106
|
+
* Environment variable used to request static catalog generation.
|
|
107
|
+
*/
|
|
84
108
|
export const ENV_WRITE_CATALOG = "GESTALT_PLUGIN_WRITE_CATALOG";
|
|
85
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Environment variable used to request generated manifest metadata export.
|
|
111
|
+
*/
|
|
112
|
+
export const ENV_WRITE_MANIFEST_METADATA =
|
|
113
|
+
"GESTALT_PLUGIN_WRITE_MANIFEST_METADATA";
|
|
114
|
+
/**
|
|
115
|
+
* Protocol version currently implemented by the TypeScript runtime.
|
|
116
|
+
*/
|
|
117
|
+
export const CURRENT_PROTOCOL_VERSION = 3;
|
|
118
|
+
/**
|
|
119
|
+
* Command-line usage for the runtime entrypoint.
|
|
120
|
+
*/
|
|
86
121
|
export const USAGE = "usage: bun run runtime.ts ROOT PROVIDER_TARGET";
|
|
122
|
+
export { createWorkflowProviderService } from "./workflow.ts";
|
|
87
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Parsed arguments for the runtime entrypoint.
|
|
126
|
+
*/
|
|
88
127
|
export type RuntimeArgs = {
|
|
89
128
|
root: string;
|
|
90
129
|
target: string;
|
|
91
130
|
};
|
|
92
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Provider implementations supported by the runtime host.
|
|
134
|
+
*/
|
|
93
135
|
export type LoadedProvider =
|
|
94
|
-
|
|
|
95
|
-
|
|
|
136
|
+
| PluginProvider
|
|
137
|
+
| AuthenticationProvider
|
|
96
138
|
| CacheProvider
|
|
97
139
|
| SecretsProvider
|
|
98
|
-
| S3Provider
|
|
140
|
+
| S3Provider
|
|
141
|
+
| WorkflowProvider;
|
|
142
|
+
|
|
143
|
+
type ProviderRuntimeEntry = {
|
|
144
|
+
isProvider: (value: unknown) => value is LoadedProvider;
|
|
145
|
+
protoKind: ProtoProviderKind;
|
|
146
|
+
registerService: (router: ConnectRouter, provider: LoadedProvider) => void;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const PROVIDER_RUNTIME_ENTRIES: Partial<
|
|
150
|
+
Record<ProviderKind, ProviderRuntimeEntry>
|
|
151
|
+
> = {
|
|
152
|
+
integration: {
|
|
153
|
+
isProvider: isPluginProvider as (value: unknown) => value is LoadedProvider,
|
|
154
|
+
protoKind: ProtoProviderKind.INTEGRATION,
|
|
155
|
+
registerService(router, provider) {
|
|
156
|
+
router.service(
|
|
157
|
+
IntegrationProviderService,
|
|
158
|
+
createProviderService(provider as PluginProvider),
|
|
159
|
+
);
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
authentication: {
|
|
163
|
+
isProvider:
|
|
164
|
+
isAuthenticationProvider as (value: unknown) => value is LoadedProvider,
|
|
165
|
+
protoKind: ProtoProviderKind.AUTHENTICATION,
|
|
166
|
+
registerService(router, provider) {
|
|
167
|
+
router.service(
|
|
168
|
+
AuthenticationProviderService,
|
|
169
|
+
createAuthenticationService(provider as AuthenticationProvider),
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
cache: {
|
|
174
|
+
isProvider: isCacheProvider as (value: unknown) => value is LoadedProvider,
|
|
175
|
+
protoKind: ProtoProviderKind.CACHE,
|
|
176
|
+
registerService(router, provider) {
|
|
177
|
+
router.service(
|
|
178
|
+
CacheService,
|
|
179
|
+
createCacheService(provider as CacheProvider),
|
|
180
|
+
);
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
secrets: {
|
|
184
|
+
isProvider: isSecretsProvider as (value: unknown) => value is LoadedProvider,
|
|
185
|
+
protoKind: ProtoProviderKind.SECRETS,
|
|
186
|
+
registerService(router, provider) {
|
|
187
|
+
router.service(
|
|
188
|
+
SecretsProviderService,
|
|
189
|
+
createSecretsService(provider as SecretsProvider),
|
|
190
|
+
);
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
s3: {
|
|
194
|
+
isProvider: isS3Provider as (value: unknown) => value is LoadedProvider,
|
|
195
|
+
protoKind: ProtoProviderKind.S3,
|
|
196
|
+
registerService(router, provider) {
|
|
197
|
+
router.service(S3Service, createS3Service(provider as S3Provider));
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
workflow: {
|
|
201
|
+
isProvider: isWorkflowProvider as (value: unknown) => value is LoadedProvider,
|
|
202
|
+
protoKind: ProtoProviderKind.WORKFLOW,
|
|
203
|
+
registerService(router, provider) {
|
|
204
|
+
router.service(
|
|
205
|
+
WorkflowProviderService,
|
|
206
|
+
createWorkflowProviderService(provider as WorkflowProvider),
|
|
207
|
+
);
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
function assertProtocolVersion(protocolVersion: number): void {
|
|
213
|
+
if (protocolVersion === CURRENT_PROTOCOL_VERSION) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
throw new ConnectError(
|
|
217
|
+
`host requested protocol version ${protocolVersion}, provider requires ${CURRENT_PROTOCOL_VERSION}`,
|
|
218
|
+
Code.FailedPrecondition,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
99
221
|
|
|
222
|
+
/**
|
|
223
|
+
* CLI entrypoint that loads a provider from source and starts serving it.
|
|
224
|
+
*/
|
|
100
225
|
export async function main(
|
|
101
226
|
argv: string[] = process.argv.slice(2),
|
|
102
227
|
): Promise<number> {
|
|
@@ -112,6 +237,9 @@ export async function main(
|
|
|
112
237
|
return 0;
|
|
113
238
|
}
|
|
114
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Parses `gestalt-ts-runtime` CLI arguments.
|
|
242
|
+
*/
|
|
115
243
|
export function parseRuntimeArgs(argv: string[]): RuntimeArgs | undefined {
|
|
116
244
|
if (argv.length !== 2) {
|
|
117
245
|
return undefined;
|
|
@@ -122,87 +250,35 @@ export function parseRuntimeArgs(argv: string[]): RuntimeArgs | undefined {
|
|
|
122
250
|
};
|
|
123
251
|
}
|
|
124
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Loads any supported provider kind from a package root and optional target.
|
|
255
|
+
*/
|
|
125
256
|
export async function loadProviderFromTarget(
|
|
126
257
|
root: string,
|
|
127
258
|
rawTarget?: string,
|
|
128
259
|
): Promise<LoadedProvider> {
|
|
129
260
|
const config = readPackageConfig(root);
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const target = parseProviderTarget(targetValue);
|
|
261
|
+
const explicitTarget = rawTarget?.trim();
|
|
262
|
+
const target = explicitTarget
|
|
263
|
+
? parseProviderTarget(explicitTarget)
|
|
264
|
+
: config.providerTarget ?? readPackageProviderTarget(root);
|
|
265
|
+
const targetValue = explicitTarget || formatProviderTarget(target);
|
|
136
266
|
const module = await import(resolveProviderImportUrl(root, target));
|
|
137
267
|
const candidate =
|
|
138
|
-
(target.exportName ? module
|
|
139
|
-
|
|
268
|
+
(target.exportName ? Reflect.get(module, target.exportName) : undefined) ??
|
|
269
|
+
resolveDefaultProviderExport(module, target.kind);
|
|
140
270
|
|
|
141
271
|
const defaultName =
|
|
142
272
|
slugName(config.name ?? "") ||
|
|
143
273
|
slugName(dirname(resolve(root, target.modulePath)));
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (!isIntegrationProvider(candidate)) {
|
|
147
|
-
throw new Error(
|
|
148
|
-
`${targetValue} did not resolve to a Gestalt integration provider`,
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
candidate.resolveName(defaultName);
|
|
152
|
-
return candidate;
|
|
153
|
-
}
|
|
154
|
-
case "auth": {
|
|
155
|
-
if (!isAuthProvider(candidate)) {
|
|
156
|
-
throw new Error(
|
|
157
|
-
`${targetValue} did not resolve to a Gestalt auth provider`,
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
candidate.resolveName(defaultName);
|
|
161
|
-
return candidate;
|
|
162
|
-
}
|
|
163
|
-
case "cache": {
|
|
164
|
-
if (!isCacheProvider(candidate)) {
|
|
165
|
-
throw new Error(
|
|
166
|
-
`${targetValue} did not resolve to a Gestalt cache provider`,
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
candidate.resolveName(defaultName);
|
|
170
|
-
return candidate;
|
|
171
|
-
}
|
|
172
|
-
case "secrets": {
|
|
173
|
-
if (!isSecretsProvider(candidate)) {
|
|
174
|
-
throw new Error(
|
|
175
|
-
`${targetValue} did not resolve to a Gestalt secrets provider`,
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
candidate.resolveName(defaultName);
|
|
179
|
-
return candidate;
|
|
180
|
-
}
|
|
181
|
-
case "s3": {
|
|
182
|
-
if (!isS3Provider(candidate)) {
|
|
183
|
-
throw new Error(`${targetValue} did not resolve to a Gestalt s3 provider`);
|
|
184
|
-
}
|
|
185
|
-
candidate.resolveName(defaultName);
|
|
186
|
-
return candidate;
|
|
187
|
-
}
|
|
188
|
-
default:
|
|
189
|
-
throw new Error(
|
|
190
|
-
`TypeScript SDK does not yet support provider kind ${JSON.stringify(target.kind)}`,
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export async function loadPluginFromTarget(
|
|
196
|
-
root: string,
|
|
197
|
-
rawTarget?: string,
|
|
198
|
-
): Promise<IntegrationProvider> {
|
|
199
|
-
const provider = await loadProviderFromTarget(root, rawTarget);
|
|
200
|
-
if (!isIntegrationProvider(provider)) {
|
|
201
|
-
throw new Error("target did not resolve to an integration provider");
|
|
202
|
-
}
|
|
274
|
+
const provider = resolveLoadedProvider(candidate, target.kind, targetValue);
|
|
275
|
+
provider.resolveName(defaultName);
|
|
203
276
|
return provider;
|
|
204
277
|
}
|
|
205
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Runs a provider that has already been loaded into memory.
|
|
281
|
+
*/
|
|
206
282
|
export async function runLoadedProvider(
|
|
207
283
|
provider: LoadedProvider,
|
|
208
284
|
options: {
|
|
@@ -217,102 +293,41 @@ export async function runLoadedProvider(
|
|
|
217
293
|
}
|
|
218
294
|
|
|
219
295
|
const catalogPath = process.env[ENV_WRITE_CATALOG];
|
|
220
|
-
|
|
221
|
-
|
|
296
|
+
const manifestMetadataPath = process.env[ENV_WRITE_MANIFEST_METADATA];
|
|
297
|
+
if (catalogPath || manifestMetadataPath) {
|
|
298
|
+
if (!isPluginProvider(provider)) {
|
|
222
299
|
throw new Error(
|
|
223
|
-
"static catalog generation
|
|
300
|
+
"static catalog and manifest metadata generation are only supported for plugin providers",
|
|
224
301
|
);
|
|
225
302
|
}
|
|
226
|
-
|
|
303
|
+
if (catalogPath) {
|
|
304
|
+
writeFileSync(catalogPath, catalogToYaml(provider.staticCatalog()), "utf8");
|
|
305
|
+
}
|
|
306
|
+
if (manifestMetadataPath && provider.supportsManifestMetadata()) {
|
|
307
|
+
provider.writeManifestMetadata(manifestMetadataPath);
|
|
308
|
+
}
|
|
227
309
|
return;
|
|
228
310
|
}
|
|
229
311
|
|
|
230
312
|
await serve(provider);
|
|
231
313
|
}
|
|
232
314
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
root?: string;
|
|
237
|
-
pluginName?: string;
|
|
238
|
-
} = {},
|
|
239
|
-
): Promise<void> {
|
|
240
|
-
const runtimeOptions: {
|
|
241
|
-
root?: string;
|
|
242
|
-
providerName?: string;
|
|
243
|
-
} = {};
|
|
244
|
-
if (options.root !== undefined) {
|
|
245
|
-
runtimeOptions.root = options.root;
|
|
246
|
-
}
|
|
247
|
-
if (options.pluginName !== undefined) {
|
|
248
|
-
runtimeOptions.providerName = options.pluginName;
|
|
249
|
-
}
|
|
250
|
-
await runLoadedProvider(plugin, runtimeOptions);
|
|
251
|
-
}
|
|
252
|
-
|
|
315
|
+
/**
|
|
316
|
+
* Runs a bundled provider export after validating its provider kind.
|
|
317
|
+
*/
|
|
253
318
|
export async function runBundledProvider(
|
|
254
319
|
provider: unknown,
|
|
255
320
|
kind: ProviderKind,
|
|
256
321
|
providerName: string,
|
|
257
322
|
): Promise<void> {
|
|
258
|
-
|
|
259
|
-
switch (kind) {
|
|
260
|
-
case "integration":
|
|
261
|
-
if (!isIntegrationProvider(provider)) {
|
|
262
|
-
throw new Error(
|
|
263
|
-
"bundled target did not resolve to a Gestalt integration provider",
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
loaded = provider;
|
|
267
|
-
break;
|
|
268
|
-
case "auth":
|
|
269
|
-
if (!isAuthProvider(provider)) {
|
|
270
|
-
throw new Error(
|
|
271
|
-
"bundled target did not resolve to a Gestalt auth provider",
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
loaded = provider;
|
|
275
|
-
break;
|
|
276
|
-
case "cache":
|
|
277
|
-
if (!isCacheProvider(provider)) {
|
|
278
|
-
throw new Error(
|
|
279
|
-
"bundled target did not resolve to a Gestalt cache provider",
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
loaded = provider;
|
|
283
|
-
break;
|
|
284
|
-
case "secrets":
|
|
285
|
-
if (!isSecretsProvider(provider)) {
|
|
286
|
-
throw new Error(
|
|
287
|
-
"bundled target did not resolve to a Gestalt secrets provider",
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
loaded = provider;
|
|
291
|
-
break;
|
|
292
|
-
case "s3":
|
|
293
|
-
if (!isS3Provider(provider)) {
|
|
294
|
-
throw new Error("bundled target did not resolve to a Gestalt s3 provider");
|
|
295
|
-
}
|
|
296
|
-
loaded = provider;
|
|
297
|
-
break;
|
|
298
|
-
default:
|
|
299
|
-
throw new Error(
|
|
300
|
-
`TypeScript SDK does not yet support provider kind ${JSON.stringify(kind)}`,
|
|
301
|
-
);
|
|
302
|
-
}
|
|
303
|
-
loaded.name = slugName(providerName);
|
|
304
|
-
await runLoadedProvider(loaded, {
|
|
323
|
+
await runLoadedProvider(resolveLoadedProvider(provider, kind, "bundled target"), {
|
|
305
324
|
providerName,
|
|
306
325
|
});
|
|
307
326
|
}
|
|
308
327
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
): Promise<void> {
|
|
313
|
-
await runBundledProvider(plugin, "integration", pluginName);
|
|
314
|
-
}
|
|
315
|
-
|
|
328
|
+
/**
|
|
329
|
+
* Starts serving a provider over the Gestalt Unix socket transport.
|
|
330
|
+
*/
|
|
316
331
|
export async function serve(provider: LoadedProvider): Promise<void> {
|
|
317
332
|
const socketPath = process.env[ENV_PROVIDER_SOCKET];
|
|
318
333
|
if (!socketPath) {
|
|
@@ -328,20 +343,7 @@ export async function serve(provider: LoadedProvider): Promise<void> {
|
|
|
328
343
|
connect: false,
|
|
329
344
|
routes(router) {
|
|
330
345
|
router.service(ProviderLifecycle, createRuntimeService(provider));
|
|
331
|
-
|
|
332
|
-
router.service(
|
|
333
|
-
IntegrationProviderService,
|
|
334
|
-
createProviderService(provider),
|
|
335
|
-
);
|
|
336
|
-
} else if (isAuthProvider(provider)) {
|
|
337
|
-
router.service(AuthProviderService, createAuthService(provider));
|
|
338
|
-
} else if (isCacheProvider(provider)) {
|
|
339
|
-
router.service(CacheService, createCacheService(provider));
|
|
340
|
-
} else if (isS3Provider(provider)) {
|
|
341
|
-
router.service(S3Service, createS3Service(provider));
|
|
342
|
-
} else if (isSecretsProvider(provider)) {
|
|
343
|
-
router.service(SecretsProviderService, createSecretsService(provider));
|
|
344
|
-
}
|
|
346
|
+
registerProviderService(router, provider);
|
|
345
347
|
},
|
|
346
348
|
});
|
|
347
349
|
|
|
@@ -392,13 +394,18 @@ export async function serve(provider: LoadedProvider): Promise<void> {
|
|
|
392
394
|
}
|
|
393
395
|
}
|
|
394
396
|
|
|
397
|
+
/**
|
|
398
|
+
* Adapts the provider lifecycle service used during startup and health checks.
|
|
399
|
+
*
|
|
400
|
+
* @internal
|
|
401
|
+
*/
|
|
395
402
|
export function createRuntimeService(
|
|
396
403
|
provider: LoadedProvider,
|
|
397
404
|
): Partial<ServiceImpl<typeof ProviderLifecycle>> {
|
|
398
405
|
return {
|
|
399
406
|
async getProviderIdentity() {
|
|
400
407
|
return create(ProviderIdentitySchema, {
|
|
401
|
-
kind:
|
|
408
|
+
kind: providerRuntimeEntry(provider.kind).protoKind,
|
|
402
409
|
name: provider.name,
|
|
403
410
|
displayName: provider.displayName,
|
|
404
411
|
description: provider.description,
|
|
@@ -409,12 +416,7 @@ export function createRuntimeService(
|
|
|
409
416
|
});
|
|
410
417
|
},
|
|
411
418
|
async configureProvider(request: ConfigureProviderRequest) {
|
|
412
|
-
|
|
413
|
-
throw new ConnectError(
|
|
414
|
-
`host requested protocol version ${request.protocolVersion}, provider requires ${CURRENT_PROTOCOL_VERSION}`,
|
|
415
|
-
Code.FailedPrecondition,
|
|
416
|
-
);
|
|
417
|
-
}
|
|
419
|
+
assertProtocolVersion(request.protocolVersion);
|
|
418
420
|
try {
|
|
419
421
|
await provider.configureProvider(
|
|
420
422
|
request.name,
|
|
@@ -451,9 +453,17 @@ export function createRuntimeService(
|
|
|
451
453
|
};
|
|
452
454
|
}
|
|
453
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Adapts a plugin provider to the shared protocol service implementation.
|
|
458
|
+
*
|
|
459
|
+
* @internal
|
|
460
|
+
*/
|
|
454
461
|
export function createProviderService(
|
|
455
|
-
provider:
|
|
462
|
+
provider: LoadedProvider,
|
|
456
463
|
): Partial<ServiceImpl<typeof IntegrationProviderService>> {
|
|
464
|
+
if (!isPluginProvider(provider)) {
|
|
465
|
+
throw new Error("provider is not a plugin provider");
|
|
466
|
+
}
|
|
457
467
|
return {
|
|
458
468
|
getMetadata() {
|
|
459
469
|
return create(ProviderMetadataSchema, {
|
|
@@ -478,6 +488,7 @@ export function createProviderService(
|
|
|
478
488
|
});
|
|
479
489
|
},
|
|
480
490
|
async startProvider(request: StartProviderRequest) {
|
|
491
|
+
assertProtocolVersion(request.protocolVersion);
|
|
481
492
|
try {
|
|
482
493
|
await provider.configureProvider(
|
|
483
494
|
request.name,
|
|
@@ -503,6 +514,7 @@ export function createProviderService(
|
|
|
503
514
|
request.token,
|
|
504
515
|
request.connectionParams,
|
|
505
516
|
request.context,
|
|
517
|
+
request.invocationToken,
|
|
506
518
|
),
|
|
507
519
|
),
|
|
508
520
|
);
|
|
@@ -542,9 +554,15 @@ export function createProviderService(
|
|
|
542
554
|
};
|
|
543
555
|
}
|
|
544
556
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
557
|
+
/**
|
|
558
|
+
* Adapts an authentication provider to the shared protocol service
|
|
559
|
+
* implementation.
|
|
560
|
+
*
|
|
561
|
+
* @internal
|
|
562
|
+
*/
|
|
563
|
+
export function createAuthenticationService(
|
|
564
|
+
provider: AuthenticationProvider,
|
|
565
|
+
): Partial<ServiceImpl<typeof AuthenticationProviderService>> {
|
|
548
566
|
return {
|
|
549
567
|
async beginLogin(request) {
|
|
550
568
|
const response = await provider.beginLogin({
|
|
@@ -557,7 +575,7 @@ export function createAuthService(
|
|
|
557
575
|
});
|
|
558
576
|
if (!response) {
|
|
559
577
|
throw new ConnectError(
|
|
560
|
-
"
|
|
578
|
+
"authentication provider returned nil response",
|
|
561
579
|
Code.Internal,
|
|
562
580
|
);
|
|
563
581
|
}
|
|
@@ -576,7 +594,7 @@ export function createAuthService(
|
|
|
576
594
|
});
|
|
577
595
|
if (!user) {
|
|
578
596
|
throw new ConnectError(
|
|
579
|
-
"
|
|
597
|
+
"authentication provider returned nil user",
|
|
580
598
|
Code.Internal,
|
|
581
599
|
);
|
|
582
600
|
}
|
|
@@ -585,7 +603,7 @@ export function createAuthService(
|
|
|
585
603
|
async validateExternalToken(request: ValidateExternalTokenRequest) {
|
|
586
604
|
if (!provider.supportsExternalTokenValidation()) {
|
|
587
605
|
throw new ConnectError(
|
|
588
|
-
"
|
|
606
|
+
"authentication provider does not support external token validation",
|
|
589
607
|
Code.Unimplemented,
|
|
590
608
|
);
|
|
591
609
|
}
|
|
@@ -598,7 +616,7 @@ export function createAuthService(
|
|
|
598
616
|
async getSessionSettings() {
|
|
599
617
|
if (!provider.supportsSessionSettings()) {
|
|
600
618
|
throw new ConnectError(
|
|
601
|
-
"
|
|
619
|
+
"authentication provider does not expose session settings",
|
|
602
620
|
Code.Unimplemented,
|
|
603
621
|
);
|
|
604
622
|
}
|
|
@@ -610,6 +628,11 @@ export function createAuthService(
|
|
|
610
628
|
};
|
|
611
629
|
}
|
|
612
630
|
|
|
631
|
+
/**
|
|
632
|
+
* Adapts a cache provider to the shared protocol service implementation.
|
|
633
|
+
*
|
|
634
|
+
* @internal
|
|
635
|
+
*/
|
|
613
636
|
export function createCacheService(
|
|
614
637
|
provider: CacheProvider,
|
|
615
638
|
): Partial<ServiceImpl<typeof CacheService>> {
|
|
@@ -674,6 +697,11 @@ export function createCacheService(
|
|
|
674
697
|
};
|
|
675
698
|
}
|
|
676
699
|
|
|
700
|
+
/**
|
|
701
|
+
* Adapts a secrets provider to the shared protocol service implementation.
|
|
702
|
+
*
|
|
703
|
+
* @internal
|
|
704
|
+
*/
|
|
677
705
|
export function createSecretsService(
|
|
678
706
|
provider: SecretsProvider,
|
|
679
707
|
): Partial<ServiceImpl<typeof SecretsProviderService>> {
|
|
@@ -687,14 +715,11 @@ export function createSecretsService(
|
|
|
687
715
|
};
|
|
688
716
|
}
|
|
689
717
|
|
|
690
|
-
export function pluginCatalogYaml(plugin: IntegrationProvider): string {
|
|
691
|
-
return catalogToYaml(plugin.staticCatalog());
|
|
692
|
-
}
|
|
693
|
-
|
|
694
718
|
function providerRequest(
|
|
695
719
|
token: string,
|
|
696
720
|
connectionParams: Record<string, string>,
|
|
697
721
|
requestContext?: ProtoRequestContext,
|
|
722
|
+
invocationToken = "",
|
|
698
723
|
): Request {
|
|
699
724
|
const subject = requestContext?.subject;
|
|
700
725
|
const credential = requestContext?.credential;
|
|
@@ -720,43 +745,44 @@ function providerRequest(
|
|
|
720
745
|
policy: access?.policy ?? "",
|
|
721
746
|
role: access?.role ?? "",
|
|
722
747
|
},
|
|
748
|
+
workflow: {
|
|
749
|
+
...(requestContext?.workflow ?? {}),
|
|
750
|
+
},
|
|
751
|
+
invocationToken,
|
|
723
752
|
};
|
|
724
753
|
}
|
|
725
754
|
|
|
726
|
-
function
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
case "secrets":
|
|
735
|
-
return ProtoProviderKind.SECRETS;
|
|
736
|
-
case "s3":
|
|
737
|
-
return ProtoProviderKind.S3;
|
|
738
|
-
case "telemetry":
|
|
739
|
-
return ProtoProviderKind.TELEMETRY;
|
|
740
|
-
default:
|
|
741
|
-
return ProtoProviderKind.UNSPECIFIED;
|
|
755
|
+
function providerRuntimeEntry(
|
|
756
|
+
kind: ProviderKind,
|
|
757
|
+
): ProviderRuntimeEntry {
|
|
758
|
+
const entry = PROVIDER_RUNTIME_ENTRIES[kind];
|
|
759
|
+
if (!entry) {
|
|
760
|
+
throw new Error(
|
|
761
|
+
`TypeScript SDK does not yet support provider kind ${JSON.stringify(kind)}`,
|
|
762
|
+
);
|
|
742
763
|
}
|
|
764
|
+
return entry;
|
|
743
765
|
}
|
|
744
766
|
|
|
745
|
-
function
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
case "s3":
|
|
756
|
-
return module.s3 ?? module.provider ?? module.default;
|
|
757
|
-
case "telemetry":
|
|
758
|
-
return module.telemetry ?? module.provider ?? module.default;
|
|
767
|
+
function resolveLoadedProvider(
|
|
768
|
+
candidate: unknown,
|
|
769
|
+
kind: ProviderKind,
|
|
770
|
+
source: string,
|
|
771
|
+
): LoadedProvider {
|
|
772
|
+
const entry = providerRuntimeEntry(kind);
|
|
773
|
+
if (!entry.isProvider(candidate)) {
|
|
774
|
+
throw new Error(
|
|
775
|
+
`${source} did not resolve to a Gestalt ${providerKindLabel(kind)}`,
|
|
776
|
+
);
|
|
759
777
|
}
|
|
778
|
+
return candidate;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
function registerProviderService(
|
|
782
|
+
router: ConnectRouter,
|
|
783
|
+
provider: LoadedProvider,
|
|
784
|
+
): void {
|
|
785
|
+
providerRuntimeEntry(provider.kind).registerService(router, provider);
|
|
760
786
|
}
|
|
761
787
|
|
|
762
788
|
function objectFromUnknown(value: unknown): Record<string, unknown> {
|