@jcbuisson/express-x 1.7.12 → 1.8.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.mjs +30 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jcbuisson/express-x",
3
- "version": "1.7.12",
3
+ "version": "1.8.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "src/index.mjs",
package/src/server.mjs CHANGED
@@ -3,6 +3,8 @@ import http from 'http'
3
3
  import { Server } from 'socket.io'
4
4
  import express from 'express'
5
5
 
6
+ import { getDMMF } from '@prisma/internals'
7
+
6
8
  /*
7
9
  * Enhance `app` express application with services and real-time features
8
10
  */
@@ -88,7 +90,7 @@ export function expressX(prisma, config) {
88
90
  * create a service `name` with given `methods`
89
91
  */
90
92
  function createService(name, methods) {
91
- const service = { name }
93
+ const service = { _name: name }
92
94
 
93
95
  for (const methodName in methods) {
94
96
  const method = methods[methodName]
@@ -105,8 +107,8 @@ export function expressX(prisma, config) {
105
107
 
106
108
  // call 'before' hooks, possibly modifying `context`
107
109
  const beforeAppHooks = appHooks?.before || []
108
- const beforeMethodHooks = service?.hooks?.before && service.hooks.before[methodName] || []
109
- const beforeAllHooks = service?.hooks?.before?.all || []
110
+ const beforeMethodHooks = service?._hooks?.before && service._hooks.before[methodName] || []
111
+ const beforeAllHooks = service?._hooks?.before?.all || []
110
112
  for (const hook of [...beforeAppHooks, ...beforeMethodHooks, ...beforeAllHooks]) {
111
113
  await hook(context)
112
114
  }
@@ -117,8 +119,8 @@ export function expressX(prisma, config) {
117
119
  context.result = result
118
120
 
119
121
  // call 'after' hooks, possibly modifying `context`
120
- const afterMethodHooks = service?.hooks?.after && service.hooks.after[methodName] || []
121
- const afterAllHooks = service?.hooks?.after?.all || []
122
+ const afterMethodHooks = service?._hooks?.after && service._hooks.after[methodName] || []
123
+ const afterAllHooks = service?._hooks?.after?.all || []
122
124
  const afterAppHooks = appHooks?.after || []
123
125
  for (const hook of [...afterMethodHooks, ...afterAllHooks, ...afterAppHooks]) {
124
126
  await hook(context)
@@ -127,10 +129,10 @@ export function expressX(prisma, config) {
127
129
  // publish event (websocket transport)
128
130
  if (config.WS_TRANSPORT && service.publishFunction) {
129
131
  const channelNames = await service.publishFunction(context)
130
- app.log('verbose', `publish channels ${service.name} ${methodName} ${channelNames}`)
132
+ app.log('verbose', `publish channels ${service._name} ${methodName} ${channelNames}`)
131
133
  const connections = await app.prisma.Connection.findMany({})
132
134
  for (const channelName of channelNames) {
133
- app.log('verbose', `service-event ${service.name} ${methodName} ${channelName}`)
135
+ app.log('verbose', `service-event ${service._name} ${methodName} ${channelName}`)
134
136
  const connectionList = connections.filter(connection => {
135
137
  const channelNames = JSON.parse(connection.channelNames)
136
138
  return channelNames.includes(channelName)
@@ -138,11 +140,11 @@ export function expressX(prisma, config) {
138
140
 
139
141
  for (const connection of connectionList) {
140
142
  const trimmedResult = result ? JSON.stringify(result).slice(0, 300) : ''
141
- app.log('verbose', `emit to ${connection.id} ${service.name} ${methodName} ${trimmedResult}`)
143
+ app.log('verbose', `emit to ${connection.id} ${service._name} ${methodName} ${trimmedResult}`)
142
144
  const socket = getSocket(connection.id)
143
145
  // emit service event
144
146
  socket && socket.emit('service-event', {
145
- name: service.name,
147
+ name: service._name,
146
148
  action: methodName,
147
149
  result,
148
150
  })
@@ -153,11 +155,14 @@ export function expressX(prisma, config) {
153
155
  return context.result
154
156
  }
155
157
 
156
- // TODO: NOT CLEAR AND PROBABLY USELESS
157
- // hooked version of method: `create`, etc., to be called from backend with no context
158
- service[methodName] = method
159
- // un-hooked version of method: `_create`, etc., to be called from backend with no context
160
- service['_' + methodName] = method
158
+ // hooked version of method to be used server-side
159
+ service[methodName] = (...args) => {
160
+ const context = {
161
+ caller: 'server'
162
+ }
163
+ const hookedMethod = service['__' + methodName]
164
+ return hookedMethod(context, ...args)
165
+ }
161
166
  }
162
167
 
163
168
  // attach pub/sub publish callback
@@ -167,7 +172,7 @@ export function expressX(prisma, config) {
167
172
 
168
173
  // attach hooks
169
174
  service.hooks = (hooks) => {
170
- service.hooks = hooks
175
+ service._hooks = hooks
171
176
  }
172
177
 
173
178
  // cache service in `services`
@@ -196,15 +201,18 @@ export function expressX(prisma, config) {
196
201
  */
197
202
  async function addHttpRest(path, service) {
198
203
  const context = {
204
+ caller: 'client',
199
205
  app,
200
206
  transport: 'http',
201
- params: { name: service.name }
207
+ params: { name: service._name }
202
208
  }
203
209
 
204
210
  // introspect schema and return a map: field name => prisma type
205
- async function getTypesMap() {
206
- const dmmf = await service.prisma._getDmmf()
207
- const fieldDescriptions = dmmf.modelMap[service.name].fields
211
+ function getTypesMap() {
212
+ // const dmmf = await service.prisma._getDmmf()
213
+ // const fieldDescriptions = dmmf.modelMap[service._name].fields
214
+ const dmmf = service.prisma._runtimeDataModel
215
+ const fieldDescriptions = dmmf.models[service._name].fields
208
216
  return fieldDescriptions.reduce((accu, descr) => {
209
217
  accu[descr.name] = descr.type
210
218
  return accu
@@ -232,7 +240,7 @@ export function expressX(prisma, config) {
232
240
  // the values in `req.query` are all strings, but Prisma need proper types
233
241
  // we need to introspect column types and do the proper transtyping
234
242
  for (const fieldName in query) {
235
- const typesDict = await getTypesMap()
243
+ const typesDict = getTypesMap()
236
244
  const fieldType = typesDict[fieldName]
237
245
 
238
246
  if (fieldType === 'Int') {
@@ -308,7 +316,7 @@ export function expressX(prisma, config) {
308
316
  }
309
317
  })
310
318
 
311
- app.log('info', `added HTTP endpoints for service '${service.name}' at path '${path}'`)
319
+ app.log('info', `added HTTP endpoints for service '${service._name}' at path '${path}'`)
312
320
  }
313
321
 
314
322
  /*
@@ -333,7 +341,6 @@ export function expressX(prisma, config) {
333
341
  setSocket(connection.id, socket)
334
342
 
335
343
  // emit 'connection' event for app (expressjs extends EventEmitter)
336
- console.log('EMIT CONNECTION')
337
344
  app.emit('connection', connection)
338
345
 
339
346
  // send 'connected' event to client
@@ -382,6 +389,7 @@ export function expressX(prisma, config) {
382
389
  const serviceMethod = service['__' + action]
383
390
  if (serviceMethod) {
384
391
  const context = {
392
+ caller: 'client',
385
393
  app,
386
394
  transport: 'ws',
387
395
  params: { connectionId: connection.id, name, action, args },