alp-node 7.0.0 → 8.0.0
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/CHANGELOG.md +24 -0
- package/README.md +7 -7
- package/dist/{AlpNodeApp-node18.mjs → AlpNodeApp-node20.mjs} +59 -77
- package/dist/AlpNodeApp-node20.mjs.map +1 -0
- package/dist/definitions/AlpNodeApp.d.ts +15 -16
- package/dist/definitions/AlpNodeApp.d.ts.map +1 -1
- package/dist/definitions/config.d.ts +4 -5
- package/dist/definitions/config.d.ts.map +1 -1
- package/dist/definitions/errors.d.ts +1 -2
- package/dist/definitions/errors.d.ts.map +1 -1
- package/dist/definitions/index.d.ts +8 -8
- package/dist/definitions/language.d.ts +1 -1
- package/dist/definitions/language.d.ts.map +1 -1
- package/dist/definitions/listen.d.ts +2 -3
- package/dist/definitions/listen.d.ts.map +1 -1
- package/dist/definitions/params/ParamValid.d.ts +2 -3
- package/dist/definitions/params/ParamValid.d.ts.map +1 -1
- package/dist/definitions/params/ParamValueFromContext.d.ts +3 -4
- package/dist/definitions/params/ParamValueFromContext.d.ts.map +1 -1
- package/dist/definitions/params/ParamValueModelValidator.d.ts +1 -1
- package/dist/definitions/params/ParamValueStringValidator.d.ts +1 -1
- package/dist/definitions/params/ParamValueValidator.d.ts +1 -1
- package/dist/definitions/params/index.d.ts +8 -4
- package/dist/definitions/params/index.d.ts.map +1 -1
- package/dist/definitions/router.d.ts +3 -4
- package/dist/definitions/router.d.ts.map +1 -1
- package/dist/definitions/translate/index.d.ts +1 -1
- package/dist/definitions/translate/load.d.ts +3 -3
- package/dist/definitions/translate/load.d.ts.map +1 -1
- package/dist/definitions/types.d.ts +6 -6
- package/dist/definitions/types.d.ts.map +1 -1
- package/dist/{index-node18.mjs → index-node20.mjs} +142 -158
- package/dist/index-node20.mjs.map +1 -0
- package/package.json +23 -23
- package/src/AlpNodeApp.ts +48 -48
- package/src/config.ts +43 -48
- package/src/errors.ts +19 -19
- package/src/index.ts +16 -16
- package/src/language.ts +18 -10
- package/src/listen.ts +16 -16
- package/src/params/ParamValid.ts +3 -3
- package/src/params/ParamValidationResult.test.ts +5 -5
- package/src/params/ParamValueFromContext.ts +5 -5
- package/src/params/ParamValueModelValidator.ts +1 -1
- package/src/params/ParamValueStringValidator.ts +3 -3
- package/src/params/ParamValueValidator.ts +1 -1
- package/src/params/index.ts +17 -13
- package/src/router.ts +7 -7
- package/src/translate/index.ts +9 -9
- package/src/translate/load.ts +13 -12
- package/src/types.ts +8 -8
- package/dist/AlpNodeApp-node18.mjs.map +0 -1
- package/dist/index-node18.mjs.map +0 -1
- package/src/.eslintrc.json +0 -31
|
@@ -1,101 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { unlinkSync, chmodSync, readFileSync, existsSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { Logger } from 'nightingale-logger';
|
|
4
|
-
import { deprecate } from 'node:util';
|
|
5
4
|
import Koa from 'koa';
|
|
6
5
|
import compress from 'koa-compress';
|
|
7
6
|
import serve from 'koa-static';
|
|
8
|
-
import deepFreeze from 'deep-freeze-es6';
|
|
9
|
-
import minimist from 'minimist';
|
|
10
|
-
import parseJSON from 'parse-json-object-as-map';
|
|
11
7
|
import { STATUS_CODES, createServer as createServer$2 } from 'node:http';
|
|
12
8
|
import ErrorHtmlRenderer from 'error-html';
|
|
13
9
|
import { defineLazyProperty } from 'object-properties';
|
|
14
10
|
import { createServer as createServer$1 } from 'node:https';
|
|
15
11
|
import IntlMessageFormatDefault from 'intl-messageformat';
|
|
12
|
+
import deepFreeze from 'deep-freeze-es6';
|
|
13
|
+
import minimist from 'minimist';
|
|
16
14
|
import { createRouterBuilder } from 'router-segments';
|
|
17
15
|
|
|
18
|
-
const
|
|
19
|
-
function _existsConfigSync(dirname, name) {
|
|
20
|
-
return existsSync(`${dirname}${name}.json`);
|
|
21
|
-
}
|
|
22
|
-
function _loadConfigSync(dirname, name) {
|
|
23
|
-
const content = readFileSync(`${dirname}${name}.json`, 'utf8');
|
|
24
|
-
return parseJSON(content);
|
|
25
|
-
}
|
|
26
|
-
class Config {
|
|
27
|
-
constructor(dirname, options) {
|
|
28
|
-
this._map = new Map();
|
|
29
|
-
this._dirname = dirname.replace(/\/*$/, '/');
|
|
30
|
-
if (options) {
|
|
31
|
-
this.loadSync(options);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
loadSync(options = {}) {
|
|
35
|
-
const env = process.env.CONFIG_ENV || process.env.NODE_ENV || 'development';
|
|
36
|
-
const {
|
|
37
|
-
argv: argvOverrides = [],
|
|
38
|
-
packageConfig,
|
|
39
|
-
version
|
|
40
|
-
} = options;
|
|
41
|
-
this.packageConfig = packageConfig;
|
|
42
|
-
const config = this.loadConfigSync('common');
|
|
43
|
-
for (const [key, value] of this.loadConfigSync(env)) {
|
|
44
|
-
config.set(key, value);
|
|
45
|
-
}
|
|
46
|
-
if (this.existsConfigSync('local')) {
|
|
47
|
-
for (const [key, value] of this.loadConfigSync('local')) {
|
|
48
|
-
config.set(key, value);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (config.has('version')) {
|
|
52
|
-
throw new Error('Cannot have "version", in config.');
|
|
53
|
-
}
|
|
54
|
-
config.set('version', String(version || argv.version || packageConfig?.version));
|
|
55
|
-
const socketPath = argv.socket || argv['socket-path'] || argv.socketPath;
|
|
56
|
-
if (socketPath) {
|
|
57
|
-
config.set('socketPath', socketPath);
|
|
58
|
-
} else if (argv.port) {
|
|
59
|
-
config.set('port', argv.port);
|
|
60
|
-
config.delete('socketPath');
|
|
61
|
-
} else if (process.env.PORT) {
|
|
62
|
-
config.set('port', Number(process.env.PORT));
|
|
63
|
-
config.delete('socketPath');
|
|
64
|
-
}
|
|
65
|
-
argvOverrides.forEach(key => {
|
|
66
|
-
const splitted = key.split('.');
|
|
67
|
-
const value = splitted.length > 0 &&
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,unicorn/no-array-reduce, @typescript-eslint/no-shadow
|
|
69
|
-
splitted.reduce((config, partialKey) => config?.[partialKey], argv);
|
|
70
|
-
if (value !== undefined) {
|
|
71
|
-
const last = splitted.pop();
|
|
72
|
-
const map = splitted.length === 0 ? config :
|
|
73
|
-
// eslint-disable-next-line unicorn/no-array-reduce
|
|
74
|
-
splitted.reduce(
|
|
75
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
76
|
-
(config, partialKey) => config.get(partialKey), config);
|
|
77
|
-
map.set(last, value);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
this._map = deepFreeze(config);
|
|
81
|
-
return this;
|
|
82
|
-
}
|
|
83
|
-
get(key) {
|
|
84
|
-
return this._map.get(key);
|
|
85
|
-
}
|
|
86
|
-
existsConfigSync(name) {
|
|
87
|
-
return _existsConfigSync(this._dirname, name);
|
|
88
|
-
}
|
|
89
|
-
loadConfigSync(name) {
|
|
90
|
-
return _loadConfigSync(this._dirname, name);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function getConfig(app, config) {
|
|
94
|
-
return config;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/* eslint-disable complexity */
|
|
98
|
-
const logger$4 = new Logger('alp:errors');
|
|
16
|
+
const logger$4 = new Logger("alp:errors");
|
|
99
17
|
const errorHtmlRenderer = new ErrorHtmlRenderer({
|
|
100
18
|
appPath: `${process.cwd()}/`
|
|
101
19
|
});
|
|
@@ -104,16 +22,16 @@ async function alpNodeErrors(ctx, next) {
|
|
|
104
22
|
await next();
|
|
105
23
|
} catch (error) {
|
|
106
24
|
// eslint-disable-next-line no-ex-assign
|
|
107
|
-
if (!error) error = new Error(
|
|
25
|
+
if (!error) error = new Error("Unknown error");
|
|
108
26
|
// eslint-disable-next-line no-ex-assign
|
|
109
|
-
if (typeof error ===
|
|
27
|
+
if (typeof error === "string") error = new Error(error);
|
|
110
28
|
ctx.status = error.status || 500;
|
|
111
29
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
112
30
|
logger$4.error(error);
|
|
113
|
-
switch (ctx.request.accepts(
|
|
114
|
-
case
|
|
115
|
-
ctx.type =
|
|
116
|
-
if (process.env.NODE_ENV !==
|
|
31
|
+
switch (ctx.request.accepts("html", "text", "json")) {
|
|
32
|
+
case "json":
|
|
33
|
+
ctx.type = "application/json";
|
|
34
|
+
if (process.env.NODE_ENV !== "production" || error.expose) {
|
|
117
35
|
ctx.body = {
|
|
118
36
|
error: error.message
|
|
119
37
|
};
|
|
@@ -123,9 +41,9 @@ async function alpNodeErrors(ctx, next) {
|
|
|
123
41
|
};
|
|
124
42
|
}
|
|
125
43
|
break;
|
|
126
|
-
case
|
|
127
|
-
ctx.type =
|
|
128
|
-
if (process.env.NODE_ENV !==
|
|
44
|
+
case "html":
|
|
45
|
+
ctx.type = "text/html";
|
|
46
|
+
if (process.env.NODE_ENV !== "production") {
|
|
129
47
|
ctx.body = errorHtmlRenderer.render(error);
|
|
130
48
|
} else if (error.expose) {
|
|
131
49
|
ctx.body = error.message;
|
|
@@ -133,10 +51,11 @@ async function alpNodeErrors(ctx, next) {
|
|
|
133
51
|
throw error;
|
|
134
52
|
}
|
|
135
53
|
break;
|
|
136
|
-
case
|
|
54
|
+
case "text":
|
|
55
|
+
case false:
|
|
137
56
|
default:
|
|
138
|
-
ctx.type =
|
|
139
|
-
if (process.env.NODE_ENV !==
|
|
57
|
+
ctx.type = "text/plain";
|
|
58
|
+
if (process.env.NODE_ENV !== "production" || error.expose) {
|
|
140
59
|
ctx.body = error.message;
|
|
141
60
|
} else {
|
|
142
61
|
throw error;
|
|
@@ -148,20 +67,20 @@ async function alpNodeErrors(ctx, next) {
|
|
|
148
67
|
|
|
149
68
|
function alpLanguage(app) {
|
|
150
69
|
const config = app.context.config;
|
|
151
|
-
const availableLanguages = config.get(
|
|
70
|
+
const availableLanguages = config.get("availableLanguages");
|
|
152
71
|
if (!availableLanguages) {
|
|
153
72
|
throw new Error('Missing config "availableLanguages"');
|
|
154
73
|
}
|
|
155
|
-
defineLazyProperty(app.context,
|
|
156
|
-
return this.acceptsLanguages(availableLanguages) || availableLanguages[0];
|
|
74
|
+
defineLazyProperty(app.context, "language", function language() {
|
|
75
|
+
return this.acceptsLanguages(availableLanguages) || availableLanguages[0] || "en";
|
|
157
76
|
});
|
|
158
|
-
defineLazyProperty(app.context,
|
|
159
|
-
return this.acceptsLanguages()[0] || availableLanguages[0];
|
|
77
|
+
defineLazyProperty(app.context, "firstAcceptedLanguage", function firstAcceptedLanguage() {
|
|
78
|
+
return this.acceptsLanguages()[0] || availableLanguages[0] || "en";
|
|
160
79
|
});
|
|
161
80
|
}
|
|
162
81
|
|
|
163
|
-
const logger$3 = new Logger(
|
|
164
|
-
const createServer = (callback, socketPath, tls, dirname =
|
|
82
|
+
const logger$3 = new Logger("alp:listen");
|
|
83
|
+
const createServer = (callback, socketPath, tls, dirname = ""
|
|
165
84
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
166
85
|
) => {
|
|
167
86
|
const createHttpServer = !socketPath && tls ? createServer$1 : createServer$2;
|
|
@@ -176,11 +95,11 @@ const createServer = (callback, socketPath, tls, dirname = ''
|
|
|
176
95
|
};
|
|
177
96
|
function alpListen(config, callback, dirname) {
|
|
178
97
|
return new Promise(resolve => {
|
|
179
|
-
const socketPath = config.get(
|
|
180
|
-
const port = config.get(
|
|
181
|
-
const hostname = config.get(
|
|
182
|
-
const tls = config.get(
|
|
183
|
-
logger$3.info(
|
|
98
|
+
const socketPath = config.get("socketPath");
|
|
99
|
+
const port = config.get("port");
|
|
100
|
+
const hostname = config.get("hostname");
|
|
101
|
+
const tls = config.get("tls");
|
|
102
|
+
logger$3.info("Creating server", socketPath ? {
|
|
184
103
|
socketPath
|
|
185
104
|
} : {
|
|
186
105
|
port
|
|
@@ -192,16 +111,16 @@ function alpListen(config, callback, dirname) {
|
|
|
192
111
|
} catch {}
|
|
193
112
|
server.listen(socketPath, () => {
|
|
194
113
|
if (socketPath) {
|
|
195
|
-
chmodSync(socketPath,
|
|
114
|
+
chmodSync(socketPath, "777");
|
|
196
115
|
}
|
|
197
|
-
logger$3.info(
|
|
116
|
+
logger$3.info("Server listening", {
|
|
198
117
|
socketPath
|
|
199
118
|
});
|
|
200
119
|
resolve(server);
|
|
201
120
|
});
|
|
202
121
|
} else {
|
|
203
122
|
server.listen(port, hostname, () => {
|
|
204
|
-
logger$3.info(
|
|
123
|
+
logger$3.info("Server listening", {
|
|
205
124
|
port
|
|
206
125
|
});
|
|
207
126
|
resolve(server);
|
|
@@ -250,7 +169,7 @@ class ParamValid extends ParamValidationResult {
|
|
|
250
169
|
this.context = context;
|
|
251
170
|
}
|
|
252
171
|
_error() {
|
|
253
|
-
this.context.throw(400,
|
|
172
|
+
this.context.throw(400, "Invalid params", {
|
|
254
173
|
validator: this
|
|
255
174
|
});
|
|
256
175
|
}
|
|
@@ -272,8 +191,8 @@ class ParamValueValidator {
|
|
|
272
191
|
|
|
273
192
|
class ParamValueStringValidator extends ParamValueValidator {
|
|
274
193
|
notEmpty() {
|
|
275
|
-
if (this.value == null || this.value.trim() ===
|
|
276
|
-
this._error(
|
|
194
|
+
if (this.value == null || this.value.trim() === "") {
|
|
195
|
+
this._error("notEmpty");
|
|
277
196
|
}
|
|
278
197
|
return this;
|
|
279
198
|
}
|
|
@@ -285,10 +204,10 @@ class ParamValueFromContext {
|
|
|
285
204
|
this.context = context;
|
|
286
205
|
}
|
|
287
206
|
namedParam(name) {
|
|
288
|
-
return new ParamValueStringValidator(this.validationResult, name, this.context.
|
|
207
|
+
return new ParamValueStringValidator(this.validationResult, name, this.context.namedRouteParam(name));
|
|
289
208
|
}
|
|
290
209
|
otherParam(position) {
|
|
291
|
-
return new ParamValueStringValidator(this.validationResult, String(position), this.context.
|
|
210
|
+
return new ParamValueStringValidator(this.validationResult, String(position), this.context.otherRouteParam(position));
|
|
292
211
|
}
|
|
293
212
|
queryParam(name) {
|
|
294
213
|
return new ParamValueStringValidator(this.validationResult, name, this.context.queryParam(name));
|
|
@@ -318,13 +237,13 @@ function alpParams(app) {
|
|
|
318
237
|
return this.body[name];
|
|
319
238
|
}
|
|
320
239
|
});
|
|
321
|
-
defineLazyProperty(app.request,
|
|
240
|
+
defineLazyProperty(app.request, "searchParams", function searchParams() {
|
|
322
241
|
return new URLSearchParams(this.search);
|
|
323
242
|
});
|
|
324
|
-
defineLazyProperty(app.context,
|
|
243
|
+
defineLazyProperty(app.context, "params", function params() {
|
|
325
244
|
return new ParamValueFromContext(this, new ParamValidationResult());
|
|
326
245
|
});
|
|
327
|
-
defineLazyProperty(app.context,
|
|
246
|
+
defineLazyProperty(app.context, "validParams", function validParams() {
|
|
328
247
|
return new ParamValueFromContext(this, new ParamValid(this));
|
|
329
248
|
});
|
|
330
249
|
}
|
|
@@ -334,32 +253,29 @@ const IntlMessageFormat =
|
|
|
334
253
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
335
254
|
IntlMessageFormatDefault.default || IntlMessageFormatDefault;
|
|
336
255
|
function load(translations, language) {
|
|
337
|
-
const result =
|
|
338
|
-
(function loadMap(
|
|
339
|
-
|
|
340
|
-
if (typeof value ===
|
|
341
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
256
|
+
const result = {};
|
|
257
|
+
(function loadMap(record, prefix) {
|
|
258
|
+
Object.entries(record).forEach(([key, value]) => {
|
|
259
|
+
if (typeof value === "object" && value !== null) {
|
|
342
260
|
loadMap(value, `${prefix}${key}.`);
|
|
343
261
|
return;
|
|
344
262
|
}
|
|
345
|
-
|
|
346
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
347
|
-
result.set(`${prefix}${key}`, new IntlMessageFormat(value, language));
|
|
263
|
+
result[`${prefix}${key}`] = new IntlMessageFormat(value, language);
|
|
348
264
|
});
|
|
349
|
-
})(translations,
|
|
265
|
+
})(translations, "");
|
|
350
266
|
return result;
|
|
351
267
|
}
|
|
352
268
|
|
|
353
|
-
const logger$2 = new Logger(
|
|
269
|
+
const logger$2 = new Logger("alp:translate");
|
|
354
270
|
function alpTranslate(dirname) {
|
|
355
|
-
dirname = dirname.replace(/\/*$/,
|
|
271
|
+
dirname = dirname.replace(/\/*$/, "/");
|
|
356
272
|
return app => {
|
|
357
273
|
const appTranslations = new Map();
|
|
358
274
|
Object.assign(app.context, {
|
|
359
275
|
t(id, args) {
|
|
360
|
-
const msg = appTranslations.get(this.language)
|
|
276
|
+
const msg = appTranslations.get(this.language)?.[id];
|
|
361
277
|
if (!msg) {
|
|
362
|
-
logger$2.warn(
|
|
278
|
+
logger$2.warn("invalid msg", {
|
|
363
279
|
language: this.language,
|
|
364
280
|
id
|
|
365
281
|
});
|
|
@@ -369,7 +285,7 @@ function alpTranslate(dirname) {
|
|
|
369
285
|
}
|
|
370
286
|
});
|
|
371
287
|
const config = app.config;
|
|
372
|
-
config.get(
|
|
288
|
+
config.get("availableLanguages").forEach(language => {
|
|
373
289
|
const translations = app.loadConfigSync(dirname + language);
|
|
374
290
|
appTranslations.set(language, load(translations, language));
|
|
375
291
|
});
|
|
@@ -377,7 +293,7 @@ function alpTranslate(dirname) {
|
|
|
377
293
|
};
|
|
378
294
|
}
|
|
379
295
|
|
|
380
|
-
const logger$1 = new Logger(
|
|
296
|
+
const logger$1 = new Logger("alp");
|
|
381
297
|
class AlpNodeApp extends Koa {
|
|
382
298
|
/**
|
|
383
299
|
* @param {Object} [options]
|
|
@@ -393,18 +309,13 @@ class AlpNodeApp extends Koa {
|
|
|
393
309
|
}) {
|
|
394
310
|
super();
|
|
395
311
|
this.dirname = path.normalize(appDirname);
|
|
396
|
-
Object.defineProperty(this, 'packageDirname', {
|
|
397
|
-
get: deprecate(() => packageDirname, 'packageDirname'),
|
|
398
|
-
configurable: false,
|
|
399
|
-
enumerable: false
|
|
400
|
-
});
|
|
401
312
|
this.certPath = certPath || `${packageDirname}/config/cert`;
|
|
402
313
|
this.publicPath = publicPath || `${packageDirname}/public/`;
|
|
403
|
-
this.config =
|
|
314
|
+
this.config = config;
|
|
404
315
|
this.context.config = this.config;
|
|
405
316
|
alpParams(this);
|
|
406
317
|
alpLanguage(this);
|
|
407
|
-
alpTranslate(
|
|
318
|
+
alpTranslate("locales")(this);
|
|
408
319
|
this.use(compress());
|
|
409
320
|
}
|
|
410
321
|
existsConfigSync(name) {
|
|
@@ -415,6 +326,7 @@ class AlpNodeApp extends Koa {
|
|
|
415
326
|
}
|
|
416
327
|
createContext(req, res) {
|
|
417
328
|
const ctx = super.createContext(req, res);
|
|
329
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
418
330
|
ctx.sanitizedState = {};
|
|
419
331
|
return ctx;
|
|
420
332
|
}
|
|
@@ -424,10 +336,8 @@ class AlpNodeApp extends Koa {
|
|
|
424
336
|
catchErrors() {
|
|
425
337
|
this.use(alpNodeErrors);
|
|
426
338
|
}
|
|
427
|
-
|
|
428
|
-
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
429
339
|
listen() {
|
|
430
|
-
throw new Error(
|
|
340
|
+
throw new Error("Use start instead");
|
|
431
341
|
}
|
|
432
342
|
|
|
433
343
|
/**
|
|
@@ -436,7 +346,7 @@ class AlpNodeApp extends Koa {
|
|
|
436
346
|
close() {
|
|
437
347
|
if (this._server) {
|
|
438
348
|
this._server.close();
|
|
439
|
-
this.emit(
|
|
349
|
+
this.emit("close");
|
|
440
350
|
}
|
|
441
351
|
}
|
|
442
352
|
async start(fn) {
|
|
@@ -444,11 +354,11 @@ class AlpNodeApp extends Koa {
|
|
|
444
354
|
try {
|
|
445
355
|
const server = await alpListen(this.config, this.callback(), this.certPath);
|
|
446
356
|
this._server = server;
|
|
447
|
-
logger$1.success(
|
|
448
|
-
if (process.send) process.send(
|
|
357
|
+
logger$1.success("started");
|
|
358
|
+
if (process.send) process.send("ready");
|
|
449
359
|
return server;
|
|
450
360
|
} catch (error) {
|
|
451
|
-
logger$1.error(
|
|
361
|
+
logger$1.error("start fail", {
|
|
452
362
|
err: error
|
|
453
363
|
});
|
|
454
364
|
throw error;
|
|
@@ -456,14 +366,88 @@ class AlpNodeApp extends Koa {
|
|
|
456
366
|
}
|
|
457
367
|
}
|
|
458
368
|
|
|
369
|
+
const argv = minimist(process.argv.slice(2));
|
|
370
|
+
function _existsConfigSync(dirname, name) {
|
|
371
|
+
return existsSync(`${dirname}${name}.json`);
|
|
372
|
+
}
|
|
373
|
+
function _loadConfigSync(dirname, name) {
|
|
374
|
+
const content = readFileSync(`${dirname}${name}.json`, "utf8");
|
|
375
|
+
return JSON.parse(content);
|
|
376
|
+
}
|
|
377
|
+
class Config {
|
|
378
|
+
constructor(dirname, options) {
|
|
379
|
+
this._record = {};
|
|
380
|
+
this._dirname = dirname.replace(/\/*$/, "/");
|
|
381
|
+
if (options) {
|
|
382
|
+
this.loadSync(options);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
loadSync(options = {}) {
|
|
386
|
+
const env = process.env.CONFIG_ENV || process.env.NODE_ENV || "development";
|
|
387
|
+
const {
|
|
388
|
+
argv: argvOverrides = [],
|
|
389
|
+
packageConfig,
|
|
390
|
+
version
|
|
391
|
+
} = options;
|
|
392
|
+
this.packageConfig = packageConfig;
|
|
393
|
+
const config = _loadConfigSync(this._dirname, "common");
|
|
394
|
+
for (const [key, value] of Object.entries(_loadConfigSync(this._dirname, env))) {
|
|
395
|
+
config[key] = value;
|
|
396
|
+
}
|
|
397
|
+
if (this.existsConfigSync("local")) {
|
|
398
|
+
for (const [key, value] of Object.entries(_loadConfigSync(this._dirname, "local"))) {
|
|
399
|
+
config[key] = value;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (config.version) {
|
|
403
|
+
throw new Error('Cannot have "version", in config.');
|
|
404
|
+
}
|
|
405
|
+
config.version = String(version || argv.version || packageConfig?.version);
|
|
406
|
+
const socketPath = argv.socket || argv["socket-path"] || argv.socketPath;
|
|
407
|
+
if (socketPath) {
|
|
408
|
+
config.socketPath = socketPath;
|
|
409
|
+
} else if (argv.port) {
|
|
410
|
+
config.port = argv.port;
|
|
411
|
+
delete config.socketPath;
|
|
412
|
+
} else if (process.env.PORT) {
|
|
413
|
+
config.port = Number(process.env.PORT);
|
|
414
|
+
delete config.socketPath;
|
|
415
|
+
}
|
|
416
|
+
argvOverrides.forEach(key => {
|
|
417
|
+
const splitted = key.split(".");
|
|
418
|
+
const value = splitted.length > 0 &&
|
|
419
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,unicorn/no-array-reduce
|
|
420
|
+
splitted.reduce((config, partialKey) => config[partialKey], argv);
|
|
421
|
+
if (value !== undefined) {
|
|
422
|
+
const last = splitted.pop();
|
|
423
|
+
const v = splitted.length === 0 ? config :
|
|
424
|
+
// eslint-disable-next-line unicorn/no-array-reduce
|
|
425
|
+
splitted.reduce((config, partialKey) => config[partialKey], config);
|
|
426
|
+
v[last] = value;
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
this._record = deepFreeze(config);
|
|
430
|
+
return this;
|
|
431
|
+
}
|
|
432
|
+
get(key) {
|
|
433
|
+
return this._record[key];
|
|
434
|
+
}
|
|
435
|
+
existsConfigSync(name) {
|
|
436
|
+
return _existsConfigSync(this._dirname, name);
|
|
437
|
+
}
|
|
438
|
+
loadConfigSync(name) {
|
|
439
|
+
return _loadConfigSync(this._dirname, name);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
459
443
|
const createAlpRouterBuilder = () => createRouterBuilder();
|
|
460
444
|
function alpRouter(router) {
|
|
461
445
|
return app => {
|
|
462
446
|
app.router = router;
|
|
463
|
-
app.context.urlGenerator = function (routeKey, params) {
|
|
447
|
+
app.context.urlGenerator = function urlGenerator(routeKey, params) {
|
|
464
448
|
return router.toLocalizedPath(this.language, routeKey, params);
|
|
465
449
|
};
|
|
466
|
-
app.context.redirectTo = function (to, params) {
|
|
450
|
+
app.context.redirectTo = function redirectTo(to, params) {
|
|
467
451
|
this.redirect(router.toLocalizedPath(this.language, to, params));
|
|
468
452
|
};
|
|
469
453
|
return async ctx => {
|
|
@@ -479,18 +463,18 @@ function alpRouter(router) {
|
|
|
479
463
|
};
|
|
480
464
|
}
|
|
481
465
|
|
|
482
|
-
const logger = new Logger(
|
|
483
|
-
const appDirname = path.resolve(
|
|
484
|
-
const packagePath = path.resolve(
|
|
466
|
+
const logger = new Logger("alp");
|
|
467
|
+
const appDirname = path.resolve("build");
|
|
468
|
+
const packagePath = path.resolve("package.json");
|
|
485
469
|
if (!packagePath) {
|
|
486
470
|
throw new Error(`Could not find package.json: "${String(packagePath)}"`);
|
|
487
471
|
}
|
|
488
472
|
const packageDirname = path.dirname(packagePath);
|
|
489
|
-
logger.debug(
|
|
473
|
+
logger.debug("init", {
|
|
490
474
|
appDirname,
|
|
491
475
|
packageDirname
|
|
492
476
|
});
|
|
493
|
-
const packageConfig = JSON.parse(readFileSync(packagePath,
|
|
477
|
+
const packageConfig = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
494
478
|
const buildedConfigPath = `${appDirname}/build/config/`;
|
|
495
479
|
const configPath = existsSync(buildedConfigPath) ? buildedConfigPath : `${appDirname}/config/`;
|
|
496
480
|
const config = new Config(configPath).loadSync({
|
|
@@ -508,4 +492,4 @@ class App extends AlpNodeApp {
|
|
|
508
492
|
}
|
|
509
493
|
|
|
510
494
|
export { Config, appDirname, config, createAlpRouterBuilder, App as default, packageConfig, packageDirname, alpRouter as router };
|
|
511
|
-
//# sourceMappingURL=index-
|
|
495
|
+
//# sourceMappingURL=index-node20.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-node20.mjs","sources":["../src/errors.ts","../src/language.ts","../src/listen.ts","../src/params/ParamValidationResult.ts","../src/params/ParamValid.ts","../src/params/ParamValueValidator.ts","../src/params/ParamValueStringValidator.ts","../src/params/ParamValueFromContext.ts","../src/params/index.ts","../src/translate/load.ts","../src/translate/index.ts","../src/AlpNodeApp.ts","../src/config.ts","../src/router.ts","../src/index.ts"],"sourcesContent":["import { STATUS_CODES } from \"node:http\";\nimport ErrorHtmlRenderer from \"error-html\";\nimport { Logger } from \"nightingale-logger\";\nimport type { Context } from \"./AlpNodeApp\";\nimport type { HtmlError } from \"./types\";\n\nconst logger = new Logger(\"alp:errors\");\nconst errorHtmlRenderer = new ErrorHtmlRenderer({\n appPath: `${process.cwd()}/`,\n});\n\nexport default async function alpNodeErrors(\n ctx: Context,\n next: () => Promise<void> | void,\n): Promise<void> {\n try {\n await next();\n } catch (error: unknown) {\n // eslint-disable-next-line no-ex-assign\n if (!error) error = new Error(\"Unknown error\");\n // eslint-disable-next-line no-ex-assign\n if (typeof error === \"string\") error = new Error(error);\n\n ctx.status = (error as HtmlError).status || 500;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n logger.error(error as any);\n\n switch (ctx.request.accepts(\"html\", \"text\", \"json\")) {\n case \"json\":\n ctx.type = \"application/json\";\n if (\n process.env.NODE_ENV !== \"production\" ||\n (error as HtmlError).expose\n ) {\n ctx.body = { error: (error as Error).message };\n } else {\n ctx.body = { error: STATUS_CODES[ctx.status] };\n }\n\n break;\n\n case \"html\":\n ctx.type = \"text/html\";\n if (process.env.NODE_ENV !== \"production\") {\n ctx.body = errorHtmlRenderer.render(error as Error);\n } else if ((error as HtmlError).expose) {\n ctx.body = (error as Error).message;\n } else {\n throw error;\n }\n\n break;\n\n case \"text\":\n case false:\n default:\n ctx.type = \"text/plain\";\n if (\n process.env.NODE_ENV !== \"production\" ||\n (error as HtmlError).expose\n ) {\n ctx.body = (error as Error).message;\n } else {\n throw error;\n }\n\n break;\n }\n }\n}\n","import type { Context } from \"koa\";\nimport { defineLazyProperty } from \"object-properties\";\nimport type { AlpNodeApp } from \"./AlpNodeApp\";\n\nexport interface AlpLanguageContext {\n readonly firstAcceptedLanguage: string;\n readonly language: string;\n}\nexport default function alpLanguage(app: AlpNodeApp): void {\n const config = app.context.config;\n const availableLanguages: string[] = config.get(\"availableLanguages\");\n if (!availableLanguages) {\n throw new Error('Missing config \"availableLanguages\"');\n }\n\n defineLazyProperty(\n app.context,\n \"language\",\n function language(this: Context): string {\n return (\n this.acceptsLanguages(availableLanguages) ||\n availableLanguages[0] ||\n \"en\"\n );\n },\n );\n\n defineLazyProperty(\n app.context,\n \"firstAcceptedLanguage\",\n function firstAcceptedLanguage(this: Context): string {\n return this.acceptsLanguages()[0] || availableLanguages[0] || \"en\";\n },\n );\n}\n","import { chmodSync, readFileSync, unlinkSync } from \"node:fs\";\nimport { createServer as createServerHttp } from \"node:http\";\nimport type { IncomingMessage, Server, ServerResponse } from \"node:http\";\nimport { createServer as createServerHttps } from \"node:https\";\nimport { Logger } from \"nightingale-logger\";\nimport type { Config } from \"./config\";\n\nconst logger = new Logger(\"alp:listen\");\n\ntype RequestListener = (req: IncomingMessage, res: ServerResponse) => void;\n\nconst createServer = (\n callback: RequestListener,\n socketPath?: string,\n tls?: boolean,\n dirname = \"\",\n // eslint-disable-next-line @typescript-eslint/max-params\n): Server => {\n const createHttpServer =\n !socketPath && tls ? createServerHttps : createServerHttp;\n\n if (!tls) {\n return (createHttpServer as typeof createServerHttps)(callback);\n }\n\n const options = {\n key: readFileSync(`${dirname}/server.key`),\n cert: readFileSync(`${dirname}/server.crt`),\n };\n\n return (createHttpServer as typeof createServerHttps)(options, callback);\n};\n\nexport default function alpListen(\n config: Config,\n callback: RequestListener,\n dirname?: string,\n): Promise<Server> {\n return new Promise((resolve) => {\n const socketPath = config.get<string>(\"socketPath\");\n const port = config.get<number>(\"port\");\n const hostname = config.get<string>(\"hostname\");\n const tls = config.get<boolean>(\"tls\");\n\n logger.info(\"Creating server\", socketPath ? { socketPath } : { port });\n const server = createServer(callback, socketPath, tls, dirname);\n\n if (socketPath) {\n try {\n unlinkSync(socketPath);\n } catch {}\n\n server.listen(socketPath, () => {\n if (socketPath) {\n chmodSync(socketPath, \"777\");\n }\n\n logger.info(\"Server listening\", { socketPath });\n resolve(server);\n });\n } else {\n server.listen(port, hostname, () => {\n logger.info(\"Server listening\", { port });\n resolve(server);\n });\n }\n });\n}\n","export type Errors = Record<string, any>;\n\nexport class ParamValidationResult {\n _errors?: Errors;\n\n _error(name: string, key: string, value: unknown): void {\n if (!this._errors) {\n this._errors = {};\n }\n\n this._errors[name] = { error: key, value };\n }\n\n getErrors(): Errors | undefined {\n return this._errors;\n }\n\n hasErrors(): boolean {\n return this._errors !== undefined;\n }\n\n isValid(): boolean {\n return this._errors === undefined;\n }\n\n // string(name: string): ParamValueStringValidator {\n // return new ParamValueStringValidator(this, name, this.context.param(name));\n // }\n /* int(name, position) {\n return new ParamValueIntValidator(this, name, this.context.param(name, position));\n }\n model(modelName, name) {\n name = name || S.string.lcFirst(modelName);\n console.log('paramvalidator model', modelName, M[modelName]);\n let data = this.context.getOrPostParam(name);\n return new ParamValueModelValidator(this, name, !data ? null : new M[modelName](data));\n } */\n}\n","import type { Context } from \"../AlpNodeApp\";\nimport { ParamValidationResult } from \"./ParamValidationResult\";\n\nexport default class ParamValid extends ParamValidationResult {\n context: Context;\n\n constructor(context: Context) {\n super();\n this.context = context;\n }\n\n override _error(): void {\n this.context.throw(400, \"Invalid params\", { validator: this });\n }\n}\n","import type { ParamValidationResult } from \"./ParamValidationResult\";\n\nexport default class ParamValueValidator<T> {\n readonly validationResult: ParamValidationResult;\n\n readonly name: string;\n\n readonly value: T;\n\n constructor(validationResult: ParamValidationResult, name: string, value: T) {\n this.validationResult = validationResult;\n this.name = name;\n this.value = value;\n }\n\n isValid(): boolean {\n return this.validationResult.isValid();\n }\n\n _error(key: string): void {\n this.validationResult._error(this.name, key, this.value);\n }\n}\n","import ParamValueValidator from \"./ParamValueValidator\";\n\nexport default class ParamValueStringValidator<\n T extends string = string,\n> extends ParamValueValidator<T | null | undefined> {\n notEmpty(): ParamValueValidator<T> {\n if (this.value == null || this.value.trim() === \"\") {\n this._error(\"notEmpty\");\n }\n\n return this as ParamValueValidator<T>;\n }\n}\n","import type { Context } from \"../AlpNodeApp\";\nimport type { ParamValidationResult } from \"./ParamValidationResult\";\nimport ParamValueStringValidator from \"./ParamValueStringValidator\";\n\nexport class ParamValueFromContext {\n readonly validationResult: ParamValidationResult;\n\n readonly context: Context;\n\n constructor(context: Context, validationResult: ParamValidationResult) {\n this.validationResult = validationResult;\n this.context = context;\n }\n\n namedParam(name: string): ParamValueStringValidator {\n return new ParamValueStringValidator(\n this.validationResult,\n name,\n this.context.namedRouteParam(name),\n );\n }\n\n otherParam(position: number): ParamValueStringValidator {\n return new ParamValueStringValidator(\n this.validationResult,\n String(position),\n this.context.otherRouteParam(position),\n );\n }\n\n queryParam(name: string): ParamValueStringValidator {\n return new ParamValueStringValidator(\n this.validationResult,\n name,\n this.context.queryParam(name),\n );\n }\n\n // bodyParam: <T>(name: string): ParamValueValidator<string | undefined> {\n\n // }\n}\n","import { defineLazyProperty } from \"object-properties\";\nimport type { AlpNodeApp, Context } from \"../AlpNodeApp\";\nimport ParamValid from \"./ParamValid\";\nimport { ParamValidationResult } from \"./ParamValidationResult\";\nimport { ParamValueFromContext } from \"./ParamValueFromContext\";\n\nexport interface AlpParamsContext {\n params: ParamValueFromContext;\n validParams: ParamValueFromContext;\n namedRouteParam: (name: string) => string | undefined;\n otherRouteParam: (position: number) => string | undefined;\n /** @deprecated use namedRouteParam */\n namedParam: never;\n /** @deprecated use otherRouteParam */\n otherParam: never;\n queryParam: (name: string) => string | undefined;\n bodyParam: <T>(name: string) => T | undefined;\n}\n\nexport interface AlpParamsRequest {\n searchParams: URLSearchParams;\n}\n\nexport default function alpParams(app: AlpNodeApp): void {\n Object.assign(app.context, {\n namedRouteParam(this: Context, name: string): string | undefined {\n const namedParams = this.route.namedParams;\n return namedParams?.get(name);\n },\n\n otherRouteParam(this: Context, position: number): string | undefined {\n const otherParams = this.route.otherParams;\n return otherParams?.[position - 1];\n },\n\n queryParam(this: Context, name: string): string | undefined {\n const searchParams = this.request.searchParams;\n return searchParams.get(name) ?? undefined;\n },\n\n bodyParam<T>(this: Context, name: string): T | undefined {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n return (this.body as any)[name];\n },\n });\n\n defineLazyProperty(\n app.request,\n \"searchParams\",\n function searchParams(this: Context[\"request\"]): URLSearchParams {\n return new URLSearchParams(this.search);\n },\n );\n\n defineLazyProperty(\n app.context,\n \"params\",\n function params(this: Context): ParamValueFromContext {\n return new ParamValueFromContext(this, new ParamValidationResult());\n },\n );\n\n defineLazyProperty(\n app.context,\n \"validParams\",\n function validParams(this: Context): ParamValueFromContext {\n return new ParamValueFromContext(this, new ParamValid(this));\n },\n );\n}\n","import IntlMessageFormatDefault from \"intl-messageformat\";\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nconst IntlMessageFormat: typeof IntlMessageFormatDefault =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (IntlMessageFormatDefault as any).default || IntlMessageFormatDefault;\n\nexport type Translations = Readonly<Record<string, IntlMessageFormatDefault>>;\n\nexport default function load(\n translations: Readonly<Record<string, unknown>>,\n language: string,\n): Translations {\n const result: Record<string, IntlMessageFormatDefault> = {};\n\n (function loadMap(record: Record<string, unknown>, prefix: string) {\n Object.entries(record).forEach(([key, value]) => {\n if (typeof value === \"object\" && value !== null) {\n loadMap(value as Record<string, unknown>, `${prefix}${key}.`);\n return;\n }\n\n result[`${prefix}${key}`] = new IntlMessageFormat(\n value as string,\n language,\n );\n });\n })(translations, \"\");\n\n return result;\n}\n","import { Logger } from \"nightingale-logger\";\nimport type { AlpNodeApp, Context } from \"../AlpNodeApp\";\nimport type { Translations } from \"./load\";\nimport load from \"./load\";\n\nconst logger = new Logger(\"alp:translate\");\n\ntype Args = Record<string, any>;\n\nexport interface TranslateBaseContext {\n t: (id: string, args: Args) => string;\n}\nexport interface TranslateContext {\n readonly language: string;\n}\n\nexport default function alpTranslate(\n dirname: string,\n): (app: AlpNodeApp) => void {\n dirname = dirname.replace(/\\/*$/, \"/\");\n return (app: AlpNodeApp) => {\n const appTranslations = new Map<string, Translations>();\n\n Object.assign(app.context, {\n t(this: Context, id: string, args: Args): string {\n const msg = appTranslations.get(this.language)?.[id];\n if (!msg) {\n logger.warn(\"invalid msg\", { language: this.language, id });\n return id;\n }\n\n return msg.format(args) as string;\n },\n });\n\n const config = app.config;\n\n config.get<string[]>(\"availableLanguages\").forEach((language) => {\n const translations = app.loadConfigSync(dirname + language);\n appTranslations.set(language, load(translations, language));\n });\n\n return appTranslations;\n };\n}\n","import type {\n IncomingMessage,\n RequestListener,\n Server,\n ServerResponse,\n} from \"node:http\";\nimport path from \"node:path\";\nimport Koa from \"koa\";\nimport type { DefaultState, ParameterizedContext } from \"koa\";\nimport compress from \"koa-compress\";\nimport serve from \"koa-static\";\nimport { Logger } from \"nightingale-logger\";\nimport type { Router } from \"router-segments\";\nimport type { Config } from \"./config\";\nimport errors from \"./errors\";\nimport type { AlpLanguageContext } from \"./language\";\nimport language from \"./language\";\nimport _listen from \"./listen\";\nimport type { AlpParamsContext, AlpParamsRequest } from \"./params/index\";\nimport params from \"./params/index\";\nimport type {\n AlpRouteRef,\n RouterContext as AlpRouterContext,\n UrlGenerator,\n} from \"./router\";\nimport type { TranslateBaseContext, TranslateContext } from \"./translate/index\";\nimport translate from \"./translate/index\";\nimport type {\n Context as AlpContext,\n ContextSanitizedState,\n ContextState,\n NodeApplication,\n NodeConfig,\n} from \"./types\";\n\nconst logger = new Logger(\"alp\");\n\nexport interface AlpNodeAppOptions {\n appDirname: string;\n packageDirname: string;\n config: Config & NodeConfig;\n certPath?: string;\n publicPath?: string;\n}\n\ndeclare module \"koa\" {\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface DefaultState extends ContextState {}\n\n interface DefaultContext\n extends AlpContext,\n AlpParamsContext,\n AlpRouterContext,\n AlpLanguageContext,\n TranslateContext {}\n\n interface BaseContext extends AlpContext, TranslateBaseContext {\n urlGenerator: UrlGenerator;\n redirectTo: <P extends Record<string, unknown>>(\n to: string,\n params?: P,\n ) => void;\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface BaseRequest extends AlpParamsRequest {}\n}\n\nexport class AlpNodeApp extends Koa<ContextState> implements NodeApplication {\n dirname: string;\n\n certPath: string;\n\n publicPath: string;\n\n config: Config & NodeConfig;\n\n _server?: Server;\n\n router?: Router<any, AlpRouteRef>;\n\n /**\n * @param {Object} [options]\n * @param {string} [options.certPath] directory of the ssl certificates\n * @param {string} [options.publicPath] directory of public files\n */\n constructor({\n appDirname,\n packageDirname,\n config,\n certPath,\n publicPath,\n }: AlpNodeAppOptions) {\n super();\n\n this.dirname = path.normalize(appDirname);\n this.certPath = certPath || `${packageDirname}/config/cert`;\n this.publicPath = publicPath || `${packageDirname}/public/`;\n\n this.config = config;\n this.context.config = this.config;\n\n params(this);\n language(this);\n translate(\"locales\")(this);\n\n this.use(compress());\n }\n\n existsConfigSync(name: string): ReturnType<Config[\"existsConfigSync\"]> {\n return this.config.existsConfigSync(name);\n }\n\n loadConfigSync(name: string): ReturnType<Config[\"loadConfigSync\"]> {\n return this.config.loadConfigSync(name);\n }\n\n override createContext<StateT = DefaultState>(\n req: IncomingMessage,\n res: ServerResponse,\n ): ParameterizedContext<StateT> {\n const ctx = super.createContext<StateT>(req, res);\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n ctx.sanitizedState = {} as ContextSanitizedState;\n return ctx;\n }\n\n servePublic(): void {\n this.use(serve(this.publicPath)); // static files\n }\n\n catchErrors(): void {\n this.use(errors);\n }\n\n override listen(): never {\n throw new Error(\"Use start instead\");\n }\n\n /**\n * Close server and emit close event\n */\n close(): void {\n if (this._server) {\n this._server.close();\n this.emit(\"close\");\n }\n }\n\n async start(fn: () => Promise<void> | void): Promise<Server> {\n await fn();\n try {\n const server = await _listen(\n this.config,\n this.callback() as RequestListener,\n this.certPath,\n );\n this._server = server;\n logger.success(\"started\");\n if (process.send) process.send(\"ready\");\n return server;\n } catch (error: unknown) {\n logger.error(\"start fail\", { err: error });\n throw error;\n }\n }\n}\n\nexport type { Context } from \"koa\";\n\nexport { type NodeApplication } from \"./types\";\n","import { existsSync, readFileSync } from \"node:fs\";\nimport deepFreeze from \"deep-freeze-es6\";\nimport minimist from \"minimist\";\nimport type { NodeConfig, PackageConfig } from \"./types\";\n\nconst argv = minimist(process.argv.slice(2));\n\nfunction _existsConfigSync(dirname: string, name: string): boolean {\n return existsSync(`${dirname}${name}.json`);\n}\n\nfunction _loadConfigSync(\n dirname: string,\n name: string,\n): Record<string, unknown> {\n const content = readFileSync(`${dirname}${name}.json`, \"utf8\");\n return JSON.parse(content) as Record<string, unknown>;\n}\n\nexport interface ConfigOptions {\n argv?: string[];\n packageConfig?: PackageConfig;\n version?: string;\n}\n\nexport class Config {\n packageConfig?: PackageConfig;\n\n private _record: Record<string, unknown>;\n\n private readonly _dirname: string;\n\n constructor(dirname: string, options?: ConfigOptions) {\n this._record = {};\n this._dirname = dirname.replace(/\\/*$/, \"/\");\n if (options) {\n this.loadSync(options);\n }\n }\n\n loadSync(options: ConfigOptions = {}): Config & NodeConfig {\n const env = process.env.CONFIG_ENV || process.env.NODE_ENV || \"development\";\n const { argv: argvOverrides = [], packageConfig, version } = options;\n this.packageConfig = packageConfig;\n\n const config = _loadConfigSync(this._dirname, \"common\");\n for (const [key, value] of Object.entries(\n _loadConfigSync(this._dirname, env),\n )) {\n config[key] = value;\n }\n\n if (this.existsConfigSync(\"local\")) {\n for (const [key, value] of Object.entries(\n _loadConfigSync(this._dirname, \"local\"),\n )) {\n config[key] = value;\n }\n }\n\n if (config.version) {\n throw new Error('Cannot have \"version\", in config.');\n }\n\n config.version = String(version || argv.version || packageConfig?.version);\n\n const socketPath: string | undefined = (argv.socket ||\n argv[\"socket-path\"] ||\n argv.socketPath) as string | undefined;\n if (socketPath) {\n config.socketPath = socketPath;\n } else if (argv.port) {\n config.port = argv.port;\n delete config.socketPath;\n } else if (process.env.PORT) {\n config.port = Number(process.env.PORT);\n delete config.socketPath;\n }\n\n argvOverrides.forEach((key) => {\n const splitted = key.split(\".\");\n const value =\n splitted.length > 0 &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return,unicorn/no-array-reduce\n splitted.reduce((config, partialKey) => config[partialKey], argv);\n if (value !== undefined) {\n const last = splitted.pop()!;\n const v =\n splitted.length === 0\n ? config\n : // eslint-disable-next-line unicorn/no-array-reduce\n splitted.reduce(\n (config, partialKey) =>\n config[partialKey] as Record<string, unknown>,\n config,\n );\n v[last] = value;\n }\n });\n\n this._record = deepFreeze(config);\n return this as unknown as Config & NodeConfig;\n }\n\n get<T>(key: string): Readonly<T> {\n return this._record[key] as T;\n }\n\n existsConfigSync(name: string): boolean {\n return _existsConfigSync(this._dirname, name);\n }\n\n loadConfigSync(name: string): Readonly<Record<string, unknown>> {\n return _loadConfigSync(this._dirname, name);\n }\n}\n","import type {\n LocaleType,\n RouteMatch,\n Router,\n RouterBuilder,\n} from \"router-segments\";\nimport { createRouterBuilder } from \"router-segments\";\nimport type { AlpNodeApp, Context } from \"./AlpNodeApp\";\n\nexport type AlpRouter<Locales extends LocaleType> = Router<\n Locales,\n AlpRouteRef\n>;\nexport type AlpRouteRef = (ctx: Context) => Promise<void> | void;\ntype ReturnType = (app: AlpNodeApp) => AlpRouteRef;\n\nexport interface RouterContext {\n route: RouteMatch<any, AlpRouteRef>;\n}\nexport const createAlpRouterBuilder = <\n Locales extends LocaleType,\n>(): RouterBuilder<Locales, AlpRouteRef> =>\n createRouterBuilder<Locales, AlpRouteRef>();\n\nexport type UrlGenerator = <P extends Record<string, unknown> | undefined>(\n routeKey: string,\n params?: P,\n) => string;\n\nexport default function alpRouter<Locales extends string>(\n router: Router<Locales, AlpRouteRef>,\n): ReturnType {\n return (app: AlpNodeApp) => {\n app.router = router;\n\n app.context.urlGenerator = function urlGenerator<\n P extends Record<string, unknown> | undefined,\n >(this: Context, routeKey: string, params?: P): string {\n return router.toLocalizedPath(this.language as Locales, routeKey, params);\n };\n\n app.context.redirectTo = function redirectTo<\n P extends Record<string, unknown> | undefined,\n >(this: Context, to: string, params?: P): void {\n this.redirect(\n router.toLocalizedPath(this.language as Locales, to, params),\n );\n };\n\n return async (ctx: Context): Promise<void> => {\n // eslint-disable-next-line unicorn/no-array-method-this-argument\n const routeMatch = router.find(ctx.request.path, ctx.language as Locales);\n\n if (!routeMatch) {\n ctx.status = 404;\n throw new Error(`Route not found: ${ctx.request.path}`);\n }\n\n ctx.route = routeMatch;\n\n await routeMatch.ref(ctx);\n };\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { Logger } from \"nightingale-logger\";\nimport type { AlpNodeAppOptions } from \"./AlpNodeApp\";\nimport { AlpNodeApp } from \"./AlpNodeApp\";\nimport { Config } from \"./config\";\n\nexport type {\n BaseContext,\n NodeApplication,\n NodeConfig,\n ContextState,\n ContextSanitizedState,\n} from \"./types\";\nexport type { Context } from \"./AlpNodeApp\";\n\nconst logger = new Logger(\"alp\");\n\nexport const appDirname = path.resolve(\"build\");\n\nconst packagePath = path.resolve(\"package.json\");\nif (!packagePath) {\n throw new Error(`Could not find package.json: \"${String(packagePath)}\"`);\n}\nexport const packageDirname = path.dirname(packagePath);\n\nlogger.debug(\"init\", { appDirname, packageDirname });\n\nexport const packageConfig: Record<string, unknown> = JSON.parse(\n readFileSync(packagePath, \"utf8\"),\n) as Record<string, unknown>;\n\nconst buildedConfigPath = `${appDirname}/build/config/`;\nconst configPath = existsSync(buildedConfigPath)\n ? buildedConfigPath\n : `${appDirname}/config/`;\n\nexport const config = new Config(configPath).loadSync({ packageConfig });\n\nexport type AppOptions = Omit<\n AlpNodeAppOptions,\n \"appDirname\" | \"config\" | \"packageDirname\"\n>;\n\nexport default class App extends AlpNodeApp {\n constructor(options?: AppOptions) {\n super({\n ...options,\n appDirname,\n packageDirname,\n config,\n });\n }\n}\n\nexport { Config } from \"./config\";\n\nexport {\n default as router,\n createAlpRouterBuilder,\n type AlpRouteRef,\n type AlpRouter,\n} from \"./router\";\n"],"names":["logger","Logger","errorHtmlRenderer","ErrorHtmlRenderer","appPath","process","cwd","alpNodeErrors","ctx","next","error","Error","status","request","accepts","type","env","NODE_ENV","expose","body","message","STATUS_CODES","render","alpLanguage","app","config","context","availableLanguages","get","defineLazyProperty","language","acceptsLanguages","firstAcceptedLanguage","createServer","callback","socketPath","tls","dirname","createHttpServer","createServerHttps","createServerHttp","options","key","readFileSync","cert","alpListen","Promise","resolve","port","hostname","info","server","unlinkSync","listen","chmodSync","ParamValidationResult","_error","name","value","_errors","getErrors","hasErrors","undefined","isValid","ParamValid","constructor","throw","validator","ParamValueValidator","validationResult","ParamValueStringValidator","notEmpty","trim","ParamValueFromContext","namedParam","namedRouteParam","otherParam","position","String","otherRouteParam","queryParam","alpParams","Object","assign","namedParams","route","otherParams","searchParams","bodyParam","URLSearchParams","search","params","validParams","IntlMessageFormat","IntlMessageFormatDefault","default","load","translations","result","loadMap","record","prefix","entries","forEach","alpTranslate","replace","appTranslations","Map","t","id","args","msg","warn","format","loadConfigSync","set","AlpNodeApp","Koa","appDirname","packageDirname","certPath","publicPath","path","normalize","translate","use","compress","existsConfigSync","createContext","req","res","sanitizedState","servePublic","serve","catchErrors","errors","close","_server","emit","start","fn","_listen","success","send","err","argv","minimist","slice","_existsConfigSync","existsSync","_loadConfigSync","content","JSON","parse","Config","_record","_dirname","loadSync","CONFIG_ENV","argvOverrides","packageConfig","version","socket","PORT","Number","splitted","split","length","reduce","partialKey","last","pop","v","deepFreeze","createAlpRouterBuilder","createRouterBuilder","alpRouter","router","urlGenerator","routeKey","toLocalizedPath","redirectTo","to","redirect","routeMatch","find","ref","packagePath","debug","buildedConfigPath","configPath","App"],"mappings":"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"}
|