@neupgroup/mapper 1.1.0 → 1.2.1

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/env.js ADDED
@@ -0,0 +1,88 @@
1
+ function stripComments(input) {
2
+ return input
3
+ .split(/\r?\n/)
4
+ .map(line => line.replace(/#.*$/, ''))
5
+ .join('\n');
6
+ }
7
+ function unquote(val) {
8
+ const trimmed = val.trim();
9
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
10
+ return trimmed.slice(1, -1);
11
+ }
12
+ return trimmed;
13
+ }
14
+ /**
15
+ * Parse a simple DSL of the form:
16
+ * connections = [
17
+ * connectionName = [
18
+ * key: value,
19
+ * key2: "value2",
20
+ * ],
21
+ * other = [
22
+ * type: SQL,
23
+ * host: localhost,
24
+ * ]
25
+ * ]
26
+ */
27
+ export function parseConnectionsDsl(text) {
28
+ const cleaned = stripComments(text);
29
+ const result = {};
30
+ // Find the connections block
31
+ const match = cleaned.match(/connections\s*=\s*\[/i);
32
+ if (!match)
33
+ return result;
34
+ // Extract everything after 'connections = [' and before the final ']'
35
+ const start = match.index + match[0].length;
36
+ const after = cleaned.slice(start);
37
+ // naive bracket balance to find end of top-level list
38
+ let depth = 1;
39
+ let endIndex = -1;
40
+ for (let i = 0; i < after.length; i++) {
41
+ const ch = after[i];
42
+ if (ch === '[')
43
+ depth++;
44
+ else if (ch === ']') {
45
+ depth--;
46
+ if (depth === 0) {
47
+ endIndex = i;
48
+ break;
49
+ }
50
+ }
51
+ }
52
+ const inner = endIndex >= 0 ? after.slice(0, endIndex) : after;
53
+ // Split by connection assignments at top level: name = [ ... ]
54
+ const connBlocks = inner.split(/\],?/).map(s => s.trim()).filter(Boolean);
55
+ for (const block of connBlocks) {
56
+ const assign = block.match(/^(\w[\w-]*)\s*=\s*\[/);
57
+ if (!assign)
58
+ continue;
59
+ const name = assign[1];
60
+ const content = block.slice(assign[0].length); // inside the [ ...
61
+ const lines = content.split(/\r?\n|,/).map(l => l.trim()).filter(l => l.length);
62
+ const map = {};
63
+ for (const line of lines) {
64
+ const kv = line.match(/^(\w[\w-]*)\s*:\s*(.+)$/);
65
+ if (!kv)
66
+ continue;
67
+ const key = kv[1];
68
+ const value = unquote(kv[2].replace(/,\s*$/, ''));
69
+ map[key] = value;
70
+ }
71
+ result[name] = map;
72
+ }
73
+ return result;
74
+ }
75
+ /**
76
+ * Convert DSL map to normalized connections compatible with library Connections.
77
+ * If no explicit type is provided, defaults to 'api'.
78
+ */
79
+ export function toNormalizedConnections(map) {
80
+ const conns = [];
81
+ for (const [name, kv] of Object.entries(map)) {
82
+ const rawType = (kv['type'] || kv['dbType'] || '').toLowerCase();
83
+ const type = ['mysql', 'sql', 'firestore', 'mongodb', 'api'].includes(rawType) ? rawType : 'api';
84
+ const { type: _omitType, dbType: _omitDbType, ...rest } = kv;
85
+ conns.push({ name, type, key: rest });
86
+ }
87
+ return conns;
88
+ }
@@ -0,0 +1,91 @@
1
+ import type { DbAdapter, QueryOptions } from './orm';
2
+ export type ColumnType = 'string' | 'number' | 'boolean' | 'date' | 'int';
3
+ export type ConnectionType = 'mysql' | 'sql' | 'firestore' | 'mongodb' | 'api';
4
+ export interface Field {
5
+ name: string;
6
+ type: ColumnType;
7
+ editable?: boolean;
8
+ autoIncrement?: boolean;
9
+ nullable?: boolean;
10
+ defaultValue?: unknown;
11
+ }
12
+ export interface SchemaDef {
13
+ name: string;
14
+ connectionName: string;
15
+ collectionName: string;
16
+ fields: Field[];
17
+ allowUndefinedFields?: boolean;
18
+ }
19
+ interface ConnectionConfig {
20
+ name: string;
21
+ type: ConnectionType;
22
+ key: Record<string, any>;
23
+ }
24
+ declare class ConnectionBuilder {
25
+ private manager;
26
+ private name;
27
+ private type;
28
+ constructor(manager: Connections, name: string, type: ConnectionType);
29
+ key(config: Record<string, any>): Connections;
30
+ }
31
+ export declare class Connections {
32
+ private connections;
33
+ private adapters;
34
+ create(name: string, type: ConnectionType): ConnectionBuilder;
35
+ register(config: ConnectionConfig): this;
36
+ attachAdapter(name: string, adapter: DbAdapter): this;
37
+ get(name: string): ConnectionConfig | undefined;
38
+ getAdapter(name: string): DbAdapter | undefined;
39
+ list(): ConnectionConfig[];
40
+ }
41
+ declare class SchemaBuilder {
42
+ private manager;
43
+ private name;
44
+ private connectionName?;
45
+ private collectionName?;
46
+ private fields;
47
+ private allowUndefinedFields;
48
+ constructor(manager: SchemaManager, name: string);
49
+ use(options: {
50
+ connection: string;
51
+ collection: string;
52
+ }): this;
53
+ setStructure(structure: Record<string, string> | Field[]): SchemaManager;
54
+ }
55
+ declare class SchemaQuery {
56
+ private manager;
57
+ private def;
58
+ private filters;
59
+ private rawWhere;
60
+ private pendingUpdate;
61
+ constructor(manager: SchemaManager, def: SchemaDef);
62
+ where(fieldOrPair: string | [string, any], value?: any, operator?: string): this;
63
+ whereComplex(raw: string): this;
64
+ private buildOptions;
65
+ to(update: Record<string, any>): this;
66
+ get(): Promise<Record<string, any>[]>;
67
+ getOne(): Promise<Record<string, any> | null>;
68
+ add(data: Record<string, any>): Promise<string>;
69
+ delete(): Promise<void>;
70
+ deleteOne(): Promise<void>;
71
+ update(): Promise<void>;
72
+ updateOne(): Promise<void>;
73
+ }
74
+ export declare class SchemaManager {
75
+ private connections;
76
+ private schemas;
77
+ constructor(connections: Connections);
78
+ create(name: string): SchemaBuilder;
79
+ register(def: SchemaDef): this;
80
+ use(name: string): SchemaQuery;
81
+ getAdapter(connectionName: string): DbAdapter | undefined;
82
+ list(): SchemaDef[];
83
+ }
84
+ export declare function connection(): Connections;
85
+ export declare function schema(conns?: Connections): SchemaManager;
86
+ export declare const schemas: SchemaManager;
87
+ export { createOrm } from './orm';
88
+ export type { DbAdapter, QueryOptions };
89
+ export { parseConnectionsDsl, toNormalizedConnections } from './env';
90
+ export type { EnvDslConnections, NormalizedConnection } from './env';
91
+ export { documentationMd, markdownToHtml, getDocumentationHtml } from './docs';
package/dist/index.js ADDED
@@ -0,0 +1,280 @@
1
+ class AdapterRegistry {
2
+ constructor() {
3
+ this.adaptersByConnection = new Map();
4
+ }
5
+ attach(connectionName, adapter) {
6
+ this.adaptersByConnection.set(connectionName, adapter);
7
+ }
8
+ get(connectionName) {
9
+ return this.adaptersByConnection.get(connectionName);
10
+ }
11
+ }
12
+ class ConnectionBuilder {
13
+ constructor(manager, name, type) {
14
+ this.manager = manager;
15
+ this.name = name;
16
+ this.type = type;
17
+ }
18
+ key(config) {
19
+ this.manager.register({ name: this.name, type: this.type, key: config });
20
+ return this.manager;
21
+ }
22
+ }
23
+ export class Connections {
24
+ constructor() {
25
+ this.connections = new Map();
26
+ this.adapters = new AdapterRegistry();
27
+ }
28
+ create(name, type) {
29
+ if (this.connections.has(name)) {
30
+ throw new Error(`Connection with name '${name}' already exists`);
31
+ }
32
+ return new ConnectionBuilder(this, name, type);
33
+ }
34
+ register(config) {
35
+ if (this.connections.has(config.name)) {
36
+ throw new Error(`Connection with name '${config.name}' already exists`);
37
+ }
38
+ this.connections.set(config.name, config);
39
+ return this;
40
+ }
41
+ attachAdapter(name, adapter) {
42
+ if (!this.connections.has(name)) {
43
+ throw new Error(`Cannot attach adapter: unknown connection '${name}'`);
44
+ }
45
+ this.adapters.attach(name, adapter);
46
+ return this;
47
+ }
48
+ get(name) {
49
+ return this.connections.get(name);
50
+ }
51
+ getAdapter(name) {
52
+ return this.adapters.get(name);
53
+ }
54
+ list() {
55
+ return Array.from(this.connections.values());
56
+ }
57
+ }
58
+ function parseDescriptorStructure(struct) {
59
+ let allowUndefinedFields = false;
60
+ const fields = [];
61
+ for (const [key, descriptor] of Object.entries(struct)) {
62
+ if (key === '?field') {
63
+ // Presence of '?field' enables accepting fields not defined in the schema
64
+ allowUndefinedFields = true;
65
+ continue;
66
+ }
67
+ const tokens = descriptor.split(/\s+/).map(t => t.trim().toLowerCase()).filter(Boolean);
68
+ const field = {
69
+ name: key,
70
+ type: tokens.find(t => ['string', 'number', 'boolean', 'date', 'int'].includes(t)) || 'string',
71
+ editable: tokens.includes('editable'),
72
+ autoIncrement: tokens.includes('auto_increment') || tokens.includes('autoincrement'),
73
+ };
74
+ fields.push(field);
75
+ }
76
+ return { fields, allowUndefinedFields };
77
+ }
78
+ class SchemaBuilder {
79
+ constructor(manager, name) {
80
+ this.manager = manager;
81
+ this.name = name;
82
+ this.fields = [];
83
+ this.allowUndefinedFields = false;
84
+ }
85
+ use(options) {
86
+ this.connectionName = options.connection;
87
+ this.collectionName = options.collection;
88
+ return this;
89
+ }
90
+ setStructure(structure) {
91
+ if (Array.isArray(structure)) {
92
+ this.fields = structure;
93
+ this.allowUndefinedFields = false;
94
+ }
95
+ else {
96
+ const parsed = parseDescriptorStructure(structure);
97
+ this.fields = parsed.fields;
98
+ this.allowUndefinedFields = parsed.allowUndefinedFields;
99
+ }
100
+ // Finalize schema registration
101
+ if (!this.connectionName || !this.collectionName) {
102
+ throw new Error('Schema.use({ connection, collection }) must be set before setStructure');
103
+ }
104
+ this.manager.register({
105
+ name: this.name,
106
+ connectionName: this.connectionName,
107
+ collectionName: this.collectionName,
108
+ fields: this.fields,
109
+ allowUndefinedFields: this.allowUndefinedFields,
110
+ });
111
+ return this.manager;
112
+ }
113
+ }
114
+ class SchemaQuery {
115
+ constructor(manager, def) {
116
+ this.manager = manager;
117
+ this.def = def;
118
+ this.filters = [];
119
+ this.rawWhere = null;
120
+ this.pendingUpdate = null;
121
+ }
122
+ // where('field','value', operator?) or where([field, value])
123
+ where(fieldOrPair, value, operator) {
124
+ if (Array.isArray(fieldOrPair)) {
125
+ const [field, v] = fieldOrPair;
126
+ this.filters.push({ field, operator: '=', value: v });
127
+ }
128
+ else {
129
+ const field = fieldOrPair;
130
+ this.filters.push({ field, operator: operator !== null && operator !== void 0 ? operator : '=', value });
131
+ }
132
+ return this;
133
+ }
134
+ // Accept a raw complex where clause string
135
+ whereComplex(raw) {
136
+ this.rawWhere = raw;
137
+ return this;
138
+ }
139
+ buildOptions() {
140
+ return {
141
+ collectionName: this.def.collectionName,
142
+ filters: this.filters.map(f => ({ field: f.field, operator: f.operator, value: f.value })),
143
+ limit: null,
144
+ offset: null,
145
+ sortBy: null,
146
+ fields: this.def.fields.map(f => f.name),
147
+ rawWhere: this.rawWhere,
148
+ };
149
+ }
150
+ to(update) {
151
+ this.pendingUpdate = update;
152
+ return this;
153
+ }
154
+ async get() {
155
+ const adapter = this.manager.getAdapter(this.def.connectionName);
156
+ if (!adapter)
157
+ throw new Error(`No adapter attached for connection '${this.def.connectionName}'`);
158
+ const options = this.buildOptions();
159
+ const docs = adapter.get ? await adapter.get(options) : await adapter.getDocuments(options);
160
+ return docs;
161
+ }
162
+ async getOne() {
163
+ var _a;
164
+ const adapter = this.manager.getAdapter(this.def.connectionName);
165
+ if (!adapter)
166
+ throw new Error(`No adapter attached for connection '${this.def.connectionName}'`);
167
+ const options = this.buildOptions();
168
+ if (adapter.getOne) {
169
+ const one = await adapter.getOne(options);
170
+ return (_a = one) !== null && _a !== void 0 ? _a : null;
171
+ }
172
+ const results = adapter.get ? await adapter.get(options) : await adapter.getDocuments(options);
173
+ return results[0] || null;
174
+ }
175
+ async add(data) {
176
+ const adapter = this.manager.getAdapter(this.def.connectionName);
177
+ if (!adapter)
178
+ throw new Error(`No adapter attached for connection '${this.def.connectionName}'`);
179
+ if (!this.def.allowUndefinedFields) {
180
+ const allowed = new Set(this.def.fields.map(f => f.name));
181
+ data = Object.fromEntries(Object.entries(data).filter(([k]) => allowed.has(k)));
182
+ }
183
+ return adapter.addDocument(this.def.collectionName, data);
184
+ }
185
+ async delete() {
186
+ const adapter = this.manager.getAdapter(this.def.connectionName);
187
+ if (!adapter)
188
+ throw new Error(`No adapter attached for connection '${this.def.connectionName}'`);
189
+ const docs = await this.get();
190
+ // Expect each doc has an 'id' field
191
+ for (const d of docs) {
192
+ const id = d.id;
193
+ if (!id)
194
+ throw new Error('Document missing id; cannot delete');
195
+ await adapter.deleteDocument(this.def.collectionName, id);
196
+ }
197
+ }
198
+ async deleteOne() {
199
+ const one = await this.getOne();
200
+ if (!one)
201
+ return;
202
+ const adapter = this.manager.getAdapter(this.def.connectionName);
203
+ if (!adapter)
204
+ throw new Error(`No adapter attached for connection '${this.def.connectionName}'`);
205
+ const id = one.id;
206
+ if (!id)
207
+ throw new Error('Document missing id; cannot deleteOne');
208
+ await adapter.deleteDocument(this.def.collectionName, id);
209
+ }
210
+ async update() {
211
+ const adapter = this.manager.getAdapter(this.def.connectionName);
212
+ if (!adapter)
213
+ throw new Error(`No adapter attached for connection '${this.def.connectionName}'`);
214
+ if (!this.pendingUpdate)
215
+ throw new Error('No update payload set; call to({ ... }) first');
216
+ const docs = await this.get();
217
+ for (const d of docs) {
218
+ const id = d.id;
219
+ if (!id)
220
+ throw new Error('Document missing id; cannot update');
221
+ await adapter.updateDocument(this.def.collectionName, id, this.pendingUpdate);
222
+ }
223
+ }
224
+ async updateOne() {
225
+ const adapter = this.manager.getAdapter(this.def.connectionName);
226
+ if (!adapter)
227
+ throw new Error(`No adapter attached for connection '${this.def.connectionName}'`);
228
+ if (!this.pendingUpdate)
229
+ throw new Error('No update payload set; call to({ ... }) first');
230
+ const one = await this.getOne();
231
+ if (!one)
232
+ return;
233
+ const id = one.id;
234
+ if (!id)
235
+ throw new Error('Document missing id; cannot updateOne');
236
+ await adapter.updateDocument(this.def.collectionName, id, this.pendingUpdate);
237
+ }
238
+ }
239
+ export class SchemaManager {
240
+ constructor(connections) {
241
+ this.connections = connections;
242
+ this.schemas = new Map();
243
+ }
244
+ create(name) {
245
+ if (this.schemas.has(name)) {
246
+ throw new Error(`Schema with name '${name}' already exists`);
247
+ }
248
+ return new SchemaBuilder(this, name);
249
+ }
250
+ register(def) {
251
+ this.schemas.set(def.name, def);
252
+ return this;
253
+ }
254
+ use(name) {
255
+ const def = this.schemas.get(name);
256
+ if (!def)
257
+ throw new Error(`Unknown schema '${name}'`);
258
+ return new SchemaQuery(this, def);
259
+ }
260
+ getAdapter(connectionName) {
261
+ return this.connections.getAdapter(connectionName);
262
+ }
263
+ list() {
264
+ return Array.from(this.schemas.values());
265
+ }
266
+ }
267
+ export function connection() {
268
+ return new Connections();
269
+ }
270
+ export function schema(conns) {
271
+ const ctx = conns || new Connections();
272
+ return new SchemaManager(ctx);
273
+ }
274
+ export const schemas = (() => {
275
+ const conns = new Connections();
276
+ return new SchemaManager(conns);
277
+ })();
278
+ export { createOrm } from './orm';
279
+ export { parseConnectionsDsl, toNormalizedConnections } from './env';
280
+ export { documentationMd, markdownToHtml, getDocumentationHtml } from './docs';
@@ -0,0 +1,10 @@
1
+ import type { DbAdapter, QueryOptions } from './types';
2
+ export declare function createOrm(adapter: DbAdapter): {
3
+ get(options: QueryOptions): Promise<import("@firebase/firestore").DocumentData[]>;
4
+ getOne(options: QueryOptions): Promise<any>;
5
+ getDocuments(options: QueryOptions): Promise<import("@firebase/firestore").DocumentData[]>;
6
+ addDocument(collectionName: string, data: Record<string, any>): Promise<string>;
7
+ updateDocument(collectionName: string, docId: string, data: Record<string, any>): Promise<void>;
8
+ deleteDocument(collectionName: string, docId: string): Promise<void>;
9
+ };
10
+ export type { DbAdapter, QueryOptions };
@@ -0,0 +1,28 @@
1
+ export function createOrm(adapter) {
2
+ return {
3
+ async get(options) {
4
+ if (adapter.get)
5
+ return adapter.get(options);
6
+ return adapter.getDocuments(options);
7
+ },
8
+ async getOne(options) {
9
+ var _a;
10
+ if (adapter.getOne)
11
+ return adapter.getOne(options);
12
+ const arr = adapter.get ? await adapter.get(options) : await adapter.getDocuments(options);
13
+ return (_a = arr[0]) !== null && _a !== void 0 ? _a : null;
14
+ },
15
+ async getDocuments(options) {
16
+ return adapter.getDocuments(options);
17
+ },
18
+ async addDocument(collectionName, data) {
19
+ return adapter.addDocument(collectionName, data);
20
+ },
21
+ async updateDocument(collectionName, docId, data) {
22
+ return adapter.updateDocument(collectionName, docId, data);
23
+ },
24
+ async deleteDocument(collectionName, docId) {
25
+ return adapter.deleteDocument(collectionName, docId);
26
+ },
27
+ };
28
+ }
@@ -0,0 +1,25 @@
1
+ import type { DocumentData } from 'firebase/firestore';
2
+ export interface QueryOptions {
3
+ collectionName: string;
4
+ filters: {
5
+ field: string;
6
+ operator: any;
7
+ value: any;
8
+ }[];
9
+ limit: number | null;
10
+ offset: number | null;
11
+ sortBy: {
12
+ field: string;
13
+ direction: 'asc' | 'desc';
14
+ } | null;
15
+ fields: string[];
16
+ rawWhere?: string | null;
17
+ }
18
+ export interface DbAdapter {
19
+ get?(options: QueryOptions): Promise<DocumentData[]>;
20
+ getOne?(options: QueryOptions): Promise<DocumentData | null>;
21
+ getDocuments(options: QueryOptions): Promise<DocumentData[]>;
22
+ addDocument(collectionName: string, data: DocumentData): Promise<string>;
23
+ updateDocument(collectionName: string, docId: string, data: DocumentData): Promise<void>;
24
+ deleteDocument(collectionName: string, docId: string): Promise<void>;
25
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,26 +1,20 @@
1
1
  {
2
2
  "name": "@neupgroup/mapper",
3
- "version": "1.1.0",
4
- "private": false,
3
+ "version": "1.2.1",
4
+ "description": "Neup.Mapper core library for schema and mapping utilities",
5
5
  "type": "module",
6
- "main": "index.js",
7
- "types": "index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./index.d.ts",
11
- "default": "./index.js"
12
- }
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "sideEffects": false,
13
+ "scripts": {
14
+ "build": "tsc -p ./tsconfig.json"
13
15
  },
14
16
  "publishConfig": {
15
17
  "access": "public"
16
- },
17
- "files": ["*.js", "*.d.ts"],
18
- "scripts": {
19
- "build": "tsc -p tsconfig.json",
20
- "typecheck": "tsc --noEmit"
21
- },
22
- "dependencies": {},
23
- "devDependencies": {
24
- "typescript": "^5"
25
18
  }
26
19
  }
20
+
package/api.d.ts DELETED
@@ -1,22 +0,0 @@
1
- export interface ApiRequest {
2
- method: string;
3
- url: string;
4
- headers?: Record<string, string>;
5
- body?: unknown;
6
- }
7
- export interface ApiResponse<T = unknown> {
8
- status: number;
9
- headers?: Record<string, string>;
10
- data?: T;
11
- }
12
- export interface ApiAdapter {
13
- request<T = unknown>(req: ApiRequest): Promise<ApiResponse<T>>;
14
- }
15
- export interface ApiClient {
16
- get<T = unknown>(path: string, headers?: Record<string, string>): Promise<ApiResponse<T>>;
17
- post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<ApiResponse<T>>;
18
- put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<ApiResponse<T>>;
19
- delete<T = unknown>(path: string, headers?: Record<string, string>): Promise<ApiResponse<T>>;
20
- }
21
- export declare function createApiClient(baseUrl: string, adapter: ApiAdapter, defaultHeaders?: Record<string, string>): ApiClient;
22
- export type { ApiAdapter as IApiAdapter };
package/api.js DELETED
@@ -1,14 +0,0 @@
1
- export function createApiClient(baseUrl, adapter, defaultHeaders) {
2
- const buildUrl = (path) => {
3
- if (!baseUrl)
4
- return path;
5
- return baseUrl.endsWith("/") ? `${baseUrl}${path.replace(/^\//, "")}` : `${baseUrl}/${path.replace(/^\//, "")}`;
6
- };
7
- const mergeHeaders = (headers) => ({ ...(defaultHeaders || {}), ...(headers || {}) });
8
- return {
9
- get: (path, headers) => adapter.request({ method: "GET", url: buildUrl(path), headers: mergeHeaders(headers) }),
10
- post: (path, body, headers) => adapter.request({ method: "POST", url: buildUrl(path), headers: mergeHeaders(headers), body }),
11
- put: (path, body, headers) => adapter.request({ method: "PUT", url: buildUrl(path), headers: mergeHeaders(headers), body }),
12
- delete: (path, headers) => adapter.request({ method: "DELETE", url: buildUrl(path), headers: mergeHeaders(headers) }),
13
- };
14
- }
package/config.d.ts DELETED
@@ -1,39 +0,0 @@
1
- import { type ApiAdapter, type ApiClient } from "./api";
2
- import { type DbAdapter, type Db } from "./db";
3
- export type MapKind = "api" | "db";
4
- export interface ApiMapConfig {
5
- kind: "api";
6
- name: string;
7
- baseUrl?: string;
8
- defaultHeaders?: Record<string, string>;
9
- adapter: ApiAdapter;
10
- }
11
- export interface DbMapConfig {
12
- kind: "db";
13
- name: string;
14
- connection?: Record<string, unknown>;
15
- adapter: DbAdapter;
16
- }
17
- export type MapConfig = ApiMapConfig | DbMapConfig;
18
- export interface MapperConfig {
19
- maps: MapConfig[];
20
- }
21
- export interface MapperRegistry {
22
- /** Get a named API client */
23
- api: (name: string) => ApiClient;
24
- /** Get a named DB client */
25
- db: (name: string) => Db;
26
- /** Get any named client (API or DB) */
27
- get: (name: string) => ApiClient | Db;
28
- /** List registered maps */
29
- list: () => {
30
- name: string;
31
- kind: MapKind;
32
- }[];
33
- }
34
- /** Helper to define config with proper type inference */
35
- export declare function defineConfig(config: MapperConfig): MapperConfig;
36
- /** Create a registry of named API/DB maps from configuration */
37
- export declare function createRegistry(config: MapperConfig): MapperRegistry;
38
- /** alias */
39
- export declare const loadConfig: typeof createRegistry;