@jcbuisson/express-x 1.3.4 → 1.3.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jcbuisson/express-x",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "src/index.mjs",
@@ -12,7 +12,7 @@
12
12
  "license": "MIT",
13
13
  "private": false,
14
14
  "scripts": {
15
- "test": "mocha --require esm 'test/**/*.test.js'",
15
+ "test": "node --test",
16
16
  "generate": "npx prisma generate",
17
17
  "migrate": "npx prisma migrate dev --name init"
18
18
  },
@@ -23,12 +23,7 @@
23
23
  "axios": "^1.4.0",
24
24
  "bcrypt": "^5.1.0",
25
25
  "config": "^3.3.9",
26
- "esm": "^3.2.25",
27
26
  "express": "^4.18.2",
28
27
  "socket.io": "^4.6.0"
29
- },
30
- "devDependencies": {
31
- "chai": "^4.3.7",
32
- "mocha": "^10.2.0"
33
28
  }
34
29
  }
package/src/server.mjs CHANGED
@@ -75,7 +75,7 @@ export function expressX(options = {}) {
75
75
  // call method
76
76
  const result = await method(...context.args)
77
77
  app.log('debug', `result ${result}`)
78
-
78
+
79
79
  // call 'after' hooks
80
80
  const afterMethodHooks = service?.hooks?.after && service.hooks.after[methodName] || []
81
81
  const afterAllHooks = service?.hooks?.after?.all || []
@@ -127,27 +127,14 @@ export function expressX(options = {}) {
127
127
  http: { name: service.name }
128
128
  }
129
129
 
130
- // introspect table schema
131
- async function getFieldTypes() {
132
- const fieldTypes = {}
133
- if (service.prisma._activeProvider === 'sqlite') {
134
- const fieldInfo = await service.prisma.$queryRawUnsafe(`
135
- PRAGMA table_info(${service.entity})
136
- `)
137
- fieldInfo.forEach(column => {
138
- fieldTypes[column.name] = column.type.toLowerCase()
139
- })
140
- } else if (service.prisma._activeProvider === 'postgresql') {
141
- const fieldInfo = await service.prisma.$queryRawUnsafe(`
142
- SELECT column_name, data_type
143
- FROM information_schema.columns
144
- WHERE table_name = '${service.entity}';
145
- `)
146
- fieldInfo.forEach(column => {
147
- fieldTypes[column.column_name] = column.data_type
148
- })
149
- }
150
- return fieldTypes
130
+ // introspect schema
131
+ async function getTypesMap() {
132
+ const dmmf = await service.prisma._getDmmf()
133
+ const fieldDescriptions = dmmf.modelMap[service.name].fields
134
+ return fieldDescriptions.reduce((accu, descr) => {
135
+ accu[descr.name] = descr.type
136
+ return accu
137
+ }, {})
151
138
  }
152
139
 
153
140
 
@@ -172,23 +159,23 @@ export function expressX(options = {}) {
172
159
  // the values in `req.query` are all strings, but Prisma need proper types
173
160
  // we need to introspect column types and do the proper transtyping
174
161
  for (const fieldName in query) {
175
- if (!service.fieldTypes) service.fieldTypes = await getFieldTypes()
176
- const fieldType = service.fieldTypes[fieldName]
162
+ const typesDict = await getTypesMap()
163
+ const fieldType = typesDict[fieldName]
177
164
 
178
- if (fieldType === 'integer') {
165
+ if (fieldType === 'Int') {
179
166
  query[fieldName] = parseInt(query[fieldName])
180
- } else if (fieldType === 'numeric') {
167
+ } else if (fieldType === 'Float') {
181
168
  query[fieldName] = parseFloat(query[fieldName])
182
- } else if (fieldType === 'boolean') {
169
+ } else if (fieldType === 'Boolean') {
183
170
  query[fieldName] = (query[fieldName] === 't') ? true : false
184
- } else if (fieldType === 'text' || fieldType === 'character varying') {
171
+ } else if (fieldType === 'String') {
185
172
  query[fieldName] = query[fieldName]
186
173
  } else {
187
174
  // ?
188
175
  query[fieldName] = query[fieldName]
189
176
  }
190
177
  }
191
-
178
+ // call __findMany
192
179
  const values = await service.__findMany(context, {
193
180
  where: query,
194
181
  })
@@ -4,7 +4,9 @@ import axios from 'axios'
4
4
  import io from 'socket.io-client'
5
5
 
6
6
 
7
- import { assert } from 'chai'
7
+ // import { assert } from 'chai'
8
+ import { describe, it, before, after, beforeEach, afterEach } from 'node:test'
9
+ import { strict as assert } from 'node:assert'
8
10
 
9
11
  import { expressX, expressXClient } from '../src/index.mjs'
10
12
 
@@ -12,13 +14,18 @@ import { expressX, expressXClient } from '../src/index.mjs'
12
14
  // `app` is a regular express application, enhanced with services and real-time features
13
15
  const app = expressX()
14
16
 
15
- app.createDatabaseService('User')
16
- app.createDatabaseService('Post')
17
-
18
17
 
19
18
 
20
19
  describe('ExpressX API (no running server)', () => {
21
20
 
21
+ before(async () => {
22
+ app.createDatabaseService('User')
23
+ app.createDatabaseService('Post')
24
+
25
+ await app.service('User').deleteMany()
26
+ await app.service('Post').deleteMany()
27
+ })
28
+
22
29
  it("can delete all users", async () => {
23
30
  const res = await app.service('User').deleteMany()
24
31
  console.log('res delete', res)
@@ -61,24 +68,41 @@ describe('HTTP/REST API', () => {
61
68
 
62
69
  let chris
63
70
 
64
- before(() => {
71
+ before(async () => {
72
+ console.log("before")
65
73
  // add body parsers for http requests
66
74
  app.use(bodyParser.json())
67
75
  app.use(bodyParser.urlencoded({ extended: false }))
68
76
 
77
+ app.createDatabaseService('User')
78
+ app.createDatabaseService('Post')
79
+
80
+ await app.service('User').deleteMany()
81
+ await app.service('Post').deleteMany()
82
+
69
83
  // add http/rest endpoints
70
84
  app.addHttpRest('/api/user', app.service('User'))
71
85
  app.addHttpRest('/api/post', app.service('Post'))
72
86
 
73
- app.server.listen(8008, () => console.log(`App listening at http://localhost:8008`))
87
+ await new Promise((resolve) => {
88
+ app.server.listen(8008, () => {
89
+ console.log(`App listening at http://localhost:8008`)
90
+ resolve()
91
+ })
92
+ })
93
+ })
94
+
95
+ after(() => {
96
+ console.log("after")
97
+ app.server.close()
74
98
  })
75
99
 
76
100
  it("can create a user", async () => {
77
101
  const res = await axios.post('http://localhost:8008/api/user', {
78
- name: "carole",
79
- email: 'carole@mail.fr'
102
+ name: "chris",
103
+ email: 'chris@mail.fr'
80
104
  })
81
- assert(res?.data?.name === 'carole')
105
+ assert(res?.data?.name === 'chris')
82
106
  })
83
107
 
84
108
  it("can find users", async () => {
@@ -110,23 +134,32 @@ describe('HTTP/REST API', () => {
110
134
  })
111
135
 
112
136
  after(async () => {
113
- await app.server.close()
137
+ app.server.close()
114
138
  })
115
139
  })
116
140
 
117
141
 
118
- // test compatibility with `express-x-client`
142
+ // test compatibility with client API
119
143
  describe('Client API', () => {
120
144
 
121
145
  let clientApp, socket
122
146
 
123
- before(() => {
124
- app.server.listen(8008, () => console.log(`App listening at http://localhost:8008`))
147
+ before(async () => {
148
+ await new Promise((resolve) => {
149
+ app.server.listen(8008, () => {
150
+ console.log(`App listening at http://localhost:8008`)
151
+ resolve()
152
+ })
153
+ })
125
154
 
126
155
  socket = io('http://localhost:8008', { transports: ["websocket"] })
127
156
  clientApp = expressXClient(socket)
128
157
  })
129
158
 
159
+ after(async () => {
160
+ app.server.close()
161
+ })
162
+
130
163
  it("can create a user", async () => {
131
164
  const user = await clientApp.service('User').create({
132
165
  data: {