remult 0.26.1 → 0.26.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/README.md +3 -2
- package/esm/remult-solid-start.js +97 -0
- package/esm/src/remult3/remult3.js +3 -1
- package/package.json +6 -1
- package/remult-solid-start.d.ts +12 -0
- package/remult-solid-start.js +134 -0
- package/src/remult3/remult3.js +3 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Remult uses **TypeScript entities** as a single source of truth for: ✅ CRUD +
|
|
|
39
39
|
|
|
40
40
|
**Remult supports all major databases**, including: PostgreSQL, MySQL, SQLite, MongoDB, MSSQL and Oracle.
|
|
41
41
|
|
|
42
|
-
**Remult is frontend and backend framework agnostic** and comes with adapters for Express, Fastify, Next.js, Nuxt, SvelteKit, Nest, Koa, Hapi and Hono.
|
|
42
|
+
**Remult is frontend and backend framework agnostic** and comes with adapters for Express, Fastify, Next.js, Nuxt, SvelteKit, SolidStart, Nest, Koa, Hapi and Hono.
|
|
43
43
|
|
|
44
44
|
Remult promotes a **consistent query syntax for both frontend and Backend code**:
|
|
45
45
|
|
|
@@ -93,7 +93,7 @@ _Example:_
|
|
|
93
93
|
// backend/index.ts
|
|
94
94
|
|
|
95
95
|
import express from 'express'
|
|
96
|
-
import { remultExpress } from 'remult/remult-express' // adapters for: Fastify,
|
|
96
|
+
import { remultExpress } from 'remult/remult-express' // adapters for: Fastify,Next.js, Nuxt, SvelteKit, SolidStart, Nest, more...
|
|
97
97
|
import { createPostgresDataProvider } from 'remult/postgres' // supported: PostgreSQL, MySQL, SQLite, MongoDB, MSSQL and Oracle
|
|
98
98
|
import { Product } from '../shared/product'
|
|
99
99
|
|
|
@@ -306,6 +306,7 @@ with a Node.js Express backend.
|
|
|
306
306
|
- [Tutorial with Vue](https://remult.dev/tutorials/vue/)
|
|
307
307
|
- [Tutorial with Next.js](https://remult.dev/tutorials/react-next/)
|
|
308
308
|
- [Tutorial with Sveltekit](https://remult.dev/tutorials/sveltekit/)
|
|
309
|
+
- [Tutorial with SolidStart](https://remult.dev/tutorials/react-next/)
|
|
309
310
|
|
|
310
311
|
## Demo
|
|
311
312
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { getRequestEvent } from 'solid-js/web';
|
|
2
|
+
import { createRemultServer } from './server/index.js';
|
|
3
|
+
export function remultSolidStart(options) {
|
|
4
|
+
let result = createRemultServer(options, {
|
|
5
|
+
buildGenericRequestInfo: (event) => ({
|
|
6
|
+
url: event.request.url,
|
|
7
|
+
method: event.request.method,
|
|
8
|
+
on: (e, do1) => {
|
|
9
|
+
if (e === 'close') {
|
|
10
|
+
event.locals['_tempOnClose'] = do1;
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
}),
|
|
14
|
+
getRequestBody: (event) => event.request.json(),
|
|
15
|
+
});
|
|
16
|
+
const serverHandler = async () => {
|
|
17
|
+
const event = await getRequestEvent();
|
|
18
|
+
let sseResponse = undefined;
|
|
19
|
+
if (event)
|
|
20
|
+
event.locals['_tempOnClose'] = () => { };
|
|
21
|
+
const response = {
|
|
22
|
+
end: () => { },
|
|
23
|
+
json: () => { },
|
|
24
|
+
send: () => { },
|
|
25
|
+
status: () => {
|
|
26
|
+
return response;
|
|
27
|
+
},
|
|
28
|
+
write: () => { },
|
|
29
|
+
writeHead: (status, headers) => {
|
|
30
|
+
if (status === 200 && headers) {
|
|
31
|
+
const contentType = headers['Content-Type'];
|
|
32
|
+
if (contentType === 'text/event-stream') {
|
|
33
|
+
const messages = [];
|
|
34
|
+
response.write = (x) => messages.push(x);
|
|
35
|
+
const stream = new ReadableStream({
|
|
36
|
+
start: (controller) => {
|
|
37
|
+
for (const message of messages) {
|
|
38
|
+
controller.enqueue(message);
|
|
39
|
+
}
|
|
40
|
+
response.write = (data) => {
|
|
41
|
+
controller.enqueue(data);
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
cancel: () => {
|
|
45
|
+
response.write = () => { };
|
|
46
|
+
event?.locals?.['_tempOnClose']?.();
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
sseResponse = new Response(stream, { headers });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const responseFromRemultHandler = await result.handle(event, response);
|
|
55
|
+
if (sseResponse !== undefined) {
|
|
56
|
+
return sseResponse;
|
|
57
|
+
}
|
|
58
|
+
if (responseFromRemultHandler) {
|
|
59
|
+
if (responseFromRemultHandler.html)
|
|
60
|
+
return new Response(responseFromRemultHandler.html, {
|
|
61
|
+
status: responseFromRemultHandler.statusCode,
|
|
62
|
+
headers: {
|
|
63
|
+
'Content-Type': 'text/html',
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const res = new Response(JSON.stringify(responseFromRemultHandler.data), {
|
|
67
|
+
status: responseFromRemultHandler.statusCode,
|
|
68
|
+
});
|
|
69
|
+
return res;
|
|
70
|
+
}
|
|
71
|
+
return new Response('Not Found', {
|
|
72
|
+
status: 404,
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const handler = {}; //async ({ event, resolve }) => {
|
|
76
|
+
// if (event.url.pathname.startsWith(options!.rootPath!)) {
|
|
77
|
+
// const result = await serverHandler(event)
|
|
78
|
+
// if (result != null && result?.status != 404) return result
|
|
79
|
+
// }
|
|
80
|
+
// return new Promise<Response>((res) => {
|
|
81
|
+
// result.withRemult(event, undefined!, async () => {
|
|
82
|
+
// res(await resolve(event))
|
|
83
|
+
// })
|
|
84
|
+
// })
|
|
85
|
+
// }
|
|
86
|
+
return Object.assign(handler, {
|
|
87
|
+
getRemult: (req) => result.getRemult(req),
|
|
88
|
+
openApiDoc: (options) => result.openApiDoc(options),
|
|
89
|
+
async withRemult(what) {
|
|
90
|
+
return result.withRemultAsync(await getRequestEvent(), what);
|
|
91
|
+
},
|
|
92
|
+
GET: serverHandler,
|
|
93
|
+
PUT: serverHandler,
|
|
94
|
+
POST: serverHandler,
|
|
95
|
+
DELETE: serverHandler,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export {};
|
|
2
2
|
//y1 - https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
3
3
|
//y1 - fix async hooks - was it fixed?
|
|
4
|
+
//p1 - prevent default in delete should not delete - and check proceed from there
|
|
4
5
|
//p1 - release solid start with example project
|
|
5
6
|
//p1 - add documentation for bun sqlite
|
|
6
7
|
//p1 - fix dark background to also work on groups
|
|
@@ -14,10 +15,11 @@ export {};
|
|
|
14
15
|
//p1 - consider upsert (where,set)
|
|
15
16
|
//p1 - consider id to also support keyof (id:['company','index'])
|
|
16
17
|
//p1 - consider including the admin in the tutorial - and maybe even in the demo when we setup the api
|
|
18
|
+
//p1 -
|
|
17
19
|
//y2 - JY suggestion of having generate as part of the ensure schema - not sure
|
|
18
20
|
//y2 - currently for string fields we default for 255 in knex (which is their default) why not just use text (varchar max) - and only use exact length when one is provided?
|
|
19
21
|
//p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
|
|
20
|
-
//p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string}
|
|
22
|
+
//p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else.
|
|
21
23
|
//p1 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
|
|
22
24
|
//y2 - fix validators cache
|
|
23
25
|
//y2 - should we validate relations
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remult",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.2",
|
|
4
4
|
"description": "A CRUD framework for full-stack TypeScript",
|
|
5
5
|
"homepage": "https://remult.dev",
|
|
6
6
|
"repository": {
|
|
@@ -140,6 +140,11 @@
|
|
|
140
140
|
"require": "./remult-nuxt.js",
|
|
141
141
|
"import": "./esm/remult-nuxt.js",
|
|
142
142
|
"types": "./remult-nuxt.d.ts"
|
|
143
|
+
},
|
|
144
|
+
"./remult-solid-start": {
|
|
145
|
+
"require": "./remult-solid-start.js",
|
|
146
|
+
"import": "./esm/remult-solid-start.js",
|
|
147
|
+
"types": "./remult-solid-start.d.ts"
|
|
143
148
|
}
|
|
144
149
|
},
|
|
145
150
|
"main": "./index.js",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RequestEvent } from 'solid-js/web';
|
|
2
|
+
import type { RemultServerCore, RemultServerOptions } from './server/index.js';
|
|
3
|
+
export declare function remultSolidStart(options: RemultServerOptions<RequestEvent>): RemultSolidStartServer;
|
|
4
|
+
type RequestHandler = (event: RequestEvent) => Promise<Response>;
|
|
5
|
+
export type RemultSolidStartServer = RemultServerCore<RequestEvent> & {
|
|
6
|
+
withRemult<T>(what: () => Promise<T>): Promise<T>;
|
|
7
|
+
GET: RequestHandler;
|
|
8
|
+
PUT: RequestHandler;
|
|
9
|
+
POST: RequestHandler;
|
|
10
|
+
DELETE: RequestHandler;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.remultSolidStart = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var web_1 = require("solid-js/web");
|
|
6
|
+
var index_js_1 = require("./server/index.js");
|
|
7
|
+
function remultSolidStart(options) {
|
|
8
|
+
var _this = this;
|
|
9
|
+
var result = (0, index_js_1.createRemultServer)(options, {
|
|
10
|
+
buildGenericRequestInfo: function (event) { return ({
|
|
11
|
+
url: event.request.url,
|
|
12
|
+
method: event.request.method,
|
|
13
|
+
on: function (e, do1) {
|
|
14
|
+
if (e === 'close') {
|
|
15
|
+
event.locals['_tempOnClose'] = do1;
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
}); },
|
|
19
|
+
getRequestBody: function (event) { return event.request.json(); },
|
|
20
|
+
});
|
|
21
|
+
var serverHandler = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
22
|
+
var event, sseResponse, response, responseFromRemultHandler, res;
|
|
23
|
+
return tslib_1.__generator(this, function (_a) {
|
|
24
|
+
switch (_a.label) {
|
|
25
|
+
case 0: return [4 /*yield*/, (0, web_1.getRequestEvent)()];
|
|
26
|
+
case 1:
|
|
27
|
+
event = _a.sent();
|
|
28
|
+
sseResponse = undefined;
|
|
29
|
+
if (event)
|
|
30
|
+
event.locals['_tempOnClose'] = function () { };
|
|
31
|
+
response = {
|
|
32
|
+
end: function () { },
|
|
33
|
+
json: function () { },
|
|
34
|
+
send: function () { },
|
|
35
|
+
status: function () {
|
|
36
|
+
return response;
|
|
37
|
+
},
|
|
38
|
+
write: function () { },
|
|
39
|
+
writeHead: function (status, headers) {
|
|
40
|
+
if (status === 200 && headers) {
|
|
41
|
+
var contentType = headers['Content-Type'];
|
|
42
|
+
if (contentType === 'text/event-stream') {
|
|
43
|
+
var messages_1 = [];
|
|
44
|
+
response.write = function (x) { return messages_1.push(x); };
|
|
45
|
+
var stream = new ReadableStream({
|
|
46
|
+
start: function (controller) {
|
|
47
|
+
var e_1, _a;
|
|
48
|
+
try {
|
|
49
|
+
for (var messages_2 = tslib_1.__values(messages_1), messages_2_1 = messages_2.next(); !messages_2_1.done; messages_2_1 = messages_2.next()) {
|
|
50
|
+
var message = messages_2_1.value;
|
|
51
|
+
controller.enqueue(message);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
55
|
+
finally {
|
|
56
|
+
try {
|
|
57
|
+
if (messages_2_1 && !messages_2_1.done && (_a = messages_2.return)) _a.call(messages_2);
|
|
58
|
+
}
|
|
59
|
+
finally { if (e_1) throw e_1.error; }
|
|
60
|
+
}
|
|
61
|
+
response.write = function (data) {
|
|
62
|
+
controller.enqueue(data);
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
cancel: function () {
|
|
66
|
+
var _a, _b;
|
|
67
|
+
response.write = function () { };
|
|
68
|
+
(_b = (_a = event === null || event === void 0 ? void 0 : event.locals) === null || _a === void 0 ? void 0 : _a['_tempOnClose']) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
sseResponse = new Response(stream, { headers: headers });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
return [4 /*yield*/, result.handle(event, response)];
|
|
77
|
+
case 2:
|
|
78
|
+
responseFromRemultHandler = _a.sent();
|
|
79
|
+
if (sseResponse !== undefined) {
|
|
80
|
+
return [2 /*return*/, sseResponse];
|
|
81
|
+
}
|
|
82
|
+
if (responseFromRemultHandler) {
|
|
83
|
+
if (responseFromRemultHandler.html)
|
|
84
|
+
return [2 /*return*/, new Response(responseFromRemultHandler.html, {
|
|
85
|
+
status: responseFromRemultHandler.statusCode,
|
|
86
|
+
headers: {
|
|
87
|
+
'Content-Type': 'text/html',
|
|
88
|
+
},
|
|
89
|
+
})];
|
|
90
|
+
res = new Response(JSON.stringify(responseFromRemultHandler.data), {
|
|
91
|
+
status: responseFromRemultHandler.statusCode,
|
|
92
|
+
});
|
|
93
|
+
return [2 /*return*/, res];
|
|
94
|
+
}
|
|
95
|
+
return [2 /*return*/, new Response('Not Found', {
|
|
96
|
+
status: 404,
|
|
97
|
+
})];
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}); };
|
|
101
|
+
var handler = {}; //async ({ event, resolve }) => {
|
|
102
|
+
// if (event.url.pathname.startsWith(options!.rootPath!)) {
|
|
103
|
+
// const result = await serverHandler(event)
|
|
104
|
+
// if (result != null && result?.status != 404) return result
|
|
105
|
+
// }
|
|
106
|
+
// return new Promise<Response>((res) => {
|
|
107
|
+
// result.withRemult(event, undefined!, async () => {
|
|
108
|
+
// res(await resolve(event))
|
|
109
|
+
// })
|
|
110
|
+
// })
|
|
111
|
+
// }
|
|
112
|
+
return Object.assign(handler, {
|
|
113
|
+
getRemult: function (req) { return result.getRemult(req); },
|
|
114
|
+
openApiDoc: function (options) { return result.openApiDoc(options); },
|
|
115
|
+
withRemult: function (what) {
|
|
116
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
117
|
+
var _a, _b;
|
|
118
|
+
return tslib_1.__generator(this, function (_c) {
|
|
119
|
+
switch (_c.label) {
|
|
120
|
+
case 0:
|
|
121
|
+
_b = (_a = result).withRemultAsync;
|
|
122
|
+
return [4 /*yield*/, (0, web_1.getRequestEvent)()];
|
|
123
|
+
case 1: return [2 /*return*/, _b.apply(_a, [_c.sent(), what])];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
GET: serverHandler,
|
|
129
|
+
PUT: serverHandler,
|
|
130
|
+
POST: serverHandler,
|
|
131
|
+
DELETE: serverHandler,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
exports.remultSolidStart = remultSolidStart;
|
package/src/remult3/remult3.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//y1 - https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
4
4
|
//y1 - fix async hooks - was it fixed?
|
|
5
|
+
//p1 - prevent default in delete should not delete - and check proceed from there
|
|
5
6
|
//p1 - release solid start with example project
|
|
6
7
|
//p1 - add documentation for bun sqlite
|
|
7
8
|
//p1 - fix dark background to also work on groups
|
|
@@ -15,10 +16,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
16
|
//p1 - consider upsert (where,set)
|
|
16
17
|
//p1 - consider id to also support keyof (id:['company','index'])
|
|
17
18
|
//p1 - consider including the admin in the tutorial - and maybe even in the demo when we setup the api
|
|
19
|
+
//p1 -
|
|
18
20
|
//y2 - JY suggestion of having generate as part of the ensure schema - not sure
|
|
19
21
|
//y2 - currently for string fields we default for 255 in knex (which is their default) why not just use text (varchar max) - and only use exact length when one is provided?
|
|
20
22
|
//p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
|
|
21
|
-
//p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string}
|
|
23
|
+
//p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else.
|
|
22
24
|
//p1 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
|
|
23
25
|
//y2 - fix validators cache
|
|
24
26
|
//y2 - should we validate relations
|