orator 6.0.4 → 6.1.1
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/docs/_cover.md +1 -1
- package/docs/_version.json +7 -0
- package/docs/architecture.md +3 -3
- package/docs/css/docuserve.css +277 -23
- package/docs/index.html +2 -2
- package/docs/lifecycle-hooks.md +2 -2
- package/docs/retold-catalog.json +20 -1
- package/docs/retold-keyword-index.json +19 -0
- package/package.json +9 -7
- package/source/Orator.js +47 -3
- package/test/Orator_static_serving_tests.js +2 -1
package/docs/_cover.md
CHANGED
package/docs/architecture.md
CHANGED
|
@@ -84,9 +84,9 @@ _Fable.Orator.invoke('GET', '/api/data', {},
|
|
|
84
84
|
The service server base class uses a template method pattern for route registration. The base class validates inputs, and derived classes implement the `do*` methods with actual behavior:
|
|
85
85
|
|
|
86
86
|
```
|
|
87
|
-
Base: get(pRoute, ...)
|
|
88
|
-
└── Restify: doGet(pRoute, ...)
|
|
89
|
-
└── IPC: doGet(pRoute, ...)
|
|
87
|
+
Base: get(pRoute, ...) -> validates pRoute -> calls doGet(pRoute, ...)
|
|
88
|
+
└── Restify: doGet(pRoute, ...) -> this.server.get(pRoute, ...)
|
|
89
|
+
└── IPC: doGet(pRoute, ...) -> this.addRouteProcessor('GET', pRoute, ...)
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
This pattern allows derived classes to focus on implementation without duplicating validation logic.
|
package/docs/css/docuserve.css
CHANGED
|
@@ -1,73 +1,327 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
|
-
Pict Docuserve - Base Styles
|
|
2
|
+
Pict Docuserve - Base Styles & Theme Variables
|
|
3
3
|
============================================================================ */
|
|
4
4
|
|
|
5
|
-
/*
|
|
6
|
-
|
|
5
|
+
/* ----------------------------------------------------------------------------
|
|
6
|
+
Theme variables — light defaults on :root.
|
|
7
|
+
Dark mode applies when either:
|
|
8
|
+
(a) the user explicitly selected dark via <html data-theme="dark">
|
|
9
|
+
(b) the user hasn't chosen anything AND the system prefers dark
|
|
10
|
+
An explicit <html data-theme="light"> pins the light palette regardless.
|
|
11
|
+
---------------------------------------------------------------------------- */
|
|
12
|
+
|
|
13
|
+
:root
|
|
14
|
+
{
|
|
15
|
+
/* Surfaces */
|
|
16
|
+
--docuserve-bg: #FDFBF7;
|
|
17
|
+
--docuserve-bg-elevated: #FFFFFF;
|
|
18
|
+
--docuserve-border: #DDD6CA;
|
|
19
|
+
--docuserve-border-soft: #EAE3D8;
|
|
20
|
+
|
|
21
|
+
/* Text */
|
|
22
|
+
--docuserve-text: #2A241E;
|
|
23
|
+
--docuserve-text-strong: #3D3229;
|
|
24
|
+
--docuserve-text-muted: #5E5549;
|
|
25
|
+
--docuserve-text-dim: #8A7F72;
|
|
26
|
+
|
|
27
|
+
/* Accent / links */
|
|
28
|
+
--docuserve-accent: #2E7D74;
|
|
29
|
+
--docuserve-accent-hover: #236660;
|
|
30
|
+
|
|
31
|
+
/* Top bar */
|
|
32
|
+
--docuserve-topbar-bg: #3D3229;
|
|
33
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
34
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
35
|
+
--docuserve-topbar-text-dim: #8A7F72;
|
|
36
|
+
--docuserve-topbar-hover-bg: #524438;
|
|
37
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.06);
|
|
38
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.08);
|
|
39
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
40
|
+
|
|
41
|
+
/* Sidebar */
|
|
42
|
+
--docuserve-sidebar-bg: #FAF7F1;
|
|
43
|
+
--docuserve-sidebar-border: #DDD6CA;
|
|
44
|
+
--docuserve-sidebar-border-soft: #E5DED1;
|
|
45
|
+
--docuserve-sidebar-text: #423D37;
|
|
46
|
+
--docuserve-sidebar-group-title: #3D3229;
|
|
47
|
+
--docuserve-sidebar-module-text: #5E5549;
|
|
48
|
+
--docuserve-sidebar-hover-bg: #EAE3D8;
|
|
49
|
+
--docuserve-sidebar-hover-text: #2E7D74;
|
|
50
|
+
--docuserve-sidebar-active-bg: #E5DED1;
|
|
51
|
+
--docuserve-sidebar-active-text: #2E7D74;
|
|
52
|
+
--docuserve-sidebar-search-bg: #FFFFFF;
|
|
53
|
+
--docuserve-sidebar-search-border: #DDD6CA;
|
|
54
|
+
|
|
55
|
+
/* Inline code */
|
|
56
|
+
--docuserve-inline-code-bg: #F0ECE4;
|
|
57
|
+
--docuserve-inline-code-text: #9E3A50;
|
|
58
|
+
|
|
59
|
+
/* Code block panel */
|
|
60
|
+
--docuserve-code-bg: #F6F3EE;
|
|
61
|
+
--docuserve-code-border: #E5DED1;
|
|
62
|
+
--docuserve-code-gutter-bg: #EFEAE0;
|
|
63
|
+
--docuserve-code-gutter-border: #DDD6CA;
|
|
64
|
+
--docuserve-code-gutter-text: #A59986;
|
|
65
|
+
--docuserve-code-text: #2A241E;
|
|
66
|
+
|
|
67
|
+
/* Syntax tokens — low-chroma dark-on-light palette */
|
|
68
|
+
--docuserve-tok-keyword: #A03472;
|
|
69
|
+
--docuserve-tok-string: #1A6640;
|
|
70
|
+
--docuserve-tok-number: #B25A00;
|
|
71
|
+
--docuserve-tok-comment: #8A7F72;
|
|
72
|
+
--docuserve-tok-operator: #2E7D74;
|
|
73
|
+
--docuserve-tok-punctuation: #2A241E;
|
|
74
|
+
--docuserve-tok-function: #2A5DB0;
|
|
75
|
+
--docuserve-tok-property: #9E3A50;
|
|
76
|
+
--docuserve-tok-tag: #9E3A50;
|
|
77
|
+
--docuserve-tok-attr-name: #B25A00;
|
|
78
|
+
--docuserve-tok-attr-value: #1A6640;
|
|
79
|
+
|
|
80
|
+
/* Tables, blockquotes, mermaid */
|
|
81
|
+
--docuserve-table-header-bg: #F5F0E8;
|
|
82
|
+
--docuserve-table-row-alt-bg: #F9F6F0;
|
|
83
|
+
--docuserve-blockquote-bg: #F7F5F0;
|
|
84
|
+
--docuserve-blockquote-border: #2E7D74;
|
|
85
|
+
--docuserve-blockquote-text: #5E5549;
|
|
86
|
+
--docuserve-mermaid-bg: #FFFFFF;
|
|
87
|
+
|
|
88
|
+
/* Scrollbars */
|
|
89
|
+
--docuserve-scrollbar-track: #F5F0E8;
|
|
90
|
+
--docuserve-scrollbar-thumb: #D4CCBE;
|
|
91
|
+
--docuserve-scrollbar-thumb-hover: #B5AA9A;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@media (prefers-color-scheme: dark)
|
|
95
|
+
{
|
|
96
|
+
:root:not([data-theme="light"])
|
|
97
|
+
{
|
|
98
|
+
--docuserve-bg: #15120F;
|
|
99
|
+
--docuserve-bg-elevated: #1B1814;
|
|
100
|
+
--docuserve-border: #2F2823;
|
|
101
|
+
--docuserve-border-soft: #26211C;
|
|
102
|
+
|
|
103
|
+
--docuserve-text: #E8E0D4;
|
|
104
|
+
--docuserve-text-strong: #F2ECE0;
|
|
105
|
+
--docuserve-text-muted: #B5AA9A;
|
|
106
|
+
--docuserve-text-dim: #7A6F62;
|
|
107
|
+
|
|
108
|
+
--docuserve-accent: #5DB8A8;
|
|
109
|
+
--docuserve-accent-hover: #7FCCB8;
|
|
110
|
+
|
|
111
|
+
--docuserve-topbar-bg: #1A1612;
|
|
112
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
113
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
114
|
+
--docuserve-topbar-text-dim: #7A6F62;
|
|
115
|
+
--docuserve-topbar-hover-bg: #2A241E;
|
|
116
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
|
|
117
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
|
|
118
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
119
|
+
|
|
120
|
+
--docuserve-sidebar-bg: #1B1814;
|
|
121
|
+
--docuserve-sidebar-border: #2F2823;
|
|
122
|
+
--docuserve-sidebar-border-soft: #26211C;
|
|
123
|
+
--docuserve-sidebar-text: #C9C0B3;
|
|
124
|
+
--docuserve-sidebar-group-title: #F2ECE0;
|
|
125
|
+
--docuserve-sidebar-module-text: #B5AA9A;
|
|
126
|
+
--docuserve-sidebar-hover-bg: #2A241E;
|
|
127
|
+
--docuserve-sidebar-hover-text: #7FCCB8;
|
|
128
|
+
--docuserve-sidebar-active-bg: #2F2823;
|
|
129
|
+
--docuserve-sidebar-active-text: #7FCCB8;
|
|
130
|
+
--docuserve-sidebar-search-bg: #26211C;
|
|
131
|
+
--docuserve-sidebar-search-border: #2F2823;
|
|
132
|
+
|
|
133
|
+
--docuserve-inline-code-bg: #2A241E;
|
|
134
|
+
--docuserve-inline-code-text: #E8B07A;
|
|
135
|
+
|
|
136
|
+
--docuserve-code-bg: #1E1A17;
|
|
137
|
+
--docuserve-code-border: #2F2823;
|
|
138
|
+
--docuserve-code-gutter-bg: #17130F;
|
|
139
|
+
--docuserve-code-gutter-border: #2F2823;
|
|
140
|
+
--docuserve-code-gutter-text: #6A6052;
|
|
141
|
+
--docuserve-code-text: #E8E0D4;
|
|
142
|
+
|
|
143
|
+
--docuserve-tok-keyword: #C678DD;
|
|
144
|
+
--docuserve-tok-string: #98C379;
|
|
145
|
+
--docuserve-tok-number: #D19A66;
|
|
146
|
+
--docuserve-tok-comment: #7F848E;
|
|
147
|
+
--docuserve-tok-operator: #56B6C2;
|
|
148
|
+
--docuserve-tok-punctuation: #E8E0D4;
|
|
149
|
+
--docuserve-tok-function: #61AFEF;
|
|
150
|
+
--docuserve-tok-property: #E06C75;
|
|
151
|
+
--docuserve-tok-tag: #E06C75;
|
|
152
|
+
--docuserve-tok-attr-name: #D19A66;
|
|
153
|
+
--docuserve-tok-attr-value: #98C379;
|
|
154
|
+
|
|
155
|
+
--docuserve-table-header-bg: #26211C;
|
|
156
|
+
--docuserve-table-row-alt-bg: #1F1B17;
|
|
157
|
+
--docuserve-blockquote-bg: #1F1B17;
|
|
158
|
+
--docuserve-blockquote-border: #5DB8A8;
|
|
159
|
+
--docuserve-blockquote-text: #C9C0B3;
|
|
160
|
+
--docuserve-mermaid-bg: #E8E0D4;
|
|
161
|
+
|
|
162
|
+
--docuserve-scrollbar-track: #1B1814;
|
|
163
|
+
--docuserve-scrollbar-thumb: #3A322B;
|
|
164
|
+
--docuserve-scrollbar-thumb-hover: #524438;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
:root[data-theme="dark"]
|
|
169
|
+
{
|
|
170
|
+
--docuserve-bg: #15120F;
|
|
171
|
+
--docuserve-bg-elevated: #1B1814;
|
|
172
|
+
--docuserve-border: #2F2823;
|
|
173
|
+
--docuserve-border-soft: #26211C;
|
|
174
|
+
|
|
175
|
+
--docuserve-text: #E8E0D4;
|
|
176
|
+
--docuserve-text-strong: #F2ECE0;
|
|
177
|
+
--docuserve-text-muted: #B5AA9A;
|
|
178
|
+
--docuserve-text-dim: #7A6F62;
|
|
179
|
+
|
|
180
|
+
--docuserve-accent: #5DB8A8;
|
|
181
|
+
--docuserve-accent-hover: #7FCCB8;
|
|
182
|
+
|
|
183
|
+
--docuserve-topbar-bg: #1A1612;
|
|
184
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
185
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
186
|
+
--docuserve-topbar-text-dim: #7A6F62;
|
|
187
|
+
--docuserve-topbar-hover-bg: #2A241E;
|
|
188
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
|
|
189
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
|
|
190
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
191
|
+
|
|
192
|
+
--docuserve-sidebar-bg: #1B1814;
|
|
193
|
+
--docuserve-sidebar-border: #2F2823;
|
|
194
|
+
--docuserve-sidebar-border-soft: #26211C;
|
|
195
|
+
--docuserve-sidebar-text: #C9C0B3;
|
|
196
|
+
--docuserve-sidebar-group-title: #F2ECE0;
|
|
197
|
+
--docuserve-sidebar-module-text: #B5AA9A;
|
|
198
|
+
--docuserve-sidebar-hover-bg: #2A241E;
|
|
199
|
+
--docuserve-sidebar-hover-text: #7FCCB8;
|
|
200
|
+
--docuserve-sidebar-active-bg: #2F2823;
|
|
201
|
+
--docuserve-sidebar-active-text: #7FCCB8;
|
|
202
|
+
--docuserve-sidebar-search-bg: #26211C;
|
|
203
|
+
--docuserve-sidebar-search-border: #2F2823;
|
|
204
|
+
|
|
205
|
+
--docuserve-inline-code-bg: #2A241E;
|
|
206
|
+
--docuserve-inline-code-text: #E8B07A;
|
|
207
|
+
|
|
208
|
+
--docuserve-code-bg: #1E1A17;
|
|
209
|
+
--docuserve-code-border: #2F2823;
|
|
210
|
+
--docuserve-code-gutter-bg: #17130F;
|
|
211
|
+
--docuserve-code-gutter-border: #2F2823;
|
|
212
|
+
--docuserve-code-gutter-text: #6A6052;
|
|
213
|
+
--docuserve-code-text: #E8E0D4;
|
|
214
|
+
|
|
215
|
+
--docuserve-tok-keyword: #C678DD;
|
|
216
|
+
--docuserve-tok-string: #98C379;
|
|
217
|
+
--docuserve-tok-number: #D19A66;
|
|
218
|
+
--docuserve-tok-comment: #7F848E;
|
|
219
|
+
--docuserve-tok-operator: #56B6C2;
|
|
220
|
+
--docuserve-tok-punctuation: #E8E0D4;
|
|
221
|
+
--docuserve-tok-function: #61AFEF;
|
|
222
|
+
--docuserve-tok-property: #E06C75;
|
|
223
|
+
--docuserve-tok-tag: #E06C75;
|
|
224
|
+
--docuserve-tok-attr-name: #D19A66;
|
|
225
|
+
--docuserve-tok-attr-value: #98C379;
|
|
226
|
+
|
|
227
|
+
--docuserve-table-header-bg: #26211C;
|
|
228
|
+
--docuserve-table-row-alt-bg: #1F1B17;
|
|
229
|
+
--docuserve-blockquote-bg: #1F1B17;
|
|
230
|
+
--docuserve-blockquote-border: #5DB8A8;
|
|
231
|
+
--docuserve-blockquote-text: #C9C0B3;
|
|
232
|
+
--docuserve-mermaid-bg: #E8E0D4;
|
|
233
|
+
|
|
234
|
+
--docuserve-scrollbar-track: #1B1814;
|
|
235
|
+
--docuserve-scrollbar-thumb: #3A322B;
|
|
236
|
+
--docuserve-scrollbar-thumb-hover: #524438;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* ----------------------------------------------------------------------------
|
|
240
|
+
Reset and base
|
|
241
|
+
---------------------------------------------------------------------------- */
|
|
242
|
+
|
|
243
|
+
*, *::before, *::after
|
|
244
|
+
{
|
|
7
245
|
box-sizing: border-box;
|
|
8
246
|
}
|
|
9
247
|
|
|
10
|
-
html, body
|
|
248
|
+
html, body
|
|
249
|
+
{
|
|
11
250
|
margin: 0;
|
|
12
251
|
padding: 0;
|
|
13
252
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
14
253
|
font-size: 16px;
|
|
15
254
|
line-height: 1.5;
|
|
16
|
-
color:
|
|
17
|
-
background-color:
|
|
255
|
+
color: var(--docuserve-text);
|
|
256
|
+
background-color: var(--docuserve-bg);
|
|
18
257
|
-webkit-font-smoothing: antialiased;
|
|
19
258
|
-moz-osx-font-smoothing: grayscale;
|
|
259
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
20
260
|
}
|
|
21
261
|
|
|
22
262
|
/* Typography */
|
|
23
|
-
h1, h2, h3, h4, h5, h6
|
|
263
|
+
h1, h2, h3, h4, h5, h6
|
|
264
|
+
{
|
|
24
265
|
margin-top: 0;
|
|
25
266
|
line-height: 1.3;
|
|
267
|
+
color: var(--docuserve-text-strong);
|
|
26
268
|
}
|
|
27
269
|
|
|
28
|
-
a
|
|
29
|
-
|
|
270
|
+
a
|
|
271
|
+
{
|
|
272
|
+
color: var(--docuserve-accent);
|
|
30
273
|
text-decoration: none;
|
|
31
274
|
}
|
|
32
275
|
|
|
33
|
-
a:hover
|
|
34
|
-
|
|
276
|
+
a:hover
|
|
277
|
+
{
|
|
278
|
+
color: var(--docuserve-accent-hover);
|
|
35
279
|
}
|
|
36
280
|
|
|
37
281
|
/* Application container */
|
|
38
|
-
#Docuserve-Application-Container
|
|
282
|
+
#Docuserve-Application-Container
|
|
283
|
+
{
|
|
39
284
|
min-height: 100vh;
|
|
40
285
|
}
|
|
41
286
|
|
|
42
287
|
/* Utility: scrollbar styling */
|
|
43
|
-
::-webkit-scrollbar
|
|
288
|
+
::-webkit-scrollbar
|
|
289
|
+
{
|
|
44
290
|
width: 8px;
|
|
291
|
+
height: 8px;
|
|
45
292
|
}
|
|
46
293
|
|
|
47
|
-
::-webkit-scrollbar-track
|
|
48
|
-
|
|
294
|
+
::-webkit-scrollbar-track
|
|
295
|
+
{
|
|
296
|
+
background: var(--docuserve-scrollbar-track);
|
|
49
297
|
}
|
|
50
298
|
|
|
51
|
-
::-webkit-scrollbar-thumb
|
|
52
|
-
|
|
299
|
+
::-webkit-scrollbar-thumb
|
|
300
|
+
{
|
|
301
|
+
background: var(--docuserve-scrollbar-thumb);
|
|
53
302
|
border-radius: 4px;
|
|
54
303
|
}
|
|
55
304
|
|
|
56
|
-
::-webkit-scrollbar-thumb:hover
|
|
57
|
-
|
|
305
|
+
::-webkit-scrollbar-thumb:hover
|
|
306
|
+
{
|
|
307
|
+
background: var(--docuserve-scrollbar-thumb-hover);
|
|
58
308
|
}
|
|
59
309
|
|
|
60
310
|
/* Responsive adjustments */
|
|
61
|
-
@media (max-width: 768px)
|
|
62
|
-
|
|
311
|
+
@media (max-width: 768px)
|
|
312
|
+
{
|
|
313
|
+
html
|
|
314
|
+
{
|
|
63
315
|
font-size: 14px;
|
|
64
316
|
}
|
|
65
317
|
|
|
66
|
-
#Docuserve-Sidebar-Container
|
|
318
|
+
#Docuserve-Sidebar-Container
|
|
319
|
+
{
|
|
67
320
|
display: none;
|
|
68
321
|
}
|
|
69
322
|
|
|
70
|
-
.docuserve-body
|
|
323
|
+
.docuserve-body
|
|
324
|
+
{
|
|
71
325
|
flex-direction: column;
|
|
72
326
|
}
|
|
73
327
|
}
|
package/docs/index.html
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
7
|
-
<meta name="description" content="Documentation
|
|
7
|
+
<meta name="description" content="Orator v6.0.4 Documentation — Unopinionated API http server abstraction - REST or IPC">
|
|
8
8
|
|
|
9
|
-
<title>Documentation</title>
|
|
9
|
+
<title>Orator v6.0.4 Documentation</title>
|
|
10
10
|
|
|
11
11
|
<!-- Application Stylesheet -->
|
|
12
12
|
<link href="css/docuserve.css" rel="stylesheet">
|
package/docs/lifecycle-hooks.md
CHANGED
|
@@ -21,11 +21,11 @@ The `onBeforeInitializeAsync` step is where the service server is set up. If no
|
|
|
21
21
|
When `startService()` is called, Orator executes these hooks in order:
|
|
22
22
|
|
|
23
23
|
```
|
|
24
|
-
[initialize()
|
|
24
|
+
[initialize() -- if not already initialized]
|
|
25
25
|
↓
|
|
26
26
|
onBeforeStartService(fNext)
|
|
27
27
|
↓
|
|
28
|
-
onStartService(fNext)
|
|
28
|
+
onStartService(fNext) -- calls serviceServer.listen()
|
|
29
29
|
↓
|
|
30
30
|
onAfterStartService(fNext)
|
|
31
31
|
```
|
package/docs/retold-catalog.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"Generated": "2026-
|
|
2
|
+
"Generated": "2026-04-10T17:23:32.342Z",
|
|
3
3
|
"GitHubOrg": "stevenvelozo",
|
|
4
4
|
"DefaultBranch": "master",
|
|
5
5
|
"Groups": [
|
|
@@ -64,6 +64,25 @@
|
|
|
64
64
|
}
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
|
+
{
|
|
68
|
+
"Name": "Docs",
|
|
69
|
+
"Key": "docs",
|
|
70
|
+
"Description": "",
|
|
71
|
+
"Modules": [
|
|
72
|
+
{
|
|
73
|
+
"Name": "css",
|
|
74
|
+
"Repo": "css",
|
|
75
|
+
"Group": "docs",
|
|
76
|
+
"Branch": "master",
|
|
77
|
+
"HasDocs": true,
|
|
78
|
+
"HasCover": false,
|
|
79
|
+
"Sidebar": [],
|
|
80
|
+
"DocFiles": [
|
|
81
|
+
"css/docuserve.css"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
},
|
|
67
86
|
{
|
|
68
87
|
"Name": "Test",
|
|
69
88
|
"Key": "test",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Generated": "2026-04-10T17:23:32.596Z",
|
|
3
|
+
"DocumentCount": 0,
|
|
4
|
+
"LunrIndex": {
|
|
5
|
+
"version": "2.3.9",
|
|
6
|
+
"fields": [
|
|
7
|
+
"title",
|
|
8
|
+
"module",
|
|
9
|
+
"group",
|
|
10
|
+
"body"
|
|
11
|
+
],
|
|
12
|
+
"fieldVectors": [],
|
|
13
|
+
"invertedIndex": [],
|
|
14
|
+
"pipeline": [
|
|
15
|
+
"stemmer"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"Documents": {}
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orator",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.1",
|
|
4
4
|
"description": "Unopinionated API http server abstraction - REST or IPC",
|
|
5
5
|
"main": "source/Orator.js",
|
|
6
6
|
"scripts": {
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"docker-dev-shell": "docker exec -it orator-dev /bin/bash"
|
|
16
16
|
},
|
|
17
17
|
"browser": {
|
|
18
|
-
"./source/Orator-Default-ServiceServer.js": "./source/Orator-Default-ServiceServer-Web.js"
|
|
18
|
+
"./source/Orator-Default-ServiceServer.js": "./source/Orator-Default-ServiceServer-Web.js",
|
|
19
|
+
"orator-static-server": false
|
|
19
20
|
},
|
|
20
21
|
"repository": {
|
|
21
22
|
"type": "git",
|
|
@@ -51,13 +52,14 @@
|
|
|
51
52
|
},
|
|
52
53
|
"homepage": "https://github.com/stevenvelozo/orator",
|
|
53
54
|
"devDependencies": {
|
|
54
|
-
"fable": "^3.1.
|
|
55
|
-
"
|
|
55
|
+
"fable": "^3.1.71",
|
|
56
|
+
"pict-docuserve": "^0.1.5",
|
|
57
|
+
"quackage": "^1.1.3"
|
|
56
58
|
},
|
|
57
59
|
"dependencies": {
|
|
58
60
|
"fable-serviceproviderbase": "^3.0.19",
|
|
59
|
-
"find-my-way": "^9.
|
|
60
|
-
"orator-serviceserver-base": "^1.0.
|
|
61
|
-
"orator-static-server": "^2.
|
|
61
|
+
"find-my-way": "^9.5.0",
|
|
62
|
+
"orator-serviceserver-base": "^1.0.7",
|
|
63
|
+
"orator-static-server": "^2.1.3"
|
|
62
64
|
}
|
|
63
65
|
}
|
package/source/Orator.js
CHANGED
|
@@ -11,7 +11,19 @@ const libFableServiceProviderBase = require('fable-serviceproviderbase');
|
|
|
11
11
|
|
|
12
12
|
const libDefaultOratorServiceServer = require('./Orator-Default-ServiceServer.js');
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// orator-static-server is lazy-loaded so that browser bundles using orator's
|
|
15
|
+
// IPC mode don't pay the cost of (or trip over) its server-only deps. Only
|
|
16
|
+
// setMimeHeader / addStaticRoute / addStaticRouteWithFallbacks need it, and
|
|
17
|
+
// none of those are reachable from IPC-only consumers.
|
|
18
|
+
let libOratorStaticServer = null;
|
|
19
|
+
const getOratorStaticServer = () =>
|
|
20
|
+
{
|
|
21
|
+
if (!libOratorStaticServer)
|
|
22
|
+
{
|
|
23
|
+
libOratorStaticServer = require('orator-static-server');
|
|
24
|
+
}
|
|
25
|
+
return libOratorStaticServer;
|
|
26
|
+
};
|
|
15
27
|
|
|
16
28
|
const defaultOratorConfiguration = require('./Orator-Default-Configuration.js');
|
|
17
29
|
|
|
@@ -381,7 +393,7 @@ class Orator extends libFableServiceProviderBase
|
|
|
381
393
|
// Force auto-registration so the method is available
|
|
382
394
|
if (!this.fable.serviceManager.servicesMap.hasOwnProperty('OratorStaticServer'))
|
|
383
395
|
{
|
|
384
|
-
this.fable.serviceManager.addServiceType('OratorStaticServer',
|
|
396
|
+
this.fable.serviceManager.addServiceType('OratorStaticServer', getOratorStaticServer());
|
|
385
397
|
}
|
|
386
398
|
this.fable.serviceManager.instantiateServiceProvider('OratorStaticServer', {}, 'OratorStaticServer-AutoInit');
|
|
387
399
|
}
|
|
@@ -404,7 +416,7 @@ class Orator extends libFableServiceProviderBase
|
|
|
404
416
|
// Auto-register the OratorStaticServer service type if it hasn't been registered yet
|
|
405
417
|
if (!this.fable.serviceManager.servicesMap.hasOwnProperty('OratorStaticServer'))
|
|
406
418
|
{
|
|
407
|
-
this.fable.serviceManager.addServiceType('OratorStaticServer',
|
|
419
|
+
this.fable.serviceManager.addServiceType('OratorStaticServer', getOratorStaticServer());
|
|
408
420
|
}
|
|
409
421
|
|
|
410
422
|
// Auto-instantiate a default OratorStaticServer instance if none exists
|
|
@@ -415,6 +427,38 @@ class Orator extends libFableServiceProviderBase
|
|
|
415
427
|
|
|
416
428
|
return this.fable.OratorStaticServer.addStaticRoute(pFilePath, pDefaultFile, pRoute, pRouteStrip, pParams);
|
|
417
429
|
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Register a static-file route with a per-file CDN fallback map.
|
|
433
|
+
*
|
|
434
|
+
* Behaves like addStaticRoute for every local hit. For any request whose
|
|
435
|
+
* relative path is a key in pFallbackMap and whose file isn't present
|
|
436
|
+
* on disk, responds with 302 to the mapped URL instead of a 404. Any
|
|
437
|
+
* request whose relative path isn't in the map behaves exactly as
|
|
438
|
+
* addStaticRoute would (local hit → stream, local miss → 404).
|
|
439
|
+
*
|
|
440
|
+
* @param {string} pFilePath The path on disk that we are serving files from.
|
|
441
|
+
* @param {string?} pDefaultFile (optional) The default file served if no specific file is requested.
|
|
442
|
+
* @param {string?} pRoute (optional) The route matcher that will be used. Defaults to everything.
|
|
443
|
+
* @param {string?} pRouteStrip (optional) If provided, this prefix will be removed from URL paths before being served.
|
|
444
|
+
* @param {object?} pParams (optional) Additional parameters to pass to serve-static.
|
|
445
|
+
* @param {Object<string,string>?} pFallbackMap (optional) Map of relative path (under the route prefix) to absolute URL for CDN fallback.
|
|
446
|
+
* @return {boolean} true if the handler was successfully installed, otherwise false.
|
|
447
|
+
*/
|
|
448
|
+
addStaticRouteWithFallbacks(pFilePath, pDefaultFile, pRoute, pRouteStrip, pParams, pFallbackMap)
|
|
449
|
+
{
|
|
450
|
+
if (!this.fable.serviceManager.servicesMap.hasOwnProperty('OratorStaticServer'))
|
|
451
|
+
{
|
|
452
|
+
this.fable.serviceManager.addServiceType('OratorStaticServer', getOratorStaticServer());
|
|
453
|
+
}
|
|
454
|
+
if (!this.fable.OratorStaticServer)
|
|
455
|
+
{
|
|
456
|
+
this.fable.serviceManager.instantiateServiceProvider('OratorStaticServer', {}, 'OratorStaticServer-AutoInit');
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return this.fable.OratorStaticServer.addStaticRouteWithFallbacks(
|
|
460
|
+
pFilePath, pDefaultFile, pRoute, pRouteStrip, pParams, pFallbackMap);
|
|
461
|
+
}
|
|
418
462
|
}
|
|
419
463
|
|
|
420
464
|
module.exports = Orator;
|
|
@@ -353,7 +353,8 @@ suite
|
|
|
353
353
|
let tmpMockResponse = { setHeader: function(pName, pValue) { tmpCapturedHeaders[pName] = pValue; } };
|
|
354
354
|
|
|
355
355
|
tmpStaticServer.setMimeHeader('app.js', tmpMockResponse);
|
|
356
|
-
|
|
356
|
+
// mime v4 returns the IANA-canonical 'text/javascript'; earlier versions returned 'application/javascript'.
|
|
357
|
+
Expect(tmpCapturedHeaders['Content-Type']).to.be.oneOf(['text/javascript', 'application/javascript']);
|
|
357
358
|
|
|
358
359
|
tmpOrator.log.info('JavaScript MIME type correctly detected');
|
|
359
360
|
return fDone();
|