@scarif/scarif-js 1.0.0
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 +451 -0
- package/dist/client.d.ts +33 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +145 -0
- package/dist/constants.d.ts +25 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +26 -0
- package/dist/index.d.ts +119 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +133 -0
- package/dist/types/api.d.ts +37 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +20 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +27 -0
- package/dist/types/queries.d.ts +53 -0
- package/dist/types/queries.d.ts.map +1 -0
- package/dist/types/queries.js +5 -0
- package/dist/types/tables.d.ts +13 -0
- package/dist/types/tables.d.ts.map +1 -0
- package/dist/types/tables.js +6 -0
- package/dist/types/types.d.ts +22 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +12 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/utils/query-builder.d.ts +84 -0
- package/dist/utils/query-builder.d.ts.map +1 -0
- package/dist/utils/query-builder.js +336 -0
- package/dist/utils/select-parser.d.ts +28 -0
- package/dist/utils/select-parser.d.ts.map +1 -0
- package/dist/utils/select-parser.js +84 -0
- package/package.json +44 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for the API SDK
|
|
3
|
+
* Exports client, types, and convenience functions
|
|
4
|
+
*/
|
|
5
|
+
import { ApiClient } from './client';
|
|
6
|
+
import { ApiClientOptions, ApiResponse, QueryBuilder, TableTypes } from './types';
|
|
7
|
+
export * from './types';
|
|
8
|
+
export * from './constants';
|
|
9
|
+
export { ApiClient } from './client';
|
|
10
|
+
/**
|
|
11
|
+
* Create a new API client instance
|
|
12
|
+
* @param options - Configuration options including API key
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { createClient } from 'stoorplek-data-api';
|
|
17
|
+
*
|
|
18
|
+
* const client = createClient({
|
|
19
|
+
* apiKey: 'sk_live_your_api_key_here'
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* const countries = await client
|
|
23
|
+
* .from('countries')
|
|
24
|
+
* .select('name, iso, cities(id, name, population)');
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function createClient(options: ApiClientOptions): ApiClient;
|
|
28
|
+
/**
|
|
29
|
+
* Configure the default client
|
|
30
|
+
* Call this once at the start of your app
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* import { configure } from 'my-api-sdk';
|
|
35
|
+
*
|
|
36
|
+
* configure({
|
|
37
|
+
* apiKey: process.env.API_KEY
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function configure(options: ApiClientOptions): void;
|
|
42
|
+
/**
|
|
43
|
+
* Start a chainable query using the default client
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* import { from } from 'stoorplek-data-api';
|
|
48
|
+
*
|
|
49
|
+
* // Simple query
|
|
50
|
+
* const countries = await from('countries')
|
|
51
|
+
* .select('name, iso');
|
|
52
|
+
*
|
|
53
|
+
* // With relations
|
|
54
|
+
* const countriesWithCities = await from('countries')
|
|
55
|
+
* .select('name, iso, cities(id, name, population)');
|
|
56
|
+
*
|
|
57
|
+
* // Complex query with filters
|
|
58
|
+
* const filtered = await from('countries')
|
|
59
|
+
* .select('name, iso, cities(id, name), languages(*)')
|
|
60
|
+
* .ilike('name', '%united%')
|
|
61
|
+
* .order('name', 'asc')
|
|
62
|
+
* .limit(10);
|
|
63
|
+
*
|
|
64
|
+
* // Get single result
|
|
65
|
+
* const usa = await from('countries')
|
|
66
|
+
* .select('*')
|
|
67
|
+
* .eq('iso', 'US')
|
|
68
|
+
* .single();
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function from<T extends keyof TableTypes>(table: T): QueryBuilder<TableTypes[T]>;
|
|
72
|
+
export declare function from<T = any>(table: string): QueryBuilder<T>;
|
|
73
|
+
/**
|
|
74
|
+
* Check API health using default client
|
|
75
|
+
*/
|
|
76
|
+
export declare function health(): Promise<ApiResponse>;
|
|
77
|
+
/**
|
|
78
|
+
* Stoorplek from function with type inference
|
|
79
|
+
* Delegates to the main from() function to avoid duplication
|
|
80
|
+
*/
|
|
81
|
+
declare function stoorplekFrom<T extends keyof TableTypes>(table: T): QueryBuilder<TableTypes[T]>;
|
|
82
|
+
declare function stoorplekFrom<T = any>(table: string): QueryBuilder<T>;
|
|
83
|
+
/**
|
|
84
|
+
* Default stoorplek object for easy importing
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const { stoorplek } = require('stoorplek-data-api');
|
|
89
|
+
*
|
|
90
|
+
* // Configure once (or use MY_API_KEY env var)
|
|
91
|
+
* stoorplek.configure({ apiKey: 'your-key' });
|
|
92
|
+
*
|
|
93
|
+
* // Use in queries
|
|
94
|
+
* const { data, error } = await stoorplek.from('countries').select('*');
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export declare const scarif: {
|
|
98
|
+
from: typeof stoorplekFrom;
|
|
99
|
+
configure: typeof configure;
|
|
100
|
+
createClient: typeof createClient;
|
|
101
|
+
health: typeof health;
|
|
102
|
+
ApiClient: typeof ApiClient;
|
|
103
|
+
};
|
|
104
|
+
declare const _default: {
|
|
105
|
+
createClient: typeof createClient;
|
|
106
|
+
configure: typeof configure;
|
|
107
|
+
from: typeof from;
|
|
108
|
+
health: typeof health;
|
|
109
|
+
ApiClient: typeof ApiClient;
|
|
110
|
+
scarif: {
|
|
111
|
+
from: typeof stoorplekFrom;
|
|
112
|
+
configure: typeof configure;
|
|
113
|
+
createClient: typeof createClient;
|
|
114
|
+
health: typeof health;
|
|
115
|
+
ApiClient: typeof ApiClient;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
export default _default;
|
|
119
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIlF,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAMrC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAEjE;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAEzD;AAuBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACxF,wBAAgB,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAK9D;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,CAEnD;AAMD;;;GAGG;AACH,iBAAS,aAAa,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1F,iBAAS,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAKhE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM;;;;;;CAMlB,CAAC;;;;;;;;;;;;;;;AAMF,wBAOE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Main entry point for the API SDK
|
|
4
|
+
* Exports client, types, and convenience functions
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.scarif = exports.ApiClient = void 0;
|
|
22
|
+
exports.createClient = createClient;
|
|
23
|
+
exports.configure = configure;
|
|
24
|
+
exports.from = from;
|
|
25
|
+
exports.health = health;
|
|
26
|
+
const client_1 = require("./client");
|
|
27
|
+
const constants_1 = require("./constants");
|
|
28
|
+
// Export all types
|
|
29
|
+
__exportStar(require("./types"), exports);
|
|
30
|
+
__exportStar(require("./constants"), exports);
|
|
31
|
+
var client_2 = require("./client");
|
|
32
|
+
Object.defineProperty(exports, "ApiClient", { enumerable: true, get: function () { return client_2.ApiClient; } });
|
|
33
|
+
// ===========================================
|
|
34
|
+
// CLIENT FACTORY
|
|
35
|
+
// ===========================================
|
|
36
|
+
/**
|
|
37
|
+
* Create a new API client instance
|
|
38
|
+
* @param options - Configuration options including API key
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* import { createClient } from 'stoorplek-data-api';
|
|
43
|
+
*
|
|
44
|
+
* const client = createClient({
|
|
45
|
+
* apiKey: 'sk_live_your_api_key_here'
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* const countries = await client
|
|
49
|
+
* .from('countries')
|
|
50
|
+
* .select('name, iso, cities(id, name, population)');
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
function createClient(options) {
|
|
54
|
+
return new client_1.ApiClient(options);
|
|
55
|
+
}
|
|
56
|
+
// ===========================================
|
|
57
|
+
// DEFAULT CLIENT & CONVENIENCE FUNCTIONS
|
|
58
|
+
// ===========================================
|
|
59
|
+
let defaultClient = null;
|
|
60
|
+
/**
|
|
61
|
+
* Configure the default client
|
|
62
|
+
* Call this once at the start of your app
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* import { configure } from 'my-api-sdk';
|
|
67
|
+
*
|
|
68
|
+
* configure({
|
|
69
|
+
* apiKey: process.env.API_KEY
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
function configure(options) {
|
|
74
|
+
defaultClient = new client_1.ApiClient(options);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get the default client instance
|
|
78
|
+
* Auto-initializes from MY_API_KEY environment variable if not configured
|
|
79
|
+
*/
|
|
80
|
+
function getDefaultClient() {
|
|
81
|
+
if (!defaultClient) {
|
|
82
|
+
const apiKey = process.env[constants_1.API_KEY_ENV_VAR];
|
|
83
|
+
if (!apiKey) {
|
|
84
|
+
throw new Error(`No default client configured. Either call configure() or set ${constants_1.API_KEY_ENV_VAR} environment variable`);
|
|
85
|
+
}
|
|
86
|
+
defaultClient = new client_1.ApiClient({ apiKey });
|
|
87
|
+
}
|
|
88
|
+
return defaultClient;
|
|
89
|
+
}
|
|
90
|
+
function from(table) {
|
|
91
|
+
return getDefaultClient().from(table);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check API health using default client
|
|
95
|
+
*/
|
|
96
|
+
async function health() {
|
|
97
|
+
return getDefaultClient().health();
|
|
98
|
+
}
|
|
99
|
+
function stoorplekFrom(table) {
|
|
100
|
+
return from(table);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Default stoorplek object for easy importing
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const { stoorplek } = require('stoorplek-data-api');
|
|
108
|
+
*
|
|
109
|
+
* // Configure once (or use MY_API_KEY env var)
|
|
110
|
+
* stoorplek.configure({ apiKey: 'your-key' });
|
|
111
|
+
*
|
|
112
|
+
* // Use in queries
|
|
113
|
+
* const { data, error } = await stoorplek.from('countries').select('*');
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
exports.scarif = {
|
|
117
|
+
from: stoorplekFrom,
|
|
118
|
+
configure,
|
|
119
|
+
createClient,
|
|
120
|
+
health,
|
|
121
|
+
ApiClient: client_1.ApiClient
|
|
122
|
+
};
|
|
123
|
+
// ===========================================
|
|
124
|
+
// DEFAULT EXPORT
|
|
125
|
+
// ===========================================
|
|
126
|
+
exports.default = {
|
|
127
|
+
createClient,
|
|
128
|
+
configure,
|
|
129
|
+
from,
|
|
130
|
+
health,
|
|
131
|
+
ApiClient: client_1.ApiClient,
|
|
132
|
+
scarif: exports.scarif
|
|
133
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface ApiClientOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ApiResponse<T = any> {
|
|
7
|
+
data: T;
|
|
8
|
+
error: {
|
|
9
|
+
message: string;
|
|
10
|
+
code?: string;
|
|
11
|
+
details?: any;
|
|
12
|
+
} | null;
|
|
13
|
+
status: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Expected structure of successful API response
|
|
17
|
+
*/
|
|
18
|
+
export interface ApiSuccessResponse<T> {
|
|
19
|
+
data: T;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Expected structure of error API response
|
|
23
|
+
*/
|
|
24
|
+
export interface ApiErrorResponse {
|
|
25
|
+
message?: string;
|
|
26
|
+
code?: string;
|
|
27
|
+
details?: any;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Type guard to check if response has data property
|
|
31
|
+
*/
|
|
32
|
+
export declare function isApiSuccessResponse<T>(response: unknown): response is ApiSuccessResponse<T>;
|
|
33
|
+
/**
|
|
34
|
+
* Type guard to check if response is an error response
|
|
35
|
+
*/
|
|
36
|
+
export declare function isApiErrorResponse(response: unknown): response is ApiErrorResponse;
|
|
37
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/types/api.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAChC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE;QACH,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,GAAG,CAAC;KACjB,GAAG,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;CAClB;AACD;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,kBAAkB,CAAC,CAAC,CAAC,CAM5F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,gBAAgB,CAMlF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isApiSuccessResponse = isApiSuccessResponse;
|
|
4
|
+
exports.isApiErrorResponse = isApiErrorResponse;
|
|
5
|
+
/**
|
|
6
|
+
* Type guard to check if response has data property
|
|
7
|
+
*/
|
|
8
|
+
function isApiSuccessResponse(response) {
|
|
9
|
+
return (typeof response === 'object' &&
|
|
10
|
+
response !== null &&
|
|
11
|
+
'data' in response);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Type guard to check if response is an error response
|
|
15
|
+
*/
|
|
16
|
+
function isApiErrorResponse(response) {
|
|
17
|
+
return (typeof response === 'object' &&
|
|
18
|
+
response !== null &&
|
|
19
|
+
('message' in response || 'code' in response));
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Central exports for all types
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.isApiErrorResponse = exports.isApiSuccessResponse = void 0;
|
|
21
|
+
__exportStar(require("./api"), exports);
|
|
22
|
+
__exportStar(require("./tables"), exports);
|
|
23
|
+
__exportStar(require("./queries"), exports);
|
|
24
|
+
// Explicitly re-export functions to ensure they work in CommonJS
|
|
25
|
+
var api_1 = require("./api");
|
|
26
|
+
Object.defineProperty(exports, "isApiSuccessResponse", { enumerable: true, get: function () { return api_1.isApiSuccessResponse; } });
|
|
27
|
+
Object.defineProperty(exports, "isApiErrorResponse", { enumerable: true, get: function () { return api_1.isApiErrorResponse; } });
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type OrderDirection = 'asc' | 'desc';
|
|
2
|
+
export interface ParsedRelation {
|
|
3
|
+
table: string;
|
|
4
|
+
columns?: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface QueryBuilder<T = any> {
|
|
7
|
+
select(query: string): this;
|
|
8
|
+
eq(column: string, value: any): this;
|
|
9
|
+
neq(column: string, value: any): this;
|
|
10
|
+
gt(column: string, value: any): this;
|
|
11
|
+
gte(column: string, value: any): this;
|
|
12
|
+
lt(column: string, value: any): this;
|
|
13
|
+
lte(column: string, value: any): this;
|
|
14
|
+
like(column: string, value: string): this;
|
|
15
|
+
ilike(column: string, value: string): this;
|
|
16
|
+
in(column: string, values: any[]): this;
|
|
17
|
+
notIn(column: string, values: any[]): this;
|
|
18
|
+
isNull(column: string): this;
|
|
19
|
+
isNotNull(column: string): this;
|
|
20
|
+
order(column: string, direction?: OrderDirection): this;
|
|
21
|
+
limit(count: number): this;
|
|
22
|
+
offset(count: number): this;
|
|
23
|
+
range(from: number, to: number): this;
|
|
24
|
+
single(): this;
|
|
25
|
+
}
|
|
26
|
+
export interface QueryState {
|
|
27
|
+
select?: {
|
|
28
|
+
primaryColumns: string[];
|
|
29
|
+
associatedTables: ParsedRelation[];
|
|
30
|
+
};
|
|
31
|
+
filters: {
|
|
32
|
+
eq?: Record<string, any>;
|
|
33
|
+
neq?: Record<string, any>;
|
|
34
|
+
gt?: Record<string, any>;
|
|
35
|
+
gte?: Record<string, any>;
|
|
36
|
+
lt?: Record<string, any>;
|
|
37
|
+
lte?: Record<string, any>;
|
|
38
|
+
like?: Record<string, any>;
|
|
39
|
+
ilike?: Record<string, any>;
|
|
40
|
+
in?: Record<string, string[]>;
|
|
41
|
+
notIn?: Record<string, string[]>;
|
|
42
|
+
isNull?: string[];
|
|
43
|
+
isNotNull?: string[];
|
|
44
|
+
};
|
|
45
|
+
order?: Array<{
|
|
46
|
+
column: string;
|
|
47
|
+
direction: OrderDirection;
|
|
48
|
+
}>;
|
|
49
|
+
limit?: number;
|
|
50
|
+
offset?: number;
|
|
51
|
+
single?: boolean;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/types/queries.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAG5C,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAMD,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,GAAG;IAEjC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAG5B,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IACrC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IACtC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IACrC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IACtC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IACrC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACxC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAGxD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAGtC,MAAM,IAAI,IAAI,CAAC;CAClB;AAMD,MAAM,WAAW,UAAU;IAEvB,MAAM,CAAC,EAAE;QACL,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,gBAAgB,EAAE,cAAc,EAAE,CAAC;KACtC,CAAC;IACF,OAAO,EAAE;QACL,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5B,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACjC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database table type definitions
|
|
3
|
+
* Add your table interfaces here as your schema grows
|
|
4
|
+
*/
|
|
5
|
+
export interface Country {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
iso: string;
|
|
9
|
+
}
|
|
10
|
+
export interface TableTypes {
|
|
11
|
+
countries: Country;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/types/tables.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACf;AAOD,MAAM,WAAW,UAAU;IACvB,SAAS,EAAE,OAAO,CAAC;CAItB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ApiClientOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ApiResponse<T = any> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: T;
|
|
8
|
+
count?: number;
|
|
9
|
+
error?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ApiError {
|
|
13
|
+
error: string;
|
|
14
|
+
message: string;
|
|
15
|
+
statusCode: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class ApiClientError extends Error {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
error: string;
|
|
20
|
+
constructor(message: string, statusCode: number, error: string);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAe,SAAQ,KAAK;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;gBAEF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAMjE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiClientError = void 0;
|
|
4
|
+
class ApiClientError extends Error {
|
|
5
|
+
constructor(message, statusCode, error) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'ApiClientError';
|
|
8
|
+
this.statusCode = statusCode;
|
|
9
|
+
this.error = error;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.ApiClientError = ApiClientError;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ApiClientOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ApiResponse<T = any> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: T;
|
|
8
|
+
count?: number;
|
|
9
|
+
error?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ApiError {
|
|
13
|
+
error: string;
|
|
14
|
+
message: string;
|
|
15
|
+
statusCode: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class ApiClientError extends Error {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
error: string;
|
|
20
|
+
constructor(message: string, statusCode: number, error: string);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAe,SAAQ,KAAK;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;gBAEF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAMjE"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiClientError = void 0;
|
|
4
|
+
class ApiClientError extends Error {
|
|
5
|
+
constructor(message, statusCode, error) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'ApiClientError';
|
|
8
|
+
this.statusCode = statusCode;
|
|
9
|
+
this.error = error;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.ApiClientError = ApiClientError;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ApiResponse, OrderDirection, QueryBuilder, QueryState } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Chainable query builder implementation
|
|
4
|
+
*/
|
|
5
|
+
export declare class QueryBuilderImpl<T = any> implements QueryBuilder<T> {
|
|
6
|
+
private table;
|
|
7
|
+
private executeFn;
|
|
8
|
+
private state;
|
|
9
|
+
constructor(table: string, executeFn: (table: string, state: QueryState) => Promise<ApiResponse<T[]>>);
|
|
10
|
+
/**
|
|
11
|
+
* Validates that a number is non-negative
|
|
12
|
+
*/
|
|
13
|
+
private validateNonNegative;
|
|
14
|
+
/**
|
|
15
|
+
* Validates that a value is not null or undefined
|
|
16
|
+
*/
|
|
17
|
+
private validateNotNull;
|
|
18
|
+
/**
|
|
19
|
+
* Validates that an array is not empty
|
|
20
|
+
*/
|
|
21
|
+
private validateNonEmptyArray;
|
|
22
|
+
/**
|
|
23
|
+
* Validates column name is a non-empty string
|
|
24
|
+
*/
|
|
25
|
+
private validateColumnName;
|
|
26
|
+
select(query: string): this;
|
|
27
|
+
/**
|
|
28
|
+
* Helper method to add object-based filters (eq, neq, gt, etc.)
|
|
29
|
+
*/
|
|
30
|
+
private addObjectFilter;
|
|
31
|
+
/**
|
|
32
|
+
* Helper method to add array-based filters (in, notIn)
|
|
33
|
+
*/
|
|
34
|
+
private addArrayFilter;
|
|
35
|
+
/**
|
|
36
|
+
* Helper method to add column list filters (isNull, isNotNull)
|
|
37
|
+
*/
|
|
38
|
+
private addColumnListFilter;
|
|
39
|
+
eq(column: string, value: any): this;
|
|
40
|
+
neq(column: string, value: any): this;
|
|
41
|
+
gt(column: string, value: any): this;
|
|
42
|
+
gte(column: string, value: any): this;
|
|
43
|
+
lt(column: string, value: any): this;
|
|
44
|
+
lte(column: string, value: any): this;
|
|
45
|
+
like(column: string, value: string): this;
|
|
46
|
+
ilike(column: string, value: string): this;
|
|
47
|
+
in(column: string, values: any[]): this;
|
|
48
|
+
notIn(column: string, values: any[]): this;
|
|
49
|
+
isNull(column: string): this;
|
|
50
|
+
isNotNull(column: string): this;
|
|
51
|
+
order(column: string, direction?: OrderDirection): this;
|
|
52
|
+
limit(count: number): this;
|
|
53
|
+
offset(count: number): this;
|
|
54
|
+
range(from: number, to: number): this;
|
|
55
|
+
single(): this;
|
|
56
|
+
then<TResult1 = ApiResponse<T | T[]>, TResult2 = never>(onfulfilled?: ((value: ApiResponse<T | T[]>) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): Promise<TResult1 | TResult2>;
|
|
57
|
+
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<ApiResponse<T | T[]> | TResult>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Builds URL query string from QueryState
|
|
61
|
+
*
|
|
62
|
+
* Transforms the internal QueryState structure into URL query parameters
|
|
63
|
+
* following the API's expected format:
|
|
64
|
+
* - Select columns: `select=col1,col2`
|
|
65
|
+
* - Relations: `with=table(col1,col2)`
|
|
66
|
+
* - Filters: `column[filterType]=value`
|
|
67
|
+
* - Ordering: `order=column.direction`
|
|
68
|
+
* - Pagination: `limit=N&offset=N`
|
|
69
|
+
*
|
|
70
|
+
* @param state - The query state containing all filters, selections, and modifiers
|
|
71
|
+
* @returns Query string with leading '?' if params exist, empty string otherwise
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const state: QueryState = {
|
|
76
|
+
* select: { primaryColumns: ['id', 'name'], associatedTables: [] },
|
|
77
|
+
* filters: { eq: { status: 'active' } },
|
|
78
|
+
* limit: 10
|
|
79
|
+
* };
|
|
80
|
+
* buildQueryString(state); // "?select=id,name&status[eq]=active&limit=10"
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildQueryString(state: QueryState): string;
|
|
84
|
+
//# sourceMappingURL=query-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-builder.d.ts","sourceRoot":"","sources":["../../src/utils/query-builder.ts"],"names":[],"mappings":"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"}
|