-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.js
143 lines (130 loc) · 5.01 KB
/
api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
const fetch = require('node-fetch');
const WebhookService = require('./services/webhook-service');
const TranslationService = require('./services/translation-service');
const { onshapeApiUrl } = require('./config');
const { forwardRequestToOnshape } = require('./utils');
const apiRouter = require('express').Router();
/**
* In-memory data storage to track the state of our requested translations
*/
const inMemoryDataStore = {};
/**
* Get the Elements of the current document/workspace.
*
* GET /api/elements
* -> 200, [ ...elements ]
* -or-
* -> 500, { error: '...' }
*/
apiRouter.get('/elements', (req, res) => {
forwardRequestToOnshape(`${onshapeApiUrl}/documents/d/${req.query.documentId}/w/${req.query.workspaceId}/elements`, req, res);
});
/**
* Get the Parts of the given Element in the current document/workspace.
*
* GET /api/elements/:eid/parts
* -> 200, [ ...parts ]
* -or-
* -> 500, { error: '...' }
*/
apiRouter.get('/elements/:eid/parts', (req, res) => {
forwardRequestToOnshape(`${onshapeApiUrl}/parts/d/${req.query.documentId}/w/${req.query.workspaceId}/e/${req.params.eid}`, req, res);
});
/**
* Get the Parts of the current document/workspace.
*
* GET /api/parts
* -> 200, [ ...parts ]
* -or-
* -> 500, { error: '...' }
*/
apiRouter.get('/parts', (req, res) => {
forwardRequestToOnshape(`${onshapeApiUrl}/parts/d/${req.query.documentId}/w/${req.query.workspaceId}`, req, res);
});
/**
* Trigger translation to GLTF from the given element.
*
* GET /api/gltf?documentId=...&workspaceId=...&gltfElementId=...
* -> 200, { ..., id: '...' }
* -or-
* -> 500, { error: '...' }
*/
apiRouter.get('/gltf', async (req, res) => {
// Extract the necessary IDs from the querystring
const did = req.query.documentId,
wid = req.query.workspaceId,
gltfElemId = req.query.gltfElementId,
partId = req.query.partId;
WebhookService.registerWebhook(req.user.accessToken, req.session.passport.user.id, did)
.catch((err) => console.error(`Failed to register webhook: ${err}`));
const translationParams = {
documentId: did,
workspaceId: wid,
resolution: 'medium',
distanceTolerance: 0.00012,
angularTolerance: 0.1090830782496456,
maximumChordLength: 10
};
try {
const resp = await (partId ? TranslationService.translatePart(req.user.accessToken, gltfElemId, partId, translationParams)
: TranslationService.translateElement(req.user.accessToken, gltfElemId, translationParams));
// Store the tid in Redis so we know that it's being processed; it will remain 'in-progress' until we
// are notified that it is complete, at which point it will be the translation ID.
if (resp.contentType.indexOf('json') >= 0) {
inMemoryDataStore[JSON.parse(resp.data).id] = 'in-progress';
}
res.status(200).contentType(resp.contentType).send(resp.data);
} catch (err) {
res.status(500).json({ error: err });
}
});
/**
* Retrieve the translated GLTF data.
*
* GET /api/gltf/:tid
* -> 200, { ...gltf_data }
* -or-
* -> 500, { error: '...' }
* -or-
* -> 404 (which may mean that the translation is still being processed)
*/
apiRouter.get('/gltf/:tid', async (req, res) => {
let results = inMemoryDataStore[req.params.tid];
if (results === null || results === undefined) {
// No record in memory => not a valid ID
res.status(404).end();
} else {
if ('in-progress' === results) {
// Valid ID, but results are not ready yet.
res.status(202).end();
} else {
// GLTF data is ready.
const transResp = await fetch(`${onshapeApiUrl}/translations/${req.params.tid}`, { headers: { 'Authorization': `Bearer ${req.user.accessToken}` } });
const transJson = await transResp.json();
if (transJson.requestState === 'FAILED') {
res.status(500).json({ error: transJson.failureReason });
} else {
forwardRequestToOnshape(`${onshapeApiUrl}/documents/d/${transJson.documentId}/externaldata/${transJson.resultExternalDataIds[0]}`, req, res);
}
const webhookID = results;
WebhookService.unregisterWebhook(webhookID, req.user.accessToken)
.then(() => console.log(`Webhook ${webhookID} unregistered successfully`))
.catch((err) => console.error(`Failed to unregister webhook ${webhookID}: ${JSON.stringify(err)}`));
delete inMemoryDataStore[req.params.tid];
}
}
});
/**
* Receive a webhook event.
*
* POST /api/event
* -> 200
*/
apiRouter.post('/event', (req, res) => {
if (req.body.event === 'onshape.model.translation.complete') {
// Save in memory so we can return to client later (& unregister the webhook).
inMemoryDataStore[req.body.translationId] = req.body.webhookId;
}
res.status(200).send();
});
module.exports = apiRouter;