@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.
@@ -0,0 +1,168 @@
1
+ 'use strict';
2
+
3
+ // src/errors.ts
4
+ var DatasourceNotFoundError = class extends Error {
5
+ constructor(uid) {
6
+ super(`datasource "${uid}" not found`);
7
+ this.name = "DatasourceNotFoundError";
8
+ }
9
+ };
10
+ var DatasourceConflictError = class extends Error {
11
+ constructor(message = "datasource was modified by another actor") {
12
+ super(message);
13
+ this.name = "DatasourceConflictError";
14
+ }
15
+ };
16
+
17
+ // src/testing.ts
18
+ function nextVersion(current) {
19
+ return String(Number(current ?? "0") + 1);
20
+ }
21
+ function defaultTypes(seed) {
22
+ const seen = /* @__PURE__ */ new Set();
23
+ const types = [];
24
+ for (const instance of seed) {
25
+ if (seen.has(instance.type)) continue;
26
+ seen.add(instance.type);
27
+ types.push({
28
+ type: instance.type,
29
+ name: instance.type,
30
+ enabled: true,
31
+ installed: true
32
+ });
33
+ }
34
+ return types;
35
+ }
36
+ function createMemoryDatasourceBackend(options = {}) {
37
+ let store = (options.instances ?? []).map((d) => ({ ...d }));
38
+ let types = (options.types ?? defaultTypes(store)).map((t) => ({ ...t }));
39
+ function findType(type) {
40
+ const info = types.find((t) => t.type === type);
41
+ if (!info) throw new DatasourceNotFoundError(type);
42
+ return info;
43
+ }
44
+ function findInstance(uid) {
45
+ const ds = store.find((d) => d.uid === uid);
46
+ if (!ds) throw new DatasourceNotFoundError(uid);
47
+ return ds;
48
+ }
49
+ return {
50
+ types: {
51
+ async list() {
52
+ return types.map((t) => ({ ...t }));
53
+ },
54
+ async get(type) {
55
+ return { ...findType(type) };
56
+ },
57
+ async install(type) {
58
+ if (!types.some((t) => t.type === type)) {
59
+ types = [...types, { type, name: type, installed: true, enabled: false }];
60
+ }
61
+ },
62
+ async uninstall(type) {
63
+ findType(type);
64
+ types = types.filter((t) => t.type !== type);
65
+ },
66
+ async enable(type) {
67
+ const current = findType(type);
68
+ types = types.map((t) => t.type === type ? { ...current, enabled: true } : t);
69
+ },
70
+ async disable(type) {
71
+ const current = findType(type);
72
+ types = types.map((t) => t.type === type ? { ...current, enabled: false } : t);
73
+ }
74
+ },
75
+ instances: {
76
+ async list(listOptions) {
77
+ let items = [...store];
78
+ const filter = listOptions?.filter;
79
+ if (filter?.type !== void 0) {
80
+ const filterTypes = Array.isArray(filter.type) ? filter.type : [filter.type];
81
+ items = items.filter((d) => filterTypes.includes(d.type));
82
+ }
83
+ if (filter?.enabled !== void 0) {
84
+ items = items.filter((d) => (d.enabled ?? true) === filter.enabled);
85
+ }
86
+ if (filter?.search !== void 0) {
87
+ const query = filter.search.toLowerCase();
88
+ items = items.filter(
89
+ (d) => d.name.toLowerCase().includes(query) || d.uid.toLowerCase().includes(query)
90
+ );
91
+ }
92
+ const total = items.length;
93
+ if (listOptions?.page !== void 0 && listOptions?.pageSize !== void 0) {
94
+ const start = listOptions.page * listOptions.pageSize;
95
+ items = items.slice(start, start + listOptions.pageSize);
96
+ } else if (listOptions?.pageSize !== void 0) {
97
+ items = items.slice(0, listOptions.pageSize);
98
+ }
99
+ return { items: items.map((d) => ({ ...d })), total };
100
+ },
101
+ async get(uid) {
102
+ return { ...findInstance(uid) };
103
+ },
104
+ async create(input) {
105
+ const now = (/* @__PURE__ */ new Date()).toISOString();
106
+ const uid = input.uid ?? `ds-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
107
+ const ds = {
108
+ uid,
109
+ type: input.type,
110
+ name: input.name,
111
+ ...input.options !== void 0 ? { options: input.options } : {},
112
+ enabled: input.enabled ?? true,
113
+ ...input.meta !== void 0 ? { meta: input.meta } : {},
114
+ version: "1",
115
+ createdAt: now,
116
+ updatedAt: now
117
+ };
118
+ store = [...store, ds];
119
+ if (!types.some((t) => t.type === input.type)) {
120
+ types = [...types, { type: input.type, name: input.type, installed: true, enabled: true }];
121
+ }
122
+ return { ...ds };
123
+ },
124
+ async update(uid, patch) {
125
+ const idx = store.findIndex((d) => d.uid === uid);
126
+ if (idx === -1) throw new DatasourceNotFoundError(uid);
127
+ const ds = store[idx];
128
+ if (patch.version !== void 0 && ds.version !== patch.version) {
129
+ throw new DatasourceConflictError(
130
+ `"${uid}" version conflict: expected ${patch.version}, got ${ds.version}`
131
+ );
132
+ }
133
+ const updated = {
134
+ ...ds,
135
+ ...patch.name !== void 0 ? { name: patch.name } : {},
136
+ ...patch.options !== void 0 ? { options: patch.options } : {},
137
+ ...patch.enabled !== void 0 ? { enabled: patch.enabled } : {},
138
+ ...patch.meta !== void 0 ? { meta: patch.meta } : {},
139
+ version: nextVersion(ds.version),
140
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
141
+ };
142
+ store = [...store.slice(0, idx), updated, ...store.slice(idx + 1)];
143
+ return { ...updated };
144
+ },
145
+ async delete(uid) {
146
+ findInstance(uid);
147
+ store = store.filter((d) => d.uid !== uid);
148
+ }
149
+ },
150
+ async query(request) {
151
+ const ds = findInstance(request.datasourceUid);
152
+ return {
153
+ columns: [
154
+ { name: "name", type: "string" },
155
+ { name: "type", type: "string" },
156
+ { name: "version", type: "string" }
157
+ ],
158
+ rows: [[ds.name, ds.type, ds.version ?? ""]],
159
+ requestId: request.id,
160
+ meta: { datasourceUid: ds.uid }
161
+ };
162
+ }
163
+ };
164
+ }
165
+
166
+ exports.createMemoryDatasourceBackend = createMemoryDatasourceBackend;
167
+ //# sourceMappingURL=testing.cjs.map
168
+ //# sourceMappingURL=testing.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/testing.ts"],"names":[],"mappings":"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","file":"testing.cjs","sourcesContent":["export class DatasourceNotFoundError extends Error {\n constructor(uid: string) {\n super(`datasource \"${uid}\" not found`)\n this.name = 'DatasourceNotFoundError'\n }\n}\n\nexport class DatasourceCapabilityError extends Error {\n constructor(uid: string, capability: string) {\n super(`datasource \"${uid}\" does not support ${capability}`)\n this.name = 'DatasourceCapabilityError'\n }\n}\n\nexport class DatasourceTypeNotRegisteredError extends Error {\n constructor(type: string) {\n super(`datasource type \"${type}\" is not registered`)\n this.name = 'DatasourceTypeNotRegisteredError'\n }\n}\n\nexport class DatasourceUnauthorizedError extends Error {\n constructor(message = 'datasource request is not authenticated') {\n super(message)\n this.name = 'DatasourceUnauthorizedError'\n }\n}\n\nexport class DatasourceForbiddenError extends Error {\n constructor(message = 'datasource request is not allowed') {\n super(message)\n this.name = 'DatasourceForbiddenError'\n }\n}\n\nexport class DatasourceConflictError extends Error {\n constructor(message = 'datasource was modified by another actor') {\n super(message)\n this.name = 'DatasourceConflictError'\n }\n}\n\nexport class DatasourceValidationError extends Error {\n constructor(\n message = 'datasource validation failed',\n readonly errors?: string[],\n ) {\n super(message)\n this.name = 'DatasourceValidationError'\n }\n}\n\nexport class DatasourceTransportError extends Error {\n constructor(\n message = 'datasource backend request failed',\n readonly status?: number,\n ) {\n super(message)\n this.name = 'DatasourceTransportError'\n }\n}\n","import { DatasourceConflictError, DatasourceNotFoundError } from './errors'\nimport type { DatasourceManagerBackend } from './manager'\nimport type {\n DataQuery,\n DatasourceCreateInput,\n DatasourceInstance,\n DatasourceListOptions,\n DatasourceListResult,\n DatasourceTypeInfo,\n DatasourceUpdateInput,\n QueryResult,\n} from './types'\n\nfunction nextVersion(current?: string): string {\n return String(Number(current ?? '0') + 1)\n}\n\nfunction defaultTypes(seed: DatasourceInstance[]): DatasourceTypeInfo[] {\n const seen = new Set<string>()\n const types: DatasourceTypeInfo[] = []\n for (const instance of seed) {\n if (seen.has(instance.type)) continue\n seen.add(instance.type)\n types.push({\n type: instance.type,\n name: instance.type,\n enabled: true,\n installed: true,\n })\n }\n return types\n}\n\nexport interface CreateMemoryDatasourceBackendOptions {\n instances?: DatasourceInstance[]\n types?: DatasourceTypeInfo[]\n}\n\nexport function createMemoryDatasourceBackend(\n options: CreateMemoryDatasourceBackendOptions = {},\n): DatasourceManagerBackend {\n let store: DatasourceInstance[] = (options.instances ?? []).map((d) => ({ ...d }))\n let types: DatasourceTypeInfo[] = (options.types ?? defaultTypes(store)).map((t) => ({ ...t }))\n\n function findType(type: string): DatasourceTypeInfo {\n const info = types.find((t) => t.type === type)\n if (!info) throw new DatasourceNotFoundError(type)\n return info\n }\n\n function findInstance(uid: string): DatasourceInstance {\n const ds = store.find((d) => d.uid === uid)\n if (!ds) throw new DatasourceNotFoundError(uid)\n return ds\n }\n\n return {\n types: {\n async list() {\n return types.map((t) => ({ ...t }))\n },\n\n async get(type) {\n return { ...findType(type) }\n },\n\n async install(type) {\n if (!types.some((t) => t.type === type)) {\n types = [...types, { type, name: type, installed: true, enabled: false }]\n }\n },\n\n async uninstall(type) {\n findType(type)\n types = types.filter((t) => t.type !== type)\n },\n\n async enable(type) {\n const current = findType(type)\n types = types.map((t) => t.type === type ? { ...current, enabled: true } : t)\n },\n\n async disable(type) {\n const current = findType(type)\n types = types.map((t) => t.type === type ? { ...current, enabled: false } : t)\n },\n },\n\n instances: {\n async list(listOptions?: DatasourceListOptions): Promise<DatasourceListResult> {\n let items = [...store]\n const filter = listOptions?.filter\n if (filter?.type !== undefined) {\n const filterTypes = Array.isArray(filter.type) ? filter.type : [filter.type]\n items = items.filter((d) => filterTypes.includes(d.type))\n }\n if (filter?.enabled !== undefined) {\n items = items.filter((d) => (d.enabled ?? true) === filter.enabled)\n }\n if (filter?.search !== undefined) {\n const query = filter.search.toLowerCase()\n items = items.filter(\n (d) => d.name.toLowerCase().includes(query) || d.uid.toLowerCase().includes(query),\n )\n }\n const total = items.length\n if (listOptions?.page !== undefined && listOptions?.pageSize !== undefined) {\n const start = listOptions.page * listOptions.pageSize\n items = items.slice(start, start + listOptions.pageSize)\n } else if (listOptions?.pageSize !== undefined) {\n items = items.slice(0, listOptions.pageSize)\n }\n return { items: items.map((d) => ({ ...d })), total }\n },\n\n async get(uid) {\n return { ...findInstance(uid) }\n },\n\n async create(input: DatasourceCreateInput) {\n const now = new Date().toISOString()\n const uid = input.uid ?? `ds-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`\n const ds: DatasourceInstance = {\n uid,\n type: input.type,\n name: input.name,\n ...(input.options !== undefined ? { options: input.options } : {}),\n enabled: input.enabled ?? true,\n ...(input.meta !== undefined ? { meta: input.meta } : {}),\n version: '1',\n createdAt: now,\n updatedAt: now,\n }\n store = [...store, ds]\n if (!types.some((t) => t.type === input.type)) {\n types = [...types, { type: input.type, name: input.type, installed: true, enabled: true }]\n }\n return { ...ds }\n },\n\n async update(uid, patch: DatasourceUpdateInput) {\n const idx = store.findIndex((d) => d.uid === uid)\n if (idx === -1) throw new DatasourceNotFoundError(uid)\n const ds = store[idx]\n if (patch.version !== undefined && ds.version !== patch.version) {\n throw new DatasourceConflictError(\n `\"${uid}\" version conflict: expected ${patch.version}, got ${ds.version}`,\n )\n }\n const updated: DatasourceInstance = {\n ...ds,\n ...(patch.name !== undefined ? { name: patch.name } : {}),\n ...(patch.options !== undefined ? { options: patch.options } : {}),\n ...(patch.enabled !== undefined ? { enabled: patch.enabled } : {}),\n ...(patch.meta !== undefined ? { meta: patch.meta } : {}),\n version: nextVersion(ds.version),\n updatedAt: new Date().toISOString(),\n }\n store = [...store.slice(0, idx), updated, ...store.slice(idx + 1)]\n return { ...updated }\n },\n\n async delete(uid) {\n findInstance(uid)\n store = store.filter((d) => d.uid !== uid)\n },\n },\n\n async query(request: DataQuery): Promise<QueryResult> {\n const ds = findInstance(request.datasourceUid)\n return {\n columns: [\n { name: 'name', type: 'string' },\n { name: 'type', type: 'string' },\n { name: 'version', type: 'string' },\n ],\n rows: [[ds.name, ds.type, ds.version ?? '']],\n requestId: request.id,\n meta: { datasourceUid: ds.uid },\n }\n },\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { j as DatasourceInstance, z as DatasourceTypeInfo, o as DatasourceManagerBackend } from './manager-C5PgvWNH.cjs';
2
+
3
+ interface CreateMemoryDatasourceBackendOptions {
4
+ instances?: DatasourceInstance[];
5
+ types?: DatasourceTypeInfo[];
6
+ }
7
+ declare function createMemoryDatasourceBackend(options?: CreateMemoryDatasourceBackendOptions): DatasourceManagerBackend;
8
+
9
+ export { type CreateMemoryDatasourceBackendOptions, createMemoryDatasourceBackend };
@@ -0,0 +1,9 @@
1
+ import { j as DatasourceInstance, z as DatasourceTypeInfo, o as DatasourceManagerBackend } from './manager-C5PgvWNH.js';
2
+
3
+ interface CreateMemoryDatasourceBackendOptions {
4
+ instances?: DatasourceInstance[];
5
+ types?: DatasourceTypeInfo[];
6
+ }
7
+ declare function createMemoryDatasourceBackend(options?: CreateMemoryDatasourceBackendOptions): DatasourceManagerBackend;
8
+
9
+ export { type CreateMemoryDatasourceBackendOptions, createMemoryDatasourceBackend };
@@ -0,0 +1,154 @@
1
+ import { DatasourceNotFoundError, DatasourceConflictError } from './chunk-Z2DGIUJ2.js';
2
+
3
+ // src/testing.ts
4
+ function nextVersion(current) {
5
+ return String(Number(current ?? "0") + 1);
6
+ }
7
+ function defaultTypes(seed) {
8
+ const seen = /* @__PURE__ */ new Set();
9
+ const types = [];
10
+ for (const instance of seed) {
11
+ if (seen.has(instance.type)) continue;
12
+ seen.add(instance.type);
13
+ types.push({
14
+ type: instance.type,
15
+ name: instance.type,
16
+ enabled: true,
17
+ installed: true
18
+ });
19
+ }
20
+ return types;
21
+ }
22
+ function createMemoryDatasourceBackend(options = {}) {
23
+ let store = (options.instances ?? []).map((d) => ({ ...d }));
24
+ let types = (options.types ?? defaultTypes(store)).map((t) => ({ ...t }));
25
+ function findType(type) {
26
+ const info = types.find((t) => t.type === type);
27
+ if (!info) throw new DatasourceNotFoundError(type);
28
+ return info;
29
+ }
30
+ function findInstance(uid) {
31
+ const ds = store.find((d) => d.uid === uid);
32
+ if (!ds) throw new DatasourceNotFoundError(uid);
33
+ return ds;
34
+ }
35
+ return {
36
+ types: {
37
+ async list() {
38
+ return types.map((t) => ({ ...t }));
39
+ },
40
+ async get(type) {
41
+ return { ...findType(type) };
42
+ },
43
+ async install(type) {
44
+ if (!types.some((t) => t.type === type)) {
45
+ types = [...types, { type, name: type, installed: true, enabled: false }];
46
+ }
47
+ },
48
+ async uninstall(type) {
49
+ findType(type);
50
+ types = types.filter((t) => t.type !== type);
51
+ },
52
+ async enable(type) {
53
+ const current = findType(type);
54
+ types = types.map((t) => t.type === type ? { ...current, enabled: true } : t);
55
+ },
56
+ async disable(type) {
57
+ const current = findType(type);
58
+ types = types.map((t) => t.type === type ? { ...current, enabled: false } : t);
59
+ }
60
+ },
61
+ instances: {
62
+ async list(listOptions) {
63
+ let items = [...store];
64
+ const filter = listOptions?.filter;
65
+ if (filter?.type !== void 0) {
66
+ const filterTypes = Array.isArray(filter.type) ? filter.type : [filter.type];
67
+ items = items.filter((d) => filterTypes.includes(d.type));
68
+ }
69
+ if (filter?.enabled !== void 0) {
70
+ items = items.filter((d) => (d.enabled ?? true) === filter.enabled);
71
+ }
72
+ if (filter?.search !== void 0) {
73
+ const query = filter.search.toLowerCase();
74
+ items = items.filter(
75
+ (d) => d.name.toLowerCase().includes(query) || d.uid.toLowerCase().includes(query)
76
+ );
77
+ }
78
+ const total = items.length;
79
+ if (listOptions?.page !== void 0 && listOptions?.pageSize !== void 0) {
80
+ const start = listOptions.page * listOptions.pageSize;
81
+ items = items.slice(start, start + listOptions.pageSize);
82
+ } else if (listOptions?.pageSize !== void 0) {
83
+ items = items.slice(0, listOptions.pageSize);
84
+ }
85
+ return { items: items.map((d) => ({ ...d })), total };
86
+ },
87
+ async get(uid) {
88
+ return { ...findInstance(uid) };
89
+ },
90
+ async create(input) {
91
+ const now = (/* @__PURE__ */ new Date()).toISOString();
92
+ const uid = input.uid ?? `ds-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
93
+ const ds = {
94
+ uid,
95
+ type: input.type,
96
+ name: input.name,
97
+ ...input.options !== void 0 ? { options: input.options } : {},
98
+ enabled: input.enabled ?? true,
99
+ ...input.meta !== void 0 ? { meta: input.meta } : {},
100
+ version: "1",
101
+ createdAt: now,
102
+ updatedAt: now
103
+ };
104
+ store = [...store, ds];
105
+ if (!types.some((t) => t.type === input.type)) {
106
+ types = [...types, { type: input.type, name: input.type, installed: true, enabled: true }];
107
+ }
108
+ return { ...ds };
109
+ },
110
+ async update(uid, patch) {
111
+ const idx = store.findIndex((d) => d.uid === uid);
112
+ if (idx === -1) throw new DatasourceNotFoundError(uid);
113
+ const ds = store[idx];
114
+ if (patch.version !== void 0 && ds.version !== patch.version) {
115
+ throw new DatasourceConflictError(
116
+ `"${uid}" version conflict: expected ${patch.version}, got ${ds.version}`
117
+ );
118
+ }
119
+ const updated = {
120
+ ...ds,
121
+ ...patch.name !== void 0 ? { name: patch.name } : {},
122
+ ...patch.options !== void 0 ? { options: patch.options } : {},
123
+ ...patch.enabled !== void 0 ? { enabled: patch.enabled } : {},
124
+ ...patch.meta !== void 0 ? { meta: patch.meta } : {},
125
+ version: nextVersion(ds.version),
126
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
127
+ };
128
+ store = [...store.slice(0, idx), updated, ...store.slice(idx + 1)];
129
+ return { ...updated };
130
+ },
131
+ async delete(uid) {
132
+ findInstance(uid);
133
+ store = store.filter((d) => d.uid !== uid);
134
+ }
135
+ },
136
+ async query(request) {
137
+ const ds = findInstance(request.datasourceUid);
138
+ return {
139
+ columns: [
140
+ { name: "name", type: "string" },
141
+ { name: "type", type: "string" },
142
+ { name: "version", type: "string" }
143
+ ],
144
+ rows: [[ds.name, ds.type, ds.version ?? ""]],
145
+ requestId: request.id,
146
+ meta: { datasourceUid: ds.uid }
147
+ };
148
+ }
149
+ };
150
+ }
151
+
152
+ export { createMemoryDatasourceBackend };
153
+ //# sourceMappingURL=testing.js.map
154
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing.ts"],"names":[],"mappings":"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","file":"testing.js","sourcesContent":["import { DatasourceConflictError, DatasourceNotFoundError } from './errors'\nimport type { DatasourceManagerBackend } from './manager'\nimport type {\n DataQuery,\n DatasourceCreateInput,\n DatasourceInstance,\n DatasourceListOptions,\n DatasourceListResult,\n DatasourceTypeInfo,\n DatasourceUpdateInput,\n QueryResult,\n} from './types'\n\nfunction nextVersion(current?: string): string {\n return String(Number(current ?? '0') + 1)\n}\n\nfunction defaultTypes(seed: DatasourceInstance[]): DatasourceTypeInfo[] {\n const seen = new Set<string>()\n const types: DatasourceTypeInfo[] = []\n for (const instance of seed) {\n if (seen.has(instance.type)) continue\n seen.add(instance.type)\n types.push({\n type: instance.type,\n name: instance.type,\n enabled: true,\n installed: true,\n })\n }\n return types\n}\n\nexport interface CreateMemoryDatasourceBackendOptions {\n instances?: DatasourceInstance[]\n types?: DatasourceTypeInfo[]\n}\n\nexport function createMemoryDatasourceBackend(\n options: CreateMemoryDatasourceBackendOptions = {},\n): DatasourceManagerBackend {\n let store: DatasourceInstance[] = (options.instances ?? []).map((d) => ({ ...d }))\n let types: DatasourceTypeInfo[] = (options.types ?? defaultTypes(store)).map((t) => ({ ...t }))\n\n function findType(type: string): DatasourceTypeInfo {\n const info = types.find((t) => t.type === type)\n if (!info) throw new DatasourceNotFoundError(type)\n return info\n }\n\n function findInstance(uid: string): DatasourceInstance {\n const ds = store.find((d) => d.uid === uid)\n if (!ds) throw new DatasourceNotFoundError(uid)\n return ds\n }\n\n return {\n types: {\n async list() {\n return types.map((t) => ({ ...t }))\n },\n\n async get(type) {\n return { ...findType(type) }\n },\n\n async install(type) {\n if (!types.some((t) => t.type === type)) {\n types = [...types, { type, name: type, installed: true, enabled: false }]\n }\n },\n\n async uninstall(type) {\n findType(type)\n types = types.filter((t) => t.type !== type)\n },\n\n async enable(type) {\n const current = findType(type)\n types = types.map((t) => t.type === type ? { ...current, enabled: true } : t)\n },\n\n async disable(type) {\n const current = findType(type)\n types = types.map((t) => t.type === type ? { ...current, enabled: false } : t)\n },\n },\n\n instances: {\n async list(listOptions?: DatasourceListOptions): Promise<DatasourceListResult> {\n let items = [...store]\n const filter = listOptions?.filter\n if (filter?.type !== undefined) {\n const filterTypes = Array.isArray(filter.type) ? filter.type : [filter.type]\n items = items.filter((d) => filterTypes.includes(d.type))\n }\n if (filter?.enabled !== undefined) {\n items = items.filter((d) => (d.enabled ?? true) === filter.enabled)\n }\n if (filter?.search !== undefined) {\n const query = filter.search.toLowerCase()\n items = items.filter(\n (d) => d.name.toLowerCase().includes(query) || d.uid.toLowerCase().includes(query),\n )\n }\n const total = items.length\n if (listOptions?.page !== undefined && listOptions?.pageSize !== undefined) {\n const start = listOptions.page * listOptions.pageSize\n items = items.slice(start, start + listOptions.pageSize)\n } else if (listOptions?.pageSize !== undefined) {\n items = items.slice(0, listOptions.pageSize)\n }\n return { items: items.map((d) => ({ ...d })), total }\n },\n\n async get(uid) {\n return { ...findInstance(uid) }\n },\n\n async create(input: DatasourceCreateInput) {\n const now = new Date().toISOString()\n const uid = input.uid ?? `ds-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`\n const ds: DatasourceInstance = {\n uid,\n type: input.type,\n name: input.name,\n ...(input.options !== undefined ? { options: input.options } : {}),\n enabled: input.enabled ?? true,\n ...(input.meta !== undefined ? { meta: input.meta } : {}),\n version: '1',\n createdAt: now,\n updatedAt: now,\n }\n store = [...store, ds]\n if (!types.some((t) => t.type === input.type)) {\n types = [...types, { type: input.type, name: input.type, installed: true, enabled: true }]\n }\n return { ...ds }\n },\n\n async update(uid, patch: DatasourceUpdateInput) {\n const idx = store.findIndex((d) => d.uid === uid)\n if (idx === -1) throw new DatasourceNotFoundError(uid)\n const ds = store[idx]\n if (patch.version !== undefined && ds.version !== patch.version) {\n throw new DatasourceConflictError(\n `\"${uid}\" version conflict: expected ${patch.version}, got ${ds.version}`,\n )\n }\n const updated: DatasourceInstance = {\n ...ds,\n ...(patch.name !== undefined ? { name: patch.name } : {}),\n ...(patch.options !== undefined ? { options: patch.options } : {}),\n ...(patch.enabled !== undefined ? { enabled: patch.enabled } : {}),\n ...(patch.meta !== undefined ? { meta: patch.meta } : {}),\n version: nextVersion(ds.version),\n updatedAt: new Date().toISOString(),\n }\n store = [...store.slice(0, idx), updated, ...store.slice(idx + 1)]\n return { ...updated }\n },\n\n async delete(uid) {\n findInstance(uid)\n store = store.filter((d) => d.uid !== uid)\n },\n },\n\n async query(request: DataQuery): Promise<QueryResult> {\n const ds = findInstance(request.datasourceUid)\n return {\n columns: [\n { name: 'name', type: 'string' },\n { name: 'type', type: 'string' },\n { name: 'version', type: 'string' },\n ],\n rows: [[ds.name, ds.type, ds.version ?? '']],\n requestId: request.id,\n meta: { datasourceUid: ds.uid },\n }\n },\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@loykin/datasourcekit",
3
+ "version": "0.0.2",
4
+ "description": "Contract layer for datasource management and execution in dashboard, alert, and reporting tools",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./testing": {
16
+ "types": "./dist/testing.d.ts",
17
+ "import": "./dist/testing.js",
18
+ "require": "./dist/testing.cjs"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "keywords": [
25
+ "datasource",
26
+ "query",
27
+ "executor",
28
+ "data",
29
+ "plugin"
30
+ ],
31
+ "license": "MIT",
32
+ "devDependencies": {
33
+ "concurrently": "^9.2.1",
34
+ "tsup": "^8.4.0",
35
+ "typescript": "^6.0.3"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc -p tsconfig.build.json --noEmit && tsup",
39
+ "build:js": "tsup",
40
+ "dev": "concurrently \"tsup --watch\" \"pnpm playground\"",
41
+ "playground": "pnpm --dir playground dev",
42
+ "playground:build": "pnpm --dir playground build",
43
+ "test": "pnpm build && node --test test/*.test.mjs",
44
+ "test:consumer": "node scripts/verify-package-consumer.mjs",
45
+ "type-check": "tsc -p tsconfig.json --noEmit"
46
+ }
47
+ }