@loykin/datasourcekit 0.0.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/dist/index.js ADDED
@@ -0,0 +1,318 @@
1
+ import { DatasourceNotFoundError, DatasourceCapabilityError, DatasourceTypeNotRegisteredError, DatasourceValidationError, DatasourceUnauthorizedError, DatasourceForbiddenError, DatasourceConflictError, DatasourceTransportError } from './chunk-Z2DGIUJ2.js';
2
+ export { DatasourceCapabilityError, DatasourceConflictError, DatasourceForbiddenError, DatasourceNotFoundError, DatasourceTransportError, DatasourceTypeNotRegisteredError, DatasourceUnauthorizedError, DatasourceValidationError } from './chunk-Z2DGIUJ2.js';
3
+
4
+ // src/registry.ts
5
+ function createDatasourceRegistry(plugins = []) {
6
+ const byType = /* @__PURE__ */ new Map();
7
+ const registry = {
8
+ register(plugin) {
9
+ byType.set(plugin.type, plugin);
10
+ },
11
+ get(type) {
12
+ return byType.get(type);
13
+ },
14
+ has(type) {
15
+ return byType.has(type);
16
+ },
17
+ list() {
18
+ return [...byType.values()];
19
+ },
20
+ getConfigEditor(type) {
21
+ return byType.get(type)?.configEditor;
22
+ },
23
+ getQueryEditor(type) {
24
+ return byType.get(type)?.queryEditor;
25
+ }
26
+ };
27
+ for (const plugin of plugins) registry.register(plugin);
28
+ return registry;
29
+ }
30
+
31
+ // src/manager.ts
32
+ function getRequestType(request) {
33
+ if (!request.datasourceType) {
34
+ throw new DatasourceValidationError("query request requires datasourceType", [
35
+ "datasourceType is required for plugin routing"
36
+ ]);
37
+ }
38
+ return request.datasourceType;
39
+ }
40
+ function getPlugin(registry, type) {
41
+ const plugin = registry.get(type);
42
+ if (!plugin) throw new DatasourceTypeNotRegisteredError(type);
43
+ return plugin;
44
+ }
45
+ async function normalizeQueryResult(raw, request, context, plugin, options) {
46
+ const normalized = plugin.backend?.transform ? await plugin.backend.transform(raw, request, context) : raw;
47
+ return options?.transform ? options.transform(normalized) : normalized;
48
+ }
49
+ function typeInfoFromPlugin(plugin) {
50
+ return {
51
+ type: plugin.type,
52
+ name: plugin.name,
53
+ ...plugin.description !== void 0 ? { description: plugin.description } : {},
54
+ installed: false,
55
+ enabled: false,
56
+ hasConfigEditor: plugin.configEditor !== void 0,
57
+ hasQueryEditor: plugin.queryEditor !== void 0,
58
+ ...plugin.meta !== void 0 ? { meta: plugin.meta } : {}
59
+ };
60
+ }
61
+ function mergeTypeInfo(backendTypes, plugins) {
62
+ const byType = /* @__PURE__ */ new Map();
63
+ for (const typeInfo of backendTypes) byType.set(typeInfo.type, { ...typeInfo });
64
+ for (const plugin of plugins) {
65
+ const current = byType.get(plugin.type);
66
+ if (current) {
67
+ byType.set(plugin.type, {
68
+ ...current,
69
+ name: current.name || plugin.name,
70
+ hasConfigEditor: plugin.configEditor !== void 0,
71
+ hasQueryEditor: plugin.queryEditor !== void 0
72
+ });
73
+ } else {
74
+ byType.set(plugin.type, typeInfoFromPlugin(plugin));
75
+ }
76
+ }
77
+ return [...byType.values()];
78
+ }
79
+ async function getInstanceOptions(backend, uid, context) {
80
+ const instance = await backend.instances.get(uid, context);
81
+ return instance.options ?? {};
82
+ }
83
+ function missingCapability(uid, capability) {
84
+ throw new DatasourceCapabilityError(uid, capability);
85
+ }
86
+ function createDatasourceManager(options) {
87
+ const registry = options.registry ?? createDatasourceRegistry(options.plugins);
88
+ if (options.registry && options.plugins) {
89
+ for (const plugin of options.plugins) registry.register(plugin);
90
+ }
91
+ const manager = {
92
+ registry,
93
+ registerPlugin(plugin) {
94
+ registry.register(plugin);
95
+ },
96
+ types: {
97
+ async list(context) {
98
+ const backendTypes = await options.backend.types.list(context);
99
+ return mergeTypeInfo(backendTypes, registry.list());
100
+ },
101
+ async get(type, context) {
102
+ const plugin = registry.get(type);
103
+ let backendType;
104
+ try {
105
+ backendType = await options.backend.types.get(type, context);
106
+ } catch (error) {
107
+ if (!(error instanceof DatasourceNotFoundError) || !plugin) throw error;
108
+ }
109
+ if (!backendType) {
110
+ if (!plugin) throw new DatasourceNotFoundError(type);
111
+ return typeInfoFromPlugin(plugin);
112
+ }
113
+ if (!plugin) return backendType;
114
+ return {
115
+ ...backendType,
116
+ hasConfigEditor: plugin.configEditor !== void 0,
117
+ hasQueryEditor: plugin.queryEditor !== void 0
118
+ };
119
+ },
120
+ ...options.backend.types.install ? { install: (type, context) => options.backend.types.install?.(type, context) ?? missingCapability(type, "types.install") } : {},
121
+ ...options.backend.types.uninstall ? { uninstall: (type, context) => options.backend.types.uninstall?.(type, context) ?? missingCapability(type, "types.uninstall") } : {},
122
+ ...options.backend.types.enable ? { enable: (type, context) => options.backend.types.enable?.(type, context) ?? missingCapability(type, "types.enable") } : {},
123
+ ...options.backend.types.disable ? { disable: (type, context) => options.backend.types.disable?.(type, context) ?? missingCapability(type, "types.disable") } : {}
124
+ },
125
+ instances: {
126
+ list: (listOptions, context) => options.backend.instances.list(listOptions, context),
127
+ get: (uid, context) => options.backend.instances.get(uid, context),
128
+ create: (input, context) => options.backend.instances.create(input, context),
129
+ update: (uid, patch, context) => options.backend.instances.update(uid, patch, context),
130
+ delete: (uid, context) => options.backend.instances.delete(uid, context),
131
+ async query(request, context, callOptions) {
132
+ const type = getRequestType(request);
133
+ const plugin = getPlugin(registry, type);
134
+ const raw = plugin.backend?.query ? await plugin.backend.query(request, context) : await options.backend.query(request, context);
135
+ return normalizeQueryResult(raw, request, context, plugin, callOptions);
136
+ },
137
+ async batchQuery(requests, context, callOptions) {
138
+ if (options.backend.batchQuery) {
139
+ const result = await options.backend.batchQuery(requests, context);
140
+ if (!callOptions?.transform) return result;
141
+ const items2 = await Promise.all(result.items.map(async (item) => {
142
+ if (item.error || !item.data) return item;
143
+ try {
144
+ return { data: await callOptions.transform(item.data) };
145
+ } catch (error) {
146
+ return { error: error instanceof Error ? error : new Error(String(error)) };
147
+ }
148
+ }));
149
+ return { items: items2 };
150
+ }
151
+ const items = await Promise.all(requests.map(async (request) => {
152
+ try {
153
+ const data = await manager.instances.query(request, context, callOptions);
154
+ return { data };
155
+ } catch (error) {
156
+ return { error: error instanceof Error ? error : new Error(String(error)) };
157
+ }
158
+ }));
159
+ return { items };
160
+ },
161
+ async healthCheck(uid, type, context) {
162
+ const plugin = getPlugin(registry, type);
163
+ if (plugin.backend?.healthCheck) {
164
+ const datasourceOptions = await getInstanceOptions(options.backend, uid, context);
165
+ return plugin.backend.healthCheck(uid, datasourceOptions, context);
166
+ }
167
+ return options.backend.healthCheck?.(uid, context) ?? missingCapability(uid, "healthCheck");
168
+ },
169
+ async validateQuery(uid, type, query, context) {
170
+ const plugin = getPlugin(registry, type);
171
+ if (plugin.backend?.validateQuery) {
172
+ return plugin.backend.validateQuery(uid, query, context);
173
+ }
174
+ return options.backend.validateQuery?.(uid, query, context) ?? missingCapability(uid, "validateQuery");
175
+ },
176
+ async listNamespaces(uid, type, context) {
177
+ const plugin = getPlugin(registry, type);
178
+ if (plugin.backend?.listNamespaces) {
179
+ const datasourceOptions = await getInstanceOptions(options.backend, uid, context);
180
+ return plugin.backend.listNamespaces(uid, datasourceOptions, context);
181
+ }
182
+ return options.backend.listNamespaces?.(uid, context) ?? missingCapability(uid, "listNamespaces");
183
+ },
184
+ async listFields(uid, type, request, context) {
185
+ const plugin = getPlugin(registry, type);
186
+ if (plugin.backend?.listFields) {
187
+ const datasourceOptions = await getInstanceOptions(options.backend, uid, context);
188
+ return plugin.backend.listFields(uid, request, datasourceOptions, context);
189
+ }
190
+ return options.backend.listFields?.(uid, request, context) ?? missingCapability(uid, "listFields");
191
+ }
192
+ }
193
+ };
194
+ return manager;
195
+ }
196
+ var defaultRestPaths = {
197
+ typesList: () => "/types",
198
+ typeGet: (type) => `/types/${encodeURIComponent(type)}`,
199
+ typeAction: (type, action) => `/types/${encodeURIComponent(type)}/${action}`,
200
+ instancesList: (qs) => qs,
201
+ instanceGet: (uid) => `/${encodeURIComponent(uid)}`,
202
+ instanceCreate: () => "",
203
+ instanceUpdate: (uid) => `/${encodeURIComponent(uid)}`,
204
+ instanceDelete: (uid) => `/${encodeURIComponent(uid)}`,
205
+ query: () => "/query",
206
+ healthCheck: (uid) => `/${encodeURIComponent(uid)}/health`,
207
+ validateQuery: (uid) => `/${encodeURIComponent(uid)}/validate-query`,
208
+ listNamespaces: (uid) => `/${encodeURIComponent(uid)}/namespaces`,
209
+ listFields: (uid) => `/${encodeURIComponent(uid)}/fields`
210
+ };
211
+ function mergeRestPaths(paths) {
212
+ return { ...defaultRestPaths, ...paths };
213
+ }
214
+ async function readJson(response) {
215
+ if (response.status === 204) return void 0;
216
+ try {
217
+ return await response.json();
218
+ } catch {
219
+ return void 0;
220
+ }
221
+ }
222
+ async function parseResponse(response, options) {
223
+ const body = await readJson(response);
224
+ if (response.ok) {
225
+ return options.unwrap ? options.unwrap(body, response) : body;
226
+ }
227
+ const customError = options.createError?.(response, body);
228
+ if (customError) throw customError;
229
+ const errorBody = body;
230
+ const message = errorBody?.message;
231
+ if (response.status === 401) throw new DatasourceUnauthorizedError(message);
232
+ if (response.status === 403) throw new DatasourceForbiddenError(message);
233
+ if (response.status === 404) throw new DatasourceNotFoundError(message ?? "unknown");
234
+ if (response.status === 409) throw new DatasourceConflictError(message);
235
+ if (response.status === 422) throw new DatasourceValidationError(message, errorBody?.errors);
236
+ throw new DatasourceTransportError(message, response.status);
237
+ }
238
+ async function requestHeaders(options, context) {
239
+ return {
240
+ "content-type": "application/json",
241
+ ...context?.authToken ? { authorization: `Bearer ${context.authToken}` } : {},
242
+ ...context?.headers ?? {},
243
+ ...await options.getHeaders?.(context)
244
+ };
245
+ }
246
+ function queryString(options) {
247
+ const params = new URLSearchParams();
248
+ if (options?.filter?.type !== void 0) {
249
+ const types = Array.isArray(options.filter.type) ? options.filter.type : [options.filter.type];
250
+ for (const type of types) params.append("type", type);
251
+ }
252
+ if (options?.filter?.enabled !== void 0) params.set("enabled", String(options.filter.enabled));
253
+ if (options?.filter?.search !== void 0) params.set("search", options.filter.search);
254
+ if (options?.page !== void 0) params.set("page", String(options.page));
255
+ if (options?.pageSize !== void 0) params.set("pageSize", String(options.pageSize));
256
+ if (options?.cursor !== void 0) params.set("cursor", options.cursor);
257
+ const qs = params.toString();
258
+ return qs ? `?${qs}` : "";
259
+ }
260
+ function createRestDatasourceManager(options) {
261
+ const fetchImpl = options.fetch ?? fetch;
262
+ const baseUrl = options.baseUrl.replace(/\/$/, "");
263
+ const paths = mergeRestPaths(options.paths);
264
+ async function send(path, init, context) {
265
+ const response = await fetchImpl(`${baseUrl}${path}`, {
266
+ ...init,
267
+ headers: await requestHeaders(options, context),
268
+ ...context?.signal ? { signal: context.signal } : {}
269
+ });
270
+ return parseResponse(response, options);
271
+ }
272
+ return {
273
+ types: {
274
+ list: (context) => send(paths.typesList(), { method: "GET" }, context),
275
+ get: (type, context) => send(paths.typeGet(type), { method: "GET" }, context),
276
+ install: (type, context) => send(paths.typeAction(type, "install"), { method: "POST" }, context),
277
+ uninstall: (type, context) => send(paths.typeAction(type, "uninstall"), { method: "POST" }, context),
278
+ enable: (type, context) => send(paths.typeAction(type, "enable"), { method: "POST" }, context),
279
+ disable: (type, context) => send(paths.typeAction(type, "disable"), { method: "POST" }, context)
280
+ },
281
+ instances: {
282
+ list: (options2, context) => send(paths.instancesList(queryString(options2)), { method: "GET" }, context),
283
+ get: (uid, context) => send(paths.instanceGet(uid), { method: "GET" }, context),
284
+ create: (input, context) => send(paths.instanceCreate(), {
285
+ method: "POST",
286
+ body: JSON.stringify(input)
287
+ }, context),
288
+ update: (uid, patch, context) => send(paths.instanceUpdate(uid), {
289
+ method: "PATCH",
290
+ body: JSON.stringify(patch)
291
+ }, context),
292
+ delete: (uid, context) => send(paths.instanceDelete(uid), { method: "DELETE" }, context)
293
+ },
294
+ query: (request, context) => send(paths.query(), {
295
+ method: "POST",
296
+ body: JSON.stringify(request)
297
+ }, context),
298
+ healthCheck: (uid, context) => send(paths.healthCheck(uid), { method: "GET" }, context),
299
+ validateQuery: (uid, query, context) => send(paths.validateQuery(uid), {
300
+ method: "POST",
301
+ body: JSON.stringify(query)
302
+ }, context),
303
+ listNamespaces: (uid, context) => send(paths.listNamespaces(uid), { method: "GET" }, context),
304
+ listFields: (uid, request, context) => send(paths.listFields(uid), {
305
+ method: "POST",
306
+ body: JSON.stringify(request)
307
+ }, context)
308
+ };
309
+ }
310
+
311
+ // src/plugin.ts
312
+ function defineDatasourcePlugin(def) {
313
+ return def;
314
+ }
315
+
316
+ export { createDatasourceManager, createDatasourceRegistry, createRestDatasourceManager, defineDatasourcePlugin };
317
+ //# sourceMappingURL=index.js.map
318
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry.ts","../src/manager.ts","../src/plugin.ts"],"names":["items","options"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n DatasourceConfigEditorProps,\n DatasourcePluginDef,\n DatasourceQueryEditorProps,\n} from './plugin'\n\nexport interface DatasourceRegistry {\n register(plugin: DatasourcePluginDef): void\n get(type: string): DatasourcePluginDef | undefined\n has(type: string): boolean\n list(): DatasourcePluginDef[]\n getConfigEditor(\n type: string,\n ): ((props: DatasourceConfigEditorProps<unknown>) => unknown) | undefined\n getQueryEditor(\n type: string,\n ): ((props: DatasourceQueryEditorProps<unknown, unknown>) => unknown) | undefined\n}\n\nexport function createDatasourceRegistry(\n plugins: readonly DatasourcePluginDef[] = [],\n): DatasourceRegistry {\n const byType = new Map<string, DatasourcePluginDef>()\n\n const registry: DatasourceRegistry = {\n register(plugin) {\n byType.set(plugin.type, plugin)\n },\n\n get(type) {\n return byType.get(type)\n },\n\n has(type) {\n return byType.has(type)\n },\n\n list() {\n return [...byType.values()]\n },\n\n getConfigEditor(type) {\n return byType.get(type)?.configEditor as\n | ((props: DatasourceConfigEditorProps<unknown>) => unknown)\n | undefined\n },\n\n getQueryEditor(type) {\n return byType.get(type)?.queryEditor as\n | ((props: DatasourceQueryEditorProps<unknown, unknown>) => unknown)\n | undefined\n },\n }\n\n for (const plugin of plugins) registry.register(plugin)\n\n return registry\n}\n","import {\n DatasourceCapabilityError,\n DatasourceConflictError,\n DatasourceForbiddenError,\n DatasourceNotFoundError,\n DatasourceTransportError,\n DatasourceTypeNotRegisteredError,\n DatasourceUnauthorizedError,\n DatasourceValidationError,\n} from './errors'\nimport type { DatasourcePluginDef } from './plugin'\nimport { createDatasourceRegistry, type DatasourceRegistry } from './registry'\nimport type {\n BatchQueryResult,\n DataQuery,\n DatasourceContext,\n DatasourceCreateInput,\n DatasourceHealthResult,\n DatasourceInstance,\n DatasourceListOptions,\n DatasourceListResult,\n DatasourceSchemaField,\n DatasourceSchemaFieldRequest,\n DatasourceSchemaNamespace,\n DatasourceTypeInfo,\n DatasourceUpdateInput,\n DatasourceValidationResult,\n QueryResult,\n} from './types'\n\nexport interface QueryCallOptions {\n transform?: (result: QueryResult) => QueryResult | Promise<QueryResult>\n}\n\nexport interface DatasourceManagerTypes {\n list(context?: DatasourceContext): Promise<DatasourceTypeInfo[]>\n get(type: string, context?: DatasourceContext): Promise<DatasourceTypeInfo>\n install?(type: string, context?: DatasourceContext): Promise<void>\n uninstall?(type: string, context?: DatasourceContext): Promise<void>\n enable?(type: string, context?: DatasourceContext): Promise<void>\n disable?(type: string, context?: DatasourceContext): Promise<void>\n}\n\nexport interface DatasourceManagerInstances {\n list(options?: DatasourceListOptions, context?: DatasourceContext): Promise<DatasourceListResult>\n get(uid: string, context?: DatasourceContext): Promise<DatasourceInstance>\n create(\n input: DatasourceCreateInput,\n context?: DatasourceContext,\n ): Promise<DatasourceInstance>\n update(\n uid: string,\n patch: DatasourceUpdateInput,\n context?: DatasourceContext,\n ): Promise<DatasourceInstance>\n delete(uid: string, context?: DatasourceContext): Promise<void>\n query(\n request: DataQuery,\n context?: DatasourceContext,\n options?: QueryCallOptions,\n ): Promise<QueryResult>\n batchQuery(\n requests: DataQuery[],\n context?: DatasourceContext,\n options?: QueryCallOptions,\n ): Promise<BatchQueryResult>\n healthCheck(uid: string, type: string, context?: DatasourceContext): Promise<DatasourceHealthResult>\n validateQuery(\n uid: string,\n type: string,\n query: unknown,\n context?: DatasourceContext,\n ): Promise<DatasourceValidationResult>\n listNamespaces(\n uid: string,\n type: string,\n context?: DatasourceContext,\n ): Promise<DatasourceSchemaNamespace[]>\n listFields(\n uid: string,\n type: string,\n request: DatasourceSchemaFieldRequest,\n context?: DatasourceContext,\n ): Promise<DatasourceSchemaField[]>\n}\n\nexport interface DatasourceManager {\n registerPlugin(plugin: DatasourcePluginDef): void\n registry: DatasourceRegistry\n types: DatasourceManagerTypes\n instances: DatasourceManagerInstances\n}\n\nexport interface DatasourceManagerBackend {\n types: {\n list(context?: DatasourceContext): Promise<DatasourceTypeInfo[]>\n get(type: string, context?: DatasourceContext): Promise<DatasourceTypeInfo>\n install?(type: string, context?: DatasourceContext): Promise<void>\n uninstall?(type: string, context?: DatasourceContext): Promise<void>\n enable?(type: string, context?: DatasourceContext): Promise<void>\n disable?(type: string, context?: DatasourceContext): Promise<void>\n }\n instances: {\n list(options?: DatasourceListOptions, context?: DatasourceContext): Promise<DatasourceListResult>\n get(uid: string, context?: DatasourceContext): Promise<DatasourceInstance>\n create(\n input: DatasourceCreateInput,\n context?: DatasourceContext,\n ): Promise<DatasourceInstance>\n update(\n uid: string,\n patch: DatasourceUpdateInput,\n context?: DatasourceContext,\n ): Promise<DatasourceInstance>\n delete(uid: string, context?: DatasourceContext): Promise<void>\n }\n query(request: DataQuery, context?: DatasourceContext): Promise<unknown>\n batchQuery?(requests: DataQuery[], context?: DatasourceContext): Promise<BatchQueryResult>\n healthCheck?(uid: string, context?: DatasourceContext): Promise<DatasourceHealthResult>\n validateQuery?(\n uid: string,\n query: unknown,\n context?: DatasourceContext,\n ): Promise<DatasourceValidationResult>\n listNamespaces?(uid: string, context?: DatasourceContext): Promise<DatasourceSchemaNamespace[]>\n listFields?(\n uid: string,\n request: DatasourceSchemaFieldRequest,\n context?: DatasourceContext,\n ): Promise<DatasourceSchemaField[]>\n}\n\nexport interface CreateDatasourceManagerOptions {\n registry?: DatasourceRegistry\n plugins?: readonly DatasourcePluginDef[]\n backend: DatasourceManagerBackend\n}\n\nfunction getRequestType(request: DataQuery): string {\n if (!request.datasourceType) {\n throw new DatasourceValidationError('query request requires datasourceType', [\n 'datasourceType is required for plugin routing',\n ])\n }\n return request.datasourceType\n}\n\nfunction getPlugin(registry: DatasourceRegistry, type: string): DatasourcePluginDef {\n const plugin = registry.get(type)\n if (!plugin) throw new DatasourceTypeNotRegisteredError(type)\n return plugin\n}\n\nasync function normalizeQueryResult(\n raw: unknown,\n request: DataQuery,\n context: DatasourceContext | undefined,\n plugin: DatasourcePluginDef,\n options: QueryCallOptions | undefined,\n): Promise<QueryResult> {\n const normalized = plugin.backend?.transform\n ? await plugin.backend.transform(raw, request, context)\n : raw as QueryResult\n return options?.transform ? options.transform(normalized) : normalized\n}\n\nfunction typeInfoFromPlugin(plugin: DatasourcePluginDef): DatasourceTypeInfo {\n return {\n type: plugin.type,\n name: plugin.name,\n ...(plugin.description !== undefined ? { description: plugin.description } : {}),\n installed: false,\n enabled: false,\n hasConfigEditor: plugin.configEditor !== undefined,\n hasQueryEditor: plugin.queryEditor !== undefined,\n ...(plugin.meta !== undefined ? { meta: plugin.meta } : {}),\n }\n}\n\nfunction mergeTypeInfo(\n backendTypes: DatasourceTypeInfo[],\n plugins: DatasourcePluginDef[],\n): DatasourceTypeInfo[] {\n const byType = new Map<string, DatasourceTypeInfo>()\n for (const typeInfo of backendTypes) byType.set(typeInfo.type, { ...typeInfo })\n\n for (const plugin of plugins) {\n const current = byType.get(plugin.type)\n if (current) {\n byType.set(plugin.type, {\n ...current,\n name: current.name || plugin.name,\n hasConfigEditor: plugin.configEditor !== undefined,\n hasQueryEditor: plugin.queryEditor !== undefined,\n })\n } else {\n byType.set(plugin.type, typeInfoFromPlugin(plugin))\n }\n }\n\n return [...byType.values()]\n}\n\nasync function getInstanceOptions(\n backend: DatasourceManagerBackend,\n uid: string,\n context?: DatasourceContext,\n): Promise<unknown> {\n const instance = await backend.instances.get(uid, context)\n return instance.options ?? {}\n}\n\nfunction missingCapability(uid: string, capability: string): never {\n throw new DatasourceCapabilityError(uid, capability)\n}\n\nexport function createDatasourceManager(options: CreateDatasourceManagerOptions): DatasourceManager {\n const registry = options.registry ?? createDatasourceRegistry(options.plugins)\n\n if (options.registry && options.plugins) {\n for (const plugin of options.plugins) registry.register(plugin)\n }\n\n const manager: DatasourceManager = {\n registry,\n\n registerPlugin(plugin) {\n registry.register(plugin)\n },\n\n types: {\n async list(context) {\n const backendTypes = await options.backend.types.list(context)\n return mergeTypeInfo(backendTypes, registry.list())\n },\n\n async get(type, context) {\n const plugin = registry.get(type)\n let backendType: DatasourceTypeInfo | undefined\n try {\n backendType = await options.backend.types.get(type, context)\n } catch (error) {\n if (!(error instanceof DatasourceNotFoundError) || !plugin) throw error\n }\n if (!backendType) {\n if (!plugin) throw new DatasourceNotFoundError(type)\n return typeInfoFromPlugin(plugin)\n }\n if (!plugin) return backendType\n return {\n ...backendType,\n hasConfigEditor: plugin.configEditor !== undefined,\n hasQueryEditor: plugin.queryEditor !== undefined,\n }\n },\n\n ...(options.backend.types.install\n ? { install: (type, context) => options.backend.types.install?.(type, context) ?? missingCapability(type, 'types.install') }\n : {}),\n ...(options.backend.types.uninstall\n ? { uninstall: (type, context) => options.backend.types.uninstall?.(type, context) ?? missingCapability(type, 'types.uninstall') }\n : {}),\n ...(options.backend.types.enable\n ? { enable: (type, context) => options.backend.types.enable?.(type, context) ?? missingCapability(type, 'types.enable') }\n : {}),\n ...(options.backend.types.disable\n ? { disable: (type, context) => options.backend.types.disable?.(type, context) ?? missingCapability(type, 'types.disable') }\n : {}),\n },\n\n instances: {\n list: (listOptions, context) => options.backend.instances.list(listOptions, context),\n get: (uid, context) => options.backend.instances.get(uid, context),\n create: (input, context) => options.backend.instances.create(input, context),\n update: (uid, patch, context) => options.backend.instances.update(uid, patch, context),\n delete: (uid, context) => options.backend.instances.delete(uid, context),\n\n async query(request, context, callOptions) {\n const type = getRequestType(request)\n const plugin = getPlugin(registry, type)\n const raw = plugin.backend?.query\n ? await plugin.backend.query(request, context)\n : await options.backend.query(request, context)\n return normalizeQueryResult(raw, request, context, plugin, callOptions)\n },\n\n async batchQuery(requests, context, callOptions) {\n if (options.backend.batchQuery) {\n const result = await options.backend.batchQuery(requests, context)\n if (!callOptions?.transform) return result\n const items = await Promise.all(result.items.map(async (item) => {\n if (item.error || !item.data) return item\n try {\n return { data: await callOptions.transform!(item.data) }\n } catch (error) {\n return { error: error instanceof Error ? error : new Error(String(error)) }\n }\n }))\n return { items }\n }\n\n const items = await Promise.all(requests.map(async (request) => {\n try {\n const data = await manager.instances.query(request, context, callOptions)\n return { data }\n } catch (error) {\n return { error: error instanceof Error ? error : new Error(String(error)) }\n }\n }))\n return { items }\n },\n\n async healthCheck(uid, type, context) {\n const plugin = getPlugin(registry, type)\n if (plugin.backend?.healthCheck) {\n const datasourceOptions = await getInstanceOptions(options.backend, uid, context)\n return plugin.backend.healthCheck(uid, datasourceOptions, context)\n }\n return options.backend.healthCheck?.(uid, context) ?? missingCapability(uid, 'healthCheck')\n },\n\n async validateQuery(uid, type, query, context) {\n const plugin = getPlugin(registry, type)\n if (plugin.backend?.validateQuery) {\n return plugin.backend.validateQuery(uid, query, context)\n }\n return options.backend.validateQuery?.(uid, query, context) ?? missingCapability(uid, 'validateQuery')\n },\n\n async listNamespaces(uid, type, context) {\n const plugin = getPlugin(registry, type)\n if (plugin.backend?.listNamespaces) {\n const datasourceOptions = await getInstanceOptions(options.backend, uid, context)\n return plugin.backend.listNamespaces(uid, datasourceOptions, context)\n }\n return options.backend.listNamespaces?.(uid, context) ?? missingCapability(uid, 'listNamespaces')\n },\n\n async listFields(uid, type, request, context) {\n const plugin = getPlugin(registry, type)\n if (plugin.backend?.listFields) {\n const datasourceOptions = await getInstanceOptions(options.backend, uid, context)\n return plugin.backend.listFields(uid, request, datasourceOptions, context)\n }\n return options.backend.listFields?.(uid, request, context) ?? missingCapability(uid, 'listFields')\n },\n },\n }\n\n return manager\n}\n\nexport interface CreateRestDatasourceManagerOptions {\n baseUrl: string\n fetch?: typeof fetch\n getHeaders?: (context?: DatasourceContext) => HeadersInit | Promise<HeadersInit>\n paths?: Partial<RestDatasourceManagerPaths>\n unwrap?<T>(body: unknown, response: Response): T\n createError?(response: Response, body: unknown): Error | undefined\n}\n\nexport interface RestDatasourceManagerPaths {\n typesList(): string\n typeGet(type: string): string\n typeAction(type: string, action: 'install' | 'uninstall' | 'enable' | 'disable'): string\n instancesList(queryString: string): string\n instanceGet(uid: string): string\n instanceCreate(): string\n instanceUpdate(uid: string): string\n instanceDelete(uid: string): string\n query(): string\n healthCheck(uid: string): string\n validateQuery(uid: string): string\n listNamespaces(uid: string): string\n listFields(uid: string): string\n}\n\nconst defaultRestPaths: RestDatasourceManagerPaths = {\n typesList: () => '/types',\n typeGet: (type) => `/types/${encodeURIComponent(type)}`,\n typeAction: (type, action) => `/types/${encodeURIComponent(type)}/${action}`,\n instancesList: (qs) => qs,\n instanceGet: (uid) => `/${encodeURIComponent(uid)}`,\n instanceCreate: () => '',\n instanceUpdate: (uid) => `/${encodeURIComponent(uid)}`,\n instanceDelete: (uid) => `/${encodeURIComponent(uid)}`,\n query: () => '/query',\n healthCheck: (uid) => `/${encodeURIComponent(uid)}/health`,\n validateQuery: (uid) => `/${encodeURIComponent(uid)}/validate-query`,\n listNamespaces: (uid) => `/${encodeURIComponent(uid)}/namespaces`,\n listFields: (uid) => `/${encodeURIComponent(uid)}/fields`,\n}\n\nfunction mergeRestPaths(paths?: Partial<RestDatasourceManagerPaths>): RestDatasourceManagerPaths {\n return { ...defaultRestPaths, ...paths }\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n if (response.status === 204) return undefined\n try {\n return await response.json()\n } catch {\n return undefined\n }\n}\n\nasync function parseResponse<T>(\n response: Response,\n options: CreateRestDatasourceManagerOptions,\n): Promise<T> {\n const body = await readJson(response)\n\n if (response.ok) {\n return options.unwrap ? options.unwrap<T>(body, response) : body as T\n }\n\n const customError = options.createError?.(response, body)\n if (customError) throw customError\n\n const errorBody = body as { message?: string; errors?: string[] } | undefined\n const message = errorBody?.message\n if (response.status === 401) throw new DatasourceUnauthorizedError(message)\n if (response.status === 403) throw new DatasourceForbiddenError(message)\n if (response.status === 404) throw new DatasourceNotFoundError(message ?? 'unknown')\n if (response.status === 409) throw new DatasourceConflictError(message)\n if (response.status === 422) throw new DatasourceValidationError(message, errorBody?.errors)\n throw new DatasourceTransportError(message, response.status)\n}\n\nasync function requestHeaders(\n options: CreateRestDatasourceManagerOptions,\n context?: DatasourceContext,\n): Promise<HeadersInit> {\n return {\n 'content-type': 'application/json',\n ...(context?.authToken ? { authorization: `Bearer ${context.authToken}` } : {}),\n ...(context?.headers ?? {}),\n ...await options.getHeaders?.(context),\n }\n}\n\nfunction queryString(options?: DatasourceListOptions): string {\n const params = new URLSearchParams()\n if (options?.filter?.type !== undefined) {\n const types = Array.isArray(options.filter.type) ? options.filter.type : [options.filter.type]\n for (const type of types) params.append('type', type)\n }\n if (options?.filter?.enabled !== undefined) params.set('enabled', String(options.filter.enabled))\n if (options?.filter?.search !== undefined) params.set('search', options.filter.search)\n if (options?.page !== undefined) params.set('page', String(options.page))\n if (options?.pageSize !== undefined) params.set('pageSize', String(options.pageSize))\n if (options?.cursor !== undefined) params.set('cursor', options.cursor)\n const qs = params.toString()\n return qs ? `?${qs}` : ''\n}\n\nexport function createRestDatasourceManager(\n options: CreateRestDatasourceManagerOptions,\n): DatasourceManagerBackend {\n const fetchImpl = options.fetch ?? fetch\n const baseUrl = options.baseUrl.replace(/\\/$/, '')\n const paths = mergeRestPaths(options.paths)\n\n async function send<T>(\n path: string,\n init: RequestInit,\n context?: DatasourceContext,\n ): Promise<T> {\n const response = await fetchImpl(`${baseUrl}${path}`, {\n ...init,\n headers: await requestHeaders(options, context),\n ...(context?.signal ? { signal: context.signal } : {}),\n })\n return parseResponse<T>(response, options)\n }\n\n return {\n types: {\n list: (context) => send<DatasourceTypeInfo[]>(paths.typesList(), { method: 'GET' }, context),\n get: (type, context) => send<DatasourceTypeInfo>(paths.typeGet(type), { method: 'GET' }, context),\n install: (type, context) => send<void>(paths.typeAction(type, 'install'), { method: 'POST' }, context),\n uninstall: (type, context) => send<void>(paths.typeAction(type, 'uninstall'), { method: 'POST' }, context),\n enable: (type, context) => send<void>(paths.typeAction(type, 'enable'), { method: 'POST' }, context),\n disable: (type, context) => send<void>(paths.typeAction(type, 'disable'), { method: 'POST' }, context),\n },\n instances: {\n list: (options, context) => send<DatasourceListResult>(paths.instancesList(queryString(options)), { method: 'GET' }, context),\n get: (uid, context) => send<DatasourceInstance>(paths.instanceGet(uid), { method: 'GET' }, context),\n create: (input, context) => send<DatasourceInstance>(paths.instanceCreate(), {\n method: 'POST',\n body: JSON.stringify(input),\n }, context),\n update: (uid, patch, context) => send<DatasourceInstance>(paths.instanceUpdate(uid), {\n method: 'PATCH',\n body: JSON.stringify(patch),\n }, context),\n delete: (uid, context) => send<void>(paths.instanceDelete(uid), { method: 'DELETE' }, context),\n },\n query: (request, context) => send<unknown>(paths.query(), {\n method: 'POST',\n body: JSON.stringify(request),\n }, context),\n healthCheck: (uid, context) => send<DatasourceHealthResult>(paths.healthCheck(uid), { method: 'GET' }, context),\n validateQuery: (uid, query, context) => send<DatasourceValidationResult>(paths.validateQuery(uid), {\n method: 'POST',\n body: JSON.stringify(query),\n }, context),\n listNamespaces: (uid, context) => send<DatasourceSchemaNamespace[]>(paths.listNamespaces(uid), { method: 'GET' }, context),\n listFields: (uid, request, context) => send<DatasourceSchemaField[]>(paths.listFields(uid), {\n method: 'POST',\n body: JSON.stringify(request),\n }, context),\n }\n}\n","import type {\n DataQuery,\n DatasourceContext,\n DatasourceHealthResult,\n DatasourceInstance,\n DatasourceSchemaField,\n DatasourceSchemaFieldRequest,\n DatasourceSchemaNamespace,\n DatasourceValidationResult,\n QueryResult,\n} from './types'\n\nexport interface DatasourceConfigEditorProps<TOptions = unknown> {\n instance: DatasourceInstance<TOptions>\n options: TOptions\n onChange(options: TOptions): void\n onSave(): void\n}\n\nexport interface DatasourceQueryEditorProps<TOptions = unknown, TQuery = unknown> {\n instance: DatasourceInstance<TOptions>\n query: TQuery\n onChange(query: TQuery): void\n onRunQuery(): void\n}\n\nexport interface DatasourcePluginBackend<TOptions = unknown, TQuery = unknown> {\n query?(request: DataQuery<TQuery>, context?: DatasourceContext): Promise<unknown>\n transform?(\n raw: unknown,\n request: DataQuery<TQuery>,\n context?: DatasourceContext,\n ): QueryResult | Promise<QueryResult>\n healthCheck?(\n uid: string,\n options: TOptions,\n context?: DatasourceContext,\n ): Promise<DatasourceHealthResult>\n validateQuery?(\n uid: string,\n query: TQuery,\n context?: DatasourceContext,\n ): Promise<DatasourceValidationResult>\n listNamespaces?(\n uid: string,\n options: TOptions,\n context?: DatasourceContext,\n ): Promise<DatasourceSchemaNamespace[]>\n listFields?(\n uid: string,\n request: DatasourceSchemaFieldRequest,\n options: TOptions,\n context?: DatasourceContext,\n ): Promise<DatasourceSchemaField[]>\n}\n\nexport interface DatasourcePluginDef<TOptions = unknown, TQuery = unknown> {\n type: string\n name: string\n description?: string\n configEditor?(props: DatasourceConfigEditorProps<TOptions>): unknown\n queryEditor?(props: DatasourceQueryEditorProps<TOptions, TQuery>): unknown\n backend?: DatasourcePluginBackend<TOptions, TQuery>\n meta?: Record<string, unknown>\n}\n\nexport function defineDatasourcePlugin<TOptions = unknown, TQuery = unknown>(\n def: DatasourcePluginDef<TOptions, TQuery>,\n): DatasourcePluginDef<TOptions, TQuery> {\n return def\n}\n"]}