@data-fair/dev-server 2.0.1 → 2.0.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/config/custom-environment-variables.js +18 -0
- package/config/default.js +17 -0
- package/config/development.js +3 -0
- package/config/production.js +1 -0
- package/config/type/.type/index.d.ts +27 -0
- package/config/type/.type/index.js +19 -0
- package/config/type/.type/validate.js +541 -0
- package/config/type/index.d.ts +1 -0
- package/config/type/index.js +1 -0
- package/config/type/schema.js +70 -0
- package/package.json +6 -3
- package/src/app.d.ts +2 -0
- package/src/config.d.ts +4 -0
- package/src/index.d.ts +2 -0
- package/src/ui-config.d.ts +13 -0
- package/src/app.ts +0 -278
- package/src/config.ts +0 -12
- package/src/index.ts +0 -25
- package/src/ui-config.ts +0 -6
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
dataFair: {
|
|
3
|
+
url: 'DATAFAIR_URL',
|
|
4
|
+
owner: {
|
|
5
|
+
type: 'DATAFAIR_OWNER_TYPE',
|
|
6
|
+
id: 'DATAFAIR_OWNER_ID',
|
|
7
|
+
department: 'DATAFAIR_OWNER_DEPARTMENT'
|
|
8
|
+
},
|
|
9
|
+
apiKey: 'DATAFAIR_API_KEY'
|
|
10
|
+
},
|
|
11
|
+
app: {
|
|
12
|
+
url: 'APP_URL',
|
|
13
|
+
proxyPaths: {
|
|
14
|
+
__name: 'APP_PROXY_PATHS',
|
|
15
|
+
__format: 'json'
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
port: 5888,
|
|
3
|
+
dataFair: {
|
|
4
|
+
url: 'https://koumoul.com/data-fair',
|
|
5
|
+
owner: {
|
|
6
|
+
type: 'organization',
|
|
7
|
+
id: '5a5dc47163ebd4a6f438589b',
|
|
8
|
+
department: null
|
|
9
|
+
},
|
|
10
|
+
apiKey: null
|
|
11
|
+
},
|
|
12
|
+
app: {
|
|
13
|
+
url: 'http://localhost:3000',
|
|
14
|
+
proxyPaths: ['/_nuxt/']
|
|
15
|
+
},
|
|
16
|
+
serveUi: true
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
export const schemaExports: string[]
|
|
3
|
+
|
|
4
|
+
// see https://github.com/bcherny/json-schema-to-typescript/issues/439 if some types are not exported
|
|
5
|
+
export type DevServerConfig = {
|
|
6
|
+
port: number;
|
|
7
|
+
dataFair: {
|
|
8
|
+
url: string;
|
|
9
|
+
owner: {
|
|
10
|
+
type: string;
|
|
11
|
+
id: string;
|
|
12
|
+
department?: string;
|
|
13
|
+
};
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
};
|
|
16
|
+
app: {
|
|
17
|
+
url: string;
|
|
18
|
+
proxyPaths: string[];
|
|
19
|
+
};
|
|
20
|
+
serveUi?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
export declare function validate(data: any): data is DevServerConfig
|
|
25
|
+
export declare function assertValid(data: any, options?: import('@data-fair/lib-validation').AssertValidOptions): asserts data is DevServerConfig
|
|
26
|
+
export declare function returnValid(data: any, options?: import('@data-fair/lib-validation').AssertValidOptions): DevServerConfig
|
|
27
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import validate from './validate.js'
|
|
5
|
+
import { assertValid as assertValidGeneric } from '@data-fair/lib-validation'
|
|
6
|
+
|
|
7
|
+
export const schemaExports = [
|
|
8
|
+
"types",
|
|
9
|
+
"validate"
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
export { validate } from './validate.js'
|
|
13
|
+
export function assertValid(data, options) {
|
|
14
|
+
assertValidGeneric(validate, data, options)
|
|
15
|
+
}
|
|
16
|
+
export function returnValid(data, options) {
|
|
17
|
+
assertValid(data, options)
|
|
18
|
+
return data
|
|
19
|
+
}
|
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
"use strict";
|
|
5
|
+
export const validate = validate14;
|
|
6
|
+
export default validate14;
|
|
7
|
+
const schema16 = {"$id":"https://github.com/data-fair/dev-server/config","x-exports":["types","validate"],"x-ajv":{"coerceTypes":"array"},"x-jstt":{"additionalProperties":false},"type":"object","title":"Dev server config","required":["port","dataFair","app"],"properties":{"port":{"type":"number"},"dataFair":{"type":"object","required":["url","owner"],"properties":{"url":{"type":"string"},"owner":{"type":"object","required":["type","id"],"properties":{"type":{"type":"string"},"id":{"type":"string"},"department":{"type":"string"}}},"apiKey":{"type":"string"}}},"app":{"type":"object","required":["url","proxyPaths"],"properties":{"url":{"type":"string"},"proxyPaths":{"type":"array","items":{"type":"string"}}}},"serveUi":{"type":"boolean"}}};
|
|
8
|
+
|
|
9
|
+
function validate14(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){
|
|
10
|
+
/*# sourceURL="https://github.com/data-fair/dev-server/config" */;
|
|
11
|
+
let vErrors = null;
|
|
12
|
+
let errors = 0;
|
|
13
|
+
if(data && typeof data == "object" && !Array.isArray(data)){
|
|
14
|
+
if(data.port === undefined){
|
|
15
|
+
const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "port"},message:"must have required property '"+"port"+"'"};
|
|
16
|
+
if(vErrors === null){
|
|
17
|
+
vErrors = [err0];
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
vErrors.push(err0);
|
|
21
|
+
}
|
|
22
|
+
errors++;
|
|
23
|
+
}
|
|
24
|
+
if(data.dataFair === undefined){
|
|
25
|
+
const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "dataFair"},message:"must have required property '"+"dataFair"+"'"};
|
|
26
|
+
if(vErrors === null){
|
|
27
|
+
vErrors = [err1];
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
vErrors.push(err1);
|
|
31
|
+
}
|
|
32
|
+
errors++;
|
|
33
|
+
}
|
|
34
|
+
if(data.app === undefined){
|
|
35
|
+
const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "app"},message:"must have required property '"+"app"+"'"};
|
|
36
|
+
if(vErrors === null){
|
|
37
|
+
vErrors = [err2];
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
vErrors.push(err2);
|
|
41
|
+
}
|
|
42
|
+
errors++;
|
|
43
|
+
}
|
|
44
|
+
if(data.port !== undefined){
|
|
45
|
+
let data0 = data.port;
|
|
46
|
+
if(!(typeof data0 == "number")){
|
|
47
|
+
let dataType0 = typeof data0;
|
|
48
|
+
let coerced0 = undefined;
|
|
49
|
+
if(dataType0 == 'object' && Array.isArray(data0) && data0.length == 1){
|
|
50
|
+
data0 = data0[0];
|
|
51
|
+
dataType0 = typeof data0;
|
|
52
|
+
if(typeof data0 == "number"){
|
|
53
|
+
coerced0 = data0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if(!(coerced0 !== undefined)){
|
|
57
|
+
if(dataType0 == "boolean" || data0 === null
|
|
58
|
+
|| (dataType0 == "string" && data0 && data0 == +data0)){
|
|
59
|
+
coerced0 = +data0;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const err3 = {instancePath:instancePath+"/port",schemaPath:"#/properties/port/type",keyword:"type",params:{type: "number"},message:"must be number"};
|
|
63
|
+
if(vErrors === null){
|
|
64
|
+
vErrors = [err3];
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
vErrors.push(err3);
|
|
68
|
+
}
|
|
69
|
+
errors++;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if(coerced0 !== undefined){
|
|
73
|
+
data0 = coerced0;
|
|
74
|
+
if(data !== undefined){
|
|
75
|
+
data["port"] = coerced0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if(data.dataFair !== undefined){
|
|
81
|
+
let data1 = data.dataFair;
|
|
82
|
+
if(data1 && typeof data1 == "object" && !Array.isArray(data1)){
|
|
83
|
+
if(data1.url === undefined){
|
|
84
|
+
const err4 = {instancePath:instancePath+"/dataFair",schemaPath:"#/properties/dataFair/required",keyword:"required",params:{missingProperty: "url"},message:"must have required property '"+"url"+"'"};
|
|
85
|
+
if(vErrors === null){
|
|
86
|
+
vErrors = [err4];
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
vErrors.push(err4);
|
|
90
|
+
}
|
|
91
|
+
errors++;
|
|
92
|
+
}
|
|
93
|
+
if(data1.owner === undefined){
|
|
94
|
+
const err5 = {instancePath:instancePath+"/dataFair",schemaPath:"#/properties/dataFair/required",keyword:"required",params:{missingProperty: "owner"},message:"must have required property '"+"owner"+"'"};
|
|
95
|
+
if(vErrors === null){
|
|
96
|
+
vErrors = [err5];
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
vErrors.push(err5);
|
|
100
|
+
}
|
|
101
|
+
errors++;
|
|
102
|
+
}
|
|
103
|
+
if(data1.url !== undefined){
|
|
104
|
+
let data2 = data1.url;
|
|
105
|
+
if(typeof data2 !== "string"){
|
|
106
|
+
let dataType1 = typeof data2;
|
|
107
|
+
let coerced1 = undefined;
|
|
108
|
+
if(dataType1 == 'object' && Array.isArray(data2) && data2.length == 1){
|
|
109
|
+
data2 = data2[0];
|
|
110
|
+
dataType1 = typeof data2;
|
|
111
|
+
if(typeof data2 === "string"){
|
|
112
|
+
coerced1 = data2;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if(!(coerced1 !== undefined)){
|
|
116
|
+
if(dataType1 == "number" || dataType1 == "boolean"){
|
|
117
|
+
coerced1 = "" + data2;
|
|
118
|
+
}
|
|
119
|
+
else if(data2 === null){
|
|
120
|
+
coerced1 = "";
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
const err6 = {instancePath:instancePath+"/dataFair/url",schemaPath:"#/properties/dataFair/properties/url/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
124
|
+
if(vErrors === null){
|
|
125
|
+
vErrors = [err6];
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
vErrors.push(err6);
|
|
129
|
+
}
|
|
130
|
+
errors++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if(coerced1 !== undefined){
|
|
134
|
+
data2 = coerced1;
|
|
135
|
+
if(data1 !== undefined){
|
|
136
|
+
data1["url"] = coerced1;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if(data1.owner !== undefined){
|
|
142
|
+
let data3 = data1.owner;
|
|
143
|
+
if(data3 && typeof data3 == "object" && !Array.isArray(data3)){
|
|
144
|
+
if(data3.type === undefined){
|
|
145
|
+
const err7 = {instancePath:instancePath+"/dataFair/owner",schemaPath:"#/properties/dataFair/properties/owner/required",keyword:"required",params:{missingProperty: "type"},message:"must have required property '"+"type"+"'"};
|
|
146
|
+
if(vErrors === null){
|
|
147
|
+
vErrors = [err7];
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
vErrors.push(err7);
|
|
151
|
+
}
|
|
152
|
+
errors++;
|
|
153
|
+
}
|
|
154
|
+
if(data3.id === undefined){
|
|
155
|
+
const err8 = {instancePath:instancePath+"/dataFair/owner",schemaPath:"#/properties/dataFair/properties/owner/required",keyword:"required",params:{missingProperty: "id"},message:"must have required property '"+"id"+"'"};
|
|
156
|
+
if(vErrors === null){
|
|
157
|
+
vErrors = [err8];
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
vErrors.push(err8);
|
|
161
|
+
}
|
|
162
|
+
errors++;
|
|
163
|
+
}
|
|
164
|
+
if(data3.type !== undefined){
|
|
165
|
+
let data4 = data3.type;
|
|
166
|
+
if(typeof data4 !== "string"){
|
|
167
|
+
let dataType2 = typeof data4;
|
|
168
|
+
let coerced2 = undefined;
|
|
169
|
+
if(dataType2 == 'object' && Array.isArray(data4) && data4.length == 1){
|
|
170
|
+
data4 = data4[0];
|
|
171
|
+
dataType2 = typeof data4;
|
|
172
|
+
if(typeof data4 === "string"){
|
|
173
|
+
coerced2 = data4;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if(!(coerced2 !== undefined)){
|
|
177
|
+
if(dataType2 == "number" || dataType2 == "boolean"){
|
|
178
|
+
coerced2 = "" + data4;
|
|
179
|
+
}
|
|
180
|
+
else if(data4 === null){
|
|
181
|
+
coerced2 = "";
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
const err9 = {instancePath:instancePath+"/dataFair/owner/type",schemaPath:"#/properties/dataFair/properties/owner/properties/type/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
185
|
+
if(vErrors === null){
|
|
186
|
+
vErrors = [err9];
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
vErrors.push(err9);
|
|
190
|
+
}
|
|
191
|
+
errors++;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if(coerced2 !== undefined){
|
|
195
|
+
data4 = coerced2;
|
|
196
|
+
if(data3 !== undefined){
|
|
197
|
+
data3["type"] = coerced2;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if(data3.id !== undefined){
|
|
203
|
+
let data5 = data3.id;
|
|
204
|
+
if(typeof data5 !== "string"){
|
|
205
|
+
let dataType3 = typeof data5;
|
|
206
|
+
let coerced3 = undefined;
|
|
207
|
+
if(dataType3 == 'object' && Array.isArray(data5) && data5.length == 1){
|
|
208
|
+
data5 = data5[0];
|
|
209
|
+
dataType3 = typeof data5;
|
|
210
|
+
if(typeof data5 === "string"){
|
|
211
|
+
coerced3 = data5;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if(!(coerced3 !== undefined)){
|
|
215
|
+
if(dataType3 == "number" || dataType3 == "boolean"){
|
|
216
|
+
coerced3 = "" + data5;
|
|
217
|
+
}
|
|
218
|
+
else if(data5 === null){
|
|
219
|
+
coerced3 = "";
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
const err10 = {instancePath:instancePath+"/dataFair/owner/id",schemaPath:"#/properties/dataFair/properties/owner/properties/id/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
223
|
+
if(vErrors === null){
|
|
224
|
+
vErrors = [err10];
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
vErrors.push(err10);
|
|
228
|
+
}
|
|
229
|
+
errors++;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if(coerced3 !== undefined){
|
|
233
|
+
data5 = coerced3;
|
|
234
|
+
if(data3 !== undefined){
|
|
235
|
+
data3["id"] = coerced3;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if(data3.department !== undefined){
|
|
241
|
+
let data6 = data3.department;
|
|
242
|
+
if(typeof data6 !== "string"){
|
|
243
|
+
let dataType4 = typeof data6;
|
|
244
|
+
let coerced4 = undefined;
|
|
245
|
+
if(dataType4 == 'object' && Array.isArray(data6) && data6.length == 1){
|
|
246
|
+
data6 = data6[0];
|
|
247
|
+
dataType4 = typeof data6;
|
|
248
|
+
if(typeof data6 === "string"){
|
|
249
|
+
coerced4 = data6;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if(!(coerced4 !== undefined)){
|
|
253
|
+
if(dataType4 == "number" || dataType4 == "boolean"){
|
|
254
|
+
coerced4 = "" + data6;
|
|
255
|
+
}
|
|
256
|
+
else if(data6 === null){
|
|
257
|
+
coerced4 = "";
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
const err11 = {instancePath:instancePath+"/dataFair/owner/department",schemaPath:"#/properties/dataFair/properties/owner/properties/department/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
261
|
+
if(vErrors === null){
|
|
262
|
+
vErrors = [err11];
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
vErrors.push(err11);
|
|
266
|
+
}
|
|
267
|
+
errors++;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if(coerced4 !== undefined){
|
|
271
|
+
data6 = coerced4;
|
|
272
|
+
if(data3 !== undefined){
|
|
273
|
+
data3["department"] = coerced4;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
const err12 = {instancePath:instancePath+"/dataFair/owner",schemaPath:"#/properties/dataFair/properties/owner/type",keyword:"type",params:{type: "object"},message:"must be object"};
|
|
281
|
+
if(vErrors === null){
|
|
282
|
+
vErrors = [err12];
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
vErrors.push(err12);
|
|
286
|
+
}
|
|
287
|
+
errors++;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if(data1.apiKey !== undefined){
|
|
291
|
+
let data7 = data1.apiKey;
|
|
292
|
+
if(typeof data7 !== "string"){
|
|
293
|
+
let dataType5 = typeof data7;
|
|
294
|
+
let coerced5 = undefined;
|
|
295
|
+
if(dataType5 == 'object' && Array.isArray(data7) && data7.length == 1){
|
|
296
|
+
data7 = data7[0];
|
|
297
|
+
dataType5 = typeof data7;
|
|
298
|
+
if(typeof data7 === "string"){
|
|
299
|
+
coerced5 = data7;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if(!(coerced5 !== undefined)){
|
|
303
|
+
if(dataType5 == "number" || dataType5 == "boolean"){
|
|
304
|
+
coerced5 = "" + data7;
|
|
305
|
+
}
|
|
306
|
+
else if(data7 === null){
|
|
307
|
+
coerced5 = "";
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
const err13 = {instancePath:instancePath+"/dataFair/apiKey",schemaPath:"#/properties/dataFair/properties/apiKey/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
311
|
+
if(vErrors === null){
|
|
312
|
+
vErrors = [err13];
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
vErrors.push(err13);
|
|
316
|
+
}
|
|
317
|
+
errors++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if(coerced5 !== undefined){
|
|
321
|
+
data7 = coerced5;
|
|
322
|
+
if(data1 !== undefined){
|
|
323
|
+
data1["apiKey"] = coerced5;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
const err14 = {instancePath:instancePath+"/dataFair",schemaPath:"#/properties/dataFair/type",keyword:"type",params:{type: "object"},message:"must be object"};
|
|
331
|
+
if(vErrors === null){
|
|
332
|
+
vErrors = [err14];
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
vErrors.push(err14);
|
|
336
|
+
}
|
|
337
|
+
errors++;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if(data.app !== undefined){
|
|
341
|
+
let data8 = data.app;
|
|
342
|
+
if(data8 && typeof data8 == "object" && !Array.isArray(data8)){
|
|
343
|
+
if(data8.url === undefined){
|
|
344
|
+
const err15 = {instancePath:instancePath+"/app",schemaPath:"#/properties/app/required",keyword:"required",params:{missingProperty: "url"},message:"must have required property '"+"url"+"'"};
|
|
345
|
+
if(vErrors === null){
|
|
346
|
+
vErrors = [err15];
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
vErrors.push(err15);
|
|
350
|
+
}
|
|
351
|
+
errors++;
|
|
352
|
+
}
|
|
353
|
+
if(data8.proxyPaths === undefined){
|
|
354
|
+
const err16 = {instancePath:instancePath+"/app",schemaPath:"#/properties/app/required",keyword:"required",params:{missingProperty: "proxyPaths"},message:"must have required property '"+"proxyPaths"+"'"};
|
|
355
|
+
if(vErrors === null){
|
|
356
|
+
vErrors = [err16];
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
vErrors.push(err16);
|
|
360
|
+
}
|
|
361
|
+
errors++;
|
|
362
|
+
}
|
|
363
|
+
if(data8.url !== undefined){
|
|
364
|
+
let data9 = data8.url;
|
|
365
|
+
if(typeof data9 !== "string"){
|
|
366
|
+
let dataType6 = typeof data9;
|
|
367
|
+
let coerced6 = undefined;
|
|
368
|
+
if(dataType6 == 'object' && Array.isArray(data9) && data9.length == 1){
|
|
369
|
+
data9 = data9[0];
|
|
370
|
+
dataType6 = typeof data9;
|
|
371
|
+
if(typeof data9 === "string"){
|
|
372
|
+
coerced6 = data9;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if(!(coerced6 !== undefined)){
|
|
376
|
+
if(dataType6 == "number" || dataType6 == "boolean"){
|
|
377
|
+
coerced6 = "" + data9;
|
|
378
|
+
}
|
|
379
|
+
else if(data9 === null){
|
|
380
|
+
coerced6 = "";
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
const err17 = {instancePath:instancePath+"/app/url",schemaPath:"#/properties/app/properties/url/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
384
|
+
if(vErrors === null){
|
|
385
|
+
vErrors = [err17];
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
vErrors.push(err17);
|
|
389
|
+
}
|
|
390
|
+
errors++;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if(coerced6 !== undefined){
|
|
394
|
+
data9 = coerced6;
|
|
395
|
+
if(data8 !== undefined){
|
|
396
|
+
data8["url"] = coerced6;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if(data8.proxyPaths !== undefined){
|
|
402
|
+
let data10 = data8.proxyPaths;
|
|
403
|
+
if(!(Array.isArray(data10))){
|
|
404
|
+
let dataType7 = typeof data10;
|
|
405
|
+
let coerced7 = undefined;
|
|
406
|
+
if(dataType7 == 'object' && Array.isArray(data10) && data10.length == 1){
|
|
407
|
+
data10 = data10[0];
|
|
408
|
+
dataType7 = typeof data10;
|
|
409
|
+
if(Array.isArray(data10)){
|
|
410
|
+
coerced7 = data10;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if(!(coerced7 !== undefined)){
|
|
414
|
+
if(dataType7 === "string" || dataType7 === "number"
|
|
415
|
+
|| dataType7 === "boolean" || data10 === null){
|
|
416
|
+
coerced7 = [data10];
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
const err18 = {instancePath:instancePath+"/app/proxyPaths",schemaPath:"#/properties/app/properties/proxyPaths/type",keyword:"type",params:{type: "array"},message:"must be array"};
|
|
420
|
+
if(vErrors === null){
|
|
421
|
+
vErrors = [err18];
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
vErrors.push(err18);
|
|
425
|
+
}
|
|
426
|
+
errors++;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if(coerced7 !== undefined){
|
|
430
|
+
data10 = coerced7;
|
|
431
|
+
if(data8 !== undefined){
|
|
432
|
+
data8["proxyPaths"] = coerced7;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if(Array.isArray(data10)){
|
|
437
|
+
const len0 = data10.length;
|
|
438
|
+
for(let i0=0; i0<len0; i0++){
|
|
439
|
+
let data11 = data10[i0];
|
|
440
|
+
if(typeof data11 !== "string"){
|
|
441
|
+
let dataType8 = typeof data11;
|
|
442
|
+
let coerced8 = undefined;
|
|
443
|
+
if(dataType8 == 'object' && Array.isArray(data11) && data11.length == 1){
|
|
444
|
+
data11 = data11[0];
|
|
445
|
+
dataType8 = typeof data11;
|
|
446
|
+
if(typeof data11 === "string"){
|
|
447
|
+
coerced8 = data11;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
if(!(coerced8 !== undefined)){
|
|
451
|
+
if(dataType8 == "number" || dataType8 == "boolean"){
|
|
452
|
+
coerced8 = "" + data11;
|
|
453
|
+
}
|
|
454
|
+
else if(data11 === null){
|
|
455
|
+
coerced8 = "";
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
const err19 = {instancePath:instancePath+"/app/proxyPaths/" + i0,schemaPath:"#/properties/app/properties/proxyPaths/items/type",keyword:"type",params:{type: "string"},message:"must be string"};
|
|
459
|
+
if(vErrors === null){
|
|
460
|
+
vErrors = [err19];
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
vErrors.push(err19);
|
|
464
|
+
}
|
|
465
|
+
errors++;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if(coerced8 !== undefined){
|
|
469
|
+
data11 = coerced8;
|
|
470
|
+
if(data10 !== undefined){
|
|
471
|
+
data10[i0] = coerced8;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
const err20 = {instancePath:instancePath+"/app",schemaPath:"#/properties/app/type",keyword:"type",params:{type: "object"},message:"must be object"};
|
|
481
|
+
if(vErrors === null){
|
|
482
|
+
vErrors = [err20];
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
vErrors.push(err20);
|
|
486
|
+
}
|
|
487
|
+
errors++;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if(data.serveUi !== undefined){
|
|
491
|
+
let data12 = data.serveUi;
|
|
492
|
+
if(typeof data12 !== "boolean"){
|
|
493
|
+
let dataType9 = typeof data12;
|
|
494
|
+
let coerced9 = undefined;
|
|
495
|
+
if(dataType9 == 'object' && Array.isArray(data12) && data12.length == 1){
|
|
496
|
+
data12 = data12[0];
|
|
497
|
+
dataType9 = typeof data12;
|
|
498
|
+
if(typeof data12 === "boolean"){
|
|
499
|
+
coerced9 = data12;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if(!(coerced9 !== undefined)){
|
|
503
|
+
if(data12 === "false" || data12 === 0 || data12 === null){
|
|
504
|
+
coerced9 = false;
|
|
505
|
+
}
|
|
506
|
+
else if(data12 === "true" || data12 === 1){
|
|
507
|
+
coerced9 = true;
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
const err21 = {instancePath:instancePath+"/serveUi",schemaPath:"#/properties/serveUi/type",keyword:"type",params:{type: "boolean"},message:"must be boolean"};
|
|
511
|
+
if(vErrors === null){
|
|
512
|
+
vErrors = [err21];
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
vErrors.push(err21);
|
|
516
|
+
}
|
|
517
|
+
errors++;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if(coerced9 !== undefined){
|
|
521
|
+
data12 = coerced9;
|
|
522
|
+
if(data !== undefined){
|
|
523
|
+
data["serveUi"] = coerced9;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
const err22 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"};
|
|
531
|
+
if(vErrors === null){
|
|
532
|
+
vErrors = [err22];
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
vErrors.push(err22);
|
|
536
|
+
}
|
|
537
|
+
errors++;
|
|
538
|
+
}
|
|
539
|
+
validate14.errors = vErrors;
|
|
540
|
+
return errors === 0;
|
|
541
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './.type/index.js'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './.type/index.js'
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
$id: 'https://github.com/data-fair/dev-server/config',
|
|
3
|
+
'x-exports': [
|
|
4
|
+
'types',
|
|
5
|
+
'validate'
|
|
6
|
+
],
|
|
7
|
+
'x-ajv': {
|
|
8
|
+
coerceTypes: 'array'
|
|
9
|
+
},
|
|
10
|
+
'x-jstt': {
|
|
11
|
+
additionalProperties: false
|
|
12
|
+
},
|
|
13
|
+
type: 'object',
|
|
14
|
+
title: 'Dev server config',
|
|
15
|
+
required: [
|
|
16
|
+
'port',
|
|
17
|
+
'dataFair',
|
|
18
|
+
'app'
|
|
19
|
+
],
|
|
20
|
+
properties: {
|
|
21
|
+
port: {
|
|
22
|
+
type: 'number'
|
|
23
|
+
},
|
|
24
|
+
dataFair: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
required: ['url', 'owner'],
|
|
27
|
+
properties: {
|
|
28
|
+
url: {
|
|
29
|
+
type: 'string'
|
|
30
|
+
},
|
|
31
|
+
owner: {
|
|
32
|
+
type: 'object',
|
|
33
|
+
required: ['type', 'id'],
|
|
34
|
+
properties: {
|
|
35
|
+
type: {
|
|
36
|
+
type: 'string'
|
|
37
|
+
},
|
|
38
|
+
id: {
|
|
39
|
+
type: 'string'
|
|
40
|
+
},
|
|
41
|
+
department: {
|
|
42
|
+
type: 'string'
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
apiKey: {
|
|
47
|
+
type: 'string'
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
app: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
required: ['url', 'proxyPaths'],
|
|
54
|
+
properties: {
|
|
55
|
+
url: {
|
|
56
|
+
type: 'string'
|
|
57
|
+
},
|
|
58
|
+
proxyPaths: {
|
|
59
|
+
type: 'array',
|
|
60
|
+
items: {
|
|
61
|
+
type: 'string'
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
serveUi: {
|
|
67
|
+
type: 'boolean'
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-fair/dev-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "A development server for optimal development experience of data-fair applications.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"cors": "^2.8.5",
|
|
59
59
|
"debug": "^4.4.1",
|
|
60
60
|
"dotenv": "^17.0.0",
|
|
61
|
+
"escape-string-regexp": "^5.0.0",
|
|
61
62
|
"express": "^5.1.0",
|
|
62
63
|
"http-proxy-middleware": "^3.0.5",
|
|
63
64
|
"parse5": "^7.3.0",
|
|
@@ -65,8 +66,10 @@
|
|
|
65
66
|
"ws": "^8.18.3"
|
|
66
67
|
},
|
|
67
68
|
"files": [
|
|
68
|
-
"./config
|
|
69
|
+
"./config/**/*.js",
|
|
70
|
+
"./config/**/*.d.ts",
|
|
69
71
|
"./ui/dist/**/*",
|
|
70
|
-
"./src
|
|
72
|
+
"./src/**/*.js",
|
|
73
|
+
"./src/**/*.d.ts"
|
|
71
74
|
]
|
|
72
75
|
}
|
package/src/app.d.ts
ADDED
package/src/config.d.ts
ADDED
package/src/index.d.ts
ADDED
package/src/app.ts
DELETED
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
// Express app for TaxMan own API and UI
|
|
2
|
-
|
|
3
|
-
import config from './config.js'
|
|
4
|
-
import uiConfig from './ui-config.js'
|
|
5
|
-
import { WebSocket, WebSocketServer } from 'ws'
|
|
6
|
-
import { createServer } from 'node:http'
|
|
7
|
-
import express from 'express'
|
|
8
|
-
import cors from 'cors'
|
|
9
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
10
|
-
import debugModule from 'debug'
|
|
11
|
-
import { createProxyMiddleware, fixRequestBody } from 'http-proxy-middleware'
|
|
12
|
-
import * as parse5 from 'parse5'
|
|
13
|
-
import chalk from 'chalk'
|
|
14
|
-
import { isElementNode, createTextNode, createElement } from '@parse5/tools'
|
|
15
|
-
import escapeStringRegexp from 'escape-string-regexp'
|
|
16
|
-
import eventPromise from '@data-fair/lib-utils/event-promise.js'
|
|
17
|
-
import { createSpaMiddleware } from '@data-fair/lib-express/serve-spa.js'
|
|
18
|
-
import { resolve } from 'node:path'
|
|
19
|
-
|
|
20
|
-
const debug = debugModule('df-dev-server')
|
|
21
|
-
|
|
22
|
-
const app = express()
|
|
23
|
-
const server = createServer(app)
|
|
24
|
-
|
|
25
|
-
// web socket server, used both by dev-server UI (opened on / path)
|
|
26
|
-
// and by application (opened on /data-fair), in this case we transmit all messages to and from data-fair
|
|
27
|
-
const wss = new WebSocketServer({ noServer: true })
|
|
28
|
-
let devServerWS: WebSocket
|
|
29
|
-
let dataFairWS: WebSocket
|
|
30
|
-
server.on('upgrade', function upgrade (req, socket, head) {
|
|
31
|
-
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
32
|
-
if (req.url === '/data-fair') {
|
|
33
|
-
if (dataFairWS) dataFairWS.terminate()
|
|
34
|
-
dataFairWS = ws
|
|
35
|
-
ws.on('message', (data: string) => {
|
|
36
|
-
if (dataFairOutputWS) {
|
|
37
|
-
const message = JSON.parse(data)
|
|
38
|
-
if (message.type === 'subscribe') message.apiKey = config.dataFair.apiKey
|
|
39
|
-
dataFairOutputWS.send(JSON.stringify(message))
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
} else {
|
|
43
|
-
if (devServerWS) devServerWS.terminate()
|
|
44
|
-
devServerWS = ws
|
|
45
|
-
}
|
|
46
|
-
wss.emit('connection', ws, req)
|
|
47
|
-
})
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
const dfWsUrl = config.dataFair.url.replace('http://', 'ws://').replace('https://', 'wss://') + '/'
|
|
51
|
-
const dataFairOutputWS = new WebSocket(dfWsUrl)
|
|
52
|
-
dataFairOutputWS.on('open', () => dataFairOutputWS.send('connect to external websocket server ' + dfWsUrl))
|
|
53
|
-
dataFairOutputWS.on('message', (data) => { if (dataFairWS) dataFairWS.send(data.toString()) })
|
|
54
|
-
dataFairOutputWS.on('error', (err) => console.error('failed to connect to external websocket server', dfWsUrl, err))
|
|
55
|
-
|
|
56
|
-
app.use(cors())
|
|
57
|
-
app.use(express.json())
|
|
58
|
-
|
|
59
|
-
// very basic CRUD of config
|
|
60
|
-
app.get('/config', (req, res, next) => {
|
|
61
|
-
const devConfig = existsSync('.dev-config.json') ? JSON.parse(readFileSync('.dev-config.json', 'utf8')) : {}
|
|
62
|
-
debug('read dev config', devConfig)
|
|
63
|
-
res.send(devConfig)
|
|
64
|
-
})
|
|
65
|
-
app.put('/config', (req, res, next) => {
|
|
66
|
-
debug('save dev config', req.body)
|
|
67
|
-
writeFileSync('.dev-config.json', JSON.stringify(req.body, null, 2))
|
|
68
|
-
res.send(req.body)
|
|
69
|
-
})
|
|
70
|
-
app.post('/config/error', (req, res) => {
|
|
71
|
-
console.log('Application sent an error', req.body)
|
|
72
|
-
if (devServerWS) devServerWS.send(JSON.stringify({ type: 'app-error', data: req.body }))
|
|
73
|
-
else console.error('no dev-server websocket open to send error to')
|
|
74
|
-
res.send()
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
// re-expose the application performing similar modifications to the body as data-fair
|
|
78
|
-
const appUrl = new URL(config.app.url)
|
|
79
|
-
const appPrefix = appUrl.pathname === '/' ? '' : appUrl.pathname
|
|
80
|
-
app.use('/app', createProxyMiddleware({
|
|
81
|
-
target: appUrl.origin,
|
|
82
|
-
secure: false,
|
|
83
|
-
changeOrigin: true,
|
|
84
|
-
selfHandleResponse: true, // so that the onProxyRes takes care of sending the response
|
|
85
|
-
on: {
|
|
86
|
-
proxyReq (proxyReq, req, res) {
|
|
87
|
-
proxyReq.path = appPrefix + proxyReq.path
|
|
88
|
-
proxyReq.setHeader('Accept-Encoding', 'identity') // disable compression
|
|
89
|
-
},
|
|
90
|
-
proxyRes (proxyRes, req, res) {
|
|
91
|
-
const configuration = existsSync('.dev-config.json') ? JSON.parse(readFileSync('.dev-config.json', 'utf8')) : {}
|
|
92
|
-
// console.log('inject config', configuration)
|
|
93
|
-
const dataBuffers: Buffer[] = []
|
|
94
|
-
proxyRes.on('data', (data) => { dataBuffers.push(data) })
|
|
95
|
-
proxyRes.on('end', async () => {
|
|
96
|
-
try {
|
|
97
|
-
let output = Buffer.concat(dataBuffers).toString()
|
|
98
|
-
if (output.includes('%APPLICATION%')) {
|
|
99
|
-
const filledBody = output.replace(/%APPLICATION%/g, JSON.stringify({
|
|
100
|
-
id: 'dev-application',
|
|
101
|
-
title: 'Dev application',
|
|
102
|
-
configuration,
|
|
103
|
-
exposedUrl: `http://localhost:${config.port}/app`,
|
|
104
|
-
href: `http://localhost:${config.port}/config`,
|
|
105
|
-
apiUrl: `http://localhost:${config.port}/data-fair/api/v1`,
|
|
106
|
-
wsUrl: `ws://localhost:${config.port}/data-fair`,
|
|
107
|
-
owner: config.dataFair && config.dataFair.owner
|
|
108
|
-
}))
|
|
109
|
-
const document = parse5.parse(filledBody)
|
|
110
|
-
const html = document.childNodes.filter(isElementNode).find(c => c.tagName === 'html')
|
|
111
|
-
if (!html) throw new Error('HTML structure is broken, expect html, head and body elements')
|
|
112
|
-
const headNode = html.childNodes.filter(isElementNode).find(c => c.tagName === 'head')
|
|
113
|
-
const bodyNode = html.childNodes.filter(isElementNode).find(c => c.tagName === 'body')
|
|
114
|
-
if (!headNode || !bodyNode) throw new Error('HTML structure is broken, expect html, head and body elements')
|
|
115
|
-
|
|
116
|
-
// add a script to simulate instrumentation by capture service
|
|
117
|
-
// @ts-ignore
|
|
118
|
-
const query: Record<string, string> = req.query
|
|
119
|
-
if (query.thumbnail === 'true') {
|
|
120
|
-
const script = createElement('script', { type: 'text/javascript' })
|
|
121
|
-
script.childNodes.push(createTextNode(`
|
|
122
|
-
console.log('[capture] Simulate a screenshot capture context')
|
|
123
|
-
var triggerCalled = false
|
|
124
|
-
window.triggerCapture = function (animationSupported) {
|
|
125
|
-
triggerCalled = true
|
|
126
|
-
console.log('[capture] triggerCapture called')
|
|
127
|
-
if (animationSupported) {
|
|
128
|
-
console.log('[capture] this application supports animated screenshots')
|
|
129
|
-
var i = 0
|
|
130
|
-
const interval = setInterval(function () {
|
|
131
|
-
i++
|
|
132
|
-
if (i === 1800) {
|
|
133
|
-
console.error('[capture] stop after the maximum number of frames was attained')
|
|
134
|
-
clearInterval(interval)
|
|
135
|
-
}
|
|
136
|
-
var stopped = window.animateCaptureFrame()
|
|
137
|
-
if (stopped) {
|
|
138
|
-
console.log('[capture] animation was stopped after ' + i + ' frames')
|
|
139
|
-
clearInterval(interval)
|
|
140
|
-
}
|
|
141
|
-
}, 67)
|
|
142
|
-
return true
|
|
143
|
-
} else {
|
|
144
|
-
console.log('[capture] this application does not support animated screenshots')
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
setTimeout(function() {
|
|
148
|
-
if (!triggerCalled) {
|
|
149
|
-
console.error('[capture] triggerCapture was not called after a 5s wait')
|
|
150
|
-
}
|
|
151
|
-
}, 5000)
|
|
152
|
-
`))
|
|
153
|
-
headNode.childNodes.push(script)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const meta: Record<string, string> = {}
|
|
157
|
-
for (const node of headNode.childNodes.filter(isElementNode)) {
|
|
158
|
-
if (node.tagName === 'meta') {
|
|
159
|
-
const name = node.attrs.find(a => a.name === 'name')?.value
|
|
160
|
-
const content = node.attrs.find(a => a.name === 'content')?.value
|
|
161
|
-
if (name !== undefined && content !== undefined) meta[name] = content
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
if (meta['df:sync-state'] === 'true' || meta['df:overflow'] === 'true') {
|
|
165
|
-
bodyNode.childNodes.push(createElement('script', {
|
|
166
|
-
type: 'text/javascript',
|
|
167
|
-
src: 'https://cdn.jsdelivr.net/npm/@data-fair/frame@0.12/dist/v-iframe-compat/d-frame-content.min.js'
|
|
168
|
-
}))
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
output = parse5.serialize(document)
|
|
172
|
-
|
|
173
|
-
// proxyRes.headers['content-length'] = output.length
|
|
174
|
-
delete proxyRes.headers['content-length']
|
|
175
|
-
delete proxyRes.headers['last-modified']
|
|
176
|
-
delete proxyRes.headers['max-age']
|
|
177
|
-
delete proxyRes.headers.etag
|
|
178
|
-
proxyRes.headers['cache-control'] = 'no-cache'
|
|
179
|
-
}
|
|
180
|
-
res.writeHead(proxyRes.statusCode ?? 200, proxyRes.headers)
|
|
181
|
-
res.end(output)
|
|
182
|
-
} catch (err: any) {
|
|
183
|
-
console.error(err)
|
|
184
|
-
res.writeHead(500)
|
|
185
|
-
res.end(err.message)
|
|
186
|
-
}
|
|
187
|
-
})
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}))
|
|
191
|
-
|
|
192
|
-
for (const proxyPath of config.app.proxyPaths) {
|
|
193
|
-
app.use(proxyPath, createProxyMiddleware({
|
|
194
|
-
target: appUrl.origin,
|
|
195
|
-
secure: false,
|
|
196
|
-
changeOrigin: true,
|
|
197
|
-
ws: true
|
|
198
|
-
}))
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// re-expose a data-fair instance to access datasets, etc.
|
|
202
|
-
const dfUrl = new URL(config.dataFair.url)
|
|
203
|
-
app.use('/data-fair', createProxyMiddleware({
|
|
204
|
-
target: dfUrl.origin,
|
|
205
|
-
secure: false,
|
|
206
|
-
changeOrigin: true,
|
|
207
|
-
selfHandleResponse: true, // so that the onProxyRes takes care of sending the response
|
|
208
|
-
on: {
|
|
209
|
-
proxyReq (proxyReq, req, res) {
|
|
210
|
-
proxyReq.path = '/data-fair' + proxyReq.path
|
|
211
|
-
|
|
212
|
-
// no gzip so that we can process the content
|
|
213
|
-
proxyReq.setHeader('accept-encoding', 'identity')
|
|
214
|
-
|
|
215
|
-
// authentication through api key only
|
|
216
|
-
proxyReq.setHeader('cookie', '')
|
|
217
|
-
if (config.dataFair.apiKey) proxyReq.setHeader('x-apiKey', config.dataFair.apiKey)
|
|
218
|
-
|
|
219
|
-
// body was already parsed by body-parser and no longer available as a stream
|
|
220
|
-
fixRequestBody(proxyReq, req)
|
|
221
|
-
},
|
|
222
|
-
proxyRes (proxyRes, req, res) {
|
|
223
|
-
// console.log('DF RES', proxyRes)
|
|
224
|
-
if (proxyRes.headers['content-type'] && proxyRes.headers['content-type'].startsWith('application/json')) {
|
|
225
|
-
let body = ''
|
|
226
|
-
proxyRes.on('data', (data) => { body += data.toString() })
|
|
227
|
-
proxyRes.on('end', () => {
|
|
228
|
-
const output = body.replace(new RegExp(escapeStringRegexp(config.dataFair.url), 'g'), 'http://localhost:5888/data-fair')
|
|
229
|
-
// proxyRes.headers['content-length'] = output.length
|
|
230
|
-
delete proxyRes.headers['content-length']
|
|
231
|
-
res.writeHead(proxyRes.statusCode ?? 200, proxyRes.headers)
|
|
232
|
-
// make all references to data-fair url point to local proxy
|
|
233
|
-
res.end(output)
|
|
234
|
-
})
|
|
235
|
-
} else {
|
|
236
|
-
res.writeHead(proxyRes.statusCode ?? 200, proxyRes.headers)
|
|
237
|
-
proxyRes.pipe(res)
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}))
|
|
242
|
-
|
|
243
|
-
// also re-expose the simple-directory instance matching data-fair
|
|
244
|
-
app.use('/simple-directory', createProxyMiddleware({
|
|
245
|
-
target: dfUrl.origin,
|
|
246
|
-
secure: false,
|
|
247
|
-
changeOrigin: true,
|
|
248
|
-
on: {
|
|
249
|
-
proxyReq (proxyReq, req, res) {
|
|
250
|
-
proxyReq.path = '/simple-directory' + proxyReq.path
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}))
|
|
254
|
-
|
|
255
|
-
if (config.serveUi) {
|
|
256
|
-
app.use(await createSpaMiddleware(resolve(import.meta.dirname, '../ui/dist'), uiConfig))
|
|
257
|
-
} else {
|
|
258
|
-
app.use('/', createProxyMiddleware({
|
|
259
|
-
target: 'http://localhost:6220',
|
|
260
|
-
secure: false
|
|
261
|
-
}))
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Run app and return it in a promise
|
|
265
|
-
export const run = async () => {
|
|
266
|
-
server.listen(config.port)
|
|
267
|
-
await eventPromise(server, 'listening')
|
|
268
|
-
console.log(chalk.bold.blue('\nDataFair dev server available on ') + chalk.underline.bold.blue(`http://localhost:${config.port}`))
|
|
269
|
-
return server
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export const stop = async () => {
|
|
273
|
-
if (devServerWS) devServerWS.terminate()
|
|
274
|
-
if (dataFairWS) dataFairWS.terminate()
|
|
275
|
-
server.close()
|
|
276
|
-
await eventPromise(server, 'close')
|
|
277
|
-
await app.get('client').close()
|
|
278
|
-
}
|
package/src/config.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { assertValid, type DevServerConfig } from '../config/type/index.js'
|
|
2
|
-
import config from 'config'
|
|
3
|
-
|
|
4
|
-
export type { DevServerConfig } from '../config/type/index.ts'
|
|
5
|
-
|
|
6
|
-
// we reload the config instead of using the singleton from the config module for testing purposes
|
|
7
|
-
// @ts-ignore
|
|
8
|
-
const devServerConfig = process.env.NODE_ENV === 'test' ? config.util.loadFileConfigs(process.env.NODE_CONFIG_DIR, { skipConfigSources: true }) : config
|
|
9
|
-
|
|
10
|
-
assertValid(devServerConfig, { lang: 'en', name: 'config', internal: true })
|
|
11
|
-
|
|
12
|
-
export default devServerConfig as DevServerConfig
|
package/src/index.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import 'dotenv/config'
|
|
4
|
-
import path from 'node:path'
|
|
5
|
-
|
|
6
|
-
process.env.NODE_CONFIG_DIR = path.join(import.meta.dirname, '../config')
|
|
7
|
-
const app = await import('./app.js')
|
|
8
|
-
|
|
9
|
-
app.run().then(app => {
|
|
10
|
-
// nothing to do
|
|
11
|
-
}, error => {
|
|
12
|
-
console.error('Failure in dev server process', error)
|
|
13
|
-
process.exit(-1)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
process.on('SIGTERM', function onSigterm () {
|
|
17
|
-
console.info('Received SIGTERM signal, shutdown gracefully...')
|
|
18
|
-
app.stop().then(() => {
|
|
19
|
-
console.log('shutting down now')
|
|
20
|
-
process.exit()
|
|
21
|
-
}, err => {
|
|
22
|
-
console.error('Failure while stopping service', err)
|
|
23
|
-
process.exit(-1)
|
|
24
|
-
})
|
|
25
|
-
})
|