@hitchy/plugin-odem-socket.io 0.2.1 → 0.2.3
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/api/services/odem/websocket-provider.js +300 -180
- package/package.json +11 -11
|
@@ -18,30 +18,47 @@ module.exports = function() {
|
|
|
18
18
|
*/
|
|
19
19
|
static start() {
|
|
20
20
|
api.once( "websocket", io => {
|
|
21
|
+
const { crud, notifications } = api.config.socket.odem;
|
|
22
|
+
|
|
21
23
|
const namespace = io.of( "/hitchy/odem" );
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
const model = api.models[modelName];
|
|
25
|
+
const txPerModel = {};
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
for ( const [ modelName, model ] of Object.entries( api.models ) ) {
|
|
28
|
+
txPerModel[modelName] = this.broadcastModelNotifications( notifications, namespace, modelName, model );
|
|
27
29
|
}
|
|
28
|
-
} );
|
|
29
|
-
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
namespace.on( "connection", socket => {
|
|
32
|
+
const rxPerModel = {};
|
|
33
|
+
|
|
34
|
+
for ( const [ modelName, model ] of Object.entries( api.models ) ) {
|
|
35
|
+
rxPerModel[modelName] = this.handleModelRequests( crud, socket, modelName, model );
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
socket.once( "disconnect", () => {
|
|
39
|
+
for ( const [ modelName, handlers ] of Object.entries( rxPerModel ) ) {
|
|
40
|
+
for ( const [ eventName, handler ] of Object.entries( handlers ) ) {
|
|
41
|
+
const prefix = api.utility.case.pascalToKebab( modelName );
|
|
42
|
+
|
|
43
|
+
socket.off( `${prefix}:${eventName}`, handler );
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} );
|
|
47
|
+
} );
|
|
48
|
+
|
|
49
|
+
api.once( "close", () => {
|
|
50
|
+
namespace.disconnectSockets( true );
|
|
42
51
|
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
for ( const [ modelName, model ] of Object.entries( api.models ) ) {
|
|
53
|
+
const handlers = txPerModel[modelName];
|
|
54
|
+
|
|
55
|
+
model.notifications
|
|
56
|
+
.off( "created", handlers.created )
|
|
57
|
+
.off( "changed", handlers.changed )
|
|
58
|
+
.off( "removed", handlers.removed );
|
|
59
|
+
}
|
|
60
|
+
} );
|
|
61
|
+
} );
|
|
45
62
|
}
|
|
46
63
|
|
|
47
64
|
/**
|
|
@@ -49,168 +66,57 @@ module.exports = function() {
|
|
|
49
66
|
* model-related actions.
|
|
50
67
|
*
|
|
51
68
|
* @param {boolean} enabled true if command handling is enabled in configuration
|
|
52
|
-
* @param {
|
|
69
|
+
* @param {WebSocket} socket socket representing established incoming connection
|
|
53
70
|
* @param {string} modelName name of model to manage
|
|
54
71
|
* @param {class<Hitchy.Plugin.Odem.Model>} model ODM-based model instance to manage
|
|
55
|
-
* @returns {
|
|
72
|
+
* @returns {Object<string,function>} map of registered handler functions
|
|
56
73
|
*/
|
|
57
|
-
static handleModelRequests( enabled,
|
|
74
|
+
static handleModelRequests( enabled, socket, modelName, model ) {
|
|
58
75
|
const prefix = api.utility.case.pascalToKebab( modelName );
|
|
59
76
|
|
|
60
77
|
if ( !enabled ) {
|
|
61
78
|
logDebug( "disabling socket-based action requests for model %s (%s)", modelName, prefix );
|
|
62
79
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
} );
|
|
80
|
+
const handlers = {
|
|
81
|
+
list: ( _, __, ___, response ) => reject( response ),
|
|
82
|
+
find: ( _, __, ___, ____, response ) => reject( response ),
|
|
83
|
+
create: ( _, __, response ) => reject( response ),
|
|
84
|
+
read: ( _, __, response ) => reject( response ),
|
|
85
|
+
update: ( _, __, ___, response ) => reject( response ),
|
|
86
|
+
delete: ( _, __, response ) => reject( response ),
|
|
87
|
+
};
|
|
72
88
|
|
|
73
|
-
|
|
89
|
+
socket
|
|
90
|
+
.on( `${prefix}:list`, handlers.list )
|
|
91
|
+
.on( `${prefix}:find`, handlers.find )
|
|
92
|
+
.on( `${prefix}:create`, handlers.create )
|
|
93
|
+
.on( `${prefix}:read`, handlers.read )
|
|
94
|
+
.on( `${prefix}:update`, handlers.update )
|
|
95
|
+
.on( `${prefix}:delete`, handlers.delete );
|
|
96
|
+
|
|
97
|
+
return handlers;
|
|
74
98
|
}
|
|
75
99
|
|
|
76
100
|
logDebug( "enabling socket-based action requests for model %s (%s)", modelName, prefix );
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
error: error.message,
|
|
97
|
-
} );
|
|
98
|
-
}
|
|
99
|
-
} )
|
|
100
|
-
.on( `${prefix}:find`, async( sessionId, query, queryOptions, loadRecords, response ) => {
|
|
101
|
-
logDebug( "request for finding %s instances matching %j w/ queryOptions %j and uuidsOnly %j", modelName, query, queryOptions, Boolean( loadRecords ) );
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
const meta = {};
|
|
105
|
-
const items = await model.find( query, queryOptions, { loadRecords: Boolean( loadRecords ), metaCollector: meta } );
|
|
106
|
-
|
|
107
|
-
response( {
|
|
108
|
-
success: true,
|
|
109
|
-
count: meta.count,
|
|
110
|
-
items: items.map( item => ( loadRecords ? item.toObject( { serialized: true } ) : { uuid: item.uuid } ) ),
|
|
111
|
-
} );
|
|
112
|
-
} catch ( error ) {
|
|
113
|
-
logError( "finding %s instances matching %j failed: %s", modelName, error.stack );
|
|
114
|
-
|
|
115
|
-
response( {
|
|
116
|
-
error: error.message,
|
|
117
|
-
} );
|
|
118
|
-
}
|
|
119
|
-
} )
|
|
120
|
-
.on( `${prefix}:create`, async( sessionId, properties, response ) => {
|
|
121
|
-
logDebug( "request for creating %s instance with %j", modelName, properties );
|
|
122
|
-
|
|
123
|
-
try {
|
|
124
|
-
const schema = model.schema;
|
|
125
|
-
const instance = new model; // eslint-disable-line new-cap
|
|
126
|
-
|
|
127
|
-
for ( const propName of Object.keys( properties ) ) {
|
|
128
|
-
if ( schema.props.hasOwnProperty( propName ) ||
|
|
129
|
-
schema.computed.hasOwnProperty( propName ) ) {
|
|
130
|
-
instance[propName] = properties[propName];
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
await instance.save();
|
|
135
|
-
|
|
136
|
-
response( {
|
|
137
|
-
success: true,
|
|
138
|
-
properties: instance.toObject( { serialized: true } ),
|
|
139
|
-
} );
|
|
140
|
-
} catch ( error ) {
|
|
141
|
-
logError( "creating %s instance failed: %s", modelName, error.stack );
|
|
142
|
-
|
|
143
|
-
response( {
|
|
144
|
-
error: error.message,
|
|
145
|
-
} );
|
|
146
|
-
}
|
|
147
|
-
} )
|
|
148
|
-
.on( `${prefix}:read`, async( sessionId, uuid, response ) => {
|
|
149
|
-
logDebug( "request for reading %s instance %s", modelName, uuid );
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
const instance = new model( uuid ); // eslint-disable-line new-cap
|
|
153
|
-
await instance.load();
|
|
154
|
-
|
|
155
|
-
response( {
|
|
156
|
-
success: true,
|
|
157
|
-
properties: instance.toObject( { serialized: true } ),
|
|
158
|
-
} );
|
|
159
|
-
} catch ( error ) {
|
|
160
|
-
logError( "reading %s instance failed: %s", modelName, error.stack );
|
|
161
|
-
|
|
162
|
-
response( {
|
|
163
|
-
error: error.message,
|
|
164
|
-
} );
|
|
165
|
-
}
|
|
166
|
-
} )
|
|
167
|
-
.on( `${prefix}:update`, async( sessionId, uuid, properties, response ) => {
|
|
168
|
-
logDebug( "request for updating %s instance %s with %j", modelName, uuid, properties );
|
|
169
|
-
|
|
170
|
-
try {
|
|
171
|
-
const instance = new model( uuid ); // eslint-disable-line new-cap
|
|
172
|
-
await instance.load();
|
|
173
|
-
|
|
174
|
-
for ( const propName of Object.keys( properties ) ) {
|
|
175
|
-
if ( model.schema.props.hasOwnProperty( propName ) || model.schema.computed.hasOwnProperty( propName ) ) {
|
|
176
|
-
instance[propName] = properties[propName];
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
await instance.save();
|
|
181
|
-
|
|
182
|
-
response( {
|
|
183
|
-
success: true,
|
|
184
|
-
properties: instance.toObject( { serialized: true } ),
|
|
185
|
-
} );
|
|
186
|
-
} catch ( error ) {
|
|
187
|
-
logError( "updating %s instance failed: %s", modelName, error.stack );
|
|
188
|
-
|
|
189
|
-
response( {
|
|
190
|
-
error: error.message,
|
|
191
|
-
} );
|
|
192
|
-
}
|
|
193
|
-
} )
|
|
194
|
-
.on( `${prefix}:delete`, async( sessionId, uuid, response ) => {
|
|
195
|
-
logDebug( "request for deleting %s instance %s", modelName, uuid );
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
const instance = new model( uuid ); // eslint-disable-line new-cap
|
|
199
|
-
await instance.remove();
|
|
200
|
-
|
|
201
|
-
response( {
|
|
202
|
-
success: true,
|
|
203
|
-
properties: { uuid },
|
|
204
|
-
} );
|
|
205
|
-
} catch ( error ) {
|
|
206
|
-
logError( "deleting %s instance %s failed: %s", modelName, uuid, error.stack );
|
|
207
|
-
|
|
208
|
-
response( {
|
|
209
|
-
error: error.message,
|
|
210
|
-
} );
|
|
211
|
-
}
|
|
212
|
-
} );
|
|
213
|
-
} );
|
|
102
|
+
const handlers = {
|
|
103
|
+
list: ( ...args ) => this.handleListRequest( modelName, model, ...args ),
|
|
104
|
+
find: ( ...args ) => this.handleFindRequest( modelName, model, ...args ),
|
|
105
|
+
create: ( ...args ) => this.handleCreateRequest( modelName, model, ...args ),
|
|
106
|
+
read: ( ...args ) => this.handleReadRequest( modelName, model, ...args ),
|
|
107
|
+
update: ( ...args ) => this.handleUpdateRequest( modelName, model, ...args ),
|
|
108
|
+
delete: ( ...args ) => this.handleDeleteRequest( modelName, model, ...args ),
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
socket
|
|
112
|
+
.on( `${prefix}:list`, handlers.list )
|
|
113
|
+
.on( `${prefix}:find`, handlers.find )
|
|
114
|
+
.on( `${prefix}:create`, handlers.create )
|
|
115
|
+
.on( `${prefix}:read`, handlers.read )
|
|
116
|
+
.on( `${prefix}:update`, handlers.update )
|
|
117
|
+
.on( `${prefix}:delete`, handlers.delete );
|
|
118
|
+
|
|
119
|
+
return handlers;
|
|
214
120
|
}
|
|
215
121
|
|
|
216
122
|
/**
|
|
@@ -218,40 +124,254 @@ module.exports = function() {
|
|
|
218
124
|
* them as broadcast events to connected clients.
|
|
219
125
|
*
|
|
220
126
|
* @param {boolean} enabled true if command handling is enabled in configuration
|
|
221
|
-
* @param {Server}
|
|
127
|
+
* @param {Server} namespace namespace managing a list of server-side sockets with common prefix
|
|
222
128
|
* @param {string} modelName name of model to manage
|
|
223
129
|
* @param {class<Hitchy.Plugin.Odem.Model>} model ODM-based model instance to manage
|
|
224
|
-
* @returns {
|
|
130
|
+
* @returns {Object<string,function>} map of registered handler functions
|
|
225
131
|
*/
|
|
226
|
-
static
|
|
132
|
+
static broadcastModelNotifications( enabled, namespace, modelName, model ) {
|
|
227
133
|
if ( enabled ) {
|
|
228
134
|
const prefix = api.utility.case.pascalToKebab( modelName );
|
|
229
135
|
|
|
230
|
-
|
|
231
|
-
|
|
136
|
+
const handlers = {
|
|
137
|
+
created: async( uuid, newRecord, asyncGeneratorFn ) => {
|
|
232
138
|
const event = {
|
|
233
139
|
change: "created",
|
|
234
140
|
properties: ( await asyncGeneratorFn() ).toObject( { serialized: true } ),
|
|
235
141
|
};
|
|
236
142
|
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
143
|
+
namespace.emit( `${prefix}:changed`, event );
|
|
144
|
+
},
|
|
145
|
+
changed: async( uuid, newRecord, oldRecord, asyncGeneratorFn ) => {
|
|
240
146
|
const event = {
|
|
241
147
|
change: "updated",
|
|
242
148
|
properties: ( await asyncGeneratorFn() ).toObject( { serialized: true } ),
|
|
243
149
|
};
|
|
244
150
|
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
151
|
+
namespace.emit( `${prefix}:changed`, event );
|
|
152
|
+
},
|
|
153
|
+
removed: uuid => {
|
|
248
154
|
const event = {
|
|
249
155
|
change: "deleted",
|
|
250
156
|
properties: { uuid: model.formatUUID( uuid ) },
|
|
251
157
|
};
|
|
252
158
|
|
|
253
|
-
|
|
254
|
-
}
|
|
159
|
+
namespace.emit( `${prefix}:changed`, event );
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
model.notifications
|
|
164
|
+
.on( "created", handlers.created )
|
|
165
|
+
.on( "changed", handlers.changed )
|
|
166
|
+
.on( "removed", handlers.removed );
|
|
167
|
+
|
|
168
|
+
return handlers;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Handles incoming request for listing items of a model.
|
|
176
|
+
*
|
|
177
|
+
* @param {string} modelName name of model
|
|
178
|
+
* @param {string} model named server-side model
|
|
179
|
+
* @param {string} sessionId client-provided session ID
|
|
180
|
+
* @param {Hitchy.Odem.ListOptions} queryOptions client-provided options for listing items
|
|
181
|
+
* @param {boolean} loadRecords if true, whole records shall be fetched per item
|
|
182
|
+
* @param {function} response callback to invoke with response
|
|
183
|
+
* @returns {Promise<void>} promise settled on request handled
|
|
184
|
+
*/
|
|
185
|
+
static async handleListRequest( modelName, model, sessionId, queryOptions, loadRecords, response ) {
|
|
186
|
+
logDebug( "request for listing %s instances w/ queryOptions %j and loadRecords %j", modelName, queryOptions, Boolean( loadRecords ) );
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
const meta = {};
|
|
190
|
+
const items = await model.list( queryOptions, { loadRecords: Boolean( loadRecords ), metaCollector: meta } );
|
|
191
|
+
|
|
192
|
+
response( {
|
|
193
|
+
success: true,
|
|
194
|
+
count: meta.count,
|
|
195
|
+
items: items.map( item => ( loadRecords ? item.toObject( { serialized: true } ) : { uuid: item.uuid } ) ),
|
|
196
|
+
} );
|
|
197
|
+
} catch ( error ) {
|
|
198
|
+
logError( "listing %s instances failed: %s", modelName, error.stack );
|
|
199
|
+
|
|
200
|
+
response( {
|
|
201
|
+
error: error.message,
|
|
202
|
+
} );
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Handles incoming request for finding items of a model matching some
|
|
208
|
+
* provided query.
|
|
209
|
+
*
|
|
210
|
+
* @param {string} modelName name of model
|
|
211
|
+
* @param {string} model named server-side model
|
|
212
|
+
* @param {string} sessionId client-provided session ID
|
|
213
|
+
* @param {Hitchy.Odem.Query} query client-provided constraints to be met by returned items
|
|
214
|
+
* @param {Hitchy.Odem.ListOptions} queryOptions client-provided options for listing items
|
|
215
|
+
* @param {boolean} loadRecords if true, whole records shall be fetched per item
|
|
216
|
+
* @param {function} response callback to invoke with response
|
|
217
|
+
* @returns {Promise<void>} promise settled on request handled
|
|
218
|
+
*/
|
|
219
|
+
static async handleFindRequest( modelName, model, sessionId, query, queryOptions, loadRecords, response ) {
|
|
220
|
+
logDebug( "request for finding %s instances matching %j w/ queryOptions %j and uuidsOnly %j", modelName, query, queryOptions, Boolean( loadRecords ) );
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
const meta = {};
|
|
224
|
+
const items = await model.find( query, queryOptions, { loadRecords: Boolean( loadRecords ), metaCollector: meta } );
|
|
225
|
+
|
|
226
|
+
response( {
|
|
227
|
+
success: true,
|
|
228
|
+
count: meta.count,
|
|
229
|
+
items: items.map( item => ( loadRecords ? item.toObject( { serialized: true } ) : { uuid: item.uuid } ) ),
|
|
230
|
+
} );
|
|
231
|
+
} catch ( error ) {
|
|
232
|
+
logError( "finding %s instances matching %j failed: %s", modelName, error.stack );
|
|
233
|
+
|
|
234
|
+
response( {
|
|
235
|
+
error: error.message,
|
|
236
|
+
} );
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Handles incoming request for creating item of a model.
|
|
242
|
+
*
|
|
243
|
+
* @param {string} modelName name of model
|
|
244
|
+
* @param {string} model named server-side model
|
|
245
|
+
* @param {string} sessionId client-provided session ID
|
|
246
|
+
* @param {Hitchy.Odem.ListOptions} properties properties of item to create
|
|
247
|
+
* @param {function} response callback to invoke with response
|
|
248
|
+
* @returns {Promise<void>} promise settled on request handled
|
|
249
|
+
*/
|
|
250
|
+
static async handleCreateRequest( modelName, model, sessionId, properties, response ) {
|
|
251
|
+
logDebug( "request for creating %s instance with %j", modelName, properties );
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
const schema = model.schema;
|
|
255
|
+
const instance = new model; // eslint-disable-line new-cap
|
|
256
|
+
|
|
257
|
+
for ( const propName of Object.keys( properties ) ) {
|
|
258
|
+
if ( schema.props.hasOwnProperty( propName ) ||
|
|
259
|
+
schema.computed.hasOwnProperty( propName ) ) {
|
|
260
|
+
instance[propName] = properties[propName];
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
await instance.save();
|
|
265
|
+
|
|
266
|
+
response( {
|
|
267
|
+
success: true,
|
|
268
|
+
properties: instance.toObject( { serialized: true } ),
|
|
269
|
+
} );
|
|
270
|
+
} catch ( error ) {
|
|
271
|
+
logError( "creating %s instance failed: %s", modelName, error.stack );
|
|
272
|
+
|
|
273
|
+
response( {
|
|
274
|
+
error: error.message,
|
|
275
|
+
} );
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Handles incoming request for reading properties of a single item.
|
|
281
|
+
*
|
|
282
|
+
* @param {string} modelName name of item's model
|
|
283
|
+
* @param {string} model named server-side model
|
|
284
|
+
* @param {string} sessionId client-provided session ID
|
|
285
|
+
* @param {string} uuid client-provided UUID of item to read
|
|
286
|
+
* @param {function} response callback to invoke with response
|
|
287
|
+
* @returns {Promise<void>} promise settled on request handled
|
|
288
|
+
*/
|
|
289
|
+
static async handleReadRequest( modelName, model, sessionId, uuid, response ) {
|
|
290
|
+
logDebug( "request for reading %s instance %s", modelName, uuid );
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
const instance = new model( uuid ); // eslint-disable-line new-cap
|
|
294
|
+
await instance.load();
|
|
295
|
+
|
|
296
|
+
response( {
|
|
297
|
+
success: true,
|
|
298
|
+
properties: instance.toObject( { serialized: true } ),
|
|
299
|
+
} );
|
|
300
|
+
} catch ( error ) {
|
|
301
|
+
logError( "reading %s instance failed: %s", modelName, error.stack );
|
|
302
|
+
|
|
303
|
+
response( {
|
|
304
|
+
error: error.message,
|
|
305
|
+
} );
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Handles incoming request for adjusting properties of a single item.
|
|
311
|
+
*
|
|
312
|
+
* @param {string} modelName name of item's model
|
|
313
|
+
* @param {string} model named server-side model
|
|
314
|
+
* @param {string} sessionId client-provided session ID
|
|
315
|
+
* @param {string} uuid client-provided UUID of item to modify
|
|
316
|
+
* @param {Object} properties client-provided properties of item replacing its existing ones
|
|
317
|
+
* @param {function} response callback to invoke with response
|
|
318
|
+
* @returns {Promise<void>} promise settled on request handled
|
|
319
|
+
*/
|
|
320
|
+
static async handleUpdateRequest( modelName, model, sessionId, uuid, properties, response ) {
|
|
321
|
+
logDebug( "request for updating %s instance %s with %j", modelName, uuid, properties );
|
|
322
|
+
|
|
323
|
+
try {
|
|
324
|
+
const instance = new model( uuid ); // eslint-disable-line new-cap
|
|
325
|
+
await instance.load();
|
|
326
|
+
|
|
327
|
+
for ( const propName of Object.keys( properties ) ) {
|
|
328
|
+
if ( model.schema.props.hasOwnProperty( propName ) || model.schema.computed.hasOwnProperty( propName ) ) {
|
|
329
|
+
instance[propName] = properties[propName];
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
await instance.save();
|
|
334
|
+
|
|
335
|
+
response( {
|
|
336
|
+
success: true,
|
|
337
|
+
properties: instance.toObject( { serialized: true } ),
|
|
338
|
+
} );
|
|
339
|
+
} catch ( error ) {
|
|
340
|
+
logError( "updating %s instance failed: %s", modelName, error.stack );
|
|
341
|
+
|
|
342
|
+
response( {
|
|
343
|
+
error: error.message,
|
|
344
|
+
} );
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Handles incoming request for removing a model's item.
|
|
350
|
+
*
|
|
351
|
+
* @param {string} modelName name of item's model
|
|
352
|
+
* @param {string} model named server-side model
|
|
353
|
+
* @param {string} sessionId client-provided session ID
|
|
354
|
+
* @param {string} uuid client-provided UUID of item to remove
|
|
355
|
+
* @param {function} response callback to invoke with response
|
|
356
|
+
* @returns {Promise<void>} promise settled on request handled
|
|
357
|
+
*/
|
|
358
|
+
static async handleDeleteRequest( modelName, model, sessionId, uuid, response ) {
|
|
359
|
+
logDebug( "request for deleting %s instance %s", modelName, uuid );
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
const instance = new model( uuid ); // eslint-disable-line new-cap
|
|
363
|
+
await instance.remove();
|
|
364
|
+
|
|
365
|
+
response( {
|
|
366
|
+
success: true,
|
|
367
|
+
properties: { uuid },
|
|
368
|
+
} );
|
|
369
|
+
} catch ( error ) {
|
|
370
|
+
logError( "deleting %s instance %s failed: %s", modelName, uuid, error.stack );
|
|
371
|
+
|
|
372
|
+
response( {
|
|
373
|
+
error: error.message,
|
|
374
|
+
} );
|
|
255
375
|
}
|
|
256
376
|
}
|
|
257
377
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hitchy/plugin-odem-socket.io",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "exposing Hitchy's ODM via websocket",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,18 +30,18 @@
|
|
|
30
30
|
"index.js"
|
|
31
31
|
],
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@hitchy/core": ">=0.
|
|
34
|
-
"@hitchy/plugin-odem": ">=0.7.
|
|
35
|
-
"@hitchy/plugin-socket.io": ">=0.1.
|
|
33
|
+
"@hitchy/core": ">=0.8.1",
|
|
34
|
+
"@hitchy/plugin-odem": ">=0.7.8",
|
|
35
|
+
"@hitchy/plugin-socket.io": ">=0.1.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@hitchy/server-dev-tools": "^0.4.
|
|
39
|
-
"c8": "^
|
|
40
|
-
"eslint": "^8.
|
|
41
|
-
"eslint-config-cepharum": "^1.0.
|
|
42
|
-
"eslint-plugin-promise": "^6.
|
|
43
|
-
"mocha": "^
|
|
38
|
+
"@hitchy/server-dev-tools": "^0.4.6",
|
|
39
|
+
"c8": "^8.0.1",
|
|
40
|
+
"eslint": "^8.47.0",
|
|
41
|
+
"eslint-config-cepharum": "^1.0.13",
|
|
42
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
43
|
+
"mocha": "^10.2.0",
|
|
44
44
|
"should": "^13.2.3",
|
|
45
|
-
"socket.io-client": "^4.
|
|
45
|
+
"socket.io-client": "^4.7.2"
|
|
46
46
|
}
|
|
47
47
|
}
|