remult 0.25.5-exp.9 → 0.25.6-exp.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/esm/graphql.js +24 -17
- package/esm/index.js +1 -0
- package/esm/package.json +1 -1
- package/esm/remult-fastify.js +3 -0
- package/esm/remult-hapi.js +3 -0
- package/esm/remult-knex/index.js +18 -6
- package/esm/remult-next.js +8 -0
- package/esm/remult-nuxt.js +3 -0
- package/esm/remult-sveltekit.js +63 -42
- package/esm/server/expressBridge.js +28 -0
- package/esm/server/get-remult-admin-html.js +3 -0
- package/esm/server/remult-admin.js +92 -0
- package/esm/src/data-providers/array-entity-data-provider.js +0 -1
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +16 -2
- package/esm/src/remult3/Fields.js +7 -1
- package/esm/src/remult3/RepositoryImplementation.js +1 -2
- package/esm/src/remult3/remult3.js +28 -3
- package/esm/src/server-action.js +3 -1
- package/graphql.js +40 -33
- package/index.d.ts +1 -0
- package/index.js +3 -1
- package/package.json +1 -1
- package/remult-fastify.js +3 -0
- package/remult-hapi.js +3 -0
- package/remult-knex/index.d.ts +3 -1
- package/remult-knex/index.js +70 -50
- package/remult-next.js +8 -0
- package/remult-nuxt.js +3 -0
- package/remult-sveltekit.d.ts +5 -1
- package/remult-sveltekit.js +85 -56
- package/server/expressBridge.d.ts +13 -1
- package/server/expressBridge.js +42 -0
- package/server/get-remult-admin-html.d.ts +1 -0
- package/server/get-remult-admin-html.js +7 -0
- package/server/remult-admin.d.ts +36 -0
- package/server/remult-admin.js +121 -0
- package/src/data-providers/array-entity-data-provider.d.ts +13 -0
- package/src/data-providers/array-entity-data-provider.js +0 -1
- package/src/data-providers/sql-database.d.ts +2 -2
- package/src/filter/filter-consumer-bridge-to-sql-request.js +28 -13
- package/src/remult3/Fields.d.ts +1 -0
- package/src/remult3/Fields.js +7 -1
- package/src/remult3/RepositoryImplementation.d.ts +2 -0
- package/src/remult3/RepositoryImplementation.js +1 -2
- package/src/remult3/remult3.d.ts +1 -1
- package/src/remult3/remult3.js +28 -3
- package/src/server-action.js +3 -1
- package/src/sql-command.d.ts +4 -2
package/esm/graphql.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getRelationFieldInfo } from './internals.js';
|
|
2
|
-
import { Remult, remult } from './index.js';
|
|
2
|
+
import { CompoundIdField, Remult, remult } from './index.js';
|
|
3
3
|
import { DataApi } from './src/data-api.js';
|
|
4
4
|
import { getRepositoryInternals } from './src/remult3/repository-internals.js';
|
|
5
5
|
const v2ConnectionAndPagination = false;
|
|
@@ -369,9 +369,12 @@ export function remultGraphql(options) {
|
|
|
369
369
|
});
|
|
370
370
|
currentType.mutation.delete.payload = upsertTypes(deletePayload);
|
|
371
371
|
const deletedResultKey = `id`;
|
|
372
|
+
const type = meta.idMetadata.field instanceof CompoundIdField
|
|
373
|
+
? 'String'
|
|
374
|
+
: getGraphqlBaseType(meta.idMetadata.field);
|
|
372
375
|
currentType.mutation.delete.payload.fields.push({
|
|
373
376
|
key: deletedResultKey,
|
|
374
|
-
value:
|
|
377
|
+
value: `${type}`,
|
|
375
378
|
}, argErrorDetail, argClientMutationId);
|
|
376
379
|
root[deleteResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
|
|
377
380
|
await dApi.delete({
|
|
@@ -388,21 +391,7 @@ export function remultGraphql(options) {
|
|
|
388
391
|
const ri = getRelationFieldInfo(f);
|
|
389
392
|
if (f.options.includeInApi === false)
|
|
390
393
|
continue;
|
|
391
|
-
|
|
392
|
-
switch (f.valueType) {
|
|
393
|
-
case Boolean:
|
|
394
|
-
type = 'Boolean';
|
|
395
|
-
break;
|
|
396
|
-
case Number:
|
|
397
|
-
{
|
|
398
|
-
if (f.valueConverter?.fieldTypeInDb === 'integer' ||
|
|
399
|
-
f.valueConverter?.fieldTypeInDb === 'autoincrement')
|
|
400
|
-
type = 'Int';
|
|
401
|
-
else
|
|
402
|
-
type = 'Float';
|
|
403
|
-
}
|
|
404
|
-
break;
|
|
405
|
-
}
|
|
394
|
+
const type = getGraphqlBaseType(f);
|
|
406
395
|
currentType.query.resultProcessors.push((r) => {
|
|
407
396
|
r[nodeIdKey] = () => getMetaType(meta) + ':' + meta.idMetadata.getId(r);
|
|
408
397
|
});
|
|
@@ -828,6 +817,24 @@ function fieldFormat(field) {
|
|
|
828
817
|
}
|
|
829
818
|
return `${strComment} ${key_value}`;
|
|
830
819
|
}
|
|
820
|
+
function getGraphqlBaseType(field) {
|
|
821
|
+
let type = 'String';
|
|
822
|
+
switch (field.valueType) {
|
|
823
|
+
case Boolean:
|
|
824
|
+
type = 'Boolean';
|
|
825
|
+
break;
|
|
826
|
+
case Number:
|
|
827
|
+
{
|
|
828
|
+
if (field.valueConverter?.fieldTypeInDb === 'integer' ||
|
|
829
|
+
field.valueConverter?.fieldTypeInDb === 'autoincrement')
|
|
830
|
+
type = 'Int';
|
|
831
|
+
else
|
|
832
|
+
type = 'Float';
|
|
833
|
+
}
|
|
834
|
+
break;
|
|
835
|
+
}
|
|
836
|
+
return type;
|
|
837
|
+
}
|
|
831
838
|
function getMetaType(entityMeta) {
|
|
832
839
|
return entityMeta.entityType.name;
|
|
833
840
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider.js';
|
|
1
2
|
export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation.js';
|
|
2
3
|
export { Entity } from './src/remult3/entity.js';
|
|
3
4
|
export { getEntityRef } from './src/remult3/getEntityRef.js';
|
package/esm/package.json
CHANGED
package/esm/remult-fastify.js
CHANGED
package/esm/remult-hapi.js
CHANGED
package/esm/remult-knex/index.js
CHANGED
|
@@ -19,6 +19,7 @@ export class KnexDataProvider {
|
|
|
19
19
|
throw 'the data provider is not an KnexDataProvider';
|
|
20
20
|
return r.knex;
|
|
21
21
|
}
|
|
22
|
+
wrapIdentifier = (x) => this.knex.ref(x) + '';
|
|
22
23
|
getEntityDataProvider(entity) {
|
|
23
24
|
if (!supportsJsonLoadingAndSaving(this.knex))
|
|
24
25
|
for (const f of entity.fields.toArray()) {
|
|
@@ -31,6 +32,17 @@ export class KnexDataProvider {
|
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
}
|
|
35
|
+
else if (this.knex.client.config.client === 'mysql2') {
|
|
36
|
+
for (const f of entity.fields.toArray()) {
|
|
37
|
+
if (f.valueConverter.fieldTypeInDb === 'json') {
|
|
38
|
+
//@ts-ignore
|
|
39
|
+
f.valueConverter = {
|
|
40
|
+
...f.valueConverter,
|
|
41
|
+
toDb: ValueConverters.JsonString.toDb,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
34
46
|
return new KnexEntityDataProvider(entity, this.knex);
|
|
35
47
|
}
|
|
36
48
|
async transaction(action) {
|
|
@@ -53,7 +65,7 @@ export class KnexDataProvider {
|
|
|
53
65
|
}
|
|
54
66
|
static async filterToRaw(entity, condition) {
|
|
55
67
|
const repo = getRepository(entity);
|
|
56
|
-
var b = new FilterConsumerBridgeToKnexRequest(await dbNamesOf(repo.metadata));
|
|
68
|
+
var b = new FilterConsumerBridgeToKnexRequest(await dbNamesOf(repo.metadata, (x) => x));
|
|
57
69
|
b._addWhere = false;
|
|
58
70
|
await (await getRepositoryInternals(repo).translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
59
71
|
let r = await b.resolveWhere();
|
|
@@ -139,7 +151,7 @@ class KnexEntityDataProvider {
|
|
|
139
151
|
});
|
|
140
152
|
}
|
|
141
153
|
async init() {
|
|
142
|
-
const r = (await dbNamesOf(this.entity));
|
|
154
|
+
const r = (await dbNamesOf(this.entity, (x) => x));
|
|
143
155
|
return {
|
|
144
156
|
$dbNameOf: (f) => {
|
|
145
157
|
let fm = f;
|
|
@@ -336,7 +348,7 @@ export class KnexSchemaBuilder {
|
|
|
336
348
|
}
|
|
337
349
|
async ensureSchema(entities) {
|
|
338
350
|
for (const entity of entities) {
|
|
339
|
-
let e = await dbNamesOf(entity);
|
|
351
|
+
let e = await dbNamesOf(entity, (x) => x);
|
|
340
352
|
try {
|
|
341
353
|
if (!entity.options.sqlExpression) {
|
|
342
354
|
if (e.$entityName.toLowerCase().indexOf('from ') < 0) {
|
|
@@ -352,7 +364,7 @@ export class KnexSchemaBuilder {
|
|
|
352
364
|
}
|
|
353
365
|
}
|
|
354
366
|
async createIfNotExist(entity) {
|
|
355
|
-
const e = await dbNamesOf(entity);
|
|
367
|
+
const e = await dbNamesOf(entity, (x) => x);
|
|
356
368
|
if (!(await this.knex.schema.hasTable(e.$entityName))) {
|
|
357
369
|
let cols = new Map();
|
|
358
370
|
for (const f of entity.fields) {
|
|
@@ -377,7 +389,7 @@ export class KnexSchemaBuilder {
|
|
|
377
389
|
}
|
|
378
390
|
}
|
|
379
391
|
async addColumnIfNotExist(entity, c) {
|
|
380
|
-
let e = await dbNamesOf(entity);
|
|
392
|
+
let e = await dbNamesOf(entity, (x) => x);
|
|
381
393
|
if (shouldNotCreateField(c(entity), e))
|
|
382
394
|
return;
|
|
383
395
|
let col = c(entity);
|
|
@@ -389,7 +401,7 @@ export class KnexSchemaBuilder {
|
|
|
389
401
|
}
|
|
390
402
|
}
|
|
391
403
|
async verifyAllColumns(entity) {
|
|
392
|
-
let e = await dbNamesOf(entity);
|
|
404
|
+
let e = await dbNamesOf(entity, (x) => x);
|
|
393
405
|
try {
|
|
394
406
|
for (const col of entity.fields.toArray()) {
|
|
395
407
|
if (!shouldNotCreateField(col, e)) {
|
package/esm/remult-next.js
CHANGED
|
@@ -57,6 +57,7 @@ export function remultNextApp(options) {
|
|
|
57
57
|
const response = {
|
|
58
58
|
end: () => { },
|
|
59
59
|
json: () => { },
|
|
60
|
+
send: () => { },
|
|
60
61
|
status: () => {
|
|
61
62
|
return response;
|
|
62
63
|
},
|
|
@@ -91,6 +92,13 @@ export function remultNextApp(options) {
|
|
|
91
92
|
return sseResponse;
|
|
92
93
|
}
|
|
93
94
|
if (responseFromRemultHandler) {
|
|
95
|
+
if (responseFromRemultHandler.html)
|
|
96
|
+
return new Response(responseFromRemultHandler.html, {
|
|
97
|
+
status: responseFromRemultHandler.statusCode,
|
|
98
|
+
headers: {
|
|
99
|
+
'Content-Type': 'text/html',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
94
102
|
return new Response(JSON.stringify(responseFromRemultHandler.data), {
|
|
95
103
|
status: responseFromRemultHandler.statusCode,
|
|
96
104
|
});
|
package/esm/remult-nuxt.js
CHANGED
|
@@ -17,6 +17,7 @@ export function remultNuxt(options) {
|
|
|
17
17
|
let sse = false;
|
|
18
18
|
const response = {
|
|
19
19
|
end: () => { },
|
|
20
|
+
send: () => { },
|
|
20
21
|
json: () => { },
|
|
21
22
|
status: () => {
|
|
22
23
|
return response;
|
|
@@ -38,6 +39,8 @@ export function remultNuxt(options) {
|
|
|
38
39
|
if (r) {
|
|
39
40
|
if (r.statusCode !== 200)
|
|
40
41
|
setResponseStatus(event, r.statusCode);
|
|
42
|
+
if (r.html)
|
|
43
|
+
return r.html;
|
|
41
44
|
return r.data;
|
|
42
45
|
}
|
|
43
46
|
};
|
package/esm/remult-sveltekit.js
CHANGED
|
@@ -12,51 +12,68 @@ export function remultSveltekit(options) {
|
|
|
12
12
|
}),
|
|
13
13
|
getRequestBody: (event) => event.request.json(),
|
|
14
14
|
});
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
15
|
+
const serverHandler = async (event) => {
|
|
16
|
+
let sseResponse = undefined;
|
|
17
|
+
event.locals['_tempOnClose'] = () => { };
|
|
18
|
+
const response = {
|
|
19
|
+
end: () => { },
|
|
20
|
+
json: () => { },
|
|
21
|
+
send: () => { },
|
|
22
|
+
status: () => {
|
|
23
|
+
return response;
|
|
24
|
+
},
|
|
25
|
+
write: () => { },
|
|
26
|
+
writeHead: (status, headers) => {
|
|
27
|
+
if (status === 200 && headers) {
|
|
28
|
+
const contentType = headers['Content-Type'];
|
|
29
|
+
if (contentType === 'text/event-stream') {
|
|
30
|
+
const messages = [];
|
|
31
|
+
response.write = (x) => messages.push(x);
|
|
32
|
+
const stream = new ReadableStream({
|
|
33
|
+
start: (controller) => {
|
|
34
|
+
for (const message of messages) {
|
|
35
|
+
controller.enqueue(message);
|
|
36
|
+
}
|
|
37
|
+
response.write = (data) => {
|
|
38
|
+
controller.enqueue(data);
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
cancel: () => {
|
|
42
|
+
response.write = () => { };
|
|
43
|
+
event.locals['_tempOnClose']();
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
sseResponse = new Response(stream, { headers });
|
|
48
47
|
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
const responseFromRemultHandler = await result.handle(event, response);
|
|
52
|
+
if (sseResponse !== undefined) {
|
|
53
|
+
return sseResponse;
|
|
54
|
+
}
|
|
55
|
+
if (responseFromRemultHandler) {
|
|
56
|
+
if (responseFromRemultHandler.html)
|
|
57
|
+
return new Response(responseFromRemultHandler.html, {
|
|
57
58
|
status: responseFromRemultHandler.statusCode,
|
|
59
|
+
headers: {
|
|
60
|
+
'Content-Type': 'text/html',
|
|
61
|
+
},
|
|
58
62
|
});
|
|
59
|
-
|
|
63
|
+
const res = new Response(JSON.stringify(responseFromRemultHandler.data), {
|
|
64
|
+
status: responseFromRemultHandler.statusCode,
|
|
65
|
+
});
|
|
66
|
+
return res;
|
|
67
|
+
}
|
|
68
|
+
return new Response('Not Found', {
|
|
69
|
+
status: 404,
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
const handler = async ({ event, resolve }) => {
|
|
73
|
+
if (event.url.pathname.startsWith(options.rootPath)) {
|
|
74
|
+
const result = await serverHandler(event);
|
|
75
|
+
if (result != null && result?.status != 404)
|
|
76
|
+
return result;
|
|
60
77
|
}
|
|
61
78
|
return new Promise((res) => {
|
|
62
79
|
result.withRemult(event, undefined, async () => {
|
|
@@ -70,5 +87,9 @@ export function remultSveltekit(options) {
|
|
|
70
87
|
withRemult(request, what) {
|
|
71
88
|
return result.withRemultAsync(request, what);
|
|
72
89
|
},
|
|
90
|
+
GET: serverHandler,
|
|
91
|
+
PUT: serverHandler,
|
|
92
|
+
POST: serverHandler,
|
|
93
|
+
DELETE: serverHandler,
|
|
73
94
|
});
|
|
74
95
|
}
|
|
@@ -12,6 +12,7 @@ import { Action, classBackendMethodsArray } from '../src/server-action.js';
|
|
|
12
12
|
import { serverActionField } from '../src/server-action-info.js';
|
|
13
13
|
import { initDataProvider } from './initDataProvider.js';
|
|
14
14
|
import { remultStatic } from '../src/remult-static.js';
|
|
15
|
+
import remultAdminHtml from './remult-admin.js';
|
|
15
16
|
export function createRemultServerCore(options, serverCoreOptions) {
|
|
16
17
|
if (!options) {
|
|
17
18
|
options = {};
|
|
@@ -194,6 +195,18 @@ export class RemultServerImplementation {
|
|
|
194
195
|
},
|
|
195
196
|
doWork: undefined,
|
|
196
197
|
}, r);
|
|
198
|
+
if (this.options.admin !== undefined && this.options.admin !== false) {
|
|
199
|
+
r.route(this.options.rootPath + '/admin*').get(this.process(async (remult, req, res, orig, origResponse) => {
|
|
200
|
+
if (remult.isAllowed(this.options.admin))
|
|
201
|
+
origResponse.send(remultAdminHtml({
|
|
202
|
+
remult: remult,
|
|
203
|
+
entities: this.options.entities,
|
|
204
|
+
baseUrl: this.options.rootPath + '/admin',
|
|
205
|
+
}));
|
|
206
|
+
else
|
|
207
|
+
res.notFound();
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
197
210
|
if (this.options.subscriptionServer instanceof SseSubscriptionServer) {
|
|
198
211
|
const streamPath = this.options.rootPath + '/' + streamUrl;
|
|
199
212
|
r.route(streamPath).get(this.process(async (remult, req, res, origReq, origRes) => {
|
|
@@ -814,6 +827,7 @@ export class RouteImplementation {
|
|
|
814
827
|
this.coreOptions = coreOptions;
|
|
815
828
|
}
|
|
816
829
|
map = new Map();
|
|
830
|
+
starRoutes = [];
|
|
817
831
|
route(path) {
|
|
818
832
|
//consider using:
|
|
819
833
|
//* https://raw.githubusercontent.com/cmorten/opine/main/src/utils/pathToRegex.ts
|
|
@@ -821,6 +835,8 @@ export class RouteImplementation {
|
|
|
821
835
|
let r = path.toLowerCase();
|
|
822
836
|
let m = new Map();
|
|
823
837
|
this.map.set(r, m);
|
|
838
|
+
if (path.endsWith('*'))
|
|
839
|
+
this.starRoutes.push({ route: r.substring(0, r.length - 1), handler: m });
|
|
824
840
|
const route = {
|
|
825
841
|
get: (h) => {
|
|
826
842
|
m.set('get', h);
|
|
@@ -864,6 +880,11 @@ export class RouteImplementation {
|
|
|
864
880
|
gRes.json(data);
|
|
865
881
|
res({ statusCode: this.statusCode, data });
|
|
866
882
|
}
|
|
883
|
+
send(html) {
|
|
884
|
+
if (gRes !== undefined)
|
|
885
|
+
gRes.send(html);
|
|
886
|
+
res({ statusCode: this.statusCode, html });
|
|
887
|
+
}
|
|
867
888
|
status(statusCode) {
|
|
868
889
|
if (gRes !== undefined)
|
|
869
890
|
gRes.status(statusCode);
|
|
@@ -913,6 +934,13 @@ export class RouteImplementation {
|
|
|
913
934
|
}
|
|
914
935
|
let lowerPath = path.toLowerCase();
|
|
915
936
|
let m = this.map.get(lowerPath);
|
|
937
|
+
if (!m)
|
|
938
|
+
for (const route of this.starRoutes) {
|
|
939
|
+
if (lowerPath.startsWith(route.route)) {
|
|
940
|
+
m = route.handler;
|
|
941
|
+
break;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
916
944
|
if (m) {
|
|
917
945
|
let h = m.get(req.method.toLowerCase());
|
|
918
946
|
if (h) {
|