@bitbeater/ssr 2.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 +259 -0
- package/dist/fields.d.ts +15 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +3 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata.d.ts +32 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +19 -0
- package/dist/metadata.js.map +1 -0
- package/dist/misc.d.ts +3 -0
- package/dist/misc.d.ts.map +1 -0
- package/dist/misc.js +7 -0
- package/dist/misc.js.map +1 -0
- package/dist/order.d.ts +16 -0
- package/dist/order.d.ts.map +1 -0
- package/dist/order.js +13 -0
- package/dist/order.js.map +1 -0
- package/dist/paginated_result.d.ts +7 -0
- package/dist/paginated_result.d.ts.map +1 -0
- package/dist/paginated_result.js +3 -0
- package/dist/paginated_result.js.map +1 -0
- package/dist/paginated_search.d.ts +28 -0
- package/dist/paginated_search.d.ts.map +1 -0
- package/dist/paginated_search.js +3 -0
- package/dist/paginated_search.js.map +1 -0
- package/dist/query_builder/sqlite3_query_builder.d.ts +22 -0
- package/dist/query_builder/sqlite3_query_builder.d.ts.map +1 -0
- package/dist/query_builder/sqlite3_query_builder.js +251 -0
- package/dist/query_builder/sqlite3_query_builder.js.map +1 -0
- package/dist/repository.d.ts +38 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +3 -0
- package/dist/repository.js.map +1 -0
- package/dist/search_operators.d.ts +41 -0
- package/dist/search_operators.d.ts.map +1 -0
- package/dist/search_operators.js +34 -0
- package/dist/search_operators.js.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
## @bitbeater/ssr — Type-safe search, fields, order, and pagination
|
|
2
|
+
|
|
3
|
+
Tiny TypeScript typings to describe search filters, selected fields, ordering, and pagination for repositories. It’s runtime-agnostic (ORM/DB/framework independent) and focuses on strong compile-time safety for your query shape.
|
|
4
|
+
|
|
5
|
+
Key ideas:
|
|
6
|
+
- Search: deep, type-safe filters with operators (equal, like, greater, lesser, between, not)
|
|
7
|
+
- Fields: precise field selection, including nested objects and arrays
|
|
8
|
+
- Order: multi-field ordering with direction, nulls handling, and priority
|
|
9
|
+
- Pagination: page + pageSize with optional search/order/fields
|
|
10
|
+
- Repository: a minimal interface to wire your data source
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i @bitbeater/ssr
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import {
|
|
24
|
+
Fields,
|
|
25
|
+
Order,
|
|
26
|
+
PaginatedResult,
|
|
27
|
+
PaginatedSearch,
|
|
28
|
+
Repository,
|
|
29
|
+
Search,
|
|
30
|
+
} from '@bitbeater/ssr';
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Person model used in examples
|
|
35
|
+
|
|
36
|
+
Includes number, string, object, date, array, and boolean types.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
type Contact = {
|
|
40
|
+
type: 'email' | 'phone';
|
|
41
|
+
value: string;
|
|
42
|
+
verified: boolean;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type Person = {
|
|
46
|
+
id: number; // number
|
|
47
|
+
name: string; // string
|
|
48
|
+
age: number; // number
|
|
49
|
+
isActive: boolean; // boolean
|
|
50
|
+
createdAt: Date; // date
|
|
51
|
+
tags: string[]; // array of scalar
|
|
52
|
+
address: { // object
|
|
53
|
+
city: string;
|
|
54
|
+
zip: number;
|
|
55
|
+
};
|
|
56
|
+
contacts: Contact[]; // array of objects
|
|
57
|
+
notes?: string | null; // nullable field
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## Search — type-safe filters
|
|
63
|
+
|
|
64
|
+
Operator shape for scalar fields:
|
|
65
|
+
- equal: T | T[]
|
|
66
|
+
- like: T
|
|
67
|
+
- range: { greater: T; lesser: T }
|
|
68
|
+
- not?: boolean (negate any of the above)
|
|
69
|
+
|
|
70
|
+
You can pass either a raw scalar (shorthand for equal) or a Find<T> object with one operator. Nested objects and arrays are supported recursively.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { Search } from '@bitbeater/ssr';
|
|
74
|
+
|
|
75
|
+
const search: Search<Person> = {
|
|
76
|
+
// scalars
|
|
77
|
+
name: { like: 'ali' },
|
|
78
|
+
age: { greater: 18 },
|
|
79
|
+
isActive: true, // shorthand for { equal: true }
|
|
80
|
+
createdAt: { greater: new Date('2024-01-01'), lesser: new Date('2024-12-31') },
|
|
81
|
+
// array of scalars -> filter by an element match
|
|
82
|
+
tags: { like: 'script' },
|
|
83
|
+
// or shorthand equal
|
|
84
|
+
// tags: 'typescript',
|
|
85
|
+
|
|
86
|
+
// nested object
|
|
87
|
+
address: {
|
|
88
|
+
city: { like: 'York' },
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// array of objects -> filter by fields on the element type
|
|
92
|
+
contacts: {
|
|
93
|
+
verified: { equal: true },
|
|
94
|
+
type: { equal: ['email', 'phone'] },
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Notes:
|
|
100
|
+
- Arrays use the element type for filtering (semantics like “any element matches” are up to your implementation).
|
|
101
|
+
- Functions are excluded by design and cannot be filtered.
|
|
102
|
+
- Nullable fields are treated as their non-nullable type for filtering (i.e., `string | null` is filtered as `string`). If you need explicit null checks, model them in your repository implementation or extend the types to support it.
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
## Fields — shape the returned data
|
|
106
|
+
|
|
107
|
+
Rules:
|
|
108
|
+
- true includes the field
|
|
109
|
+
- object selects nested fields recursively
|
|
110
|
+
- arrays accept either true (whole element) or a nested object describing the element shape
|
|
111
|
+
- functions are excluded
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { Fields } from '@bitbeater/ssr';
|
|
115
|
+
|
|
116
|
+
const fields: Fields<Person> = {
|
|
117
|
+
id: true,
|
|
118
|
+
name: true,
|
|
119
|
+
address: { city: true },
|
|
120
|
+
tags: true, // include array values
|
|
121
|
+
contacts: { type: true, verified: true },
|
|
122
|
+
// Omitting a key excludes it (unless the root is set to true)
|
|
123
|
+
};
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
## Order — multi-field ordering
|
|
128
|
+
|
|
129
|
+
Each ordered field accepts a strategy:
|
|
130
|
+
- direction: 'ASC' | 'DESC'
|
|
131
|
+
- nulls?: 'FIRST' | 'LAST'
|
|
132
|
+
- priority?: number (lower number = higher precedence)
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { Order } from '@bitbeater/ssr';
|
|
136
|
+
|
|
137
|
+
const order: Order<Person> = {
|
|
138
|
+
createdAt: { direction: 'DESC', nulls: 'LAST', priority: 1 },
|
|
139
|
+
name: { direction: 'ASC', priority: 2 },
|
|
140
|
+
// order within arrays-of-objects is expressed over the element type
|
|
141
|
+
contacts: { verified: { direction: 'DESC', priority: 1 } },
|
|
142
|
+
};
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
## PaginatedSearch and PaginatedResult
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { PaginatedSearch, PaginatedResult } from '@bitbeater/ssr';
|
|
150
|
+
|
|
151
|
+
const query: PaginatedSearch<Person> = {
|
|
152
|
+
page: 0, // default 0
|
|
153
|
+
pageSize: 20, // omit to fetch until the end
|
|
154
|
+
fields, // optional: return all when omitted/empty
|
|
155
|
+
order, // optional
|
|
156
|
+
search, // optional: match-all when omitted
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Your data source returns this shape
|
|
160
|
+
const result: PaginatedResult<Person> = {
|
|
161
|
+
page: 0,
|
|
162
|
+
pageSize: 20,
|
|
163
|
+
totalCount: 2,
|
|
164
|
+
items: [/* persons */],
|
|
165
|
+
};
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
## Repository interface
|
|
170
|
+
|
|
171
|
+
Bring your own persistence. These types describe a minimal repo surface.
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { Repository } from '@bitbeater/ssr';
|
|
175
|
+
|
|
176
|
+
const peopleRepo: Repository<Person> = {
|
|
177
|
+
save: async (people) => people, // create/update
|
|
178
|
+
search: async (q) => ({ page: q?.page ?? 0, pageSize: q?.pageSize, totalCount: 0, items: [] }),
|
|
179
|
+
remove: async (s) => [],
|
|
180
|
+
};
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
## Type-only package
|
|
185
|
+
|
|
186
|
+
This library exports TypeScript types with no runtime. Use them to type your query-building and repository contracts in any stack (SQL, NoSQL, REST, GraphQL, ORM, etc.).
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
## API surface
|
|
190
|
+
|
|
191
|
+
- Fields<T>: describe selected fields
|
|
192
|
+
- Search<T>: describe filters by field with operators
|
|
193
|
+
- Order<T>: describe ordering with direction/nulls/priority
|
|
194
|
+
- PaginatedSearch<T>: page, pageSize, order, fields, search
|
|
195
|
+
- PaginatedResult<T>: page, pageSize, totalCount, items
|
|
196
|
+
- Repository<T>: save, search, remove function types
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
## Query Builder
|
|
200
|
+
A simple SQLite query builder implementation is included to demonstrate how to use the types in practice. It supports basic filtering, field selection, ordering, and pagination.
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import { buildQueryString } from '@bitbeater/ssr/query_builder/sqlite3_query_builder';
|
|
204
|
+
import { Condition, OrderDirection } from '@bitbeater/ssr';
|
|
205
|
+
import { Metadata, QueryParam } from '@bitbeater/ssr/metadata';
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
type Tag = {
|
|
209
|
+
id: number;
|
|
210
|
+
name: string
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
type Bio = {
|
|
214
|
+
height: number;
|
|
215
|
+
eyeColor: string;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
type Address = {
|
|
219
|
+
city: string;
|
|
220
|
+
zip: number;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
type Person = {
|
|
224
|
+
id: number;
|
|
225
|
+
name: string;
|
|
226
|
+
bio: Bio;
|
|
227
|
+
address: Address;
|
|
228
|
+
tags: Tag[];
|
|
229
|
+
children: Person[];
|
|
230
|
+
parent: Person;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
/*
|
|
235
|
+
sql schema:
|
|
236
|
+
CREATE TABLE person (
|
|
237
|
+
id INTEGER PRIMARY KEY,
|
|
238
|
+
name TEXT,
|
|
239
|
+
parentId INTEGER,
|
|
240
|
+
addressId INTEGER,
|
|
241
|
+
FOREIGN KEY(parentId) REFERENCES person(id)
|
|
242
|
+
FOREIGN KEY(addressId) REFERENCES address(id),
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
CREATE TABLE bio (
|
|
246
|
+
id INTEGER PRIMARY KEY,
|
|
247
|
+
personId INTEGER,
|
|
248
|
+
height INTEGER,
|
|
249
|
+
eyeColor TEXT,
|
|
250
|
+
FOREIGN KEY(personId) REFERENCES person(id)
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
*/
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
## License
|
|
259
|
+
ISC
|
package/dist/fields.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ScalarValue } from "./misc";
|
|
2
|
+
/**
|
|
3
|
+
* Fields to select in a search
|
|
4
|
+
* if a field is set to true, it will be included in the result
|
|
5
|
+
* if a field is set to false, it will be excluded from the result
|
|
6
|
+
* if a field is an object, it will be recursively processed
|
|
7
|
+
* if a field is not present, it will be excluded from the result
|
|
8
|
+
* if the whole object is set to true, all fields will be included
|
|
9
|
+
* if the field is a function, it will be excluded
|
|
10
|
+
*/
|
|
11
|
+
export type Field<FieldType> = FieldType extends ScalarValue ? true : FieldType extends Function ? never : FieldType extends Array<infer ArrayType> ? Field<ArrayType> | true : FieldType extends object ? Fields<FieldType> | true : never;
|
|
12
|
+
export type Fields<Entity> = {
|
|
13
|
+
[Key in keyof Entity]?: Field<NonNullable<Entity[Key]>>;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC;;;;;;;;GAQG;AAEH,MAAM,MAAM,KAAK,CAAC,SAAS,IAC1B,SAAS,SAAS,WAAW,GAC7B,IAAI,GAEJ,SAAS,SAAS,QAAQ,GAC1B,KAAK,GAEL,SAAS,SAAS,KAAK,CAAC,MAAM,SAAS,CAAC,GACxC,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,GAEvB,SAAS,SAAS,MAAM,GACxB,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,GAExB,KAAK,CAAA;AAGN,MAAM,MAAM,MAAM,CAAC,MAAM,IACxB;KACE,GAAG,IAAI,MAAM,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;CACvD,CAAA"}
|
package/dist/fields.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './fields';
|
|
2
|
+
export * from './order';
|
|
3
|
+
export * from './paginated_result';
|
|
4
|
+
export * from './paginated_search';
|
|
5
|
+
export * from './search_operators';
|
|
6
|
+
export * from './repository';
|
|
7
|
+
export * from './metadata';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./fields"), exports);
|
|
18
|
+
__exportStar(require("./order"), exports);
|
|
19
|
+
__exportStar(require("./paginated_result"), exports);
|
|
20
|
+
__exportStar(require("./paginated_search"), exports);
|
|
21
|
+
__exportStar(require("./search_operators"), exports);
|
|
22
|
+
__exportStar(require("./repository"), exports);
|
|
23
|
+
__exportStar(require("./metadata"), exports);
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,0CAAwB;AACxB,qDAAmC;AACnC,qDAAmC;AACnC,qDAAmC;AACnC,+CAA6B;AAC7B,6CAA2B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ScalarValue } from "./misc";
|
|
2
|
+
export type Regular = string;
|
|
3
|
+
export type BridgeLink<T> = {
|
|
4
|
+
targetMetadata: Metadata<T>;
|
|
5
|
+
bridgeTable: string;
|
|
6
|
+
sourceRefKey: string;
|
|
7
|
+
targetRefKey: string;
|
|
8
|
+
bridgeSourceForeignKey: string;
|
|
9
|
+
bridgeTargetForeignKey: string;
|
|
10
|
+
};
|
|
11
|
+
export type OutcomeingLink<T> = {
|
|
12
|
+
targetMetadata: Metadata<T>;
|
|
13
|
+
sourceForeignkey: string;
|
|
14
|
+
targetRefKey: string;
|
|
15
|
+
};
|
|
16
|
+
export type IncomingLink<T> = {
|
|
17
|
+
targetMetadata: Metadata<T>;
|
|
18
|
+
sourceRefKey: string;
|
|
19
|
+
targetForeignKey: string;
|
|
20
|
+
};
|
|
21
|
+
export type Relation<T> = BridgeLink<T> | OutcomeingLink<T> | IncomingLink<T>;
|
|
22
|
+
export type FieldMetadata<FieldType> = FieldType extends ScalarValue ? Regular : FieldType extends Function ? never : FieldType extends Array<infer ArrayType> ? BridgeLink<ArrayType> | IncomingLink<ArrayType> : FieldType extends object ? BridgeLink<FieldType> | OutcomeingLink<FieldType> : never;
|
|
23
|
+
export type Metadata<Entity> = {
|
|
24
|
+
[Key in keyof Entity]?: FieldMetadata<NonNullable<Entity[Key]>>;
|
|
25
|
+
} & {
|
|
26
|
+
tableName: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function isRelation<T>(obj: unknown): obj is Relation<T>;
|
|
29
|
+
export declare function isBridgeLink<T>(obj: unknown): obj is BridgeLink<T>;
|
|
30
|
+
export declare function isOutcomeingLink<T>(obj: unknown): obj is OutcomeingLink<T>;
|
|
31
|
+
export declare function isIncomingLink<T>(obj: unknown): obj is IncomingLink<T>;
|
|
32
|
+
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAKrC,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAAE,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,sBAAsB,EAAE,MAAM,CAAC;IAAC,sBAAsB,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7L,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAAE,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAAE,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9G,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAI9E,MAAM,MAAM,aAAa,CAAC,SAAS,IAClC,SAAS,SAAS,WAAW,GAC7B,OAAO,GAEP,SAAS,SAAS,QAAQ,GAC1B,KAAK,GAEL,SAAS,SAAS,KAAK,CAAC,MAAM,SAAS,CAAC,GACxC,UAAU,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC,SAAS,CAAC,GAE/C,SAAS,SAAS,MAAM,GACxB,UAAU,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC,SAAS,CAAC,GAEjD,KAAK,CAAA;AAGN,MAAM,MAAM,QAAQ,CAAC,MAAM,IAC1B;KAEE,GAAG,IAAI,MAAM,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;CAC/D,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAK3B,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,CAE9D;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAElE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,CAE1E;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAEtE"}
|
package/dist/metadata.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRelation = isRelation;
|
|
4
|
+
exports.isBridgeLink = isBridgeLink;
|
|
5
|
+
exports.isOutcomeingLink = isOutcomeingLink;
|
|
6
|
+
exports.isIncomingLink = isIncomingLink;
|
|
7
|
+
function isRelation(obj) {
|
|
8
|
+
return !!obj?.targetMetadata;
|
|
9
|
+
}
|
|
10
|
+
function isBridgeLink(obj) {
|
|
11
|
+
return !!obj.bridgeTable;
|
|
12
|
+
}
|
|
13
|
+
function isOutcomeingLink(obj) {
|
|
14
|
+
return !!obj.sourceForeignkey;
|
|
15
|
+
}
|
|
16
|
+
function isIncomingLink(obj) {
|
|
17
|
+
return !!obj.targetForeignKey;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":";;AA0CA,gCAEC;AAED,oCAEC;AAED,4CAEC;AAED,wCAEC;AAdD,SAAgB,UAAU,CAAI,GAAY;IACzC,OAAO,CAAC,CAAE,GAAmB,EAAE,cAAc,CAAC;AAC/C,CAAC;AAED,SAAgB,YAAY,CAAI,GAAY;IAC3C,OAAO,CAAC,CAAE,GAAqB,CAAC,WAAW,CAAC;AAC7C,CAAC;AAED,SAAgB,gBAAgB,CAAI,GAAY;IAC/C,OAAO,CAAC,CAAE,GAAyB,CAAC,gBAAgB,CAAC;AACtD,CAAC;AAED,SAAgB,cAAc,CAAI,GAAY;IAC7C,OAAO,CAAC,CAAE,GAAuB,CAAC,gBAAgB,CAAC;AACpD,CAAC"}
|
package/dist/misc.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../src/misc.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAE1E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAElE"}
|
package/dist/misc.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isScalarValue = isScalarValue;
|
|
4
|
+
function isScalarValue(value) {
|
|
5
|
+
return ['string', 'number', 'boolean'].includes(typeof value) || value instanceof Date;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=misc.js.map
|
package/dist/misc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../src/misc.ts"],"names":[],"mappings":";;AAEA,sCAEC;AAFD,SAAgB,aAAa,CAAC,KAAc;IACxC,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC;AAC3F,CAAC"}
|
package/dist/order.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ScalarValue } from './misc';
|
|
2
|
+
export declare enum OrderDirection {
|
|
3
|
+
ASC = "ASC",
|
|
4
|
+
DESC = "DESC"
|
|
5
|
+
}
|
|
6
|
+
export type OrderStrategy = {
|
|
7
|
+
direction: OrderDirection;
|
|
8
|
+
nulls?: 'FIRST' | 'LAST';
|
|
9
|
+
priority?: number;
|
|
10
|
+
};
|
|
11
|
+
export type OrderField<FieldType> = FieldType extends ScalarValue ? OrderStrategy : FieldType extends Function ? never : FieldType extends Array<infer ArrayType> ? OrderField<ArrayType> : FieldType extends object ? Order<FieldType> : never;
|
|
12
|
+
export type Order<T> = {
|
|
13
|
+
[P in keyof T]?: OrderField<NonNullable<T[P]>>;
|
|
14
|
+
};
|
|
15
|
+
export declare function isOrderStrategy(obj: unknown): obj is OrderStrategy;
|
|
16
|
+
//# sourceMappingURL=order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAGrC,oBAAY,cAAc;IACzB,GAAG,QAAQ;IACX,IAAI,SAAS;CACb;AAED,MAAM,MAAM,aAAa,GAAG;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAElB,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,SAAS,IAC/B,SAAS,SAAS,WAAW,GAC7B,aAAa,GAEb,SAAS,SAAS,QAAQ,GAC1B,KAAK,GAEL,SAAS,SAAS,KAAK,CAAC,MAAM,SAAS,CAAC,GACxC,UAAU,CAAC,SAAS,CAAC,GAErB,SAAS,SAAS,MAAM,GACxB,KAAK,CAAC,SAAS,CAAC,GAEhB,KAAK,CAAA;AAIN,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI;KACrB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,aAAa,CAElE"}
|
package/dist/order.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrderDirection = void 0;
|
|
4
|
+
exports.isOrderStrategy = isOrderStrategy;
|
|
5
|
+
var OrderDirection;
|
|
6
|
+
(function (OrderDirection) {
|
|
7
|
+
OrderDirection["ASC"] = "ASC";
|
|
8
|
+
OrderDirection["DESC"] = "DESC";
|
|
9
|
+
})(OrderDirection || (exports.OrderDirection = OrderDirection = {}));
|
|
10
|
+
function isOrderStrategy(obj) {
|
|
11
|
+
return [OrderDirection.ASC, OrderDirection.DESC].includes(obj?.direction);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":";;;AAoCA,0CAEC;AAnCD,IAAY,cAGX;AAHD,WAAY,cAAc;IACzB,6BAAW,CAAA;IACX,+BAAa,CAAA;AACd,CAAC,EAHW,cAAc,8BAAd,cAAc,QAGzB;AA8BD,SAAgB,eAAe,CAAC,GAAY;IAC3C,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAE,GAAqB,EAAE,SAAS,CAAC,CAAC;AAC9F,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginated_result.d.ts","sourceRoot":"","sources":["../src/paginated_result.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;CACZ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginated_result.js","sourceRoot":"","sources":["../src/paginated_result.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Fields } from './fields';
|
|
2
|
+
import { Order } from './order';
|
|
3
|
+
import { Search } from './search_operators';
|
|
4
|
+
/**
|
|
5
|
+
* describes a paginated and ordered search.
|
|
6
|
+
* if page is not provided, defau
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export interface PaginatedSearch<T> {
|
|
10
|
+
/**
|
|
11
|
+
* @default 0
|
|
12
|
+
*/
|
|
13
|
+
page?: number;
|
|
14
|
+
/**
|
|
15
|
+
* if not provided returns all entities til the end
|
|
16
|
+
*/
|
|
17
|
+
pageSize?: number;
|
|
18
|
+
order?: Order<T>;
|
|
19
|
+
/**
|
|
20
|
+
* list of fields to return, if empty or null return all.
|
|
21
|
+
* */
|
|
22
|
+
fields?: Fields<T>;
|
|
23
|
+
/**
|
|
24
|
+
* if not provided returns all entities
|
|
25
|
+
*/
|
|
26
|
+
search?: Search<T>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=paginated_search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginated_search.d.ts","sourceRoot":"","sources":["../src/paginated_search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IACjC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEjB;;SAEK;IACL,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginated_search.js","sourceRoot":"","sources":["../src/paginated_search.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Metadata } from "../metadata";
|
|
2
|
+
import { PaginatedSearch } from "../paginated_search";
|
|
3
|
+
import { Search } from "../search_operators";
|
|
4
|
+
import { Order } from "../order";
|
|
5
|
+
type QueryParam = boolean | number | string;
|
|
6
|
+
/**
|
|
7
|
+
* Builds a SQL query string and its parameters from a paginated search object and metadata.
|
|
8
|
+
* @param paginatedSearch
|
|
9
|
+
* @param metadata
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildQueryString<T>(paginatedSearch: PaginatedSearch<T>, metadata: Metadata<T>): [string, QueryParam[]];
|
|
13
|
+
export declare function makeOrderByClause<T>(order: Order<T>, metadata: Metadata<T>): string;
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param searchConditions
|
|
17
|
+
* @param metadata
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildWhereQueryString<T>(searchConditions: Search<T>, metadata: Metadata<T>): [string, QueryParam[]];
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=sqlite3_query_builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite3_query_builder.d.ts","sourceRoot":"","sources":["../../src/query_builder/sqlite3_query_builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAwF,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAE7I,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAiH,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE5J,OAAO,EAAmB,KAAK,EAAiC,MAAM,UAAU,CAAC;AAEjF,KAAK,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AA8C5C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAWtH;AAiBD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CA6BxF;AAiBD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAsBxH"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildQueryString = buildQueryString;
|
|
4
|
+
exports.makeOrderByClause = makeOrderByClause;
|
|
5
|
+
exports.buildWhereQueryString = buildWhereQueryString;
|
|
6
|
+
const metadata_1 = require("../metadata");
|
|
7
|
+
const misc_1 = require("../misc");
|
|
8
|
+
const search_operators_1 = require("../search_operators");
|
|
9
|
+
const object_1 = require("iggs-utils/object");
|
|
10
|
+
const order_1 = require("../order");
|
|
11
|
+
/*
|
|
12
|
+
* Limitations:
|
|
13
|
+
* - no Composite Key: handles only single primary/foreign keys based relations.
|
|
14
|
+
* - can only handle one to many self references. (e.g. a person has many childs, but a child has only one father and one mother)
|
|
15
|
+
* @Example
|
|
16
|
+
* ```ts
|
|
17
|
+
* interface Person {
|
|
18
|
+
* id: number;
|
|
19
|
+
* name: string;
|
|
20
|
+
* childs: Person[]; // can't query persons that have childs with certain conditions
|
|
21
|
+
* father: Person; // many to one self reference
|
|
22
|
+
* mother: Person; // many to one self reference
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* const personMetadata: Metadata<Person> = {
|
|
26
|
+
* tableName: 'person',
|
|
27
|
+
* id: 'id',
|
|
28
|
+
* name: 'name'
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* personMetadata.father = {
|
|
32
|
+
* targetRefKey: 'id',
|
|
33
|
+
* sourceForeignkey: 'fatherId',
|
|
34
|
+
* targetMetadata: personMetadata
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* personMetadata.mother = {
|
|
38
|
+
* targetRefKey: 'id',
|
|
39
|
+
* sourceForeignkey: 'motherId',
|
|
40
|
+
* targetMetadata: personMetadata
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* personMetadata.childs = {
|
|
44
|
+
* sourceRefKey: 'id',
|
|
45
|
+
* targetForeignKey: 'fatherId', // or motherId can't both
|
|
46
|
+
* targetMetadata: personMetadata
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* Builds a SQL query string and its parameters from a paginated search object and metadata.
|
|
52
|
+
* @param paginatedSearch
|
|
53
|
+
* @param metadata
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
function buildQueryString(paginatedSearch, metadata) {
|
|
57
|
+
const selectFields = makeSelectedFields(paginatedSearch.fields, metadata);
|
|
58
|
+
const from = `FROM ${metadata.tableName}`;
|
|
59
|
+
const [whereClause, queryParams] = buildWhereQueryString(paginatedSearch.search, metadata);
|
|
60
|
+
const orderByClause = makeOrderByClause(paginatedSearch.order, metadata);
|
|
61
|
+
const paginationClause = buildPaginationClause(paginatedSearch);
|
|
62
|
+
// let query = `${selectFields} FROM ${metadata.tableName} ${whereClause.length ? whereClause : ''} ${orderByClause} ${paginationClause}`.trim();
|
|
63
|
+
let query = [selectFields, from, whereClause, orderByClause, paginationClause].filter(e => e?.length).join(' ').trim();
|
|
64
|
+
return [query, queryParams];
|
|
65
|
+
}
|
|
66
|
+
function makeSelectedFields(selectedFields = {}, metadata) {
|
|
67
|
+
const fields = [];
|
|
68
|
+
for (const [selectedField, isSelected] of Object.entries(selectedFields)) {
|
|
69
|
+
if (isSelected !== true)
|
|
70
|
+
continue;
|
|
71
|
+
const metadataField = metadata[selectedField];
|
|
72
|
+
const fieldName = (typeof metadataField === 'string') ? metadataField : selectedField;
|
|
73
|
+
fields.push(`${metadata.tableName}.${fieldName}`);
|
|
74
|
+
}
|
|
75
|
+
return 'SELECT ' + (fields.length ? fields.join(',') : `${metadata.tableName}.*`);
|
|
76
|
+
}
|
|
77
|
+
function makeOrderByClause(order = {}, metadata) {
|
|
78
|
+
// ORDER BY FirstName DESC, YearOfBirth ASC
|
|
79
|
+
let orders = [];
|
|
80
|
+
for (const [field, orderStrategy] of Object.entries(order)) {
|
|
81
|
+
if (!(0, order_1.isOrderStrategy)(orderStrategy))
|
|
82
|
+
continue;
|
|
83
|
+
if (typeof metadata[field] === 'object')
|
|
84
|
+
continue;
|
|
85
|
+
const fieldName = metadata[field] || field;
|
|
86
|
+
orders.push({ ...orderStrategy, fieldName });
|
|
87
|
+
}
|
|
88
|
+
orders = orders.sort((a, b) => (a.priority || 0) - (b.priority || 0));
|
|
89
|
+
if (!orders.length)
|
|
90
|
+
return '';
|
|
91
|
+
const orderClauseChunks = [];
|
|
92
|
+
for (const order of orders) {
|
|
93
|
+
let clause = `${metadata.tableName}.${order.fieldName}`;
|
|
94
|
+
clause += order.direction === order_1.OrderDirection.DESC ? ' DESC' : ' ASC';
|
|
95
|
+
if (order.nulls === "FIRST")
|
|
96
|
+
clause += ' NULLS FIRST';
|
|
97
|
+
if (order.nulls === "LAST")
|
|
98
|
+
clause += ' NULLS LAST';
|
|
99
|
+
orderClauseChunks.push(clause);
|
|
100
|
+
}
|
|
101
|
+
return 'ORDER BY ' + orderClauseChunks.join(', ');
|
|
102
|
+
}
|
|
103
|
+
function buildPaginationClause(paginatedSearch) {
|
|
104
|
+
let clause = '';
|
|
105
|
+
if (paginatedSearch.pageSize > 0) {
|
|
106
|
+
clause += `LIMIT ${paginatedSearch.pageSize}`;
|
|
107
|
+
if (paginatedSearch.page > 0)
|
|
108
|
+
clause += ` OFFSET ${paginatedSearch.page * paginatedSearch.pageSize}`;
|
|
109
|
+
}
|
|
110
|
+
return clause;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
*
|
|
114
|
+
* @param searchConditions
|
|
115
|
+
* @param metadata
|
|
116
|
+
* @returns
|
|
117
|
+
*/
|
|
118
|
+
function buildWhereQueryString(searchConditions = {}, metadata) {
|
|
119
|
+
const queryParams = [];
|
|
120
|
+
const queryParts = [];
|
|
121
|
+
for (const key of (0, object_1.keysOf)(searchConditions)) {
|
|
122
|
+
if (key === search_operators_1.Condition.NOT)
|
|
123
|
+
continue;
|
|
124
|
+
const [query, params] = makeCondition(key, searchConditions, metadata);
|
|
125
|
+
if (query) {
|
|
126
|
+
queryParts.push(query);
|
|
127
|
+
queryParams.push(...params);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!queryParts.length)
|
|
131
|
+
return ['', []];
|
|
132
|
+
if (searchConditions[search_operators_1.Condition.NOT])
|
|
133
|
+
return [`WHERE NOT (${queryParts.join(" OR ")})`, queryParams];
|
|
134
|
+
else
|
|
135
|
+
return ['WHERE ' + queryParts.join(" AND "), queryParams];
|
|
136
|
+
}
|
|
137
|
+
function makeCondition(field, search, metadata) {
|
|
138
|
+
// if where is a scalar value or array of scalar values, treat it as equality
|
|
139
|
+
const fieldSearch = search[field];
|
|
140
|
+
if (!fieldSearch)
|
|
141
|
+
return ['', []];
|
|
142
|
+
if ((0, misc_1.isScalarValue)(fieldSearch) || Array.isArray(fieldSearch)) {
|
|
143
|
+
return makeEqualCondition(field, { [search_operators_1.Condition.EQUAL]: fieldSearch }, metadata);
|
|
144
|
+
}
|
|
145
|
+
if ((0, search_operators_1.isEqualCondition)(fieldSearch)) {
|
|
146
|
+
return makeEqualCondition(field, fieldSearch, metadata);
|
|
147
|
+
}
|
|
148
|
+
if ((0, search_operators_1.isLikeCondition)(fieldSearch)) {
|
|
149
|
+
return makeLikeCondition(field, fieldSearch, metadata);
|
|
150
|
+
}
|
|
151
|
+
if ((0, search_operators_1.isRangeCondition)(fieldSearch)) {
|
|
152
|
+
return makeRangeCondition(field, fieldSearch, metadata);
|
|
153
|
+
}
|
|
154
|
+
if ((0, metadata_1.isRelation)(metadata[field])) {
|
|
155
|
+
return makeRelationCondition(field, fieldSearch, metadata);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function makeEqualCondition(field, value, metadata) {
|
|
159
|
+
let query = '';
|
|
160
|
+
const params = [];
|
|
161
|
+
const fieldName = `${metadata.tableName}.${String(metadata?.[field] || field)}`;
|
|
162
|
+
const valueToMatch = value[search_operators_1.Condition.EQUAL];
|
|
163
|
+
if (Array.isArray(valueToMatch)) {
|
|
164
|
+
const placeholders = valueToMatch.map(() => '?').join(', ');
|
|
165
|
+
query = `${value[search_operators_1.Condition.NOT] ? 'NOT ' : ''}${fieldName} IN (${placeholders})`;
|
|
166
|
+
params.push(...valueToMatch.map(v => scalarValueToSql(v)));
|
|
167
|
+
}
|
|
168
|
+
else if ((0, misc_1.isScalarValue)(valueToMatch)) {
|
|
169
|
+
query = `${value[search_operators_1.Condition.NOT] ? 'NOT ' : ''}${fieldName} = ?`;
|
|
170
|
+
params.push(scalarValueToSql(valueToMatch));
|
|
171
|
+
}
|
|
172
|
+
return [query, params];
|
|
173
|
+
}
|
|
174
|
+
function makeLikeCondition(field, likeCondtition, metadata) {
|
|
175
|
+
const fieldName = `${metadata.tableName}.${String(metadata?.[field] || field)}`;
|
|
176
|
+
const query = `${likeCondtition[search_operators_1.Condition.NOT] ? 'NOT ' : ''}${fieldName} LIKE ?`;
|
|
177
|
+
const params = [scalarValueToSql(likeCondtition[search_operators_1.Condition.LIKE])];
|
|
178
|
+
return [query, params];
|
|
179
|
+
}
|
|
180
|
+
function makeRangeCondition(field, rangeCondition, metadata) {
|
|
181
|
+
const fieldName = `${metadata.tableName}.${String(metadata?.[field] || field)}`;
|
|
182
|
+
const parts = [];
|
|
183
|
+
const params = [];
|
|
184
|
+
if (rangeCondition[search_operators_1.Condition.GREATER]) {
|
|
185
|
+
parts.push(`${fieldName} > ?`);
|
|
186
|
+
params.push(scalarValueToSql(rangeCondition[search_operators_1.Condition.GREATER]));
|
|
187
|
+
}
|
|
188
|
+
if (rangeCondition[search_operators_1.Condition.LESSER]) {
|
|
189
|
+
parts.push(`${fieldName} < ?`);
|
|
190
|
+
params.push(scalarValueToSql(rangeCondition[search_operators_1.Condition.LESSER]));
|
|
191
|
+
}
|
|
192
|
+
let query = parts.join(' AND ');
|
|
193
|
+
if (rangeCondition[search_operators_1.Condition.NOT])
|
|
194
|
+
query = `NOT (${query})`;
|
|
195
|
+
return [query, params];
|
|
196
|
+
}
|
|
197
|
+
function scalarValueToSql(value) {
|
|
198
|
+
if (value instanceof Date) {
|
|
199
|
+
return `'${value.toISOString().slice(0, 19).replace('T', ' ')}'`; // format as 'YYYY-MM-DD HH:MM:SS'
|
|
200
|
+
}
|
|
201
|
+
if (value instanceof Promise) {
|
|
202
|
+
throw new Error('Promise is not a valid ScalarValue');
|
|
203
|
+
}
|
|
204
|
+
return value;
|
|
205
|
+
}
|
|
206
|
+
function makeRelationCondition(field, search, metadata) {
|
|
207
|
+
const sourceTable = metadata.tableName;
|
|
208
|
+
const relationMetadata = metadata[field];
|
|
209
|
+
if ((0, metadata_1.isBridgeLink)(relationMetadata)) {
|
|
210
|
+
return buildBridgeLinkQueryString(search, sourceTable, relationMetadata);
|
|
211
|
+
}
|
|
212
|
+
if ((0, metadata_1.isOutcomeingLink)(relationMetadata)) {
|
|
213
|
+
return buildOutcomeingLinkQueryString(search, sourceTable, relationMetadata);
|
|
214
|
+
}
|
|
215
|
+
if ((0, metadata_1.isIncomingLink)(relationMetadata)) {
|
|
216
|
+
return buildIncomingLinkQueryString(search, sourceTable, relationMetadata);
|
|
217
|
+
}
|
|
218
|
+
throw new Error('Unsupported Relation type');
|
|
219
|
+
}
|
|
220
|
+
function buildBridgeLinkQueryString(search, sourceTable, bridgeLink) {
|
|
221
|
+
const bridgeTable = bridgeLink.bridgeTable;
|
|
222
|
+
const targetTable = bridgeLink.targetMetadata.tableName;
|
|
223
|
+
const sourceRefKey = `${sourceTable}.${bridgeLink.sourceRefKey}`;
|
|
224
|
+
const targetRefKey = `${targetTable}.${bridgeLink.targetRefKey}`;
|
|
225
|
+
const bridgeSourceFK = `${bridgeTable}.${bridgeLink.bridgeSourceForeignKey}`;
|
|
226
|
+
const bridgeTargetFK = `${bridgeTable}.${bridgeLink.bridgeTargetForeignKey}`;
|
|
227
|
+
const [WHERE_Target, values] = buildWhereQueryString(search, bridgeLink.targetMetadata); // split and filter empty
|
|
228
|
+
const selectTargetRefsQuery = `SELECT ${targetRefKey} FROM ${targetTable} ${WHERE_Target}`;
|
|
229
|
+
const selectSourceRefsQuery = `SELECT ${bridgeSourceFK} FROM ${bridgeTable} WHERE ${bridgeTargetFK} IN (${selectTargetRefsQuery})`;
|
|
230
|
+
const queryString = `${sourceRefKey} IN (${selectSourceRefsQuery})`;
|
|
231
|
+
return [queryString, values];
|
|
232
|
+
}
|
|
233
|
+
function buildIncomingLinkQueryString(search, sourceTable, incomingLink) {
|
|
234
|
+
const targetTable = incomingLink.targetMetadata.tableName;
|
|
235
|
+
const sourceRefKey = `${sourceTable}.${incomingLink.sourceRefKey}`;
|
|
236
|
+
const targetFK = `${targetTable}.${incomingLink.targetForeignKey}`;
|
|
237
|
+
const [WHERE_Target, values] = buildWhereQueryString(search, incomingLink.targetMetadata); // split and filter empty
|
|
238
|
+
const selectTargetRefsQuery = `SELECT ${targetFK} FROM ${targetTable} ${WHERE_Target}`;
|
|
239
|
+
const queryString = `${sourceRefKey} IN (${selectTargetRefsQuery})`;
|
|
240
|
+
return [queryString, values];
|
|
241
|
+
}
|
|
242
|
+
function buildOutcomeingLinkQueryString(search, sourceTable, outcomeingLink) {
|
|
243
|
+
const targetTable = outcomeingLink.targetMetadata.tableName;
|
|
244
|
+
const sourceFK = `${sourceTable}.${outcomeingLink.sourceForeignkey}`;
|
|
245
|
+
const targetRefKey = `${targetTable}.${outcomeingLink.targetRefKey}`;
|
|
246
|
+
const [WHERE_Target, values] = buildWhereQueryString(search, outcomeingLink.targetMetadata); // split and filter empty
|
|
247
|
+
const selectTargetRefsQuery = `SELECT ${targetRefKey} FROM ${targetTable} ${WHERE_Target}`;
|
|
248
|
+
const queryString = `${sourceFK} IN (${selectTargetRefsQuery})`;
|
|
249
|
+
return [queryString, values];
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=sqlite3_query_builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite3_query_builder.js","sourceRoot":"","sources":["../../src/query_builder/sqlite3_query_builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { PaginatedResult } from './paginated_result';
|
|
2
|
+
import { PaginatedSearch } from './paginated_search';
|
|
3
|
+
import { Search } from './search_operators';
|
|
4
|
+
/**
|
|
5
|
+
* create or update one or more entities
|
|
6
|
+
* @param e
|
|
7
|
+
*/
|
|
8
|
+
export type SaveFn<T> = (e: T[]) => Promise<T[]>;
|
|
9
|
+
/**
|
|
10
|
+
* perform a paginated and ordered search on entities
|
|
11
|
+
* if search is not provided, all entities are returned
|
|
12
|
+
* @param search
|
|
13
|
+
*/
|
|
14
|
+
export type SearchFn<T> = (search?: PaginatedSearch<T>) => Promise<PaginatedResult<T>>;
|
|
15
|
+
/**
|
|
16
|
+
* delete entities matching the search parameters
|
|
17
|
+
* @param search
|
|
18
|
+
**/
|
|
19
|
+
export type RemoveFn<T> = (search: Search<T>) => Promise<T[]>;
|
|
20
|
+
export interface Repository<T> {
|
|
21
|
+
/**
|
|
22
|
+
* create or update one or more entities
|
|
23
|
+
* @param e
|
|
24
|
+
*/
|
|
25
|
+
save: SaveFn<T>;
|
|
26
|
+
/**
|
|
27
|
+
* perform a paginated and ordered search on entities
|
|
28
|
+
* if search is not provided, all entities are returned
|
|
29
|
+
* @param search
|
|
30
|
+
*/
|
|
31
|
+
search: SearchFn<T>;
|
|
32
|
+
/**
|
|
33
|
+
* delete entities matching the search parameters
|
|
34
|
+
* @param search
|
|
35
|
+
**/
|
|
36
|
+
remove: RemoveFn<T>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAI5C;;;GAGG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvF;;;IAGI;AACJ,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;AAG9D,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAEhB;;;;OAIG;IACH,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEpB;;;QAGI;IACJ,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ScalarValue } from './misc';
|
|
2
|
+
export declare enum Condition {
|
|
3
|
+
EQUAL = "$_eq",
|
|
4
|
+
LIKE = "$_lk",
|
|
5
|
+
GREATER = "$_gt",
|
|
6
|
+
LESSER = "$_lt",
|
|
7
|
+
NOT = "$_not"
|
|
8
|
+
}
|
|
9
|
+
export interface EqualCondition<T extends ScalarValue> {
|
|
10
|
+
/** `Equal` Condition*/
|
|
11
|
+
[Condition.EQUAL]: T | T[];
|
|
12
|
+
}
|
|
13
|
+
export interface LikeCondition<T extends ScalarValue> {
|
|
14
|
+
/** `Like` Condition*/
|
|
15
|
+
[Condition.LIKE]: T;
|
|
16
|
+
}
|
|
17
|
+
export type RangeCondition<T extends ScalarValue> = {
|
|
18
|
+
/** `Only Greater than` Condition*/
|
|
19
|
+
[Condition.GREATER]: T;
|
|
20
|
+
} | {
|
|
21
|
+
/** `Only Less than` Condition*/
|
|
22
|
+
[Condition.LESSER]: T;
|
|
23
|
+
};
|
|
24
|
+
type Without<T, U> = {
|
|
25
|
+
[P in Exclude<keyof T, keyof U>]?: never;
|
|
26
|
+
};
|
|
27
|
+
type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
|
|
28
|
+
export type Operator<T extends ScalarValue> = XOR<XOR<EqualCondition<T>, LikeCondition<T>>, RangeCondition<T>> & {
|
|
29
|
+
[Condition.NOT]?: true;
|
|
30
|
+
};
|
|
31
|
+
export type Where<FieldType> = FieldType extends ScalarValue ? Operator<FieldType> | FieldType | FieldType[] : FieldType extends Function ? never : FieldType extends Array<infer ArrayType> ? Where<ArrayType> : FieldType extends object ? Search<FieldType> : never;
|
|
32
|
+
export type Search<Entity> = {
|
|
33
|
+
[P in keyof Entity]?: Where<NonNullable<Entity[P]>>;
|
|
34
|
+
} & {
|
|
35
|
+
[Condition.NOT]?: true;
|
|
36
|
+
};
|
|
37
|
+
export declare function isEqualCondition(operator: unknown): operator is EqualCondition<ScalarValue>;
|
|
38
|
+
export declare function isLikeCondition(operator: unknown): operator is LikeCondition<ScalarValue>;
|
|
39
|
+
export declare function isRangeCondition(operator: unknown): operator is RangeCondition<ScalarValue>;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=search_operators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search_operators.d.ts","sourceRoot":"","sources":["../src/search_operators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,WAAW,EAAE,MAAM,QAAQ,CAAC;AAGpD,oBAAY,SAAS;IACpB,KAAK,SAAS;IACd,IAAI,SAAS;IACb,OAAO,SAAS;IAChB,MAAM,SAAS;IACf,GAAG,UAAU;CACb;AAGD,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,WAAW;IACpD,uBAAuB;IACvB,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;CAC3B;AAGD,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,WAAW;IACnD,sBAAsB;IACtB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;CACpB;AAKD,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,WAAW,IAAI;IACnD,mCAAmC;IACnC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;CACvB,GAAG;IACH,gCAAgC;IAChC,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;CACtB,CAAA;AAED,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI;KAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK;CAAE,CAAC;AAClE,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAG5F,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,WAAW,IAAI,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAQ5I,MAAM,MAAM,KAAK,CAAC,SAAS,IAC1B,SAAS,SAAS,WAAW,GAC7B,QAAQ,CAAC,SAAS,CAAC,GAAG,SAAS,GAAG,SAAS,EAAE,GAE7C,SAAS,SAAS,QAAQ,GAC1B,KAAK,GAEL,SAAS,SAAS,KAAK,CAAC,MAAM,SAAS,CAAC,GACxC,KAAK,CAAC,SAAS,CAAC,GAEhB,SAAS,SAAS,MAAM,GACxB,MAAM,CAAC,SAAS,CAAC,GAEjB,KAAK,CAAA;AAEN,MAAM,MAAM,MAAM,CAAC,MAAM,IAAI;KAC3B,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;CACnD,GAAG;IACH,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC;CACvB,CAAC;AAWF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,cAAc,CAAC,WAAW,CAAC,CAE3F;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,aAAa,CAAC,WAAW,CAAC,CAEzF;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,cAAc,CAAC,WAAW,CAAC,CAE3F"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Condition = void 0;
|
|
4
|
+
exports.isEqualCondition = isEqualCondition;
|
|
5
|
+
exports.isLikeCondition = isLikeCondition;
|
|
6
|
+
exports.isRangeCondition = isRangeCondition;
|
|
7
|
+
var Condition;
|
|
8
|
+
(function (Condition) {
|
|
9
|
+
Condition["EQUAL"] = "$_eq";
|
|
10
|
+
Condition["LIKE"] = "$_lk";
|
|
11
|
+
Condition["GREATER"] = "$_gt";
|
|
12
|
+
Condition["LESSER"] = "$_lt";
|
|
13
|
+
Condition["NOT"] = "$_not";
|
|
14
|
+
})(Condition || (exports.Condition = Condition = {}));
|
|
15
|
+
const op = { $_eq: 5, }; // should be invalid
|
|
16
|
+
const op0 = { $_lk: 20 }; // should be invalid
|
|
17
|
+
const op1 = { $_gt: 10, $_lt: 20 }; // should be invalid
|
|
18
|
+
// export function isOperator<T extends ScalarValue>(operator: unknown): operator is Operator<T> {
|
|
19
|
+
// return isScalarValue(operator) ||
|
|
20
|
+
// Array.isArray(operator) ||
|
|
21
|
+
// isEqualCondition(operator) ||
|
|
22
|
+
// isLikeCondition(operator) ||
|
|
23
|
+
// isRangeCondition(operator);
|
|
24
|
+
// }
|
|
25
|
+
function isEqualCondition(operator) {
|
|
26
|
+
return Object.keys(operator).includes(Condition.EQUAL);
|
|
27
|
+
}
|
|
28
|
+
function isLikeCondition(operator) {
|
|
29
|
+
return Object.keys(operator).includes(Condition.LIKE);
|
|
30
|
+
}
|
|
31
|
+
function isRangeCondition(operator) {
|
|
32
|
+
return Object.keys(operator).includes(Condition.GREATER) || Object.keys(operator).includes(Condition.LESSER);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=search_operators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search_operators.js","sourceRoot":"","sources":["../src/search_operators.ts"],"names":[],"mappings":";;;AA4EA,4CAEC;AAED,0CAEC;AAED,4CAEC;AAnFD,IAAY,SAMX;AAND,WAAY,SAAS;IACpB,2BAAc,CAAA;IACd,0BAAa,CAAA;IACb,6BAAgB,CAAA;IAChB,4BAAe,CAAA;IACf,0BAAa,CAAA;AACd,CAAC,EANW,SAAS,yBAAT,SAAS,QAMpB;AA+BD,MAAM,EAAE,GAAqB,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,oBAAoB;AAC/D,MAAM,GAAG,GAAqB,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,oBAAoB;AAChE,MAAM,GAAG,GAAqB,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,oBAAoB;AAyB1E,kGAAkG;AAElG,qCAAqC;AACrC,+BAA+B;AAC/B,kCAAkC;AAClC,iCAAiC;AACjC,gCAAgC;AAChC,IAAI;AAEJ,SAAgB,gBAAgB,CAAC,QAAiB;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,SAAgB,eAAe,CAAC,QAAiB;IAChD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAED,SAAgB,gBAAgB,CAAC,QAAiB;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAC9G,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bitbeater/ssr",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": "20.x || 22.x || 23.x || 24.x"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./query_builder/sqlite3": {
|
|
19
|
+
"default": "./dist/query_builder/sqlite3_query_builder.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"registry": "https://registry.npmjs.org/",
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/bitBeater/ssr.git"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"test": "tsc && tsc --noEmit ./tests/valid_types.ts && node --test -r ./node_modules/ts-node/register/transpile-only.js ./tests/**/*.test.ts"
|
|
32
|
+
},
|
|
33
|
+
"author": "",
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
37
|
+
"@types/node": "^24.3.1",
|
|
38
|
+
"better-sqlite3": "^12.2.0",
|
|
39
|
+
"ts-node": "^10.9.2",
|
|
40
|
+
"type-fest": "^2.14.0"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"iggs-utils": "^2.4.0"
|
|
44
|
+
}
|
|
45
|
+
}
|