@plurid/plurid-react-server 0.0.0-14 → 0.0.0-16
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/README.md +69 -5
- package/distribution/index.d.mts +244 -0
- package/distribution/index.d.ts +244 -6
- package/distribution/index.js +1573 -1056
- package/distribution/index.js.map +1 -0
- package/distribution/index.mjs +1642 -0
- package/distribution/index.mjs.map +1 -0
- package/package.json +129 -133
- package/distribution/__tests__/sanity.test.d.ts +0 -0
- package/distribution/data/constants/general/index.d.ts +0 -34
- package/distribution/data/constants/index.d.ts +0 -2
- package/distribution/data/constants/stiller/index.d.ts +0 -2
- package/distribution/data/interfaces/external/index.d.ts +0 -151
- package/distribution/data/interfaces/index.d.ts +0 -2
- package/distribution/data/interfaces/internal/index.d.ts +0 -83
- package/distribution/data/templates/index.d.ts +0 -2
- package/distribution/index.es.js +0 -1095
- package/distribution/objects/ContentGenerator/index.d.ts +0 -7
- package/distribution/objects/LiveServer/index.d.ts +0 -13
- package/distribution/objects/Renderer/index.d.ts +0 -22
- package/distribution/objects/Renderer/template/index.d.ts +0 -3
- package/distribution/objects/Server/index.d.ts +0 -57
- package/distribution/objects/Stiller/__tests__/index.test.d.ts +0 -1
- package/distribution/objects/Stiller/index.d.ts +0 -24
- package/distribution/objects/StillsGenerator/index.d.ts +0 -8
- package/distribution/objects/StillsManager/index.d.ts +0 -9
- package/distribution/utilities/pttp/index.d.ts +0 -6
- package/distribution/utilities/template/index.d.ts +0 -9
- package/distribution/utilities/wrapping/index.d.ts +0 -28
|
@@ -0,0 +1,1642 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// source/objects/Server/index.ts
|
|
9
|
+
import fs2 from "fs";
|
|
10
|
+
import path2 from "path";
|
|
11
|
+
import express from "express";
|
|
12
|
+
import compression from "compression";
|
|
13
|
+
import open from "open";
|
|
14
|
+
import {
|
|
15
|
+
ServerStyleSheet
|
|
16
|
+
} from "styled-components";
|
|
17
|
+
import {
|
|
18
|
+
time,
|
|
19
|
+
uuid
|
|
20
|
+
} from "@plurid/plurid-functions";
|
|
21
|
+
import {
|
|
22
|
+
routing
|
|
23
|
+
} from "@plurid/plurid-engine";
|
|
24
|
+
import {
|
|
25
|
+
serverComputeMetastate
|
|
26
|
+
} from "@plurid/plurid-react";
|
|
27
|
+
|
|
28
|
+
// source/data/constants/general/index.ts
|
|
29
|
+
var DEFAULT_SERVER_PORT = process.env.PORT ? parseInt(process.env.PORT) : 8080;
|
|
30
|
+
var DEFAULT_SERVER_OPTIONS_SERVER_NAME = "Plurid Server";
|
|
31
|
+
var DEFAULT_SERVER_OPTIONS_HOSTNAME = "origin";
|
|
32
|
+
var DEFAULT_SERVER_OPTIONS_QUIET = false;
|
|
33
|
+
var DEFAULT_SERVER_OPTIONS_COMPRESSION = true;
|
|
34
|
+
var DEFAULT_SERVER_OPTIONS_OPEN = false;
|
|
35
|
+
var DEFAULT_SERVER_OPTIONS_BUILD_DIRECTORY = "build";
|
|
36
|
+
var DEFAULT_SERVER_OPTIONS_ASSETS_DIRECTORY = "assets";
|
|
37
|
+
var DEFAULT_SERVER_OPTIONS_STILLS_DIRECTORY = "stills";
|
|
38
|
+
var DEFAULT_SERVER_OPTIONS_GATEWAY = "/gateway";
|
|
39
|
+
var DEFAULT_SERVER_OPTIONS = {
|
|
40
|
+
SERVER_NAME: DEFAULT_SERVER_OPTIONS_SERVER_NAME,
|
|
41
|
+
HOSTNAME: DEFAULT_SERVER_OPTIONS_HOSTNAME,
|
|
42
|
+
QUIET: DEFAULT_SERVER_OPTIONS_QUIET,
|
|
43
|
+
COMPRESSION: DEFAULT_SERVER_OPTIONS_COMPRESSION,
|
|
44
|
+
OPEN: DEFAULT_SERVER_OPTIONS_OPEN,
|
|
45
|
+
BUILD_DIRECTORY: DEFAULT_SERVER_OPTIONS_BUILD_DIRECTORY,
|
|
46
|
+
ASSETS_DIRECTORY: DEFAULT_SERVER_OPTIONS_ASSETS_DIRECTORY,
|
|
47
|
+
STILLS_DIRECTORY: DEFAULT_SERVER_OPTIONS_STILLS_DIRECTORY,
|
|
48
|
+
GATEWAY: DEFAULT_SERVER_OPTIONS_GATEWAY
|
|
49
|
+
};
|
|
50
|
+
var DEFAULT_RENDERER_LANGUAGE = "en";
|
|
51
|
+
var DEFAULT_RENDERER_ROOT = "root";
|
|
52
|
+
var DEFAULT_RENDERER_PLURID_STATE = "{}";
|
|
53
|
+
var DEFAULT_RENDERER_VENDOR_SCRIPT_SOURCE = "/vendor.js";
|
|
54
|
+
var DEFAULT_RENDERER_MAIN_SCRIPT_SOURCE = "/index.js";
|
|
55
|
+
var DEFAULT__PRELOADED_PLURID_METASTATE__ = "__PRELOADED_PLURID_METASTATE__";
|
|
56
|
+
var CATCH_ALL_ROUTE = "*";
|
|
57
|
+
var CATCH_ALL_ROUTE_PATTERN = /.*/;
|
|
58
|
+
var NOT_FOUND_ROUTE = process.env.PLURID_SERVER_NOT_FOUND_ROUTE || "/not-found";
|
|
59
|
+
var PTTP_ROUTE = process.env.PLURID_SERVER_PTTP_ROUTE || "/pttp";
|
|
60
|
+
var environment = {
|
|
61
|
+
production: process.env.ENV_MODE === "production",
|
|
62
|
+
development: process.env.ENV_MODE === "development"
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// source/data/constants/stiller/index.ts
|
|
66
|
+
var defaultStillerOptions = {
|
|
67
|
+
waitUntil: "networkidle0",
|
|
68
|
+
timeout: 3e4,
|
|
69
|
+
ignore: []
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// source/utilities/template/index.ts
|
|
73
|
+
import {
|
|
74
|
+
minify
|
|
75
|
+
} from "html-minifier-terser";
|
|
76
|
+
var cleanTemplate = (template2) => {
|
|
77
|
+
return minify(
|
|
78
|
+
template2,
|
|
79
|
+
{
|
|
80
|
+
collapseWhitespace: true,
|
|
81
|
+
conservativeCollapse: true,
|
|
82
|
+
collapseInlineTagWhitespace: false
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
var resolveBackgroundStyle = (store) => {
|
|
87
|
+
const defaultBackground = {
|
|
88
|
+
gradientBackground: "hsl(220, 10%, 32%)",
|
|
89
|
+
gradientForeground: "hsl(220, 10%, 18%)"
|
|
90
|
+
};
|
|
91
|
+
try {
|
|
92
|
+
const storeJSON = JSON.parse(store);
|
|
93
|
+
const generalPluridTheme = storeJSON?.themes?.general;
|
|
94
|
+
if (!generalPluridTheme) {
|
|
95
|
+
return defaultBackground;
|
|
96
|
+
}
|
|
97
|
+
const gradientBackground = generalPluridTheme.type === "dark" ? generalPluridTheme.backgroundColorTertiary : generalPluridTheme.backgroundColorPrimary;
|
|
98
|
+
const gradientForeground = generalPluridTheme.type === "dark" ? generalPluridTheme.backgroundColorPrimary : generalPluridTheme.backgroundColorTertiary;
|
|
99
|
+
return {
|
|
100
|
+
gradientBackground,
|
|
101
|
+
gradientForeground
|
|
102
|
+
};
|
|
103
|
+
} catch (error) {
|
|
104
|
+
return defaultBackground;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var escapeAttribute = (value) => {
|
|
108
|
+
return String(value).replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
109
|
+
};
|
|
110
|
+
var recordToString = (record) => {
|
|
111
|
+
if (!record) {
|
|
112
|
+
return "";
|
|
113
|
+
}
|
|
114
|
+
return Object.entries(record).map(([key, value]) => `${key}="${escapeAttribute(value)}"`).join(" ");
|
|
115
|
+
};
|
|
116
|
+
var assetsPathRewrite = (content) => {
|
|
117
|
+
return content.replace(
|
|
118
|
+
/="client\//g,
|
|
119
|
+
'="/'
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
var safeStore = (store) => {
|
|
123
|
+
return store.replace(
|
|
124
|
+
/</g,
|
|
125
|
+
"\\u003c"
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
var globalsInjector = (globals) => {
|
|
129
|
+
let globalsScript = "";
|
|
130
|
+
for (const [key, value] of Object.entries(globals)) {
|
|
131
|
+
const globalScript = `window.${key} = ${value};
|
|
132
|
+
`;
|
|
133
|
+
globalsScript += globalScript;
|
|
134
|
+
}
|
|
135
|
+
return globalsScript;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// source/data/templates/index.ts
|
|
139
|
+
var NOT_FOUND_TEMPLATE = cleanTemplate(`
|
|
140
|
+
<!DOCTYPE html>
|
|
141
|
+
<html>
|
|
142
|
+
<head>
|
|
143
|
+
<title>[404] Not Found</title>
|
|
144
|
+
<style>
|
|
145
|
+
html, body {
|
|
146
|
+
margin: 0;
|
|
147
|
+
background: #242b33;
|
|
148
|
+
color: #ddd;
|
|
149
|
+
user-select: none;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.not-found {
|
|
153
|
+
position: absolute;
|
|
154
|
+
top: 50%;
|
|
155
|
+
left: 50%;
|
|
156
|
+
transform: translate(-50%, -50%);
|
|
157
|
+
font-family: 'Ubuntu', -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto;
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
160
|
+
</head>
|
|
161
|
+
|
|
162
|
+
<body>
|
|
163
|
+
<div class="not-found">[404] Not Found</div>
|
|
164
|
+
</body>
|
|
165
|
+
</html>
|
|
166
|
+
`);
|
|
167
|
+
var SERVER_ERROR_TEMPLATE = cleanTemplate(`
|
|
168
|
+
<!DOCTYPE html>
|
|
169
|
+
<html>
|
|
170
|
+
<head>
|
|
171
|
+
<title>[500] Server Error</title>
|
|
172
|
+
<style>
|
|
173
|
+
html, body {
|
|
174
|
+
margin: 0;
|
|
175
|
+
background: #242b33;
|
|
176
|
+
color: #ddd;
|
|
177
|
+
user-select: none;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.error {
|
|
181
|
+
position: absolute;
|
|
182
|
+
top: 50%;
|
|
183
|
+
left: 50%;
|
|
184
|
+
transform: translate(-50%, -50%);
|
|
185
|
+
font-family: 'Ubuntu', -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto;
|
|
186
|
+
}
|
|
187
|
+
</style>
|
|
188
|
+
</head>
|
|
189
|
+
|
|
190
|
+
<body>
|
|
191
|
+
<div class="error">[500] Server Error</div>
|
|
192
|
+
</body>
|
|
193
|
+
</html>
|
|
194
|
+
`);
|
|
195
|
+
|
|
196
|
+
// source/objects/Renderer/template/index.ts
|
|
197
|
+
var template = async (data) => {
|
|
198
|
+
const {
|
|
199
|
+
htmlLanguage,
|
|
200
|
+
head,
|
|
201
|
+
htmlAttributes,
|
|
202
|
+
bodyAttributes,
|
|
203
|
+
defaultStyle,
|
|
204
|
+
styles,
|
|
205
|
+
headScripts,
|
|
206
|
+
bodyScripts,
|
|
207
|
+
vendorScriptSource,
|
|
208
|
+
mainScriptSource,
|
|
209
|
+
root,
|
|
210
|
+
content,
|
|
211
|
+
defaultPreloadedPluridMetastate,
|
|
212
|
+
pluridMetastate,
|
|
213
|
+
globals,
|
|
214
|
+
minify: minify2
|
|
215
|
+
} = data;
|
|
216
|
+
const injectedGlobals = globalsInjector(globals);
|
|
217
|
+
const templateString = `
|
|
218
|
+
<!DOCTYPE html>
|
|
219
|
+
<html lang="${htmlLanguage}" ${htmlAttributes}>
|
|
220
|
+
<head>
|
|
221
|
+
${head}
|
|
222
|
+
|
|
223
|
+
${defaultStyle && `<style>
|
|
224
|
+
${defaultStyle}
|
|
225
|
+
</style>`}
|
|
226
|
+
|
|
227
|
+
${styles}
|
|
228
|
+
|
|
229
|
+
${headScripts.join("\n")}
|
|
230
|
+
|
|
231
|
+
<script src="${vendorScriptSource}"></script>
|
|
232
|
+
<script defer src="${mainScriptSource}"></script>
|
|
233
|
+
</head>
|
|
234
|
+
<body ${bodyAttributes}>
|
|
235
|
+
<div id="${root}">${content}</div>
|
|
236
|
+
|
|
237
|
+
<script>
|
|
238
|
+
${injectedGlobals}
|
|
239
|
+
window.${defaultPreloadedPluridMetastate} = ${safeStore(pluridMetastate)};
|
|
240
|
+
</script>
|
|
241
|
+
|
|
242
|
+
${bodyScripts.join("\n")}
|
|
243
|
+
</body>
|
|
244
|
+
</html>
|
|
245
|
+
`;
|
|
246
|
+
if (!minify2) {
|
|
247
|
+
return templateString;
|
|
248
|
+
}
|
|
249
|
+
return cleanTemplate(templateString);
|
|
250
|
+
};
|
|
251
|
+
var template_default = template;
|
|
252
|
+
|
|
253
|
+
// source/objects/Renderer/index.ts
|
|
254
|
+
var PluridRenderer = class {
|
|
255
|
+
htmlLanguage;
|
|
256
|
+
head;
|
|
257
|
+
htmlAttributes;
|
|
258
|
+
bodyAttributes;
|
|
259
|
+
defaultStyle;
|
|
260
|
+
styles;
|
|
261
|
+
headScripts;
|
|
262
|
+
bodyScripts;
|
|
263
|
+
vendorScriptSource;
|
|
264
|
+
mainScriptSource;
|
|
265
|
+
root;
|
|
266
|
+
content;
|
|
267
|
+
defaultPreloadedPluridMetastate;
|
|
268
|
+
pluridMetastate;
|
|
269
|
+
globals;
|
|
270
|
+
minify;
|
|
271
|
+
constructor(configuration) {
|
|
272
|
+
const {
|
|
273
|
+
htmlLanguage,
|
|
274
|
+
head,
|
|
275
|
+
htmlAttributes,
|
|
276
|
+
bodyAttributes,
|
|
277
|
+
defaultStyle,
|
|
278
|
+
styles,
|
|
279
|
+
headScripts,
|
|
280
|
+
bodyScripts,
|
|
281
|
+
vendorScriptSource,
|
|
282
|
+
mainScriptSource,
|
|
283
|
+
content,
|
|
284
|
+
root,
|
|
285
|
+
defaultPreloadedPluridMetastate,
|
|
286
|
+
pluridMetastate,
|
|
287
|
+
globals,
|
|
288
|
+
minify: minify2
|
|
289
|
+
} = configuration;
|
|
290
|
+
const {
|
|
291
|
+
gradientBackground,
|
|
292
|
+
gradientForeground
|
|
293
|
+
// The metastate carries `themes.general` (see `serverComputeMetastate`), so the SSR'd background
|
|
294
|
+
// gradient matches the active theme; `resolveBackgroundStyle` falls back to a default if it can't parse.
|
|
295
|
+
} = resolveBackgroundStyle(pluridMetastate || "");
|
|
296
|
+
const defaultStyleBasic = `
|
|
297
|
+
body {
|
|
298
|
+
background: radial-gradient(ellipse at center, ${gradientBackground} 0%, ${gradientForeground} 100%);
|
|
299
|
+
height: 100%;
|
|
300
|
+
margin: 0;
|
|
301
|
+
}
|
|
302
|
+
`;
|
|
303
|
+
this.htmlLanguage = htmlLanguage || DEFAULT_RENDERER_LANGUAGE;
|
|
304
|
+
this.head = head || "";
|
|
305
|
+
this.htmlAttributes = htmlAttributes;
|
|
306
|
+
this.bodyAttributes = bodyAttributes || "";
|
|
307
|
+
this.defaultStyle = defaultStyle ?? defaultStyleBasic;
|
|
308
|
+
this.styles = styles;
|
|
309
|
+
this.headScripts = headScripts;
|
|
310
|
+
this.bodyScripts = bodyScripts;
|
|
311
|
+
this.vendorScriptSource = vendorScriptSource || DEFAULT_RENDERER_VENDOR_SCRIPT_SOURCE;
|
|
312
|
+
this.mainScriptSource = mainScriptSource || DEFAULT_RENDERER_MAIN_SCRIPT_SOURCE;
|
|
313
|
+
this.root = root || DEFAULT_RENDERER_ROOT;
|
|
314
|
+
this.content = assetsPathRewrite(content) || "";
|
|
315
|
+
this.defaultPreloadedPluridMetastate = defaultPreloadedPluridMetastate || DEFAULT__PRELOADED_PLURID_METASTATE__;
|
|
316
|
+
this.pluridMetastate = pluridMetastate || DEFAULT_RENDERER_PLURID_STATE;
|
|
317
|
+
this.globals = globals ?? {};
|
|
318
|
+
this.minify = minify2 ?? true;
|
|
319
|
+
}
|
|
320
|
+
async html() {
|
|
321
|
+
const data = {
|
|
322
|
+
htmlLanguage: this.htmlLanguage,
|
|
323
|
+
head: this.head,
|
|
324
|
+
htmlAttributes: this.htmlAttributes,
|
|
325
|
+
bodyAttributes: this.bodyAttributes,
|
|
326
|
+
defaultStyle: this.defaultStyle,
|
|
327
|
+
styles: this.styles,
|
|
328
|
+
headScripts: this.headScripts,
|
|
329
|
+
bodyScripts: this.bodyScripts,
|
|
330
|
+
vendorScriptSource: this.vendorScriptSource,
|
|
331
|
+
mainScriptSource: this.mainScriptSource,
|
|
332
|
+
root: this.root,
|
|
333
|
+
content: this.content,
|
|
334
|
+
defaultPreloadedPluridMetastate: this.defaultPreloadedPluridMetastate,
|
|
335
|
+
pluridMetastate: this.pluridMetastate,
|
|
336
|
+
globals: this.globals,
|
|
337
|
+
minify: this.minify
|
|
338
|
+
};
|
|
339
|
+
return template_default(data);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
var Renderer_default = PluridRenderer;
|
|
343
|
+
|
|
344
|
+
// source/objects/ContentGenerator/index.tsx
|
|
345
|
+
import React2 from "react";
|
|
346
|
+
import {
|
|
347
|
+
renderToString
|
|
348
|
+
} from "react-dom/server";
|
|
349
|
+
import {
|
|
350
|
+
StyleSheetManager
|
|
351
|
+
} from "styled-components";
|
|
352
|
+
import {
|
|
353
|
+
HelmetProvider
|
|
354
|
+
} from "react-helmet-async";
|
|
355
|
+
import {
|
|
356
|
+
PluridProvider,
|
|
357
|
+
PluridRouterStatic
|
|
358
|
+
} from "@plurid/plurid-react";
|
|
359
|
+
|
|
360
|
+
// source/utilities/wrapping/index.tsx
|
|
361
|
+
import React from "react";
|
|
362
|
+
var wrapping = (WrappedComponent, WrappeeComponent, properties) => {
|
|
363
|
+
return class extends React.Component {
|
|
364
|
+
constructor(props) {
|
|
365
|
+
super(props);
|
|
366
|
+
}
|
|
367
|
+
render() {
|
|
368
|
+
return /* @__PURE__ */ React.createElement(
|
|
369
|
+
WrappedComponent,
|
|
370
|
+
{
|
|
371
|
+
...properties
|
|
372
|
+
},
|
|
373
|
+
/* @__PURE__ */ React.createElement(WrappeeComponent, null)
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
};
|
|
378
|
+
var wrapping_default = wrapping;
|
|
379
|
+
|
|
380
|
+
// source/objects/ContentGenerator/index.tsx
|
|
381
|
+
var PluridContentGenerator = class {
|
|
382
|
+
data;
|
|
383
|
+
constructor(data) {
|
|
384
|
+
this.data = data;
|
|
385
|
+
}
|
|
386
|
+
async render() {
|
|
387
|
+
const {
|
|
388
|
+
pluridMetastate,
|
|
389
|
+
routes,
|
|
390
|
+
planes,
|
|
391
|
+
exterior,
|
|
392
|
+
shell,
|
|
393
|
+
routerProperties,
|
|
394
|
+
gateway,
|
|
395
|
+
gatewayEndpoint,
|
|
396
|
+
gatewayQuery,
|
|
397
|
+
helmet,
|
|
398
|
+
services,
|
|
399
|
+
stylesheet,
|
|
400
|
+
preserveResult,
|
|
401
|
+
matchedPlane,
|
|
402
|
+
pathname,
|
|
403
|
+
hostname
|
|
404
|
+
} = this.data;
|
|
405
|
+
const RoutedApplication = () => /* @__PURE__ */ React2.createElement(
|
|
406
|
+
PluridProvider,
|
|
407
|
+
{
|
|
408
|
+
metastate: pluridMetastate
|
|
409
|
+
},
|
|
410
|
+
/* @__PURE__ */ React2.createElement(
|
|
411
|
+
PluridRouterStatic,
|
|
412
|
+
{
|
|
413
|
+
path: pathname,
|
|
414
|
+
directPlane: matchedPlane?.value,
|
|
415
|
+
routes,
|
|
416
|
+
planes,
|
|
417
|
+
exterior,
|
|
418
|
+
shell,
|
|
419
|
+
gateway,
|
|
420
|
+
gatewayEndpoint,
|
|
421
|
+
gatewayQuery,
|
|
422
|
+
hostname,
|
|
423
|
+
routerProperties
|
|
424
|
+
}
|
|
425
|
+
)
|
|
426
|
+
);
|
|
427
|
+
let Wrap = wrapping_default(
|
|
428
|
+
HelmetProvider,
|
|
429
|
+
RoutedApplication,
|
|
430
|
+
{
|
|
431
|
+
context: helmet
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
for (const service of services) {
|
|
435
|
+
const preserveProperties = preserveResult?.providers?.[service.name];
|
|
436
|
+
Wrap = wrapping_default(
|
|
437
|
+
service.Provider,
|
|
438
|
+
Wrap,
|
|
439
|
+
{
|
|
440
|
+
...service.properties,
|
|
441
|
+
...preserveProperties
|
|
442
|
+
}
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
const content = renderToString(
|
|
446
|
+
/* @__PURE__ */ React2.createElement(
|
|
447
|
+
StyleSheetManager,
|
|
448
|
+
{
|
|
449
|
+
sheet: stylesheet.instance
|
|
450
|
+
},
|
|
451
|
+
/* @__PURE__ */ React2.createElement(Wrap, null)
|
|
452
|
+
)
|
|
453
|
+
);
|
|
454
|
+
return content;
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
var ContentGenerator_default = PluridContentGenerator;
|
|
458
|
+
|
|
459
|
+
// source/objects/StillsManager/index.ts
|
|
460
|
+
import path from "path";
|
|
461
|
+
import {
|
|
462
|
+
existsSync,
|
|
463
|
+
promises as fs
|
|
464
|
+
} from "fs";
|
|
465
|
+
var StillsManager = class {
|
|
466
|
+
options;
|
|
467
|
+
stills = /* @__PURE__ */ new Map();
|
|
468
|
+
constructor(options) {
|
|
469
|
+
this.options = options;
|
|
470
|
+
this.findStills();
|
|
471
|
+
}
|
|
472
|
+
get(url) {
|
|
473
|
+
const still = this.stills.get(url);
|
|
474
|
+
if (!still) {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
return still.html;
|
|
478
|
+
}
|
|
479
|
+
async findStills() {
|
|
480
|
+
const {
|
|
481
|
+
buildDirectory,
|
|
482
|
+
stillsDirectory
|
|
483
|
+
} = this.options;
|
|
484
|
+
const stillsLocation = `${buildDirectory}/${stillsDirectory}`;
|
|
485
|
+
const stillsPath = path.join(process.cwd(), stillsLocation);
|
|
486
|
+
if (!existsSync(stillsPath)) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
try {
|
|
490
|
+
const stillsMetadata = path.join(stillsPath, "metadata.json");
|
|
491
|
+
const stillsMetadataFile = await fs.readFile(stillsMetadata, "utf-8");
|
|
492
|
+
const stillsMetadataJSON = JSON.parse(stillsMetadataFile);
|
|
493
|
+
if (!Array.isArray(stillsMetadataJSON)) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
for (const still of stillsMetadataJSON) {
|
|
497
|
+
const stillFilePath = path.join(stillsPath, still.name);
|
|
498
|
+
const stillFileData = await fs.readFile(stillFilePath, "utf-8");
|
|
499
|
+
const stillFileJSON = JSON.parse(stillFileData);
|
|
500
|
+
if (!stillFileJSON) {
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
this.stills.set(stillFileJSON.route, stillFileJSON);
|
|
504
|
+
}
|
|
505
|
+
} catch (error) {
|
|
506
|
+
if (this.options.debug !== "none" && !this.options.quiet) {
|
|
507
|
+
const errorText = "Plurid Server Error: Could not read stills.";
|
|
508
|
+
if (this.options.debug === "error") {
|
|
509
|
+
console.error(errorText, error);
|
|
510
|
+
} else {
|
|
511
|
+
console.log(errorText);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
var StillsManager_default = StillsManager;
|
|
519
|
+
|
|
520
|
+
// source/utilities/pttp/index.ts
|
|
521
|
+
var resolveElementFromPlaneMatch = (planeMatch, elementqlEndpoint) => {
|
|
522
|
+
if (typeof planeMatch.data.component === "function") {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
if (typeof planeMatch.data.component === "string") {
|
|
526
|
+
return {
|
|
527
|
+
name: planeMatch.data.component,
|
|
528
|
+
url: elementqlEndpoint
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
return {
|
|
532
|
+
name: planeMatch.data.component.name,
|
|
533
|
+
url: planeMatch.data.component.url || elementqlEndpoint
|
|
534
|
+
};
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
// source/objects/Server/index.ts
|
|
538
|
+
var {
|
|
539
|
+
IsoMatcher: PluridIsoMatcher
|
|
540
|
+
} = routing;
|
|
541
|
+
var PluridServer = class {
|
|
542
|
+
routes;
|
|
543
|
+
planes;
|
|
544
|
+
preserves;
|
|
545
|
+
helmet;
|
|
546
|
+
styles;
|
|
547
|
+
middleware;
|
|
548
|
+
exterior;
|
|
549
|
+
shell;
|
|
550
|
+
routerProperties;
|
|
551
|
+
services;
|
|
552
|
+
options;
|
|
553
|
+
template;
|
|
554
|
+
usePTTP;
|
|
555
|
+
pttpHandler;
|
|
556
|
+
elementqlEndpoint;
|
|
557
|
+
serverApplication;
|
|
558
|
+
server;
|
|
559
|
+
port;
|
|
560
|
+
stills;
|
|
561
|
+
isoMatcher;
|
|
562
|
+
constructor(configuration) {
|
|
563
|
+
const {
|
|
564
|
+
routes,
|
|
565
|
+
planes,
|
|
566
|
+
preserves,
|
|
567
|
+
helmet,
|
|
568
|
+
styles,
|
|
569
|
+
middleware,
|
|
570
|
+
exterior,
|
|
571
|
+
shell,
|
|
572
|
+
routerProperties,
|
|
573
|
+
services,
|
|
574
|
+
options,
|
|
575
|
+
template: template2,
|
|
576
|
+
usePTTP,
|
|
577
|
+
pttpHandler,
|
|
578
|
+
elementqlEndpoint
|
|
579
|
+
} = configuration;
|
|
580
|
+
this.routes = routes;
|
|
581
|
+
this.planes = planes || [];
|
|
582
|
+
this.preserves = preserves;
|
|
583
|
+
this.helmet = helmet;
|
|
584
|
+
this.styles = styles || [];
|
|
585
|
+
this.middleware = middleware || [];
|
|
586
|
+
this.exterior = exterior;
|
|
587
|
+
this.shell = shell;
|
|
588
|
+
this.routerProperties = routerProperties || {};
|
|
589
|
+
this.services = services || [];
|
|
590
|
+
this.options = this.handleOptions(options);
|
|
591
|
+
this.template = template2;
|
|
592
|
+
this.usePTTP = usePTTP ?? false;
|
|
593
|
+
this.pttpHandler = pttpHandler;
|
|
594
|
+
this.elementqlEndpoint = elementqlEndpoint;
|
|
595
|
+
this.serverApplication = express();
|
|
596
|
+
this.port = DEFAULT_SERVER_PORT;
|
|
597
|
+
this.stills = new StillsManager_default(this.options);
|
|
598
|
+
this.isoMatcher = new PluridIsoMatcher(
|
|
599
|
+
{
|
|
600
|
+
routes: this.routes,
|
|
601
|
+
routePlanes: this.planes
|
|
602
|
+
},
|
|
603
|
+
this.options.hostname
|
|
604
|
+
);
|
|
605
|
+
this.configureServer();
|
|
606
|
+
this.handleEndpoints();
|
|
607
|
+
if (this.options.attachSignalHandlers) {
|
|
608
|
+
this.attachSignalHandlers();
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
handleProcessSignal = () => {
|
|
612
|
+
this.stop();
|
|
613
|
+
process.exit(0);
|
|
614
|
+
};
|
|
615
|
+
signalHandlersAttached = false;
|
|
616
|
+
attachSignalHandlers() {
|
|
617
|
+
if (this.signalHandlersAttached) {
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
process.on("SIGINT", this.handleProcessSignal);
|
|
621
|
+
process.on("SIGTERM", this.handleProcessSignal);
|
|
622
|
+
this.signalHandlersAttached = true;
|
|
623
|
+
}
|
|
624
|
+
detachSignalHandlers() {
|
|
625
|
+
process.removeListener("SIGINT", this.handleProcessSignal);
|
|
626
|
+
process.removeListener("SIGTERM", this.handleProcessSignal);
|
|
627
|
+
this.signalHandlersAttached = false;
|
|
628
|
+
}
|
|
629
|
+
static analysis(pluridServer) {
|
|
630
|
+
return {
|
|
631
|
+
routes: pluridServer.routes,
|
|
632
|
+
options: pluridServer.options
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
start(port = this.port) {
|
|
636
|
+
this.port = port;
|
|
637
|
+
const serverlink = `http://localhost:${port}`;
|
|
638
|
+
if (this.debugAllows("info")) {
|
|
639
|
+
console.info(
|
|
640
|
+
`
|
|
641
|
+
[${time.stamp()}] ${this.options.serverName} Started on Port ${port}: ${serverlink}
|
|
642
|
+
`
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
this.server = this.serverApplication.listen(port);
|
|
646
|
+
this.open(serverlink);
|
|
647
|
+
return this.server;
|
|
648
|
+
}
|
|
649
|
+
stop() {
|
|
650
|
+
this.detachSignalHandlers();
|
|
651
|
+
if (this.server) {
|
|
652
|
+
if (this.debugAllows("info")) {
|
|
653
|
+
console.info(
|
|
654
|
+
`
|
|
655
|
+
[${time.stamp()}] ${this.options.serverName} Stopped on Port ${this.port}
|
|
656
|
+
`
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
this.server.close();
|
|
660
|
+
} else {
|
|
661
|
+
if (this.debugAllows("info")) {
|
|
662
|
+
console.info(
|
|
663
|
+
`
|
|
664
|
+
[${time.stamp()}] ${this.options.serverName} Could not be Stopped on Port ${this.port}
|
|
665
|
+
`
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
handle() {
|
|
671
|
+
return {
|
|
672
|
+
post: (path4, ...handlers) => {
|
|
673
|
+
this.serverApplication.post(path4, ...handlers);
|
|
674
|
+
return this.serverApplication;
|
|
675
|
+
},
|
|
676
|
+
patch: (path4, ...handlers) => {
|
|
677
|
+
this.serverApplication.patch(path4, ...handlers);
|
|
678
|
+
return this.serverApplication;
|
|
679
|
+
},
|
|
680
|
+
put: (path4, ...handlers) => {
|
|
681
|
+
this.serverApplication.put(path4, ...handlers);
|
|
682
|
+
return this.serverApplication;
|
|
683
|
+
},
|
|
684
|
+
delete: (path4, ...handlers) => {
|
|
685
|
+
this.serverApplication.delete(path4, ...handlers);
|
|
686
|
+
return this.serverApplication;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
instance() {
|
|
691
|
+
return this.serverApplication;
|
|
692
|
+
}
|
|
693
|
+
handleEndpoints() {
|
|
694
|
+
this.serverApplication.get(
|
|
695
|
+
CATCH_ALL_ROUTE_PATTERN,
|
|
696
|
+
async (request, response, next) => {
|
|
697
|
+
this.handleGetRequest(
|
|
698
|
+
request,
|
|
699
|
+
response,
|
|
700
|
+
next
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
);
|
|
704
|
+
if (this.usePTTP) {
|
|
705
|
+
this.serverApplication.post(
|
|
706
|
+
PTTP_ROUTE,
|
|
707
|
+
express.json(),
|
|
708
|
+
// body parsing is built into Express 5
|
|
709
|
+
async (request, response, next) => {
|
|
710
|
+
this.handlePTTPRequest(
|
|
711
|
+
request,
|
|
712
|
+
response
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
async handleGetRequest(request, response, next) {
|
|
719
|
+
const requestID = request.requestID || uuid.generate();
|
|
720
|
+
try {
|
|
721
|
+
if (this.debugAllows("info")) {
|
|
722
|
+
console.info(
|
|
723
|
+
`[${time.stamp()} :: ${requestID}] (000 Start) Handling GET ${request.path}`
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
const ignorable = this.ignoreGetRequest(
|
|
727
|
+
request.path
|
|
728
|
+
);
|
|
729
|
+
if (ignorable) {
|
|
730
|
+
if (this.debugAllows("info")) {
|
|
731
|
+
const requestTime = this.computeRequestTime(request);
|
|
732
|
+
console.info(
|
|
733
|
+
`[${time.stamp()} :: ${requestID}] (204 No Content) Ignored GET ${request.path}${requestTime}`
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
next();
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
const {
|
|
740
|
+
preserveResponded,
|
|
741
|
+
preserveResult,
|
|
742
|
+
preserveAfterServe
|
|
743
|
+
} = await this.resolvePreserve(
|
|
744
|
+
request,
|
|
745
|
+
response
|
|
746
|
+
);
|
|
747
|
+
if (preserveResponded) {
|
|
748
|
+
if (this.debugAllows("info")) {
|
|
749
|
+
const requestTime = this.computeRequestTime(request);
|
|
750
|
+
console.info(
|
|
751
|
+
`[${time.stamp()} :: ${requestID}] (204 No Content) Preserve handled GET ${request.path}${requestTime}`
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const {
|
|
757
|
+
externalRedirect,
|
|
758
|
+
matchingPath
|
|
759
|
+
} = this.resolveMatchingPath(
|
|
760
|
+
preserveResult,
|
|
761
|
+
request.originalUrl
|
|
762
|
+
);
|
|
763
|
+
if (externalRedirect) {
|
|
764
|
+
if (this.debugAllows("info")) {
|
|
765
|
+
const requestTime = this.computeRequestTime(request);
|
|
766
|
+
console.info(
|
|
767
|
+
`[${time.stamp()} :: ${requestID}] (302 Redirect) Handled GET ${request.path} redirect to ${matchingPath}${requestTime}`
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
response.status(302).redirect(matchingPath);
|
|
771
|
+
this.resolvePreserveAfterServe(
|
|
772
|
+
preserveAfterServe,
|
|
773
|
+
request,
|
|
774
|
+
response
|
|
775
|
+
);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
const still = this.stills.get(matchingPath);
|
|
779
|
+
if (still) {
|
|
780
|
+
if (this.debugAllows("info")) {
|
|
781
|
+
const requestTime = this.computeRequestTime(request);
|
|
782
|
+
console.info(
|
|
783
|
+
`[${time.stamp()} :: ${requestID}] (200 OK) Still Handled GET ${matchingPath}${requestTime}`
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
response.send(still);
|
|
787
|
+
this.resolvePreserveAfterServe(
|
|
788
|
+
preserveAfterServe,
|
|
789
|
+
request,
|
|
790
|
+
response
|
|
791
|
+
);
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
const isoMatch = this.isoMatcher.match(
|
|
795
|
+
matchingPath,
|
|
796
|
+
"route"
|
|
797
|
+
);
|
|
798
|
+
if (!isoMatch) {
|
|
799
|
+
const notFoundStill = this.stills.get(NOT_FOUND_ROUTE);
|
|
800
|
+
if (notFoundStill) {
|
|
801
|
+
if (this.debugAllows("info")) {
|
|
802
|
+
const requestTime = this.computeRequestTime(request);
|
|
803
|
+
console.info(
|
|
804
|
+
`[${time.stamp()} :: ${requestID}] (404 Not Found) Handled GET ${matchingPath}${requestTime}`
|
|
805
|
+
);
|
|
806
|
+
}
|
|
807
|
+
response.status(404).send(notFoundStill);
|
|
808
|
+
this.resolvePreserveAfterServe(
|
|
809
|
+
preserveAfterServe,
|
|
810
|
+
request,
|
|
811
|
+
response
|
|
812
|
+
);
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
const isoMatchNotFound = this.isoMatcher.match(
|
|
816
|
+
NOT_FOUND_ROUTE,
|
|
817
|
+
"route"
|
|
818
|
+
);
|
|
819
|
+
if (!isoMatchNotFound) {
|
|
820
|
+
if (this.debugAllows("info")) {
|
|
821
|
+
const requestTime = this.computeRequestTime(request);
|
|
822
|
+
console.info(
|
|
823
|
+
`[${time.stamp()} :: ${requestID}] (404 Not Found) Handled GET ${matchingPath}${requestTime}`
|
|
824
|
+
);
|
|
825
|
+
}
|
|
826
|
+
response.status(404).send(NOT_FOUND_TEMPLATE);
|
|
827
|
+
this.resolvePreserveAfterServe(
|
|
828
|
+
preserveAfterServe,
|
|
829
|
+
request,
|
|
830
|
+
response
|
|
831
|
+
);
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
const renderer2 = await this.renderApplication(
|
|
835
|
+
isoMatchNotFound,
|
|
836
|
+
preserveResult
|
|
837
|
+
);
|
|
838
|
+
if (this.debugAllows("info")) {
|
|
839
|
+
const requestTime = this.computeRequestTime(request);
|
|
840
|
+
console.info(
|
|
841
|
+
`[${time.stamp()} :: ${requestID}] (404 Not Found) Handled GET ${matchingPath}${requestTime}`
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
response.status(404).send(await renderer2.html());
|
|
845
|
+
this.resolvePreserveAfterServe(
|
|
846
|
+
preserveAfterServe,
|
|
847
|
+
request,
|
|
848
|
+
response
|
|
849
|
+
);
|
|
850
|
+
response.status(404).end();
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
const renderer = await this.renderApplication(
|
|
854
|
+
isoMatch,
|
|
855
|
+
preserveResult
|
|
856
|
+
);
|
|
857
|
+
if (this.debugAllows("info")) {
|
|
858
|
+
const requestTime = this.computeRequestTime(request);
|
|
859
|
+
console.info(
|
|
860
|
+
`[${time.stamp()} :: ${requestID}] (200 OK) Handled GET ${matchingPath}${requestTime}`
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
response.send(await renderer.html());
|
|
864
|
+
this.resolvePreserveAfterServe(
|
|
865
|
+
preserveAfterServe,
|
|
866
|
+
request,
|
|
867
|
+
response
|
|
868
|
+
);
|
|
869
|
+
return;
|
|
870
|
+
} catch (error) {
|
|
871
|
+
if (this.debugAllows("error")) {
|
|
872
|
+
const requestTime = this.computeRequestTime(request);
|
|
873
|
+
console.error(
|
|
874
|
+
`[${time.stamp()} :: ${requestID}] (500 Server Error) Could not handle GET ${request.path}${requestTime}`,
|
|
875
|
+
error
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
response.status(500).send(SERVER_ERROR_TEMPLATE);
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
async handlePTTPRequest(request, response) {
|
|
883
|
+
const requestID = request.requestID || uuid.generate();
|
|
884
|
+
try {
|
|
885
|
+
if (this.debugAllows("info")) {
|
|
886
|
+
console.info(
|
|
887
|
+
`[${time.stamp()} :: ${requestID}] (000 Start) Handling POST ${request.path}`
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
response.setHeader("Access-Control-Allow-Origin", request.headers.origin || "");
|
|
891
|
+
response.setHeader("Access-Control-Allow-Credentials", "true");
|
|
892
|
+
const data = request.body;
|
|
893
|
+
if (!data || !data.path) {
|
|
894
|
+
if (this.debugAllows("warn")) {
|
|
895
|
+
const requestTime = this.computeRequestTime(request);
|
|
896
|
+
console.info(
|
|
897
|
+
`[${time.stamp()} :: ${requestID}] (400 Bad Request) Could not handle POST ${request.path}${requestTime}`
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
response.status(400).end();
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
if (this.pttpHandler) {
|
|
904
|
+
const pttpHandled = await this.pttpHandler(
|
|
905
|
+
data.path
|
|
906
|
+
);
|
|
907
|
+
if (pttpHandled) {
|
|
908
|
+
if (this.debugAllows("info")) {
|
|
909
|
+
const requestTime = this.computeRequestTime(request);
|
|
910
|
+
console.info(
|
|
911
|
+
`[${time.stamp()} :: ${requestID}] (200 OK) Handled POST ${request.path}${requestTime} in custom handler`
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
const planeMatch = this.isoMatcher.match(
|
|
918
|
+
data.path
|
|
919
|
+
);
|
|
920
|
+
if (!planeMatch) {
|
|
921
|
+
if (this.debugAllows("warn")) {
|
|
922
|
+
const requestTime = this.computeRequestTime(request);
|
|
923
|
+
console.info(
|
|
924
|
+
`[${time.stamp()} :: ${requestID}] (400 Bad Request) Could not handle POST ${request.path}${requestTime}`
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
response.status(400).end();
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
const elementMatch = resolveElementFromPlaneMatch(
|
|
931
|
+
planeMatch,
|
|
932
|
+
this.elementqlEndpoint
|
|
933
|
+
);
|
|
934
|
+
if (!elementMatch) {
|
|
935
|
+
if (this.debugAllows("warn")) {
|
|
936
|
+
const requestTime = this.computeRequestTime(request);
|
|
937
|
+
console.info(
|
|
938
|
+
`[${time.stamp()} :: ${requestID}] (404 Not Found) Could not handle POST ${request.path}${requestTime}`
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
response.status(404).end();
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
const elementURL = elementMatch.url;
|
|
945
|
+
if (!elementURL) {
|
|
946
|
+
if (this.debugAllows("warn")) {
|
|
947
|
+
const requestTime = this.computeRequestTime(request);
|
|
948
|
+
console.info(
|
|
949
|
+
`[${time.stamp()} :: ${requestID}] (400 Bad Request) Could not handle POST ${request.path}${requestTime}`
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
response.status(400).end();
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
if (this.debugAllows("info")) {
|
|
956
|
+
const requestTime = this.computeRequestTime(request);
|
|
957
|
+
console.info(
|
|
958
|
+
`[${time.stamp()} :: ${requestID}] (200 OK) Handled POST ${request.path}${requestTime}`
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
const elementName = elementMatch.name;
|
|
962
|
+
const linksTo = [];
|
|
963
|
+
const element = {
|
|
964
|
+
url: elementURL,
|
|
965
|
+
name: elementName,
|
|
966
|
+
json: {
|
|
967
|
+
elements: [
|
|
968
|
+
{
|
|
969
|
+
name: elementName
|
|
970
|
+
}
|
|
971
|
+
]
|
|
972
|
+
},
|
|
973
|
+
linksTo
|
|
974
|
+
};
|
|
975
|
+
response.json({
|
|
976
|
+
element
|
|
977
|
+
});
|
|
978
|
+
} catch (error) {
|
|
979
|
+
if (this.debugAllows("error")) {
|
|
980
|
+
const requestTime = this.computeRequestTime(request);
|
|
981
|
+
console.error(
|
|
982
|
+
`[${time.stamp()} :: ${requestID}] (500 Server Error) Could not handle POST ${request.path}${requestTime}`,
|
|
983
|
+
error
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
response.status(500).send(SERVER_ERROR_TEMPLATE);
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
ignoreGetRequest(path4) {
|
|
991
|
+
for (const ignore of this.options.ignore) {
|
|
992
|
+
const normalizedIgnore = ignore.endsWith("/") && ignore.length > 1 ? ignore.slice(0, ignore.length - 1) : ignore;
|
|
993
|
+
if (path4 === normalizedIgnore) {
|
|
994
|
+
return true;
|
|
995
|
+
}
|
|
996
|
+
if (normalizedIgnore.endsWith("/*")) {
|
|
997
|
+
const curatedIgnore = normalizedIgnore.replace("/*", "");
|
|
998
|
+
if (path4.startsWith(curatedIgnore)) {
|
|
999
|
+
return true;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
return false;
|
|
1004
|
+
}
|
|
1005
|
+
resolveMatchingPath(preserveResult, path4) {
|
|
1006
|
+
const redirect = preserveResult ? preserveResult.redirect : "";
|
|
1007
|
+
const externalRedirect = !!redirect?.startsWith("http");
|
|
1008
|
+
const matchingPath = redirect || path4;
|
|
1009
|
+
return {
|
|
1010
|
+
externalRedirect,
|
|
1011
|
+
matchingPath
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
async resolvePreserve(request, response) {
|
|
1015
|
+
const catchAll = this.preserves.find(
|
|
1016
|
+
(preserve) => preserve.serve === CATCH_ALL_ROUTE
|
|
1017
|
+
);
|
|
1018
|
+
const notFound = this.preserves.find(
|
|
1019
|
+
(preserve) => preserve.serve === NOT_FOUND_ROUTE
|
|
1020
|
+
);
|
|
1021
|
+
const isoMatch = this.isoMatcher.match(
|
|
1022
|
+
request.originalUrl,
|
|
1023
|
+
"route"
|
|
1024
|
+
);
|
|
1025
|
+
let preserveOnServe;
|
|
1026
|
+
let preserveAfterServe;
|
|
1027
|
+
let preserveOnError;
|
|
1028
|
+
if (isoMatch || catchAll || notFound) {
|
|
1029
|
+
const preserve = catchAll ? catchAll : notFound && !isoMatch ? notFound : this.preserves.find(
|
|
1030
|
+
(preserve2) => preserve2.serve === isoMatch?.data.value
|
|
1031
|
+
);
|
|
1032
|
+
if (preserve) {
|
|
1033
|
+
preserveOnServe = preserve.onServe;
|
|
1034
|
+
preserveAfterServe = preserve.afterServe;
|
|
1035
|
+
preserveOnError = preserve.onError;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
let preserveResult;
|
|
1039
|
+
if (preserveOnServe) {
|
|
1040
|
+
const transmission = {
|
|
1041
|
+
context: {
|
|
1042
|
+
route: request.originalUrl,
|
|
1043
|
+
match: isoMatch
|
|
1044
|
+
},
|
|
1045
|
+
request,
|
|
1046
|
+
response
|
|
1047
|
+
};
|
|
1048
|
+
try {
|
|
1049
|
+
preserveResult = await preserveOnServe(transmission);
|
|
1050
|
+
if (preserveResult) {
|
|
1051
|
+
if (preserveResult.responded) {
|
|
1052
|
+
return {
|
|
1053
|
+
preserveResponded: true,
|
|
1054
|
+
preserveResult,
|
|
1055
|
+
preserveAfterServe
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
} catch (error) {
|
|
1060
|
+
if (preserveOnError) {
|
|
1061
|
+
const onErrorResponse = await preserveOnError(
|
|
1062
|
+
error,
|
|
1063
|
+
transmission
|
|
1064
|
+
);
|
|
1065
|
+
if (onErrorResponse) {
|
|
1066
|
+
if (onErrorResponse.responded) {
|
|
1067
|
+
return {
|
|
1068
|
+
preserveResponded: true,
|
|
1069
|
+
preserveResult,
|
|
1070
|
+
preserveAfterServe
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
if (!onErrorResponse.depreserve) {
|
|
1074
|
+
return {
|
|
1075
|
+
preserveResponded: false,
|
|
1076
|
+
preserveResult,
|
|
1077
|
+
preserveAfterServe
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
return {
|
|
1085
|
+
preserveResponded: false,
|
|
1086
|
+
preserveResult,
|
|
1087
|
+
preserveAfterServe
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
async resolvePreserveAfterServe(preserveAfterServe, request, response) {
|
|
1091
|
+
if (preserveAfterServe) {
|
|
1092
|
+
const isoMatch = this.isoMatcher.match(
|
|
1093
|
+
request.originalUrl,
|
|
1094
|
+
"route"
|
|
1095
|
+
);
|
|
1096
|
+
const transmission = {
|
|
1097
|
+
context: {
|
|
1098
|
+
route: request.originalUrl,
|
|
1099
|
+
match: isoMatch
|
|
1100
|
+
},
|
|
1101
|
+
request,
|
|
1102
|
+
response
|
|
1103
|
+
};
|
|
1104
|
+
await preserveAfterServe(transmission);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
async handleGateway(path4, request, preserveResult) {
|
|
1108
|
+
const {
|
|
1109
|
+
gatewayEndpoint
|
|
1110
|
+
} = this.options;
|
|
1111
|
+
if (path4 !== gatewayEndpoint) {
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
const gatewayRoute = {
|
|
1115
|
+
path: {
|
|
1116
|
+
value: gatewayEndpoint
|
|
1117
|
+
},
|
|
1118
|
+
pathname: gatewayEndpoint,
|
|
1119
|
+
parameters: {},
|
|
1120
|
+
query: {
|
|
1121
|
+
__gatewayQuery: request.originalUrl
|
|
1122
|
+
},
|
|
1123
|
+
fragments: {
|
|
1124
|
+
texts: [],
|
|
1125
|
+
elements: []
|
|
1126
|
+
},
|
|
1127
|
+
route: gatewayEndpoint
|
|
1128
|
+
};
|
|
1129
|
+
return "";
|
|
1130
|
+
}
|
|
1131
|
+
async renderApplication(isoMatch, preserveResult, matchedPlane) {
|
|
1132
|
+
const globals = preserveResult?.globals;
|
|
1133
|
+
const mergedHtmlLanguage = preserveResult?.template?.htmlLanguage || this.template?.htmlLanguage;
|
|
1134
|
+
const pluridMetastate = await serverComputeMetastate(
|
|
1135
|
+
isoMatch,
|
|
1136
|
+
this.routes,
|
|
1137
|
+
globals,
|
|
1138
|
+
this.options.hostname
|
|
1139
|
+
);
|
|
1140
|
+
const {
|
|
1141
|
+
content,
|
|
1142
|
+
styles
|
|
1143
|
+
} = await this.getContentAndStyles(
|
|
1144
|
+
isoMatch,
|
|
1145
|
+
pluridMetastate,
|
|
1146
|
+
preserveResult,
|
|
1147
|
+
matchedPlane
|
|
1148
|
+
);
|
|
1149
|
+
const stringedStyles = this.styles.reduce(
|
|
1150
|
+
(accumulator, style) => accumulator + style,
|
|
1151
|
+
""
|
|
1152
|
+
);
|
|
1153
|
+
const preserveStyles = preserveResult?.template?.styles?.join(" ") || "";
|
|
1154
|
+
const mergedStyles = styles + stringedStyles + preserveStyles;
|
|
1155
|
+
const {
|
|
1156
|
+
helmet
|
|
1157
|
+
} = this.helmet;
|
|
1158
|
+
const head = helmet ? `
|
|
1159
|
+
${helmet.meta.toString()}
|
|
1160
|
+
${helmet.title.toString()}
|
|
1161
|
+
${helmet.base.toString()}
|
|
1162
|
+
${helmet.link.toString()}
|
|
1163
|
+
${helmet.style.toString()}
|
|
1164
|
+
${helmet.noscript.toString()}
|
|
1165
|
+
${helmet.script.toString()}
|
|
1166
|
+
` : "";
|
|
1167
|
+
const htmlAttributes = {
|
|
1168
|
+
...this.template?.htmlAttributes,
|
|
1169
|
+
...helmet?.htmlAttributes.toComponent()
|
|
1170
|
+
};
|
|
1171
|
+
const mergedHtmlAttributes = recordToString(htmlAttributes) + (preserveResult?.template?.htmlAttributes || "");
|
|
1172
|
+
const bodyAttributes = helmet?.bodyAttributes.toString() || "";
|
|
1173
|
+
const preserveBodyAttributes = preserveResult?.template?.bodyAttributes || "";
|
|
1174
|
+
const mergedBodyAttributes = bodyAttributes + preserveBodyAttributes;
|
|
1175
|
+
const headScripts = this.template?.headScripts || [];
|
|
1176
|
+
const mergedHeadScripts = [
|
|
1177
|
+
...headScripts,
|
|
1178
|
+
...preserveResult?.template?.headScripts || []
|
|
1179
|
+
];
|
|
1180
|
+
const bodyScripts = this.template?.bodyScripts || [];
|
|
1181
|
+
const mergedBodyScripts = [
|
|
1182
|
+
...bodyScripts,
|
|
1183
|
+
...preserveResult?.template?.bodyScripts || []
|
|
1184
|
+
];
|
|
1185
|
+
const renderer = new Renderer_default({
|
|
1186
|
+
htmlLanguage: mergedHtmlLanguage,
|
|
1187
|
+
head,
|
|
1188
|
+
htmlAttributes: mergedHtmlAttributes,
|
|
1189
|
+
bodyAttributes: mergedBodyAttributes,
|
|
1190
|
+
defaultStyle: this.template?.defaultStyle,
|
|
1191
|
+
styles: mergedStyles,
|
|
1192
|
+
headScripts: mergedHeadScripts,
|
|
1193
|
+
bodyScripts: mergedBodyScripts,
|
|
1194
|
+
vendorScriptSource: this.template?.vendorScriptSource,
|
|
1195
|
+
mainScriptSource: this.template?.mainScriptSource,
|
|
1196
|
+
root: this.template?.root,
|
|
1197
|
+
content,
|
|
1198
|
+
defaultPreloadedPluridMetastate: this.template?.defaultPreloadedPluridMetastate,
|
|
1199
|
+
pluridMetastate: JSON.stringify(pluridMetastate),
|
|
1200
|
+
globals,
|
|
1201
|
+
minify: this.template?.minify
|
|
1202
|
+
});
|
|
1203
|
+
return renderer;
|
|
1204
|
+
}
|
|
1205
|
+
async getContentAndStyles(isoMatch, pluridMetastate, preserveResult, matchedPlane) {
|
|
1206
|
+
const stylesheet = new ServerStyleSheet();
|
|
1207
|
+
let content = "";
|
|
1208
|
+
let styles = "";
|
|
1209
|
+
try {
|
|
1210
|
+
const gateway = false;
|
|
1211
|
+
const gatewayQuery = "";
|
|
1212
|
+
const {
|
|
1213
|
+
gatewayEndpoint
|
|
1214
|
+
} = this.options;
|
|
1215
|
+
const contentHandler = new ContentGenerator_default({
|
|
1216
|
+
services: this.services,
|
|
1217
|
+
stylesheet,
|
|
1218
|
+
exterior: this.exterior,
|
|
1219
|
+
shell: this.shell,
|
|
1220
|
+
routerProperties: this.routerProperties,
|
|
1221
|
+
helmet: this.helmet,
|
|
1222
|
+
routes: this.routes,
|
|
1223
|
+
planes: this.planes,
|
|
1224
|
+
pluridMetastate,
|
|
1225
|
+
gateway,
|
|
1226
|
+
gatewayEndpoint,
|
|
1227
|
+
gatewayQuery,
|
|
1228
|
+
preserveResult,
|
|
1229
|
+
pathname: isoMatch.match.value,
|
|
1230
|
+
hostname: this.options.hostname,
|
|
1231
|
+
matchedPlane: isoMatch.kind === "RoutePlane" ? {
|
|
1232
|
+
value: isoMatch.match.value
|
|
1233
|
+
} : void 0
|
|
1234
|
+
});
|
|
1235
|
+
content = await contentHandler.render();
|
|
1236
|
+
styles = stylesheet.getStyleTags();
|
|
1237
|
+
} catch (error) {
|
|
1238
|
+
if (this.options.debug !== "none" && !this.options.quiet) {
|
|
1239
|
+
const errorText = `${this.options.serverName} Error: Something went wrong in getContentAndStyles().`;
|
|
1240
|
+
if (this.debugAllows("error")) {
|
|
1241
|
+
console.error(
|
|
1242
|
+
errorText,
|
|
1243
|
+
error
|
|
1244
|
+
);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return {
|
|
1248
|
+
content: "",
|
|
1249
|
+
styles: ""
|
|
1250
|
+
};
|
|
1251
|
+
} finally {
|
|
1252
|
+
stylesheet.seal();
|
|
1253
|
+
}
|
|
1254
|
+
return {
|
|
1255
|
+
content,
|
|
1256
|
+
styles
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
computeRequestTime(request) {
|
|
1260
|
+
const requestTime = request.requestTime;
|
|
1261
|
+
if (!requestTime) {
|
|
1262
|
+
return "";
|
|
1263
|
+
}
|
|
1264
|
+
const now = Date.now();
|
|
1265
|
+
const difference = now - requestTime;
|
|
1266
|
+
return ` in ${difference} ms`;
|
|
1267
|
+
}
|
|
1268
|
+
handleOptions(partialOptions) {
|
|
1269
|
+
const options = {
|
|
1270
|
+
serverName: partialOptions?.serverName || DEFAULT_SERVER_OPTIONS.SERVER_NAME,
|
|
1271
|
+
hostname: partialOptions?.hostname || DEFAULT_SERVER_OPTIONS.HOSTNAME,
|
|
1272
|
+
quiet: partialOptions?.quiet || DEFAULT_SERVER_OPTIONS.QUIET,
|
|
1273
|
+
debug: partialOptions?.debug ? partialOptions?.debug : environment.production ? "error" : "info",
|
|
1274
|
+
compression: partialOptions?.compression ?? DEFAULT_SERVER_OPTIONS.COMPRESSION,
|
|
1275
|
+
open: partialOptions?.open ?? DEFAULT_SERVER_OPTIONS.OPEN,
|
|
1276
|
+
buildDirectory: partialOptions?.buildDirectory || DEFAULT_SERVER_OPTIONS.BUILD_DIRECTORY,
|
|
1277
|
+
assetsDirectory: partialOptions?.assetsDirectory || DEFAULT_SERVER_OPTIONS.ASSETS_DIRECTORY,
|
|
1278
|
+
gatewayEndpoint: partialOptions?.gatewayEndpoint || DEFAULT_SERVER_OPTIONS.GATEWAY,
|
|
1279
|
+
staticCache: partialOptions?.staticCache || 0,
|
|
1280
|
+
ignore: partialOptions?.ignore || [],
|
|
1281
|
+
stillsDirectory: partialOptions?.stillsDirectory || DEFAULT_SERVER_OPTIONS.STILLS_DIRECTORY,
|
|
1282
|
+
stiller: partialOptions?.stiller || defaultStillerOptions,
|
|
1283
|
+
attachSignalHandlers: partialOptions?.attachSignalHandlers ?? true
|
|
1284
|
+
};
|
|
1285
|
+
return options;
|
|
1286
|
+
}
|
|
1287
|
+
configureServer() {
|
|
1288
|
+
const clientPath = path2.join(this.options.buildDirectory, "./client");
|
|
1289
|
+
this.serverApplication.disable("x-powered-by");
|
|
1290
|
+
this.serverApplication.use(
|
|
1291
|
+
(request, _, next) => {
|
|
1292
|
+
const requestID = uuid.generate();
|
|
1293
|
+
request.requestID = requestID;
|
|
1294
|
+
const requestTime = Date.now();
|
|
1295
|
+
request.requestTime = requestTime;
|
|
1296
|
+
next();
|
|
1297
|
+
}
|
|
1298
|
+
);
|
|
1299
|
+
if (this.options.compression) {
|
|
1300
|
+
this.serverApplication.use(
|
|
1301
|
+
compression()
|
|
1302
|
+
// @types/compression targets Express 4's handler type
|
|
1303
|
+
);
|
|
1304
|
+
this.serverApplication.get(
|
|
1305
|
+
"/vendor.js",
|
|
1306
|
+
(request, response, next) => {
|
|
1307
|
+
response.setHeader(
|
|
1308
|
+
"Content-Type",
|
|
1309
|
+
"application/javascript"
|
|
1310
|
+
);
|
|
1311
|
+
const vendorBrotliExists = fs2.existsSync(
|
|
1312
|
+
path2.join(clientPath, "vendor.js.br")
|
|
1313
|
+
);
|
|
1314
|
+
const acceptEncoding = request.header("Accept-Encoding");
|
|
1315
|
+
if (acceptEncoding?.includes("br") && vendorBrotliExists) {
|
|
1316
|
+
request.url += ".br";
|
|
1317
|
+
response.set("Content-Encoding", "br");
|
|
1318
|
+
next();
|
|
1319
|
+
return;
|
|
1320
|
+
}
|
|
1321
|
+
next();
|
|
1322
|
+
}
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
this.serverApplication.use(
|
|
1326
|
+
express.static(clientPath, {
|
|
1327
|
+
maxAge: this.options.staticCache
|
|
1328
|
+
})
|
|
1329
|
+
);
|
|
1330
|
+
this.loadMiddleware();
|
|
1331
|
+
}
|
|
1332
|
+
loadMiddleware() {
|
|
1333
|
+
for (const middleware of this.middleware) {
|
|
1334
|
+
this.serverApplication.use(
|
|
1335
|
+
(req, res, next) => middleware(req, res, next)
|
|
1336
|
+
);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
open(serverlink) {
|
|
1340
|
+
try {
|
|
1341
|
+
const processDoNotOpen = process.env.PLURID_OPEN === "false" ? true : false;
|
|
1342
|
+
if (processDoNotOpen) {
|
|
1343
|
+
return;
|
|
1344
|
+
}
|
|
1345
|
+
if (this.options.open) {
|
|
1346
|
+
open(serverlink);
|
|
1347
|
+
}
|
|
1348
|
+
} catch (error) {
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
debugAllows(level) {
|
|
1353
|
+
if (this.options.quiet) {
|
|
1354
|
+
return false;
|
|
1355
|
+
}
|
|
1356
|
+
if (this.options.debug === "none") {
|
|
1357
|
+
return false;
|
|
1358
|
+
}
|
|
1359
|
+
switch (level) {
|
|
1360
|
+
case "error":
|
|
1361
|
+
return true;
|
|
1362
|
+
case "warn":
|
|
1363
|
+
if (this.options.debug === "error") {
|
|
1364
|
+
return false;
|
|
1365
|
+
}
|
|
1366
|
+
return true;
|
|
1367
|
+
case "info":
|
|
1368
|
+
if (this.options.debug === "error" || this.options.debug === "warn") {
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
return true;
|
|
1372
|
+
default:
|
|
1373
|
+
return false;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
var Server_default = PluridServer;
|
|
1378
|
+
|
|
1379
|
+
// source/objects/LiveServer/index.ts
|
|
1380
|
+
import http from "http";
|
|
1381
|
+
import express2 from "express";
|
|
1382
|
+
var LiveServer = class {
|
|
1383
|
+
options;
|
|
1384
|
+
expressServer;
|
|
1385
|
+
httpServer;
|
|
1386
|
+
sockets = [];
|
|
1387
|
+
constructor(options) {
|
|
1388
|
+
this.options = this.resolveOptions(options);
|
|
1389
|
+
this.expressServer = express2();
|
|
1390
|
+
this.setupExpressServer();
|
|
1391
|
+
this.httpServer = http.createServer(this.expressServer);
|
|
1392
|
+
this.setupHttpServer();
|
|
1393
|
+
}
|
|
1394
|
+
resolveOptions = (options) => {
|
|
1395
|
+
const defaultServerPath = "./source/server/index.ts";
|
|
1396
|
+
const resolvedOptions = {
|
|
1397
|
+
server: options?.server || defaultServerPath
|
|
1398
|
+
};
|
|
1399
|
+
return resolvedOptions;
|
|
1400
|
+
};
|
|
1401
|
+
setupExpressServer() {
|
|
1402
|
+
}
|
|
1403
|
+
setupHttpServer() {
|
|
1404
|
+
this.httpServer.on("connection", (socket) => {
|
|
1405
|
+
this.sockets.push(socket);
|
|
1406
|
+
socket.once("close", () => {
|
|
1407
|
+
this.sockets.splice(this.sockets.indexOf(socket), 1);
|
|
1408
|
+
});
|
|
1409
|
+
});
|
|
1410
|
+
this.httpServer.on("error", (error) => {
|
|
1411
|
+
throw error;
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
start() {
|
|
1415
|
+
throw new Error(
|
|
1416
|
+
"PluridLiveServer is not implemented yet. Use `PluridServer` (production) or a bundler dev server (tsx/Vite) for live reload."
|
|
1417
|
+
);
|
|
1418
|
+
}
|
|
1419
|
+
};
|
|
1420
|
+
var LiveServer_default = LiveServer;
|
|
1421
|
+
|
|
1422
|
+
// source/objects/StillsGenerator/index.ts
|
|
1423
|
+
import path3 from "path";
|
|
1424
|
+
import {
|
|
1425
|
+
promises as fs3
|
|
1426
|
+
} from "fs";
|
|
1427
|
+
import {
|
|
1428
|
+
fork
|
|
1429
|
+
} from "child_process";
|
|
1430
|
+
import detectPort from "detect-port";
|
|
1431
|
+
import {
|
|
1432
|
+
uuid as uuid2
|
|
1433
|
+
} from "@plurid/plurid-functions";
|
|
1434
|
+
|
|
1435
|
+
// source/objects/Stiller/index.ts
|
|
1436
|
+
var replacePluridResolution = (html) => {
|
|
1437
|
+
const normalResolution = "width: 1366px; height: 768px;";
|
|
1438
|
+
const zeroResolution = "width: 0px; height: 0px;";
|
|
1439
|
+
return html.replace(normalResolution, zeroResolution);
|
|
1440
|
+
};
|
|
1441
|
+
var isCurrentUserRoot = () => {
|
|
1442
|
+
return typeof process.getuid === "function" && process.getuid() === 0;
|
|
1443
|
+
};
|
|
1444
|
+
var render = async (browser, host, route, configuration) => {
|
|
1445
|
+
const start = Date.now();
|
|
1446
|
+
const page = await browser.newPage();
|
|
1447
|
+
try {
|
|
1448
|
+
const url = host + route;
|
|
1449
|
+
await page.goto(
|
|
1450
|
+
url,
|
|
1451
|
+
{
|
|
1452
|
+
waitUntil: configuration.waitUntil,
|
|
1453
|
+
timeout: configuration.timeout
|
|
1454
|
+
}
|
|
1455
|
+
);
|
|
1456
|
+
const pageContent = await page.content();
|
|
1457
|
+
const html = replacePluridResolution(pageContent);
|
|
1458
|
+
const stilltime = Date.now() - start;
|
|
1459
|
+
console.info(` Stilled '${route}' in ${(stilltime / 1e3).toFixed(2)} seconds.`);
|
|
1460
|
+
return {
|
|
1461
|
+
route,
|
|
1462
|
+
html,
|
|
1463
|
+
stilltime
|
|
1464
|
+
};
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1467
|
+
throw new Error(`Could not still '${route}': ${reason}`, { cause: error });
|
|
1468
|
+
} finally {
|
|
1469
|
+
await page.close();
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1472
|
+
var Stiller = class {
|
|
1473
|
+
puppeteer = null;
|
|
1474
|
+
host;
|
|
1475
|
+
routes;
|
|
1476
|
+
configuration;
|
|
1477
|
+
constructor(options) {
|
|
1478
|
+
try {
|
|
1479
|
+
this.puppeteer = __require("puppeteer");
|
|
1480
|
+
} catch (_error) {
|
|
1481
|
+
this.puppeteer = null;
|
|
1482
|
+
}
|
|
1483
|
+
const {
|
|
1484
|
+
host,
|
|
1485
|
+
routes,
|
|
1486
|
+
configuration
|
|
1487
|
+
} = options;
|
|
1488
|
+
this.host = host;
|
|
1489
|
+
this.routes = routes;
|
|
1490
|
+
this.configuration = configuration;
|
|
1491
|
+
}
|
|
1492
|
+
async *still() {
|
|
1493
|
+
if (!this.puppeteer) {
|
|
1494
|
+
throw new Error(
|
|
1495
|
+
"Plurid Stiller: the optional 'puppeteer' dependency is not installed. Install it to generate stills (npm install puppeteer)."
|
|
1496
|
+
);
|
|
1497
|
+
}
|
|
1498
|
+
const browser = await this.puppeteer.launch({
|
|
1499
|
+
defaultViewport: {
|
|
1500
|
+
width: 1366,
|
|
1501
|
+
height: 768
|
|
1502
|
+
},
|
|
1503
|
+
headless: true,
|
|
1504
|
+
args: isCurrentUserRoot() ? ["--no-sandbox"] : void 0
|
|
1505
|
+
});
|
|
1506
|
+
try {
|
|
1507
|
+
for (const route of this.routes) {
|
|
1508
|
+
yield await render(
|
|
1509
|
+
browser,
|
|
1510
|
+
this.host,
|
|
1511
|
+
route,
|
|
1512
|
+
this.configuration
|
|
1513
|
+
);
|
|
1514
|
+
}
|
|
1515
|
+
} finally {
|
|
1516
|
+
await browser.close();
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
var Stiller_default = Stiller;
|
|
1521
|
+
|
|
1522
|
+
// source/objects/StillsGenerator/index.ts
|
|
1523
|
+
var StillsGenerator = class {
|
|
1524
|
+
options;
|
|
1525
|
+
constructor(options) {
|
|
1526
|
+
this.options = this.resolveOptions(options);
|
|
1527
|
+
}
|
|
1528
|
+
resolveOptions(options) {
|
|
1529
|
+
const stillsGeneratorOptions = {
|
|
1530
|
+
server: options?.server ?? "./build/server.js",
|
|
1531
|
+
build: options?.build ?? "./build/"
|
|
1532
|
+
};
|
|
1533
|
+
return stillsGeneratorOptions;
|
|
1534
|
+
}
|
|
1535
|
+
async initialize() {
|
|
1536
|
+
const serverPath = path3.join(process.cwd(), this.options.server);
|
|
1537
|
+
const buildPath = path3.join(process.cwd(), this.options.build);
|
|
1538
|
+
let serverModule;
|
|
1539
|
+
try {
|
|
1540
|
+
serverModule = __require(serverPath);
|
|
1541
|
+
} catch (error) {
|
|
1542
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1543
|
+
throw new Error(
|
|
1544
|
+
`Plurid StillsGenerator: could not load the built server at '${serverPath}'. Build the server first so the generator can read its routes. (${reason})`,
|
|
1545
|
+
{ cause: error }
|
|
1546
|
+
);
|
|
1547
|
+
}
|
|
1548
|
+
const pluridServer = serverModule?.default ?? serverModule;
|
|
1549
|
+
const serverInformation = Server_default.analysis(pluridServer);
|
|
1550
|
+
const stillerOptions = serverInformation.options.stiller;
|
|
1551
|
+
const serverPort = await detectPort(9900) + "";
|
|
1552
|
+
const child = fork(serverPath, [], {
|
|
1553
|
+
stdio: "pipe",
|
|
1554
|
+
env: {
|
|
1555
|
+
PORT: serverPort,
|
|
1556
|
+
PLURID_OPEN: "false"
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
try {
|
|
1560
|
+
const stillRoutes = [];
|
|
1561
|
+
for (const route of serverInformation.routes) {
|
|
1562
|
+
if (route.value.includes("/:")) {
|
|
1563
|
+
continue;
|
|
1564
|
+
}
|
|
1565
|
+
if (stillerOptions.ignore.includes(route.value)) {
|
|
1566
|
+
continue;
|
|
1567
|
+
}
|
|
1568
|
+
stillRoutes.push(route);
|
|
1569
|
+
}
|
|
1570
|
+
const stillRoutesPaths = stillRoutes.map((stillRoute) => stillRoute.value);
|
|
1571
|
+
console.info("\n Parsed the following still routes:");
|
|
1572
|
+
for (const stillRoutePath of stillRoutesPaths) {
|
|
1573
|
+
console.info(` ${stillRoutePath}`);
|
|
1574
|
+
}
|
|
1575
|
+
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
1576
|
+
const startTime = Date.now();
|
|
1577
|
+
const estimatedDuration = 3 * serverInformation.routes.length;
|
|
1578
|
+
console.info(`
|
|
1579
|
+
Starting to generate stills... (this may take about ${estimatedDuration} seconds)
|
|
1580
|
+
`);
|
|
1581
|
+
const stiller = new Stiller_default({
|
|
1582
|
+
host: "http://localhost:" + serverPort,
|
|
1583
|
+
routes: [
|
|
1584
|
+
...stillRoutesPaths
|
|
1585
|
+
],
|
|
1586
|
+
configuration: {
|
|
1587
|
+
waitUntil: stillerOptions.waitUntil,
|
|
1588
|
+
timeout: stillerOptions.timeout
|
|
1589
|
+
}
|
|
1590
|
+
});
|
|
1591
|
+
const sequence = stiller.still();
|
|
1592
|
+
const stills = [];
|
|
1593
|
+
let next;
|
|
1594
|
+
while (!(next = await sequence.next()).done) {
|
|
1595
|
+
stills.push(next.value);
|
|
1596
|
+
}
|
|
1597
|
+
const endTime = Date.now();
|
|
1598
|
+
const duration = (endTime - startTime) / 1e3;
|
|
1599
|
+
const plural = stills.length === 1 ? "" : "s";
|
|
1600
|
+
console.info(`
|
|
1601
|
+
Generated ${stills.length} still${plural} in ${duration.toFixed(2)} seconds.
|
|
1602
|
+
`);
|
|
1603
|
+
const stillsPath = path3.join(buildPath, "./stills");
|
|
1604
|
+
await fs3.mkdir(
|
|
1605
|
+
stillsPath,
|
|
1606
|
+
{
|
|
1607
|
+
recursive: true
|
|
1608
|
+
}
|
|
1609
|
+
);
|
|
1610
|
+
const metadataFile = [];
|
|
1611
|
+
for (const still of stills) {
|
|
1612
|
+
if (!still) {
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
const stillName = uuid2.generate() + ".json";
|
|
1616
|
+
const metadataItem = {
|
|
1617
|
+
route: still.route,
|
|
1618
|
+
name: stillName
|
|
1619
|
+
};
|
|
1620
|
+
metadataFile.push(metadataItem);
|
|
1621
|
+
const stillJSON = JSON.stringify(still, null, 4);
|
|
1622
|
+
const stillFile = path3.join(stillsPath, stillName);
|
|
1623
|
+
await fs3.writeFile(stillFile, stillJSON);
|
|
1624
|
+
}
|
|
1625
|
+
const metadataFilePath = path3.join(stillsPath, "metadata.json");
|
|
1626
|
+
const metadataJSON = JSON.stringify(metadataFile, null, 4);
|
|
1627
|
+
await fs3.writeFile(metadataFilePath, metadataJSON);
|
|
1628
|
+
} finally {
|
|
1629
|
+
child.kill("SIGTERM");
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
var StillsGenerator_default = StillsGenerator;
|
|
1634
|
+
|
|
1635
|
+
// source/index.ts
|
|
1636
|
+
var index_default = Server_default;
|
|
1637
|
+
export {
|
|
1638
|
+
LiveServer_default as PluridLiveServer,
|
|
1639
|
+
StillsGenerator_default as PluridStillsGenerator,
|
|
1640
|
+
index_default as default
|
|
1641
|
+
};
|
|
1642
|
+
//# sourceMappingURL=index.mjs.map
|