rads-db 3.0.84 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.cjs +637 -0
- package/dist/config.d.ts +23 -0
- package/{integrations/lib.mjs → dist/config.mjs} +46 -3
- package/dist/index.cjs +4 -4
- package/dist/index.d.ts +7 -440
- package/dist/index.mjs +5 -5
- package/dist/types-7e792d1f.d.ts +449 -0
- package/integrations/cli.cjs +1 -16
- package/integrations/cli.mjs +1 -16
- package/integrations/node.cjs +54 -62
- package/integrations/node.d.ts +5 -4
- package/integrations/node.mjs +56 -52
- package/integrations/vite.cjs +1 -1
- package/integrations/vite.mjs +1 -1
- package/package.json +8 -2
- package/integrations/lib.cjs +0 -603
- package/integrations/lib.d.ts +0 -1
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { SyntaxKind, createSourceFile, ScriptTarget } from 'typescript';
|
|
4
|
+
import _ from 'lodash';
|
|
5
|
+
|
|
3
6
|
const supportedPrimitiveTypes = ["string", "number", "boolean", "Record<string, string>", "Record<string, any>"];
|
|
4
|
-
|
|
7
|
+
function parseSchema(typescriptFiles) {
|
|
5
8
|
const typeNodesMap = getTypeNodesMap(typescriptFiles);
|
|
6
9
|
const schema = getSchema(typeNodesMap);
|
|
7
10
|
resolveIsExtending(schema);
|
|
@@ -582,3 +585,43 @@ function verifyRelationFields(result) {
|
|
|
582
585
|
}
|
|
583
586
|
}
|
|
584
587
|
}
|
|
588
|
+
|
|
589
|
+
function defineRadsConfig(config) {
|
|
590
|
+
return config;
|
|
591
|
+
}
|
|
592
|
+
function schemaFromFiles(entitiesDir) {
|
|
593
|
+
return async () => {
|
|
594
|
+
if (!fs.existsSync(entitiesDir))
|
|
595
|
+
await fs.promises.mkdir(entitiesDir, { recursive: true });
|
|
596
|
+
const response = await fs.promises.readdir(entitiesDir, { withFileTypes: true });
|
|
597
|
+
const entities = {};
|
|
598
|
+
for (const file of response) {
|
|
599
|
+
if (!file.isFile())
|
|
600
|
+
continue;
|
|
601
|
+
if (!file.name.endsWith(".ts"))
|
|
602
|
+
continue;
|
|
603
|
+
const text = await fs.promises.readFile(path.resolve(entitiesDir, file.name), "utf-8");
|
|
604
|
+
entities[file.name.slice(0, -3)] = text;
|
|
605
|
+
}
|
|
606
|
+
return { schema: parseSchema(entities), entitiesDir };
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
function schemaFromRadsApi(radsApiUrl) {
|
|
610
|
+
return async () => {
|
|
611
|
+
if (!radsApiUrl.endsWith("/"))
|
|
612
|
+
radsApiUrl += "/";
|
|
613
|
+
const url = new URL("radsTunnel", radsApiUrl);
|
|
614
|
+
const fetchResponse = await fetch(url.href, {
|
|
615
|
+
method: "POST",
|
|
616
|
+
headers: { "content-type": "application/json" },
|
|
617
|
+
body: JSON.stringify({ method: "_schema" })
|
|
618
|
+
});
|
|
619
|
+
const schema = await fetchResponse.json();
|
|
620
|
+
if (!schema) {
|
|
621
|
+
throw new Error("Could not download schema from the server. Please check the server URL.");
|
|
622
|
+
}
|
|
623
|
+
return { schema };
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
export { defineRadsConfig, schemaFromFiles, schemaFromRadsApi };
|
package/dist/index.cjs
CHANGED
|
@@ -1273,13 +1273,13 @@ function keepHistory() {
|
|
|
1273
1273
|
};
|
|
1274
1274
|
}
|
|
1275
1275
|
|
|
1276
|
-
function createRadsDb(args) {
|
|
1276
|
+
function createRadsDb(dataSourceKey, args) {
|
|
1277
1277
|
args = { ...args };
|
|
1278
|
-
const s = args.schema || _radsDb.
|
|
1278
|
+
const s = args.schema || _radsDb.schemas[dataSourceKey];
|
|
1279
1279
|
const validators = generateValidators(s);
|
|
1280
1280
|
return generateMethods(s, validators, args);
|
|
1281
1281
|
}
|
|
1282
|
-
function createRadsDbClient(args) {
|
|
1282
|
+
function createRadsDbClient(dataSourceKey, args) {
|
|
1283
1283
|
const radsDbArgs = {
|
|
1284
1284
|
...args,
|
|
1285
1285
|
noComputed: true,
|
|
@@ -1287,7 +1287,7 @@ function createRadsDbClient(args) {
|
|
|
1287
1287
|
keepNulls: true,
|
|
1288
1288
|
driver: restApi(args?.driver)
|
|
1289
1289
|
};
|
|
1290
|
-
const s = radsDbArgs.schema || _radsDb.
|
|
1290
|
+
const s = radsDbArgs.schema || _radsDb.schemas[dataSourceKey];
|
|
1291
1291
|
const validators = generateValidators(s);
|
|
1292
1292
|
return generateMethods(s, validators, radsDbArgs);
|
|
1293
1293
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,441 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { E as EntityDecoratorArgs, U as UiDecoratorArgs, a as UiFieldDecoratorArgs, V as ValidateEntityDecoratorArgs, b as ValidateFieldDecoratorArgs, F as FieldDecoratorArgs, C as ComputedDecoratorArgs, S as Schema, D as DriverConstructor, c as Driver, d as ComputedContext, R as RadsRequestContext, e as CreateRadsDbArgs, f as CreateRadsDbClientArgs } from './types-7e792d1f.js';
|
|
2
|
+
export { N as Change, x as ComputedContextGlobal, k as CreateRadsArgsDrivers, m as CreateRadsDbArgsNormalized, aj as DeepKeys, ae as DeepPartial, ac as DeepPartialWithNulls, ad as DeepPartialWithNullsItem, ak as EntityMethods, w as EnumDefinition, v as FieldDefinition, I as FileSystemNode, u as FileUploadArgs, q as FileUploadDriver, p as FileUploadResult, B as GenerateClientNormalizedOptions, A as GenerateClientOptions, a8 as Get, _ as GetAggArgs, $ as GetAggArgsAgg, a2 as GetAggArgsAny, a5 as GetAggResponse, Z as GetArgs, a1 as GetArgsAny, a4 as GetArgsInclude, O as GetManyArgs, a0 as GetManyArgsAny, a6 as GetManyResponse, a7 as GetResponse, a9 as GetResponseInclude, aa as GetResponseIncludeSelect, ab as GetResponseNoInclude, s as GetRestRoutesArgs, G as GetRestRoutesOptions, t as GetRestRoutesResponse, ag as InverseRelation, M as MinimalDriver, ai as Put, ah as PutArgs, P as PutEffect, g as RadsConfig, h as RadsConfigDataSource, r as RadsDbInstance, L as RadsFeature, y as RadsHookDoc, K as RadsUiSlotDefinition, J as RadsUiSlotName, H as RadsVitePluginOptions, af as Relation, i as RequiredFields, l as RestDriverOptions, z as RestFileUploadDriverOptions, n as SchemaLoadResult, o as SchemaValidators, T as TypeDefinition, j as ValidateStringDecoratorArgs, Q as VerifyManyArgs, a3 as VerifyManyArgsAny, X as VerifyManyResponse, Y as Where, W as WhereJsonContains } from './types-7e792d1f.js';
|
|
3
|
+
import { RadsDb } from '_rads-db';
|
|
2
4
|
export { RadsDb } from '_rads-db';
|
|
3
5
|
|
|
4
|
-
type MaybePromise$1<T> = Promise<T> | T;
|
|
5
|
-
type Change<T> = {
|
|
6
|
-
[K in keyof T]?: T[K] extends any[] ? T[K] : T[K] extends {} ? Change<T[K]> : T[K];
|
|
7
|
-
};
|
|
8
|
-
interface GetManyArgs<EN extends keyof EntityMeta> extends GetArgs<EN> {
|
|
9
|
-
cursor?: string | null;
|
|
10
|
-
maxItemCount?: number;
|
|
11
|
-
orderBy?: string;
|
|
12
|
-
}
|
|
13
|
-
interface VerifyManyArgs<EN extends keyof EntityMeta> extends GetManyArgs<EN> {
|
|
14
|
-
recompute?: string[];
|
|
15
|
-
dryRun?: boolean;
|
|
16
|
-
}
|
|
17
|
-
interface VerifyManyResponse {
|
|
18
|
-
cursor: string | null;
|
|
19
|
-
correctCount: number;
|
|
20
|
-
incorrectCount: number;
|
|
21
|
-
incorrectDocs: {
|
|
22
|
-
id: string;
|
|
23
|
-
diff: any;
|
|
24
|
-
toRemove?: any;
|
|
25
|
-
}[];
|
|
26
|
-
}
|
|
27
|
-
type Where<EN extends keyof EntityMeta> = EntityMeta[EN]['whereType'] & {
|
|
28
|
-
_not?: Where<EN>;
|
|
29
|
-
_and?: Where<EN>[];
|
|
30
|
-
_or?: Where<EN>[];
|
|
31
|
-
};
|
|
32
|
-
interface GetArgs<EN extends keyof EntityMeta> {
|
|
33
|
-
where?: Where<EN>;
|
|
34
|
-
include?: GetArgsInclude<EN>;
|
|
35
|
-
}
|
|
36
|
-
interface GetAggArgs<EN extends keyof EntityMeta> {
|
|
37
|
-
where?: Where<EN>;
|
|
38
|
-
agg: GetAggArgsAgg<EN>;
|
|
39
|
-
}
|
|
40
|
-
type GetAggArgsAgg<EN extends keyof EntityMeta, F extends string = EntityMeta[EN]['aggregates']> = ('_count' | `${F}_min` | `${F}_max` | `${F}_sum`)[];
|
|
41
|
-
type GetManyArgsAny = GetManyArgs<any>;
|
|
42
|
-
type GetArgsAny = GetArgs<any>;
|
|
43
|
-
type GetAggArgsAny = GetAggArgs<any>;
|
|
44
|
-
type VerifyManyArgsAny = VerifyManyArgs<any>;
|
|
45
|
-
type RelationsAndNestedObjects<EN extends keyof EntityMeta> = EntityMeta[EN]['relations'] & EntityMeta[EN]['nestedObjects'];
|
|
46
|
-
type GetArgsInclude<EN extends keyof EntityMeta, R extends keyof RelationsAndNestedObjects<EN> = keyof RelationsAndNestedObjects<EN>> = [R] extends [never] ? {
|
|
47
|
-
_pick?: EntityMeta[EN]['primitives'][];
|
|
48
|
-
} : {
|
|
49
|
-
_pick?: EntityMeta[EN]['primitives'][];
|
|
50
|
-
} & {
|
|
51
|
-
[K in R]?: GetArgsInclude<RelationsAndNestedObjects<EN>[K]['entityName']>;
|
|
52
|
-
};
|
|
53
|
-
type GetAggResponse<EN extends keyof EntityMeta, A extends GetAggArgs<EN>> = {
|
|
54
|
-
[K in A['agg'][0]]: K extends '_count' ? number : number | undefined;
|
|
55
|
-
};
|
|
56
|
-
interface GetManyResponse<EN extends keyof EntityMeta, A extends GetArgs<EN>> {
|
|
57
|
-
nodes: GetResponse<EN, A>[];
|
|
58
|
-
cursor: string | null;
|
|
59
|
-
}
|
|
60
|
-
type GetResponse<EN extends keyof EntityMeta, A extends GetArgs<EN>> = A extends {
|
|
61
|
-
include: any;
|
|
62
|
-
} ? GetResponseInclude<EN, A['include']> : GetResponseNoInclude<EN>;
|
|
63
|
-
type Get<EntityName extends keyof EntityMeta, Include extends keyof EntityMeta[EntityName]['relations'] | GetArgsInclude<EntityName> = {}> = [Include] extends [Record<string, any>] ? GetResponse<EntityName, {
|
|
64
|
-
include: Include;
|
|
65
|
-
}> : GetResponse<EntityName, {
|
|
66
|
-
include: {
|
|
67
|
-
[K in Include]: {};
|
|
68
|
-
};
|
|
69
|
-
}>;
|
|
70
|
-
type RelationData<EN extends keyof EntityMeta, K extends keyof EntityMeta[EN]['relations']> = Pick<EntityMeta[EN]['relations'][K]['entity'], EntityMeta[EN]['relations'][K]['denormFields']>;
|
|
71
|
-
type KeepArray<TMaybeArray, TType> = NonNullable<TMaybeArray> extends any[] ? TType[] : TType;
|
|
72
|
-
type GetResponseInclude<EN extends keyof EntityMeta, I extends GetArgsInclude<EN>> = I extends {
|
|
73
|
-
_pick: string[];
|
|
74
|
-
} ? GetResponseIncludeSelect<EN, I> : {
|
|
75
|
-
[K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof I ? KeepArray<EntityMeta[EN]['type'][K], GetResponseInclude<EntityMeta[EN]['relations'][K]['entityName'], I[K]>> : KeepArray<EntityMeta[EN]['type'][K], RelationData<EN, K>> : EntityMeta[EN]['type'][K];
|
|
76
|
-
};
|
|
77
|
-
interface GetResponseIncludeSelect<EN extends keyof EntityMeta, I> {
|
|
78
|
-
}
|
|
79
|
-
type GetResponseNoInclude<EN extends keyof EntityMeta> = {
|
|
80
|
-
[K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? KeepArray<EntityMeta[EN]['type'][K], RelationData<EN, K>> : EntityMeta[EN]['type'][K];
|
|
81
|
-
};
|
|
82
|
-
type DeepPartialWithNulls<T> = {
|
|
83
|
-
[K in keyof T]?: NonNullable<T[K]> extends any[] ? DeepPartialWithNullsItem<NonNullable<T[K]>[number]>[] : DeepPartialWithNullsItem<NonNullable<T[K]>>;
|
|
84
|
-
};
|
|
85
|
-
type DeepPartialWithNullsItem<T> = T extends {
|
|
86
|
-
id: string;
|
|
87
|
-
} ? {
|
|
88
|
-
id: string;
|
|
89
|
-
} | null : T extends Record<string, any> ? DeepPartialWithNulls<T> | null : T | null;
|
|
90
|
-
type DeepPartial<T> = {
|
|
91
|
-
[K in keyof T]?: NonNullable<T[K]> extends any[] ? DeepPartial<NonNullable<T[K]>[number]>[] : NonNullable<T[K]> extends Record<string, any> ? DeepPartial<T[K]> : T[K];
|
|
92
|
-
};
|
|
93
|
-
/** Indicates that this field is a relation to another entity in the database.
|
|
94
|
-
* Only id will be stored in the database.
|
|
95
|
-
* If you want to store additional fields, please, pass them as the second type argument */
|
|
96
|
-
type Relation<T extends {
|
|
97
|
-
id: any;
|
|
98
|
-
}, K extends Exclude<keyof T, 'id'> = never> = Pick<T, K | 'id'>;
|
|
99
|
-
/** Indicates that this is computed field - all documents that point to this document via Relation<>.
|
|
100
|
-
* Note: this field is not stored in the database at all. Returns up to 100 items and doesn't support pagination
|
|
101
|
-
* If you need more control, please, use separate request instead.
|
|
102
|
-
*/
|
|
103
|
-
type InverseRelation<EN extends keyof EntityMeta, _Field extends keyof EntityMeta[EN]['relations']> = EntityMeta[EN]['type'];
|
|
104
|
-
type PutArgs<T> = {
|
|
105
|
-
id: string;
|
|
106
|
-
} & DeepPartialWithNulls<T>;
|
|
107
|
-
type Put<EntityName extends keyof EntityMeta> = PutArgs<EntityMeta[EntityName]['type']>;
|
|
108
|
-
type DeepKeys<T> = T extends object ? {
|
|
109
|
-
[K in (string | number) & keyof T]: `${`.${K}` | (`${K}` extends `${number}` ? `[${K}]` : never)}${'' | DeepKeys<T[K]>}`;
|
|
110
|
-
}[(string | number) & keyof T] : never;
|
|
111
|
-
interface EntityMethods<E, EN extends keyof EntityMeta> {
|
|
112
|
-
/** Returns object with with random UUID as `id` and prefilled default values */
|
|
113
|
-
construct(defaultValues?: DeepPartial<E>): E;
|
|
114
|
-
/** Used to access underlying mechanism of storage directly.
|
|
115
|
-
* Warning: bypasses all rads features - schema won't be validated, default values won't be filled, etc. */
|
|
116
|
-
driver: Driver;
|
|
117
|
-
get<A extends GetArgs<EN>>(args: A, ctx?: RadsRequestContext): MaybePromise$1<GetResponse<EN, A>>;
|
|
118
|
-
getMany<A extends GetManyArgs<EN>>(args?: A, ctx?: RadsRequestContext): MaybePromise$1<GetManyResponse<EN, A>>;
|
|
119
|
-
getAgg<A extends GetAggArgs<EN>>(args: A, ctx?: RadsRequestContext): MaybePromise$1<GetAggResponse<EN, A>>;
|
|
120
|
-
getAll<A extends GetManyArgs<EN>>(args?: A, ctx?: RadsRequestContext): MaybePromise$1<GetManyResponse<EN, A>['nodes']>;
|
|
121
|
-
put(data: PutArgs<E>, ctx?: RadsRequestContext): MaybePromise$1<GetResponseNoInclude<EN>>;
|
|
122
|
-
putMany(data: PutArgs<E>[], ctx?: RadsRequestContext): MaybePromise$1<GetResponseNoInclude<EN>[]>;
|
|
123
|
-
verifyMany<A extends VerifyManyArgs<EN>>(args?: A, ctx?: RadsRequestContext): MaybePromise$1<VerifyManyResponse>;
|
|
124
|
-
verifyAll<A extends VerifyManyArgs<EN>>(args?: A, ctx?: RadsRequestContext): MaybePromise$1<Pick<VerifyManyResponse, 'correctCount' | 'incorrectCount'>>;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
type MaybePromise<T> = Promise<T> | T;
|
|
128
|
-
type RequiredFields<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
129
|
-
type ValidateFieldDecoratorArgs<T> = T extends string ? ValidateStringDecoratorArgs : T extends number ? ValidateNumberDecoratorArgs : ValidateAnyDecoratorArgs;
|
|
130
|
-
interface ValidateEntityDecoratorArgs {
|
|
131
|
-
}
|
|
132
|
-
interface ValidateAnyDecoratorArgs {
|
|
133
|
-
}
|
|
134
|
-
interface ValidateNumberDecoratorArgs {
|
|
135
|
-
isWhole?: boolean;
|
|
136
|
-
min?: number;
|
|
137
|
-
max?: number;
|
|
138
|
-
}
|
|
139
|
-
interface ValidateStringDecoratorArgs {
|
|
140
|
-
preset?: 'text' | 'html' | 'markdown' | 'alpha' | 'alphanum' | 'number' | 'decimalNumber' | 'email' | 'icon' | 'imageUrl' | 'fileUrl' | 'absoluteUrl' | 'relativeUrl' | 'phoneNumber' | 'datetime' | 'date' | 'time' | 'timeInterval' | 'duration';
|
|
141
|
-
regex?: RegExp | string;
|
|
142
|
-
minLength?: number;
|
|
143
|
-
maxLength?: number;
|
|
144
|
-
}
|
|
145
|
-
interface UiFieldDecoratorArgs {
|
|
146
|
-
/** User-friendly name of the entity (singular).
|
|
147
|
-
* Used as editor field label and column name in exports.
|
|
148
|
-
* Defaults to `_.startCase(fieldName)` */
|
|
149
|
-
name?: string;
|
|
150
|
-
/** Icon to display as editor field icon. E.g. `mdi-user`. */
|
|
151
|
-
icon?: string;
|
|
152
|
-
/** Free text - hint to display under editor field in UI */
|
|
153
|
-
hint?: string;
|
|
154
|
-
/** If true, field is hidden from the rads-ui */
|
|
155
|
-
isHidden?: boolean;
|
|
156
|
-
/** If true, field is readonly in the rads-ui */
|
|
157
|
-
isReadonly?: boolean;
|
|
158
|
-
/** If true, field can be edited only during creation */
|
|
159
|
-
isImmutable?: boolean;
|
|
160
|
-
/** TODO: Preferred component to display or edit this value */
|
|
161
|
-
component?: string;
|
|
162
|
-
}
|
|
163
|
-
interface UiDecoratorArgs<T = any> {
|
|
164
|
-
/** User-friendly name of the entity (singular).
|
|
165
|
-
* Defaults to `_.startCase(entityName).split(' ').slice(1).join(' ')` (i.e. removes the prefix) */
|
|
166
|
-
name?: string;
|
|
167
|
-
/** User-friendly name of the entity (plural)
|
|
168
|
-
* Defaults to `pluralize(entityName)` */
|
|
169
|
-
namePlural?: string;
|
|
170
|
-
/** Icon to display near this entity. Defaults to `mdi-file-outline` */
|
|
171
|
-
icon?: string;
|
|
172
|
-
/** Field that contains "name" value.
|
|
173
|
-
* Used by Rads UI to set up default search and display behaviour
|
|
174
|
-
* Defaults to (if field with such name exists) `name` > `title` > `id` */
|
|
175
|
-
nameField?: keyof T;
|
|
176
|
-
/** Some important-to-know fields, like "id" or "code" or "description".
|
|
177
|
-
* Used by Rads UI to display in the list view
|
|
178
|
-
* Defaults to `["id"]` */
|
|
179
|
-
captionFields?: (keyof T)[];
|
|
180
|
-
/** Field that contains value that points to either:
|
|
181
|
-
* - icon (e.g. 'mdi-test')
|
|
182
|
-
* - image URL (e.g. 'https://radsjs.com/icon.png'). Make sure it's not too big (around 200x200px)
|
|
183
|
-
* Used by Rads UI to display it in the list view.
|
|
184
|
-
* Defaults to (if exists) `image` > `photo` > `thumbnail` > `icon` > undefined */
|
|
185
|
-
iconField?: keyof T;
|
|
186
|
-
/** Search operator that's used in simple search by name. Defaults to 'istartsWith' */
|
|
187
|
-
searchOperator?: 'startsWith' | 'istartsWith' | 'contains' | 'icontains';
|
|
188
|
-
/** Defines section name in rads-ui where this entity will be grouped under */
|
|
189
|
-
group?: string;
|
|
190
|
-
/** If true, field is hidden from the rads-ui */
|
|
191
|
-
isHidden?: boolean;
|
|
192
|
-
}
|
|
193
|
-
interface EntityDecoratorArgs {
|
|
194
|
-
driver?: string;
|
|
195
|
-
}
|
|
196
|
-
interface ComputedDecoratorArgs {
|
|
197
|
-
preset: string;
|
|
198
|
-
}
|
|
199
|
-
interface FieldDecoratorArgs {
|
|
200
|
-
relation?: Function;
|
|
201
|
-
}
|
|
202
|
-
type DriverConstructor = (schema: Schema, entity: string) => MinimalDriver;
|
|
203
|
-
interface CreateRadsArgsDrivers {
|
|
204
|
-
default: DriverConstructor;
|
|
205
|
-
[driverName: string]: DriverConstructor;
|
|
206
|
-
}
|
|
207
|
-
interface RestDriverOptions {
|
|
208
|
-
/** @default '/api' */
|
|
209
|
-
baseUrl?: string;
|
|
210
|
-
fetch?: (url: string, options?: {
|
|
211
|
-
body?: any;
|
|
212
|
-
headers?: any;
|
|
213
|
-
method?: string;
|
|
214
|
-
}) => any;
|
|
215
|
-
getHeaders?: (radsDbRequest: {
|
|
216
|
-
args?: any;
|
|
217
|
-
context?: RadsRequestContext;
|
|
218
|
-
}) => Record<string, string> | undefined;
|
|
219
|
-
}
|
|
220
|
-
interface CreateRadsDbArgs {
|
|
221
|
-
schema?: Schema;
|
|
222
|
-
driver?: DriverConstructor | CreateRadsArgsDrivers;
|
|
223
|
-
fileUploadDriver?: FileUploadDriver;
|
|
224
|
-
noComputed?: boolean;
|
|
225
|
-
noCustomDrivers?: boolean;
|
|
226
|
-
computed?: Record<string, Record<string, Function> | {
|
|
227
|
-
_entity?: {
|
|
228
|
-
compute: Function;
|
|
229
|
-
recomputeWhen: Record<string, (args: any) => boolean>;
|
|
230
|
-
};
|
|
231
|
-
}>;
|
|
232
|
-
beforeGet?: (args: GetArgsAny, ctx: RadsRequestContext, context: ComputedContext) => MaybePromise<void>;
|
|
233
|
-
context?: Record<string, any> & Omit<RadsRequestContext, 'dryRun' | 'silent'>;
|
|
234
|
-
features?: RadsFeature[];
|
|
235
|
-
keepNulls?: boolean;
|
|
236
|
-
}
|
|
237
|
-
type CreateRadsDbArgsNormalized = RequiredFields<CreateRadsDbArgs, 'computed' | 'features'> & {
|
|
238
|
-
driver: CreateRadsArgsDrivers;
|
|
239
|
-
};
|
|
240
|
-
type CreateRadsDbClientArgs = Omit<CreateRadsDbArgs, 'noComputed' | 'noCustomDrivers' | 'driver'> & {
|
|
241
|
-
driver?: RestDriverOptions;
|
|
242
|
-
};
|
|
243
|
-
type Schema = Record<string, TypeDefinition>;
|
|
244
|
-
type SchemaValidators = Record<string, (item: any) => any>;
|
|
245
|
-
interface TypeDefinition {
|
|
246
|
-
name: string;
|
|
247
|
-
decorators: Record<string, Record<string, any>>;
|
|
248
|
-
comment?: string;
|
|
249
|
-
precomputedFields?: string[];
|
|
250
|
-
computedFields?: string[];
|
|
251
|
-
nestedTypeFields?: string[];
|
|
252
|
-
fields?: Record<string, FieldDefinition>;
|
|
253
|
-
enumValues?: Record<string, EnumDefinition>;
|
|
254
|
-
handle?: string;
|
|
255
|
-
handlePlural?: string;
|
|
256
|
-
isExtending?: string;
|
|
257
|
-
keepHistoryFields?: string[];
|
|
258
|
-
sourceFile?: string;
|
|
259
|
-
}
|
|
260
|
-
interface FileUploadResult {
|
|
261
|
-
url: string;
|
|
262
|
-
}
|
|
263
|
-
interface FileUploadDriver {
|
|
264
|
-
driverName: string;
|
|
265
|
-
client?: any;
|
|
266
|
-
uploadFile(args: FileUploadArgs, ctx?: RadsRequestContext): Promise<FileUploadResult>;
|
|
267
|
-
}
|
|
268
|
-
interface GetRestRoutesOptions {
|
|
269
|
-
/** Instance of RadsDb */
|
|
270
|
-
db: RadsDb;
|
|
271
|
-
/** Prefix to use for generated routes. Defaults to "/api/" */
|
|
272
|
-
prefix?: string;
|
|
273
|
-
/** By default, rest endpoints for manipulating local files are exposed when NODE_ENV === 'development'. Set to true or false to override. */
|
|
274
|
-
exposeFilesystem?: boolean;
|
|
275
|
-
}
|
|
276
|
-
interface GetRestRoutesArgs {
|
|
277
|
-
body?: any;
|
|
278
|
-
context: any;
|
|
279
|
-
headers: Record<string, string | undefined>;
|
|
280
|
-
}
|
|
281
|
-
type GetRestRoutesResponse = Record<string, Partial<Record<string, (args: GetRestRoutesArgs, ctx?: RadsRequestContext) => Promise<any>>>>;
|
|
282
|
-
interface FileUploadArgs {
|
|
283
|
-
blob: Blob;
|
|
284
|
-
fileName: string;
|
|
285
|
-
containerName?: string;
|
|
286
|
-
options?: any;
|
|
287
|
-
}
|
|
288
|
-
interface MinimalDriver {
|
|
289
|
-
driverName: string;
|
|
290
|
-
/** raw underlying data access service - e.g. sql client or azure storage client */
|
|
291
|
-
client?: any;
|
|
292
|
-
putMany: (item: Record<string, any>[], ctx?: RadsRequestContext) => MaybePromise<void>;
|
|
293
|
-
getMany: (args?: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise<{
|
|
294
|
-
nodes: Record<string, any>[];
|
|
295
|
-
cursor: string | null;
|
|
296
|
-
}>;
|
|
297
|
-
get?: (args: GetArgsAny, ctx?: RadsRequestContext) => MaybePromise<Record<string, any> | null>;
|
|
298
|
-
getAll?: (args: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise<Record<string, any>[]>;
|
|
299
|
-
getAgg?: (args: GetAggArgsAny, ctx?: RadsRequestContext) => MaybePromise<Record<string, any>>;
|
|
300
|
-
deleteMany?: (args: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise<{
|
|
301
|
-
nodes: Record<string, any>[];
|
|
302
|
-
cursor: string | null;
|
|
303
|
-
}>;
|
|
304
|
-
deleteAll?: (args: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise<Record<string, any>[]>;
|
|
305
|
-
put?: (data: Record<string, any>, ctx?: RadsRequestContext) => MaybePromise<void>;
|
|
306
|
-
verifyMany?: (args?: VerifyManyArgsAny, ctx?: RadsRequestContext) => MaybePromise<VerifyManyResponse>;
|
|
307
|
-
}
|
|
308
|
-
type Driver = Required<Omit<MinimalDriver, 'verifyMany' | 'client'>> & Pick<MinimalDriver, 'verifyMany' | 'client'>;
|
|
309
|
-
interface FieldDefinition {
|
|
310
|
-
name: string;
|
|
311
|
-
type: string;
|
|
312
|
-
defaultValue?: any;
|
|
313
|
-
defaultValueClass?: string;
|
|
314
|
-
defaultValueCopyFrom?: string;
|
|
315
|
-
isRequired?: boolean;
|
|
316
|
-
isArray?: boolean;
|
|
317
|
-
isRelation?: boolean;
|
|
318
|
-
isInverseRelation?: boolean;
|
|
319
|
-
isChange?: boolean;
|
|
320
|
-
inverseRelationField?: string;
|
|
321
|
-
relationDenormFields?: string[];
|
|
322
|
-
comment?: string;
|
|
323
|
-
decorators?: Record<string, Record<string, any>>;
|
|
324
|
-
}
|
|
325
|
-
interface EnumDefinition {
|
|
326
|
-
name: string;
|
|
327
|
-
comment?: string;
|
|
328
|
-
decorators?: Record<string, Record<string, any>>;
|
|
329
|
-
}
|
|
330
|
-
interface ComputedContextGlobal {
|
|
331
|
-
db: RadsDb;
|
|
332
|
-
schema: Schema;
|
|
333
|
-
validators: SchemaValidators;
|
|
334
|
-
options: CreateRadsDbArgs;
|
|
335
|
-
drivers: Record<string, Driver>;
|
|
336
|
-
effects: Record<string, PutEffect[]>;
|
|
337
|
-
}
|
|
338
|
-
interface ComputedContext extends ComputedContextGlobal {
|
|
339
|
-
typeName: string;
|
|
340
|
-
handle: string;
|
|
341
|
-
}
|
|
342
|
-
interface RadsHookDoc {
|
|
343
|
-
/** Updated document that will be saved to the database */
|
|
344
|
-
doc: any;
|
|
345
|
-
/** Previous version of document - i.e. one that is currently in the database (before saving) */
|
|
346
|
-
oldDoc: any;
|
|
347
|
-
/** If current entity is event sourcing aggregate, you can access all events in the chronological order */
|
|
348
|
-
events?: any;
|
|
349
|
-
}
|
|
350
|
-
interface PutEffect {
|
|
351
|
-
beforePut?: (computedContext: ComputedContext, docs: RadsHookDoc[], ctx: RadsRequestContext) => MaybePromise<any>;
|
|
352
|
-
afterPut: (computedContext: ComputedContext, docs: RadsHookDoc[], beforePutResult: any, ctx: RadsRequestContext) => MaybePromise<any>;
|
|
353
|
-
}
|
|
354
|
-
interface RestFileUploadDriverOptions {
|
|
355
|
-
/** @default '/api' */
|
|
356
|
-
baseUrl?: string;
|
|
357
|
-
fetch?: (url: string, options?: {
|
|
358
|
-
body?: any;
|
|
359
|
-
headers?: any;
|
|
360
|
-
method?: string;
|
|
361
|
-
}) => any;
|
|
362
|
-
/** If true, "multipart/form-data" body will be used (sometimes causes problems in serverless environments).
|
|
363
|
-
* Otherwise, "application/json" body (with base64-encoded binary content) will be used */
|
|
364
|
-
useFormData?: boolean;
|
|
365
|
-
}
|
|
366
|
-
type GenerateClientOptions = GenerateClientNormalizedOptions;
|
|
367
|
-
interface GenerateClientNormalizedOptions {
|
|
368
|
-
/** For servers - path to your entities directory, e.g. "./entities" */
|
|
369
|
-
entitiesDir?: string;
|
|
370
|
-
/** For client-only integrations - base url of your API, e.g. "https://my-website/api" */
|
|
371
|
-
apiUrl?: string;
|
|
372
|
-
}
|
|
373
|
-
interface RadsVitePluginOptions extends GenerateClientOptions {
|
|
374
|
-
/** To simplify debugging, makes modules available on window.
|
|
375
|
-
* For example, "/src/stores/userStore.ts" will be available at window.stores.userStore.
|
|
376
|
-
* You can pass the regex - if filename satisfies it, it will be exposed.
|
|
377
|
-
* Path inside window is determined by first matching group in said regex.
|
|
378
|
-
* If `true`, default regex is used - `/\/src\/((services|stores)\/(.+))\.[tj]s$/` */
|
|
379
|
-
exposeModulesInDev?: boolean | RegExp;
|
|
380
|
-
}
|
|
381
|
-
interface RadsRequestContext {
|
|
382
|
-
_logs?: any[];
|
|
383
|
-
log?: (requestInfo: any) => void;
|
|
384
|
-
getUser?: () => {
|
|
385
|
-
id: string;
|
|
386
|
-
role: string;
|
|
387
|
-
} | undefined;
|
|
388
|
-
/** If true, no changes made to the database - instead, all changes are returned as logs */
|
|
389
|
-
dryRun?: boolean;
|
|
390
|
-
/** (Not supported yet) If true, updatedAt/updatedBy properties are not updated, and log records are not created */
|
|
391
|
-
silent?: boolean;
|
|
392
|
-
/** Mostly for internal use. When entity name is specified, indicates that calling put* on this entity is allowed, even if it's marked as @precomputed or @readonly */
|
|
393
|
-
skipPrecomputedCheckFor?: string;
|
|
394
|
-
/** Method that was called - get, getAll, getMany, getAgg, put, putMany, etc */
|
|
395
|
-
method?: 'get' | 'getAll' | 'getMany' | 'getAgg' | 'put' | 'putMany' | 'deleteMany' | 'deleteAll';
|
|
396
|
-
/** if true, all cache layers will be bypassed */
|
|
397
|
-
noCache?: boolean;
|
|
398
|
-
[key: string]: any;
|
|
399
|
-
}
|
|
400
|
-
interface FileSystemNode {
|
|
401
|
-
path: string;
|
|
402
|
-
size?: number;
|
|
403
|
-
type: 'blob' | 'tree';
|
|
404
|
-
}
|
|
405
|
-
interface WhereJsonContains {
|
|
406
|
-
/** Checks for existence of this path inside json object
|
|
407
|
-
* Example: "meta.countries[0].name". */
|
|
408
|
-
path: string;
|
|
409
|
-
/** Checks if value from "path" is exactly null. Note: it is not the same as not having the key in the object. */
|
|
410
|
-
isNull?: boolean;
|
|
411
|
-
/** Checks if value from "path" equals provided value */
|
|
412
|
-
value?: number | string | boolean;
|
|
413
|
-
}
|
|
414
|
-
type RadsUiSlotName = 'entityListActions' | 'entityActions' | 'fieldActions';
|
|
415
|
-
interface RadsUiSlotDefinition {
|
|
416
|
-
entityName?: string | {
|
|
417
|
-
regExp: string;
|
|
418
|
-
};
|
|
419
|
-
fieldName?: string | {
|
|
420
|
-
regExp: string;
|
|
421
|
-
};
|
|
422
|
-
label: string;
|
|
423
|
-
icon?: string;
|
|
424
|
-
endpoint: string;
|
|
425
|
-
}
|
|
426
|
-
interface RadsFeature {
|
|
427
|
-
name: string;
|
|
428
|
-
radsUiSlots?: Record<RadsUiSlotName, RadsUiSlotDefinition[]>;
|
|
429
|
-
init?: (db: Record<string, any>, context: ComputedContextGlobal) => void;
|
|
430
|
-
enhanceEntityMethods?: (context: ComputedContext, entityMethodsObj: EntityMethods<any, any>) => void;
|
|
431
|
-
beforeGet?: (args: GetArgsAny, ctx: RadsRequestContext, context: ComputedContext) => MaybePromise<any>;
|
|
432
|
-
afterGet?: (items: any[], args: GetArgsAny, ctx: RadsRequestContext, context: ComputedContext) => MaybePromise<void>;
|
|
433
|
-
beforePut?: (items: RadsHookDoc[], ctx: RadsRequestContext, computedContext: ComputedContext) => void;
|
|
434
|
-
afterPut?: (items: RadsHookDoc[], ctx: RadsRequestContext, computedContext: ComputedContext) => void;
|
|
435
|
-
beforeUploadFile?: (args: FileUploadArgs) => MaybePromise<any>;
|
|
436
|
-
afterUploadFile?: (result: FileUploadResult, args: FileUploadArgs) => MaybePromise<void>;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
6
|
declare function entity<T>(meta?: EntityDecoratorArgs): (classConstructor: new () => T, _ctx?: ClassDecoratorContext<any>) => void;
|
|
440
7
|
declare function ui<T>(args: T extends new () => any ? UiDecoratorArgs<InstanceType<T>> : UiFieldDecoratorArgs): (classConstructor: T, _ctx?: ClassDecoratorContext | ClassFieldDecoratorContext) => void;
|
|
441
8
|
declare function validate<T, C, F>(args: T extends new () => any ? ValidateEntityDecoratorArgs : ValidateFieldDecoratorArgs<F>): (classConstructor: T, _ctx?: ClassDecoratorContext | ClassFieldDecoratorContext<C, F>) => void;
|
|
@@ -459,12 +26,12 @@ declare function cleanUndefinedAndNull(obj: Record<string, any>, isChange?: bool
|
|
|
459
26
|
* Creates instance of rads db - object that provides access to all entities.
|
|
460
27
|
* Intended to be used on the backend. On the client you may want to opt for "createRadsDbClient" instead.
|
|
461
28
|
* */
|
|
462
|
-
declare function createRadsDb(args?: CreateRadsDbArgs): RadsDb;
|
|
29
|
+
declare function createRadsDb<T extends keyof RadsDb>(dataSourceKey: T, args?: CreateRadsDbArgs): RadsDb[T];
|
|
463
30
|
/**
|
|
464
31
|
* Creates instance of rads db client - object that provides access to all entities.
|
|
465
32
|
* Intended to be used on the frontend. Uses "fetch" to communicate with the server's API.
|
|
466
|
-
* It is a shortcut for `createRadsDb({ driver: radsRestApi(), noComputed: true, noCustomDrivers: true })`
|
|
33
|
+
* It is a shortcut for `createRadsDb('db', { driver: radsRestApi(), noComputed: true, noCustomDrivers: true })`
|
|
467
34
|
*/
|
|
468
|
-
declare function createRadsDbClient(args?: CreateRadsDbClientArgs): RadsDb;
|
|
35
|
+
declare function createRadsDbClient<T extends keyof RadsDb>(dataSourceKey: T, args?: CreateRadsDbClientArgs): RadsDb[T];
|
|
469
36
|
|
|
470
|
-
export {
|
|
37
|
+
export { ComputedContext, ComputedDecoratorArgs, CreateRadsDbArgs, CreateRadsDbClientArgs, Driver, DriverConstructor, EntityDecoratorArgs, FieldDecoratorArgs, RadsRequestContext, Schema, UiDecoratorArgs, UiFieldDecoratorArgs, ValidateEntityDecoratorArgs, ValidateFieldDecoratorArgs, cleanUndefinedAndNull, computed, createRadsDb, createRadsDbClient, diff, entity, field, getDriverInstance, handlePrecomputed, keepHistory, merge, precomputed, ui, validate };
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { z, ZodNullable, ZodOptional, ZodLazy, ZodObject, ZodError } from 'zod';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import { v4 } from 'uuid';
|
|
4
4
|
import createMerge from '@fastify/deepmerge';
|
|
5
|
-
import {
|
|
5
|
+
import { schemas } from '_rads-db';
|
|
6
6
|
|
|
7
7
|
function generateValidators(schema) {
|
|
8
8
|
const zodSchemas = {};
|
|
@@ -1266,13 +1266,13 @@ function keepHistory() {
|
|
|
1266
1266
|
};
|
|
1267
1267
|
}
|
|
1268
1268
|
|
|
1269
|
-
function createRadsDb(args) {
|
|
1269
|
+
function createRadsDb(dataSourceKey, args) {
|
|
1270
1270
|
args = { ...args };
|
|
1271
|
-
const s = args.schema ||
|
|
1271
|
+
const s = args.schema || schemas[dataSourceKey];
|
|
1272
1272
|
const validators = generateValidators(s);
|
|
1273
1273
|
return generateMethods(s, validators, args);
|
|
1274
1274
|
}
|
|
1275
|
-
function createRadsDbClient(args) {
|
|
1275
|
+
function createRadsDbClient(dataSourceKey, args) {
|
|
1276
1276
|
const radsDbArgs = {
|
|
1277
1277
|
...args,
|
|
1278
1278
|
noComputed: true,
|
|
@@ -1280,7 +1280,7 @@ function createRadsDbClient(args) {
|
|
|
1280
1280
|
keepNulls: true,
|
|
1281
1281
|
driver: restApi(args?.driver)
|
|
1282
1282
|
};
|
|
1283
|
-
const s = radsDbArgs.schema ||
|
|
1283
|
+
const s = radsDbArgs.schema || schemas[dataSourceKey];
|
|
1284
1284
|
const validators = generateValidators(s);
|
|
1285
1285
|
return generateMethods(s, validators, radsDbArgs);
|
|
1286
1286
|
}
|