rads-db 0.1.8 → 0.1.11
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/index.cjs +8 -8
- package/dist/index.d.ts +54 -28
- package/dist/index.mjs +7 -7
- package/drivers/restApi.d.ts +1 -1
- package/integrations/cli.cjs +7 -0
- package/integrations/cli.d.ts +2 -0
- package/integrations/cli.mjs +3 -0
- package/integrations/node.cjs +110 -5
- package/integrations/node.mjs +124 -5
- package/integrations/nuxtModuleHandler.cjs +2 -1
- package/integrations/nuxtModuleHandler.mjs +2 -1
- package/package.json +8 -2
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const defaultSchema = require('.rads-db/schema.json');
|
|
4
3
|
const zod = require('zod');
|
|
5
4
|
const _ = require('lodash');
|
|
6
5
|
const pluralize = require('pluralize');
|
|
6
|
+
const schema = require('_rads-db');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
9
9
|
|
|
10
|
-
const defaultSchema__default = /*#__PURE__*/_interopDefaultCompat(defaultSchema);
|
|
11
10
|
const ___default = /*#__PURE__*/_interopDefaultCompat(_);
|
|
12
11
|
const pluralize__default = /*#__PURE__*/_interopDefaultCompat(pluralize);
|
|
12
|
+
const schema__default = /*#__PURE__*/_interopDefaultCompat(schema);
|
|
13
13
|
|
|
14
14
|
function generateValidators(schema) {
|
|
15
15
|
const zodSchemas = {};
|
|
@@ -379,15 +379,15 @@ function field(meta) {
|
|
|
379
379
|
|
|
380
380
|
function createRads(args) {
|
|
381
381
|
args = { ...args };
|
|
382
|
-
const
|
|
383
|
-
const validators = generateValidators(
|
|
384
|
-
return generateMethods(
|
|
382
|
+
const s = args.schema || schema__default;
|
|
383
|
+
const validators = generateValidators(s);
|
|
384
|
+
return generateMethods(s, validators, args);
|
|
385
385
|
}
|
|
386
386
|
function getRestRoutes(db, prefix = "/") {
|
|
387
387
|
const routes = {};
|
|
388
|
-
const
|
|
389
|
-
for (const key in
|
|
390
|
-
const entity =
|
|
388
|
+
const schema2 = db._schema;
|
|
389
|
+
for (const key in schema2) {
|
|
390
|
+
const entity = schema2[key];
|
|
391
391
|
if (!entity.decorators?.entity)
|
|
392
392
|
continue;
|
|
393
393
|
routes[`${prefix}${entity.handle}`] = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,51 @@
|
|
|
1
1
|
import { HTTPMethod } from 'h3';
|
|
2
|
+
import { EntityMeta, RadsDb } from '_rads-db';
|
|
3
|
+
export { RadsDb } from '_rads-db';
|
|
4
|
+
|
|
5
|
+
interface GetManyArgs<E, EN extends keyof EntityMeta, W> extends GetArgs<E, EN, W> {
|
|
6
|
+
cursor?: string;
|
|
7
|
+
maxItemCount?: number;
|
|
8
|
+
orderBy?: string;
|
|
9
|
+
}
|
|
10
|
+
interface GetArgs<E, EN extends keyof EntityMeta, W> {
|
|
11
|
+
where?: W;
|
|
12
|
+
include?: GetArgsInclude<E, EN>;
|
|
13
|
+
}
|
|
14
|
+
type GetManyArgsAny = GetManyArgs<any, any, any>;
|
|
15
|
+
type GetArgsAny = GetArgs<any, any, any>;
|
|
16
|
+
type GetArgsInclude<E, EN extends keyof EntityMeta, R extends keyof E = keyof EntityMeta[EN]['relations'] & keyof E> = [R] extends [never] ? Record<string, never> : {
|
|
17
|
+
_select?: EntityMeta[EN]['primitives'][];
|
|
18
|
+
} & {
|
|
19
|
+
[K in R]?: GetArgsInclude<NonNullable<E[K]>, EntityMeta[EN]['relations'][K]>;
|
|
20
|
+
};
|
|
21
|
+
interface GetManyResponse<E, EN extends keyof EntityMeta, A extends GetArgs<E, EN, any>> {
|
|
22
|
+
nodes: GetResponse<E, EN, A>[];
|
|
23
|
+
cursor?: string | null;
|
|
24
|
+
}
|
|
25
|
+
type GetResponse<E, EN extends keyof EntityMeta, A extends GetArgs<E, EN, any>> = A extends {
|
|
26
|
+
include: any;
|
|
27
|
+
} ? GetResponseInclude<E, EN, A['include']> : GetResponseNoInclude<E, EN>;
|
|
28
|
+
type GetResponseInclude<E, EN extends keyof EntityMeta, I extends GetArgsInclude<E, EN>> = I extends {
|
|
29
|
+
_select: string[];
|
|
30
|
+
} ? GetResponseIncludeSelect<E, I> : {
|
|
31
|
+
[K in keyof E]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof I ? GetResponseInclude<E[K], EntityMeta[EN]['relations'][K], I[K]> : Pick<E[K], 'id'> : E[K];
|
|
32
|
+
};
|
|
33
|
+
interface GetResponseIncludeSelect<E, I> {
|
|
34
|
+
}
|
|
35
|
+
type GetResponseNoInclude<E, EN extends keyof EntityMeta> = {
|
|
36
|
+
[K in keyof E]: K extends keyof EntityMeta[EN]['relations'] ? Pick<E[K], 'id'> : E[K];
|
|
37
|
+
};
|
|
38
|
+
type PutArgs<T> = T extends object ? {
|
|
39
|
+
id: string;
|
|
40
|
+
} & {
|
|
41
|
+
[P in keyof T]?: PutArgs<T[P]>;
|
|
42
|
+
} : T;
|
|
43
|
+
interface EntityMethods<E, EN extends keyof EntityMeta, W> {
|
|
44
|
+
get<A extends GetArgs<E, EN, W>>(args: A): GetResponse<E, EN, A>;
|
|
45
|
+
getMany<A extends GetManyArgs<E, EN, W>>(args: A): GetManyResponse<E, EN, A>;
|
|
46
|
+
put(data: PutArgs<E>): GetResponseNoInclude<E, EN>;
|
|
47
|
+
putMany(data: PutArgs<E>[]): GetResponseNoInclude<E, EN>[];
|
|
48
|
+
}
|
|
2
49
|
|
|
3
50
|
interface EntityDecoratorArgs {
|
|
4
51
|
driver?: string;
|
|
@@ -25,13 +72,13 @@ interface TypeDefinition {
|
|
|
25
72
|
type MaybePromise<T> = Promise<T> | T;
|
|
26
73
|
interface MinimalDriver {
|
|
27
74
|
putMany: <T extends Record<string, any>>(item: T[]) => MaybePromise<void>;
|
|
28
|
-
getMany: (args: GetManyArgs) => MaybePromise<{
|
|
75
|
+
getMany: (args: GetManyArgs<any, any, any>) => MaybePromise<{
|
|
29
76
|
nodes: Record<string, any>[];
|
|
30
77
|
cursor: string | null;
|
|
31
78
|
}>;
|
|
32
79
|
}
|
|
33
80
|
interface Driver extends MinimalDriver {
|
|
34
|
-
getAll: (args: GetManyArgs) => MaybePromise<Record<string, any>[]>;
|
|
81
|
+
getAll: (args: GetManyArgs<any, any, any>) => MaybePromise<Record<string, any>[]>;
|
|
35
82
|
}
|
|
36
83
|
interface FieldDefinition {
|
|
37
84
|
name: string;
|
|
@@ -41,25 +88,6 @@ interface FieldDefinition {
|
|
|
41
88
|
comment?: string;
|
|
42
89
|
decorators?: Record<string, Record<string, any>>;
|
|
43
90
|
}
|
|
44
|
-
interface GetManyArgs extends GetArgs {
|
|
45
|
-
orderBy?: string;
|
|
46
|
-
maxItemCount?: number;
|
|
47
|
-
cursor?: string;
|
|
48
|
-
}
|
|
49
|
-
interface GetArgs {
|
|
50
|
-
where?: Record<string, any>;
|
|
51
|
-
include?: Record<string, any>;
|
|
52
|
-
}
|
|
53
|
-
interface EntityMethods<T = Record<string, any>> {
|
|
54
|
-
get: (args: GetArgs) => Promise<T>;
|
|
55
|
-
getMany: (args: GetManyArgs) => Promise<{
|
|
56
|
-
nodes: T[];
|
|
57
|
-
cursor: string | null;
|
|
58
|
-
}>;
|
|
59
|
-
getAll: (args: GetManyArgs) => Promise<T[]>;
|
|
60
|
-
put: (data: T) => Promise<T>;
|
|
61
|
-
putMany: (data: T[]) => Promise<T[]>;
|
|
62
|
-
}
|
|
63
91
|
interface RestDriverOptions {
|
|
64
92
|
type: 'restApi';
|
|
65
93
|
/** @default '/api' */
|
|
@@ -74,17 +102,15 @@ interface MemoryDriverOptions {
|
|
|
74
102
|
type: 'memory';
|
|
75
103
|
}
|
|
76
104
|
type DriverOptions = RestDriverOptions | MemoryDriverOptions;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
interface GenerateClientOptions {
|
|
81
|
-
entitiesDir?: string;
|
|
105
|
+
type GenerateClientOptions = Partial<GenerateClientNormalizedOptions>;
|
|
106
|
+
interface GenerateClientNormalizedOptions {
|
|
107
|
+
entitiesDir: string;
|
|
82
108
|
}
|
|
83
109
|
|
|
84
110
|
declare function entity(meta?: EntityDecoratorArgs): (classConstructor: Function, _ctx?: ClassDecoratorContext<any>) => void;
|
|
85
111
|
declare function field(meta?: FieldDecoratorArgs): (a: any, b?: ClassFieldDecoratorContext) => void;
|
|
86
112
|
|
|
87
|
-
declare function createRads(args?: CreateRadsArgs):
|
|
113
|
+
declare function createRads(args?: CreateRadsArgs): Record<string, any>;
|
|
88
114
|
declare function getRestRoutes(db: RadsDb, prefix?: string): Record<string, Record<string, Function>>;
|
|
89
115
|
|
|
90
|
-
export { CreateRadsArgs, Driver, DriverOptions, EntityDecoratorArgs, EntityMethods, FieldDecoratorArgs, FieldDefinition, GenerateClientOptions, GetArgs, GetManyArgs, MemoryDriverOptions, MinimalDriver,
|
|
116
|
+
export { CreateRadsArgs, Driver, DriverOptions, EntityDecoratorArgs, EntityMethods, FieldDecoratorArgs, FieldDefinition, GenerateClientNormalizedOptions, GenerateClientOptions, GetArgs, GetArgsAny, GetArgsInclude, GetManyArgs, GetManyArgsAny, GetManyResponse, GetResponse, GetResponseInclude, GetResponseIncludeSelect, GetResponseNoInclude, MemoryDriverOptions, MinimalDriver, PutArgs, RestDriverOptions, Schema, SchemaValidators, TypeDefinition, createRads, entity, field, getRestRoutes };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import defaultSchema from '.rads-db/schema.json';
|
|
2
1
|
import { z } from 'zod';
|
|
3
2
|
import _ from 'lodash';
|
|
4
3
|
import pluralize from 'pluralize';
|
|
4
|
+
import schema from '_rads-db';
|
|
5
5
|
|
|
6
6
|
function generateValidators(schema) {
|
|
7
7
|
const zodSchemas = {};
|
|
@@ -371,15 +371,15 @@ function field(meta) {
|
|
|
371
371
|
|
|
372
372
|
function createRads(args) {
|
|
373
373
|
args = { ...args };
|
|
374
|
-
const
|
|
375
|
-
const validators = generateValidators(
|
|
376
|
-
return generateMethods(
|
|
374
|
+
const s = args.schema || schema;
|
|
375
|
+
const validators = generateValidators(s);
|
|
376
|
+
return generateMethods(s, validators, args);
|
|
377
377
|
}
|
|
378
378
|
function getRestRoutes(db, prefix = "/") {
|
|
379
379
|
const routes = {};
|
|
380
|
-
const
|
|
381
|
-
for (const key in
|
|
382
|
-
const entity =
|
|
380
|
+
const schema2 = db._schema;
|
|
381
|
+
for (const key in schema2) {
|
|
382
|
+
const entity = schema2[key];
|
|
383
383
|
if (!entity.decorators?.entity)
|
|
384
384
|
continue;
|
|
385
385
|
routes[`${prefix}${entity.handle}`] = {
|
package/drivers/restApi.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
declare const _default: (schema: Schema, entity: string, options: RestDriverOptions) => {
|
|
2
|
-
getMany(args: GetManyArgs): Promise<any>;
|
|
2
|
+
getMany(args: GetManyArgs<any, any, any>): Promise<any>;
|
|
3
3
|
putMany<T extends Record<string, any>>(item: T): Promise<void>;
|
|
4
4
|
};
|
|
5
5
|
export default _default;
|
package/integrations/node.cjs
CHANGED
|
@@ -7,6 +7,7 @@ exports.generateClient = generateClient;
|
|
|
7
7
|
var _promises = _interopRequireDefault(require("node:fs/promises"));
|
|
8
8
|
var _nodeFs = _interopRequireDefault(require("node:fs"));
|
|
9
9
|
var _nodePath = _interopRequireDefault(require("node:path"));
|
|
10
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
10
11
|
var _lib = require("./lib.cjs");
|
|
11
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
13
|
async function generateClient(options) {
|
|
@@ -18,6 +19,7 @@ async function generateClient(options) {
|
|
|
18
19
|
entitiesDir
|
|
19
20
|
} = normalizedOptions;
|
|
20
21
|
console.time("[rads-db] Schema generated in");
|
|
22
|
+
if (!_nodeFs.default.existsSync(entitiesDir)) await _promises.default.mkdir(entitiesDir);
|
|
21
23
|
const response = await _promises.default.readdir(entitiesDir, {
|
|
22
24
|
withFileTypes: true
|
|
23
25
|
});
|
|
@@ -30,19 +32,122 @@ async function generateClient(options) {
|
|
|
30
32
|
}
|
|
31
33
|
const schema = (0, _lib.parseSchema)(entities);
|
|
32
34
|
const nodeModulesPath = _nodePath.default.resolve("./node_modules");
|
|
33
|
-
const radsDbPath = _nodePath.default.join(nodeModulesPath, "
|
|
35
|
+
const radsDbPath = _nodePath.default.join(nodeModulesPath, "./_rads-db");
|
|
34
36
|
if (!_nodeFs.default.existsSync(nodeModulesPath)) {
|
|
35
37
|
throw new Error(`node_modules was not found! Please ensure that node_modules is present in the current working directory.`);
|
|
36
38
|
}
|
|
37
39
|
if (!_nodeFs.default.existsSync(radsDbPath)) {
|
|
38
40
|
await _promises.default.mkdir(radsDbPath);
|
|
39
41
|
}
|
|
40
|
-
|
|
42
|
+
const indexJsText = `
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.schema=${JSON.stringify(schema)}
|
|
45
|
+
`.trim();
|
|
46
|
+
const indexMjsText = `
|
|
47
|
+
export const schema = ${JSON.stringify(schema)}
|
|
48
|
+
`.trim();
|
|
49
|
+
await _promises.default.writeFile(_nodePath.default.join(radsDbPath, "./index.js"), indexJsText);
|
|
50
|
+
await _promises.default.writeFile(_nodePath.default.join(radsDbPath, "./index.mjs"), indexMjsText);
|
|
51
|
+
await _promises.default.writeFile(_nodePath.default.join(radsDbPath, "./index.d.ts"), getIndexDts(schema, normalizedOptions));
|
|
41
52
|
await _promises.default.writeFile(_nodePath.default.join(radsDbPath, "./package.json"), JSON.stringify({
|
|
42
|
-
name: "
|
|
43
|
-
|
|
44
|
-
|
|
53
|
+
name: "_rads-db",
|
|
54
|
+
main: "./index.js",
|
|
55
|
+
module: "./index.mjs",
|
|
56
|
+
types: "./index.d.ts"
|
|
45
57
|
// browser: 'index-browser.js',
|
|
46
58
|
}, null, 2));
|
|
47
59
|
console.timeEnd("[rads-db] Schema generated in");
|
|
60
|
+
}
|
|
61
|
+
function getIndexDts(schema, options) {
|
|
62
|
+
const imports = [];
|
|
63
|
+
const rootFields = [];
|
|
64
|
+
const whereTypes = [];
|
|
65
|
+
const entityMeta = [];
|
|
66
|
+
for (const key in schema) {
|
|
67
|
+
const type = schema[key];
|
|
68
|
+
if (!type.decorators.entity) continue;
|
|
69
|
+
imports.push(`import type { ${type.name} } from '../../${options.entitiesDir}/${key}'`);
|
|
70
|
+
rootFields.push(`${type.handle}: EntityMethods<${type.name}, '${type.name}', ${type.name}_Where>`);
|
|
71
|
+
const fieldsArray = Object.values(type.fields);
|
|
72
|
+
entityMeta.push({
|
|
73
|
+
type: type.name,
|
|
74
|
+
relations: _lodash.default.fromPairs(fieldsArray.filter(f => schema[f.type]?.decorators?.entity).map(x => [x.name, x.type])),
|
|
75
|
+
primitives: fieldsArray.filter(f => !schema[f.type]?.decorators?.entity).map(x => `'${x.name}'`).join(" | ")
|
|
76
|
+
});
|
|
77
|
+
const whereFields = getWhereFields(schema, type);
|
|
78
|
+
whereTypes.push(`
|
|
79
|
+
export interface ${type.name}_Where {
|
|
80
|
+
${whereFields.join("\n")}
|
|
81
|
+
}`.trim());
|
|
82
|
+
}
|
|
83
|
+
const entityMetaStr = entityMeta.map(x => `
|
|
84
|
+
'${x.type}': {
|
|
85
|
+
type: ${x.type}
|
|
86
|
+
primitives: ${x.primitives}
|
|
87
|
+
relations: ${JSON.stringify(x.relations)}
|
|
88
|
+
}
|
|
89
|
+
`.trim()).join("\n");
|
|
90
|
+
return `
|
|
91
|
+
import type { EntityMethods } from 'rads-db'
|
|
92
|
+
${imports.join("\n")}
|
|
93
|
+
|
|
94
|
+
export interface EntityMeta {
|
|
95
|
+
${entityMetaStr}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface Reference_Where {
|
|
99
|
+
id?: string
|
|
100
|
+
id_in?: string[]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
${whereTypes.join("\n\n")}
|
|
104
|
+
|
|
105
|
+
export interface RadsDb {
|
|
106
|
+
_schema: any
|
|
107
|
+
${rootFields.join("\n")}
|
|
108
|
+
}
|
|
109
|
+
`.trim();
|
|
110
|
+
}
|
|
111
|
+
function getWhereFields(schema, type) {
|
|
112
|
+
const result = [];
|
|
113
|
+
for (const f in type.fields) {
|
|
114
|
+
result.push(...getWhereFieldsFor(schema, type, f));
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
function getWhereFieldsFor(schema, type, fieldKey) {
|
|
119
|
+
const field = type.fields[fieldKey];
|
|
120
|
+
const {
|
|
121
|
+
name
|
|
122
|
+
} = field;
|
|
123
|
+
const fieldTypeName = field.type;
|
|
124
|
+
let whereTypeName = fieldTypeName;
|
|
125
|
+
const fieldType = schema[fieldTypeName];
|
|
126
|
+
const result = getWhereFieldsForInner(schema, type, fieldKey);
|
|
127
|
+
if (fieldType) {
|
|
128
|
+
if (fieldType?.decorators?.entity) {
|
|
129
|
+
whereTypeName = `{ id?: string, id_in?: string[] }`;
|
|
130
|
+
}
|
|
131
|
+
if (fieldType.fields) whereTypeName = `Partial<${whereTypeName}>`;
|
|
132
|
+
} else {
|
|
133
|
+
result.unshift(`${name}_in?: ${whereTypeName}[]`);
|
|
134
|
+
}
|
|
135
|
+
if (!field.isRequired) {
|
|
136
|
+
result.unshift(`${name}_isNull?: boolean`);
|
|
137
|
+
}
|
|
138
|
+
result.unshift(`${name}?: ${whereTypeName}`);
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
function getWhereFieldsForInner(schema, type, fieldKey) {
|
|
142
|
+
const field = type.fields[fieldKey];
|
|
143
|
+
const {
|
|
144
|
+
name
|
|
145
|
+
} = field;
|
|
146
|
+
if (field.type === "string") {
|
|
147
|
+
return [`${name}_istartsWith?: string`, `${name}_startsWith?: string`, `${name}_icontains?: string`, `${name}_contains?: string`, `${name}_iendsWith?: string`, `${name}_endsWith?: string`, `${name}_gt?: string`, `${name}_gte?: string`, `${name}_lt?: string`, `${name}_lte?: string`];
|
|
148
|
+
}
|
|
149
|
+
if (field.type === "number") {
|
|
150
|
+
return [`${name}_gt?: number`, `${name}_gte?: number`, `${name}_lt?: string`, `${name}_lte?: string`];
|
|
151
|
+
}
|
|
152
|
+
return [];
|
|
48
153
|
}
|
package/integrations/node.mjs
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import fs2 from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import _ from "lodash";
|
|
4
5
|
import { parseSchema } from "./lib.mjs";
|
|
5
6
|
export async function generateClient(options) {
|
|
6
7
|
const normalizedOptions = { entitiesDir: "./entities", ...options };
|
|
7
8
|
const { entitiesDir } = normalizedOptions;
|
|
8
9
|
console.time("[rads-db] Schema generated in");
|
|
10
|
+
if (!fs2.existsSync(entitiesDir))
|
|
11
|
+
await fs.mkdir(entitiesDir);
|
|
9
12
|
const response = await fs.readdir(entitiesDir, { withFileTypes: true });
|
|
10
13
|
const entities = {};
|
|
11
14
|
for (const file of response) {
|
|
@@ -18,7 +21,7 @@ export async function generateClient(options) {
|
|
|
18
21
|
}
|
|
19
22
|
const schema = parseSchema(entities);
|
|
20
23
|
const nodeModulesPath = path.resolve("./node_modules");
|
|
21
|
-
const radsDbPath = path.join(nodeModulesPath, "
|
|
24
|
+
const radsDbPath = path.join(nodeModulesPath, "./_rads-db");
|
|
22
25
|
if (!fs2.existsSync(nodeModulesPath)) {
|
|
23
26
|
throw new Error(
|
|
24
27
|
`node_modules was not found! Please ensure that node_modules is present in the current working directory.`
|
|
@@ -27,14 +30,24 @@ export async function generateClient(options) {
|
|
|
27
30
|
if (!fs2.existsSync(radsDbPath)) {
|
|
28
31
|
await fs.mkdir(radsDbPath);
|
|
29
32
|
}
|
|
30
|
-
|
|
33
|
+
const indexJsText = `
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.schema=${JSON.stringify(schema)}
|
|
36
|
+
`.trim();
|
|
37
|
+
const indexMjsText = `
|
|
38
|
+
export const schema = ${JSON.stringify(schema)}
|
|
39
|
+
`.trim();
|
|
40
|
+
await fs.writeFile(path.join(radsDbPath, "./index.js"), indexJsText);
|
|
41
|
+
await fs.writeFile(path.join(radsDbPath, "./index.mjs"), indexMjsText);
|
|
42
|
+
await fs.writeFile(path.join(radsDbPath, "./index.d.ts"), getIndexDts(schema, normalizedOptions));
|
|
31
43
|
await fs.writeFile(
|
|
32
44
|
path.join(radsDbPath, "./package.json"),
|
|
33
45
|
JSON.stringify(
|
|
34
46
|
{
|
|
35
|
-
name: "
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
name: "_rads-db",
|
|
48
|
+
main: "./index.js",
|
|
49
|
+
module: "./index.mjs",
|
|
50
|
+
types: "./index.d.ts"
|
|
38
51
|
// browser: 'index-browser.js',
|
|
39
52
|
},
|
|
40
53
|
null,
|
|
@@ -43,3 +56,109 @@ export async function generateClient(options) {
|
|
|
43
56
|
);
|
|
44
57
|
console.timeEnd("[rads-db] Schema generated in");
|
|
45
58
|
}
|
|
59
|
+
function getIndexDts(schema, options) {
|
|
60
|
+
const imports = [];
|
|
61
|
+
const rootFields = [];
|
|
62
|
+
const whereTypes = [];
|
|
63
|
+
const entityMeta = [];
|
|
64
|
+
for (const key in schema) {
|
|
65
|
+
const type = schema[key];
|
|
66
|
+
if (!type.decorators.entity)
|
|
67
|
+
continue;
|
|
68
|
+
imports.push(`import type { ${type.name} } from '../../${options.entitiesDir}/${key}'`);
|
|
69
|
+
rootFields.push(`${type.handle}: EntityMethods<${type.name}, '${type.name}', ${type.name}_Where>`);
|
|
70
|
+
const fieldsArray = Object.values(type.fields);
|
|
71
|
+
entityMeta.push({
|
|
72
|
+
type: type.name,
|
|
73
|
+
relations: _.fromPairs(fieldsArray.filter((f) => schema[f.type]?.decorators?.entity).map((x) => [x.name, x.type])),
|
|
74
|
+
primitives: fieldsArray.filter((f) => !schema[f.type]?.decorators?.entity).map((x) => `'${x.name}'`).join(" | ")
|
|
75
|
+
});
|
|
76
|
+
const whereFields = getWhereFields(schema, type);
|
|
77
|
+
whereTypes.push(
|
|
78
|
+
`
|
|
79
|
+
export interface ${type.name}_Where {
|
|
80
|
+
${whereFields.join("\n")}
|
|
81
|
+
}`.trim()
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
const entityMetaStr = entityMeta.map(
|
|
85
|
+
(x) => `
|
|
86
|
+
'${x.type}': {
|
|
87
|
+
type: ${x.type}
|
|
88
|
+
primitives: ${x.primitives}
|
|
89
|
+
relations: ${JSON.stringify(x.relations)}
|
|
90
|
+
}
|
|
91
|
+
`.trim()
|
|
92
|
+
).join("\n");
|
|
93
|
+
return `
|
|
94
|
+
import type { EntityMethods } from 'rads-db'
|
|
95
|
+
${imports.join("\n")}
|
|
96
|
+
|
|
97
|
+
export interface EntityMeta {
|
|
98
|
+
${entityMetaStr}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
interface Reference_Where {
|
|
102
|
+
id?: string
|
|
103
|
+
id_in?: string[]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
${whereTypes.join("\n\n")}
|
|
107
|
+
|
|
108
|
+
export interface RadsDb {
|
|
109
|
+
_schema: any
|
|
110
|
+
${rootFields.join("\n")}
|
|
111
|
+
}
|
|
112
|
+
`.trim();
|
|
113
|
+
}
|
|
114
|
+
function getWhereFields(schema, type) {
|
|
115
|
+
const result = [];
|
|
116
|
+
for (const f in type.fields) {
|
|
117
|
+
result.push(...getWhereFieldsFor(schema, type, f));
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
function getWhereFieldsFor(schema, type, fieldKey) {
|
|
122
|
+
const field = type.fields[fieldKey];
|
|
123
|
+
const { name } = field;
|
|
124
|
+
const fieldTypeName = field.type;
|
|
125
|
+
let whereTypeName = fieldTypeName;
|
|
126
|
+
const fieldType = schema[fieldTypeName];
|
|
127
|
+
const result = getWhereFieldsForInner(schema, type, fieldKey);
|
|
128
|
+
if (fieldType) {
|
|
129
|
+
if (fieldType?.decorators?.entity) {
|
|
130
|
+
whereTypeName = `{ id?: string, id_in?: string[] }`;
|
|
131
|
+
}
|
|
132
|
+
if (fieldType.fields)
|
|
133
|
+
whereTypeName = `Partial<${whereTypeName}>`;
|
|
134
|
+
} else {
|
|
135
|
+
result.unshift(`${name}_in?: ${whereTypeName}[]`);
|
|
136
|
+
}
|
|
137
|
+
if (!field.isRequired) {
|
|
138
|
+
result.unshift(`${name}_isNull?: boolean`);
|
|
139
|
+
}
|
|
140
|
+
result.unshift(`${name}?: ${whereTypeName}`);
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
function getWhereFieldsForInner(schema, type, fieldKey) {
|
|
144
|
+
const field = type.fields[fieldKey];
|
|
145
|
+
const { name } = field;
|
|
146
|
+
if (field.type === "string") {
|
|
147
|
+
return [
|
|
148
|
+
`${name}_istartsWith?: string`,
|
|
149
|
+
`${name}_startsWith?: string`,
|
|
150
|
+
`${name}_icontains?: string`,
|
|
151
|
+
`${name}_contains?: string`,
|
|
152
|
+
`${name}_iendsWith?: string`,
|
|
153
|
+
`${name}_endsWith?: string`,
|
|
154
|
+
`${name}_gt?: string`,
|
|
155
|
+
`${name}_gte?: string`,
|
|
156
|
+
`${name}_lt?: string`,
|
|
157
|
+
`${name}_lte?: string`
|
|
158
|
+
];
|
|
159
|
+
}
|
|
160
|
+
if (field.type === "number") {
|
|
161
|
+
return [`${name}_gt?: number`, `${name}_gte?: number`, `${name}_lt?: string`, `${name}_lte?: string`];
|
|
162
|
+
}
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
@@ -14,6 +14,7 @@ var _default = (0, _h.defineEventHandler)(event => {
|
|
|
14
14
|
const p = (0, _h.getRequestPath)(event);
|
|
15
15
|
const query = (0, _h.getQuery)(event);
|
|
16
16
|
const rp = (0, _h.getRouterParams)(event);
|
|
17
|
+
const prefix = "";
|
|
17
18
|
console.log(path, p, query, rp);
|
|
18
19
|
if (method === "POST") {}
|
|
19
20
|
if (path === `${prefix}tcUser`) {
|
|
@@ -32,7 +33,7 @@ var _default = (0, _h.defineEventHandler)(event => {
|
|
|
32
33
|
});
|
|
33
34
|
module.exports = _default;
|
|
34
35
|
function getRoutes(entities) {
|
|
35
|
-
const
|
|
36
|
+
const prefix = "/api/";
|
|
36
37
|
const routes2 = {};
|
|
37
38
|
for (const entityKey in entities) {}
|
|
38
39
|
}
|
|
@@ -7,6 +7,7 @@ export default defineEventHandler((event) => {
|
|
|
7
7
|
const p = getRequestPath(event);
|
|
8
8
|
const query = getQuery(event);
|
|
9
9
|
const rp = getRouterParams(event);
|
|
10
|
+
const prefix = "";
|
|
10
11
|
console.log(path, p, query, rp);
|
|
11
12
|
if (method === "POST") {
|
|
12
13
|
}
|
|
@@ -21,7 +22,7 @@ export default defineEventHandler((event) => {
|
|
|
21
22
|
console.log(schema);
|
|
22
23
|
});
|
|
23
24
|
function getRoutes(entities) {
|
|
24
|
-
const
|
|
25
|
+
const prefix = "/api/";
|
|
25
26
|
const routes2 = {};
|
|
26
27
|
for (const entityKey in entities) {
|
|
27
28
|
}
|
package/package.json
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
"drivers",
|
|
6
6
|
"integrations"
|
|
7
7
|
],
|
|
8
|
+
"bin": {
|
|
9
|
+
"rads-db": "integrations/cli.cjs"
|
|
10
|
+
},
|
|
8
11
|
"main": "./dist/index.cjs",
|
|
9
12
|
"module": "./dist/index.mjs",
|
|
10
13
|
"types": "./dist/index.d.ts",
|
|
@@ -25,7 +28,7 @@
|
|
|
25
28
|
"require": "./integrations/*.cjs"
|
|
26
29
|
}
|
|
27
30
|
},
|
|
28
|
-
"version": "0.1.
|
|
31
|
+
"version": "0.1.11",
|
|
29
32
|
"description": "Say goodbye to boilerplate code and hello to efficient and elegant syntax.",
|
|
30
33
|
"keywords": [],
|
|
31
34
|
"author": "",
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
},
|
|
37
40
|
"devDependencies": {
|
|
38
41
|
"@vitest/ui": "^0.31.0",
|
|
42
|
+
"symlink-dir": "^5.1.1",
|
|
39
43
|
"tsup": "^6.7.0",
|
|
40
44
|
"unbuild": "^1.2.1",
|
|
41
45
|
"vite": "^4.0.0",
|
|
@@ -52,8 +56,10 @@
|
|
|
52
56
|
"zod": "^3.21.4"
|
|
53
57
|
},
|
|
54
58
|
"scripts": {
|
|
55
|
-
"test": "vitest",
|
|
59
|
+
"test": "vitest && vitest typecheck",
|
|
60
|
+
"generate-test-client": "symlink-dir ./test/_rads-db ./node_modules/_rads-db && node ./test/generateClient.ts",
|
|
56
61
|
"dev": "pnpm install --frozen-lockfile && vitest --ui",
|
|
62
|
+
"dev-typecheck": "vitest typecheck --ui",
|
|
57
63
|
"build": "unbuild"
|
|
58
64
|
}
|
|
59
65
|
}
|