@jcbuisson/express-x 1.0.12 → 1.0.14
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/package.json +1 -1
- package/src/index.mjs +38 -33
package/package.json
CHANGED
package/src/index.mjs
CHANGED
|
@@ -1,35 +1,33 @@
|
|
|
1
1
|
|
|
2
2
|
import http from 'http'
|
|
3
3
|
import { Server } from "socket.io"
|
|
4
|
-
import { PrismaClient } from '@prisma/client'
|
|
5
4
|
|
|
6
5
|
/*
|
|
7
6
|
* Enhance `app` express application with Feathers-like services
|
|
8
7
|
*/
|
|
9
|
-
function expressX(app) {
|
|
10
|
-
const prisma = new PrismaClient()
|
|
11
|
-
app.set('prisma', prisma) // ?? BOF
|
|
8
|
+
function expressX(app, options) {
|
|
12
9
|
|
|
13
10
|
const services = {}
|
|
14
11
|
const connections = {}
|
|
15
12
|
|
|
16
13
|
let lastConnectionId = 1
|
|
17
|
-
let isDebug = false
|
|
18
14
|
|
|
19
15
|
/*
|
|
20
16
|
* create a service `name` based on Prisma table `entity`
|
|
21
17
|
*/
|
|
22
18
|
function createDatabaseService(name, { entity=name, client='prisma' }) {
|
|
23
|
-
|
|
19
|
+
const prisma = app.get('prisma')
|
|
20
|
+
|
|
21
|
+
const service = createService(name, {
|
|
24
22
|
create: (data) => {
|
|
25
|
-
if (
|
|
23
|
+
if (options.debug) console.log('create', name, data)
|
|
26
24
|
return prisma[entity].create({
|
|
27
25
|
data,
|
|
28
26
|
})
|
|
29
27
|
},
|
|
30
28
|
|
|
31
29
|
get: (id) => {
|
|
32
|
-
if (
|
|
30
|
+
if (options.debug) console.log('get', name, id)
|
|
33
31
|
return prisma[entity].findUnique({
|
|
34
32
|
where: {
|
|
35
33
|
id,
|
|
@@ -38,7 +36,7 @@ function expressX(app) {
|
|
|
38
36
|
},
|
|
39
37
|
|
|
40
38
|
patch: (id, data) => {
|
|
41
|
-
if (
|
|
39
|
+
if (options.debug) console.log('patch', name, id, data)
|
|
42
40
|
return prisma[entity].update({
|
|
43
41
|
where: {
|
|
44
42
|
id,
|
|
@@ -48,24 +46,25 @@ function expressX(app) {
|
|
|
48
46
|
},
|
|
49
47
|
|
|
50
48
|
remove: (id) => {
|
|
51
|
-
if (
|
|
49
|
+
if (options.debug) console.log('remove', name, id)
|
|
52
50
|
return prisma[entity].delete({
|
|
53
51
|
where: {
|
|
54
52
|
id,
|
|
55
53
|
},
|
|
56
|
-
})
|
|
57
|
-
},
|
|
54
|
+
})},
|
|
58
55
|
|
|
59
56
|
find: (options) => {
|
|
60
|
-
if (
|
|
57
|
+
if (options.debug) console.log('find', name, options)
|
|
61
58
|
return prisma[entity].findMany(options)
|
|
62
59
|
},
|
|
63
60
|
|
|
64
61
|
upsert: (options) => {
|
|
65
|
-
if (
|
|
62
|
+
if (options.debug) console.log('upsert', name, options)
|
|
66
63
|
return prisma[entity].upsert(options)
|
|
67
64
|
},
|
|
68
65
|
})
|
|
66
|
+
if (options.debug) console.log(`created service '${name}' over table '${entity}'`)
|
|
67
|
+
return service
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
/*
|
|
@@ -79,7 +78,7 @@ function expressX(app) {
|
|
|
79
78
|
|
|
80
79
|
// `context` is the context of execution (transport type, connection, app)
|
|
81
80
|
// `args` is the list of arguments of the method
|
|
82
|
-
|
|
81
|
+
service['__' + methodName] = async (context, ...args) => {
|
|
83
82
|
context.args = args
|
|
84
83
|
|
|
85
84
|
// if a hook or the method throws an error, it will be caught by `socket.on('client-request'`
|
|
@@ -94,7 +93,7 @@ function expressX(app) {
|
|
|
94
93
|
|
|
95
94
|
// call method
|
|
96
95
|
const result = await method(...context.args)
|
|
97
|
-
// if (
|
|
96
|
+
// if (options.debug) console.log('result', result)
|
|
98
97
|
|
|
99
98
|
// call 'after' hooks
|
|
100
99
|
const afterMethodHooks = service?.hooks?.after && service.hooks.after[methodName] || []
|
|
@@ -105,11 +104,8 @@ function expressX(app) {
|
|
|
105
104
|
return result
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
// hooked version of method, used by client calls
|
|
109
|
-
service['__' + methodName] = hookedMethod
|
|
110
|
-
|
|
111
107
|
// hooked version of method: `create`, etc., to be called from backend with no context
|
|
112
|
-
service[methodName] =
|
|
108
|
+
service[methodName] = method
|
|
113
109
|
|
|
114
110
|
// un-hooked version of method: `_create`, etc., to be called from backend with no context
|
|
115
111
|
service['_' + methodName] = method
|
|
@@ -145,36 +141,48 @@ function expressX(app) {
|
|
|
145
141
|
* add an HTTP REST endpoint at `path`, based on `service`
|
|
146
142
|
*/
|
|
147
143
|
function addHttpRestRoutes(path, service) {
|
|
148
|
-
|
|
149
144
|
const context = {
|
|
150
145
|
app,
|
|
151
146
|
transport: 'http',
|
|
147
|
+
name: service.name,
|
|
152
148
|
}
|
|
153
149
|
|
|
154
150
|
app.post(path, async (req, res) => {
|
|
151
|
+
context.action = 'create'
|
|
152
|
+
context.args = [req.body]
|
|
155
153
|
const value = await service.__create(context, req.body)
|
|
156
154
|
res.json(value)
|
|
157
155
|
})
|
|
158
156
|
|
|
159
157
|
app.get(path, async (req, res) => {
|
|
158
|
+
context.action = 'find'
|
|
159
|
+
context.args = [req.body]
|
|
160
160
|
const values = await service.__find(context, req.body)
|
|
161
161
|
res.json(values)
|
|
162
162
|
})
|
|
163
163
|
|
|
164
164
|
app.get(`${path}/:id`, async (req, res) => {
|
|
165
|
+
context.action = 'get'
|
|
166
|
+
context.args = [req.params.id]
|
|
165
167
|
const value = await service.__get(context, parseInt(req.params.id))
|
|
166
168
|
res.json(value)
|
|
167
169
|
})
|
|
168
170
|
|
|
169
171
|
app.patch(`${path}/:id`, async (req, res) => {
|
|
172
|
+
context.action = 'patch'
|
|
173
|
+
context.args = [req.params.id, req.body]
|
|
170
174
|
const value = await service.__patch(context, parseInt(req.params.id), req.body)
|
|
171
175
|
res.json(value)
|
|
172
176
|
})
|
|
173
177
|
|
|
174
178
|
app.delete(`${path}/:id`, async (req, res) => {
|
|
179
|
+
context.action = 'remove'
|
|
180
|
+
context.args = [req.params.id]
|
|
175
181
|
const value = await service.__remove(context, parseInt(req.params.id))
|
|
176
182
|
res.json(value)
|
|
177
183
|
})
|
|
184
|
+
|
|
185
|
+
if (options.debug) console.log(`added HTTP endpoints for service '${service.name}' at path '${path}'`)
|
|
178
186
|
}
|
|
179
187
|
|
|
180
188
|
/*
|
|
@@ -184,7 +192,7 @@ function expressX(app) {
|
|
|
184
192
|
const io = new Server(server)
|
|
185
193
|
|
|
186
194
|
io.on('connection', function(socket) {
|
|
187
|
-
if (
|
|
195
|
+
if (options.debug) console.log('Client connected to the WebSocket')
|
|
188
196
|
const connection = {
|
|
189
197
|
id: lastConnectionId++,
|
|
190
198
|
socket,
|
|
@@ -192,7 +200,7 @@ function expressX(app) {
|
|
|
192
200
|
}
|
|
193
201
|
// store connection in cache
|
|
194
202
|
connections[connection.id] = connection
|
|
195
|
-
if (
|
|
203
|
+
if (options.debug) console.log('active connections', Object.keys(connections))
|
|
196
204
|
|
|
197
205
|
// emit 'connection' event for app (expressjs extends EventEmitter)
|
|
198
206
|
app.emit('connection', connection)
|
|
@@ -201,7 +209,7 @@ function expressX(app) {
|
|
|
201
209
|
socket.emit('connected', connection.id)
|
|
202
210
|
|
|
203
211
|
socket.on('disconnect', () => {
|
|
204
|
-
if (
|
|
212
|
+
if (options.debug) console.log('Client disconnected', connection.id)
|
|
205
213
|
delete connections[connection.id]
|
|
206
214
|
})
|
|
207
215
|
|
|
@@ -211,7 +219,7 @@ function expressX(app) {
|
|
|
211
219
|
* Emit in return a 'client-response' message
|
|
212
220
|
*/
|
|
213
221
|
socket.on('client-request', async ({ uid, name, action, args }) => {
|
|
214
|
-
if (
|
|
222
|
+
if (options.debug) console.log("client-request", uid, name, action, args)
|
|
215
223
|
if (name in services) {
|
|
216
224
|
const service = services[name]
|
|
217
225
|
try {
|
|
@@ -223,6 +231,7 @@ function expressX(app) {
|
|
|
223
231
|
connection,
|
|
224
232
|
name,
|
|
225
233
|
action,
|
|
234
|
+
args,
|
|
226
235
|
}
|
|
227
236
|
const result = await serviceMethod(context, ...args)
|
|
228
237
|
|
|
@@ -234,12 +243,12 @@ function expressX(app) {
|
|
|
234
243
|
const publishFunc = service.publishCallback
|
|
235
244
|
if (publishFunc) {
|
|
236
245
|
const channelNames = await publishFunc(result, app)
|
|
237
|
-
if (
|
|
246
|
+
if (options.debug) console.log('publish channels', name, action, channelNames)
|
|
238
247
|
for (const channelName of channelNames) {
|
|
239
|
-
if (
|
|
248
|
+
if (options.debug) console.log('service-event', name, action, channelName)
|
|
240
249
|
const connectionList = Object.values(connections).filter(cnx => cnx.channelNames.has(channelName))
|
|
241
250
|
for (const connection of connectionList) {
|
|
242
|
-
if (
|
|
251
|
+
if (options.debug) console.log('emit to', connection.id, name, action, result)
|
|
243
252
|
connection.socket.emit('service-event', {
|
|
244
253
|
name,
|
|
245
254
|
action,
|
|
@@ -278,12 +287,9 @@ function expressX(app) {
|
|
|
278
287
|
connection.channelNames.delete(channelName)
|
|
279
288
|
}
|
|
280
289
|
|
|
281
|
-
function setDebug(isOn) {
|
|
282
|
-
isDebug = isOn
|
|
283
|
-
}
|
|
284
|
-
|
|
285
290
|
// enhance `app` with objects and methods
|
|
286
291
|
Object.assign(app, {
|
|
292
|
+
options,
|
|
287
293
|
createDatabaseService,
|
|
288
294
|
createService,
|
|
289
295
|
service,
|
|
@@ -292,7 +298,6 @@ function expressX(app) {
|
|
|
292
298
|
server,
|
|
293
299
|
joinChannel,
|
|
294
300
|
leaveChannel,
|
|
295
|
-
setDebug,
|
|
296
301
|
})
|
|
297
302
|
return app
|
|
298
303
|
}
|