alp-node 6.1.1 → 7.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/AlpNodeApp-node18.mjs +303 -12
  3. package/dist/AlpNodeApp-node18.mjs.map +1 -1
  4. package/dist/definitions/AlpNodeApp.d.ts +15 -7
  5. package/dist/definitions/AlpNodeApp.d.ts.map +1 -1
  6. package/dist/definitions/config.d.ts +18 -0
  7. package/dist/definitions/config.d.ts.map +1 -0
  8. package/dist/definitions/errors.d.ts +4 -0
  9. package/dist/definitions/errors.d.ts.map +1 -0
  10. package/dist/definitions/index.d.ts +5 -3
  11. package/dist/definitions/index.d.ts.map +1 -1
  12. package/dist/definitions/language.d.ts +7 -0
  13. package/dist/definitions/language.d.ts.map +1 -0
  14. package/dist/definitions/listen.d.ts +7 -0
  15. package/dist/definitions/listen.d.ts.map +1 -0
  16. package/dist/definitions/params/ParamValid.d.ts +9 -0
  17. package/dist/definitions/params/ParamValid.d.ts.map +1 -0
  18. package/dist/definitions/params/ParamValidationResult.d.ts +9 -0
  19. package/dist/definitions/params/ParamValidationResult.d.ts.map +1 -0
  20. package/dist/definitions/params/ParamValidationResult.test.d.ts +2 -0
  21. package/dist/definitions/params/ParamValidationResult.test.d.ts.map +1 -0
  22. package/dist/definitions/params/ParamValueFromContext.d.ts +13 -0
  23. package/dist/definitions/params/ParamValueFromContext.d.ts.map +1 -0
  24. package/dist/definitions/params/ParamValueModelValidator.d.ts +4 -0
  25. package/dist/definitions/params/ParamValueModelValidator.d.ts.map +1 -0
  26. package/dist/definitions/params/ParamValueStringValidator.d.ts +5 -0
  27. package/dist/definitions/params/ParamValueStringValidator.d.ts.map +1 -0
  28. package/dist/definitions/params/ParamValueValidator.d.ts +10 -0
  29. package/dist/definitions/params/ParamValueValidator.d.ts.map +1 -0
  30. package/dist/definitions/params/index.d.ts +15 -0
  31. package/dist/definitions/params/index.d.ts.map +1 -0
  32. package/dist/definitions/router.d.ts +14 -0
  33. package/dist/definitions/router.d.ts.map +1 -0
  34. package/dist/definitions/translate/index.d.ts +11 -0
  35. package/dist/definitions/translate/index.d.ts.map +1 -0
  36. package/dist/definitions/translate/load.d.ts +4 -0
  37. package/dist/definitions/translate/load.d.ts.map +1 -0
  38. package/dist/definitions/types.d.ts +53 -0
  39. package/dist/definitions/types.d.ts.map +1 -0
  40. package/dist/index-node18.mjs +402 -15
  41. package/dist/index-node18.mjs.map +1 -1
  42. package/package.json +8 -9
  43. package/src/AlpNodeApp.ts +42 -21
  44. package/src/config.ts +121 -0
  45. package/src/errors.ts +70 -0
  46. package/src/index.ts +18 -3
  47. package/src/language.ts +27 -0
  48. package/src/listen.ts +68 -0
  49. package/src/params/ParamValid.ts +15 -0
  50. package/src/params/ParamValidationResult.test.ts +65 -0
  51. package/src/params/ParamValidationResult.ts +38 -0
  52. package/src/params/ParamValueFromContext.ts +42 -0
  53. package/src/params/ParamValueModelValidator.ts +36 -0
  54. package/src/params/ParamValueStringValidator.ts +13 -0
  55. package/src/params/ParamValueValidator.ts +23 -0
  56. package/src/params/index.ts +66 -0
  57. package/src/router.ts +64 -0
  58. package/src/translate/index.ts +45 -0
  59. package/src/translate/load.ts +30 -0
  60. package/src/types.ts +67 -0
@@ -0,0 +1,9 @@
1
+ export type Errors = Record<string, any>;
2
+ export declare class ParamValidationResult {
3
+ _errors?: Errors;
4
+ _error(name: string, key: string, value: unknown): void;
5
+ getErrors(): Errors | undefined;
6
+ hasErrors(): boolean;
7
+ isValid(): boolean;
8
+ }
9
+ //# sourceMappingURL=ParamValidationResult.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamValidationResult.d.ts","sourceRoot":"","sources":["../../../src/params/ParamValidationResult.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEzC,qBAAa,qBAAqB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQvD,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B,SAAS,IAAI,OAAO;IAIpB,OAAO,IAAI,OAAO;CAgBnB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ParamValidationResult.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamValidationResult.test.d.ts","sourceRoot":"","sources":["../../../src/params/ParamValidationResult.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ /// <reference types="koa" />
2
+ import type { Context } from '../AlpNodeApp';
3
+ import type { ParamValidationResult } from './ParamValidationResult';
4
+ import ParamValueStringValidator from './ParamValueStringValidator';
5
+ export declare class ParamValueFromContext {
6
+ readonly validationResult: ParamValidationResult;
7
+ readonly context: Context;
8
+ constructor(context: Context, validationResult: ParamValidationResult);
9
+ namedParam(name: string): ParamValueStringValidator;
10
+ otherParam(position: number): ParamValueStringValidator;
11
+ queryParam(name: string): ParamValueStringValidator;
12
+ }
13
+ //# sourceMappingURL=ParamValueFromContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamValueFromContext.d.ts","sourceRoot":"","sources":["../../../src/params/ParamValueFromContext.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,yBAAyB,MAAM,6BAA6B,CAAC;AAEpE,qBAAa,qBAAqB;IAChC,QAAQ,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;IAEjD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,qBAAqB;IAKrE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,yBAAyB;IAQnD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,yBAAyB;IAQvD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,yBAAyB;CAWpD"}
@@ -0,0 +1,4 @@
1
+ import ParamValueValidator from './ParamValueValidator';
2
+ export default class ParamValueModelValidator<T> extends ParamValueValidator<T> {
3
+ }
4
+ //# sourceMappingURL=ParamValueModelValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamValueModelValidator.d.ts","sourceRoot":"","sources":["../../../src/params/ParamValueModelValidator.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AAExD,MAAM,CAAC,OAAO,OAAO,wBAAwB,CAC3C,CAAC,CACD,SAAQ,mBAAmB,CAAC,CAAC,CAAC;CA+B/B"}
@@ -0,0 +1,5 @@
1
+ import ParamValueValidator from './ParamValueValidator';
2
+ export default class ParamValueStringValidator<T extends string = string> extends ParamValueValidator<T | null | undefined> {
3
+ notEmpty(): ParamValueValidator<T>;
4
+ }
5
+ //# sourceMappingURL=ParamValueStringValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamValueStringValidator.d.ts","sourceRoot":"","sources":["../../../src/params/ParamValueStringValidator.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AAExD,MAAM,CAAC,OAAO,OAAO,yBAAyB,CAC5C,CAAC,SAAS,MAAM,GAAG,MAAM,CACzB,SAAQ,mBAAmB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD,QAAQ,IAAI,mBAAmB,CAAC,CAAC,CAAC;CAOnC"}
@@ -0,0 +1,10 @@
1
+ import type { ParamValidationResult } from './ParamValidationResult';
2
+ export default class ParamValueValidator<T> {
3
+ readonly validationResult: ParamValidationResult;
4
+ readonly name: string;
5
+ readonly value: T;
6
+ constructor(validationResult: ParamValidationResult, name: string, value: T);
7
+ isValid(): boolean;
8
+ _error(key: string): void;
9
+ }
10
+ //# sourceMappingURL=ParamValueValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamValueValidator.d.ts","sourceRoot":"","sources":["../../../src/params/ParamValueValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,MAAM,CAAC,OAAO,OAAO,mBAAmB,CAAC,CAAC;IACxC,QAAQ,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;IAEjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;gBAEN,gBAAgB,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAM3E,OAAO,IAAI,OAAO;IAIlB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG1B"}
@@ -0,0 +1,15 @@
1
+ import type { AlpNodeApp } from '../AlpNodeApp';
2
+ import { ParamValueFromContext } from './ParamValueFromContext';
3
+ export interface AlpParamsContext {
4
+ params: ParamValueFromContext;
5
+ validParams: ParamValueFromContext;
6
+ namedParam: (name: string) => string | undefined;
7
+ otherParam: (position: number) => string | undefined;
8
+ queryParam: (name: string) => string | undefined;
9
+ bodyParam: <T>(name: string) => T | undefined;
10
+ }
11
+ export interface AlpParamsRequest {
12
+ searchParams: URLSearchParams;
13
+ }
14
+ export default function alpParams(app: AlpNodeApp): void;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/params/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,eAAe,CAAC;AAGzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,WAAW,EAAE,qBAAqB,CAAC;IACnC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACjD,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACrD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACjD,SAAS,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,eAAe,CAAC;CAC/B;AAED,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CA8CvD"}
@@ -0,0 +1,14 @@
1
+ /// <reference types="koa" />
2
+ import type { Router, LocaleType, RouterBuilder, RouteMatch } from 'router-segments';
3
+ import type { AlpNodeApp, Context } from './AlpNodeApp';
4
+ export type AlpRouter<Locales extends LocaleType> = Router<Locales, AlpRouteRef>;
5
+ export type AlpRouteRef = (ctx: Context) => Promise<void> | void;
6
+ type ReturnType = (app: AlpNodeApp) => AlpRouteRef;
7
+ export interface RouterContext {
8
+ route: RouteMatch<any, AlpRouteRef>;
9
+ }
10
+ export declare const createAlpRouterBuilder: <Locales extends string>() => RouterBuilder<Locales, AlpRouteRef>;
11
+ export type UrlGenerator = <P extends Record<string, unknown> | undefined>(routeKey: string, params?: P) => string;
12
+ export default function alpRouter<Locales extends string>(router: Router<Locales, AlpRouteRef>): ReturnType;
13
+ export {};
14
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/router.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,aAAa,EACb,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,MAAM,SAAS,CAAC,OAAO,SAAS,UAAU,IAAI,MAAM,CACxD,OAAO,EACP,WAAW,CACZ,CAAC;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjE,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,WAAW,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;CACrC;AACD,eAAO,MAAM,sBAAsB,mEAGU,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACvE,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,CAAC,KACP,MAAM,CAAC;AAEZ,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,OAAO,SAAS,MAAM,EACtD,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,GACnC,UAAU,CAgCZ"}
@@ -0,0 +1,11 @@
1
+ import type { AlpNodeApp } from '../AlpNodeApp';
2
+ type Args = Record<string, any>;
3
+ export interface TranslateBaseContext {
4
+ t: (id: string, args: Args) => string;
5
+ }
6
+ export interface TranslateContext {
7
+ readonly language: string;
8
+ }
9
+ export default function alpTranslate(dirname: string): (app: AlpNodeApp) => void;
10
+ export {};
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/translate/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,eAAe,CAAC;AAMzD,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEhC,MAAM,WAAW,oBAAoB;IACnC,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;CACvC;AACD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,OAAO,EAAE,MAAM,GACd,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CA0B3B"}
@@ -0,0 +1,4 @@
1
+ import IntlMessageFormatDefault from 'intl-messageformat';
2
+ export type Translations = ReadonlyMap<string, IntlMessageFormatDefault>;
3
+ export default function load(translations: ReadonlyMap<string, unknown>, language: string): Translations;
4
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/translate/load.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,MAAM,oBAAoB,CAAC;AAO1D,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;AAEzE,MAAM,CAAC,OAAO,UAAU,IAAI,CAC1B,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,QAAQ,EAAE,MAAM,GACf,YAAY,CAiBd"}
@@ -0,0 +1,53 @@
1
+ type RawConfig = ReadonlyMap<string, any>;
2
+ export interface Config {
3
+ get: <T>(key: string) => T;
4
+ }
5
+ export type PackageConfig = Record<string, any>;
6
+ export interface NodeConfig extends Config {
7
+ loadConfigSync: (name: string) => RawConfig;
8
+ readonly packageConfig: PackageConfig;
9
+ }
10
+ export interface ContextState {
11
+ }
12
+ export interface ContextSanitizedState {
13
+ }
14
+ export interface BaseContext {
15
+ config: Config;
16
+ }
17
+ export interface Context extends BaseContext {
18
+ state: ContextState;
19
+ sanitizedState: ContextSanitizedState;
20
+ status: number;
21
+ response: any;
22
+ redirect: (url: string) => Promise<void>;
23
+ [key: string]: any;
24
+ }
25
+ export interface ApplicationInCreation {
26
+ config?: Config;
27
+ context: BaseContext;
28
+ }
29
+ export interface Application extends ApplicationInCreation {
30
+ config: Config;
31
+ }
32
+ export interface NodeApplicationInCreation extends ApplicationInCreation {
33
+ loadConfigSync: (name: string) => RawConfig;
34
+ }
35
+ export interface BrowserApplicationInCreation extends ApplicationInCreation {
36
+ appVersion: string;
37
+ existsConfig: (name: string) => Promise<boolean> | boolean;
38
+ loadConfig: (name: string) => Promise<RawConfig>;
39
+ createContext: () => Context;
40
+ }
41
+ export interface NodeApplication extends Application, NodeApplicationInCreation {
42
+ config: NodeConfig;
43
+ dirname: string;
44
+ on: (event: 'close', callback: () => void) => void;
45
+ existsConfigSync: (name: string) => boolean;
46
+ loadConfigSync: (name: string) => RawConfig;
47
+ }
48
+ export interface HtmlError extends Error {
49
+ status: number;
50
+ expose?: true;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE1C,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,CAAC;CAC5B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEhD,MAAM,WAAW,UAAW,SAAQ,MAAM;IACxC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IAC5C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;CACvC;AAGD,MAAM,WAAW,YAAY;CAAG;AAGhC,MAAM,WAAW,qBAAqB;CAAG;AAEzC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAQ,SAAQ,WAAW;IAC1C,KAAK,EAAE,YAAY,CAAC;IACpB,cAAc,EAAE,qBAAqB,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;IAEf,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,qBAAqB;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACtE,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;CAC7C;AAED,MAAM,WAAW,4BAA6B,SAAQ,qBAAqB;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC3D,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,aAAa,EAAE,MAAM,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,eACf,SAAQ,WAAW,EACjB,yBAAyB;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;CAC7C;AAED,MAAM,WAAW,SAAU,SAAQ,KAAK;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;CACf"}
@@ -1,17 +1,381 @@
1
- import { readFileSync, existsSync } from 'node:fs';
1
+ import { existsSync, readFileSync, unlinkSync, chmodSync } from 'node:fs';
2
2
  import path from 'node:path';
3
- import _config, { Config } from 'alp-node-config';
4
- export { Config } from 'alp-node-config';
5
3
  import { Logger } from 'nightingale-logger';
6
4
  import { deprecate } from 'node:util';
7
- import _listen from 'alp-listen';
8
- import errors from 'alp-node-errors';
9
- import language from 'alp-node-language';
10
- import params from 'alp-params';
11
- import translate from 'alp-translate';
12
5
  import Koa from 'koa';
13
6
  import compress from 'koa-compress';
14
7
  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
+ import { STATUS_CODES, createServer as createServer$2 } from 'node:http';
12
+ import ErrorHtmlRenderer from 'error-html';
13
+ import { defineLazyProperty } from 'object-properties';
14
+ import { createServer as createServer$1 } from 'node:https';
15
+ import IntlMessageFormatDefault from 'intl-messageformat';
16
+ import { createRouterBuilder } from 'router-segments';
17
+
18
+ const argv = minimist(process.argv.slice(2));
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');
99
+ const errorHtmlRenderer = new ErrorHtmlRenderer({
100
+ appPath: `${process.cwd()}/`
101
+ });
102
+ async function alpNodeErrors(ctx, next) {
103
+ try {
104
+ await next();
105
+ } catch (error) {
106
+ // eslint-disable-next-line no-ex-assign
107
+ if (!error) error = new Error('Unknown error');
108
+ // eslint-disable-next-line no-ex-assign
109
+ if (typeof error === 'string') error = new Error(error);
110
+ ctx.status = error.status || 500;
111
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
112
+ logger$4.error(error);
113
+ switch (ctx.request.accepts('html', 'text', 'json')) {
114
+ case 'json':
115
+ ctx.type = 'application/json';
116
+ if (process.env.NODE_ENV !== 'production' || error.expose) {
117
+ ctx.body = {
118
+ error: error.message
119
+ };
120
+ } else {
121
+ ctx.body = {
122
+ error: STATUS_CODES[ctx.status]
123
+ };
124
+ }
125
+ break;
126
+ case 'html':
127
+ ctx.type = 'text/html';
128
+ if (process.env.NODE_ENV !== 'production') {
129
+ ctx.body = errorHtmlRenderer.render(error);
130
+ } else if (error.expose) {
131
+ ctx.body = error.message;
132
+ } else {
133
+ throw error;
134
+ }
135
+ break;
136
+ case 'text':
137
+ default:
138
+ ctx.type = 'text/plain';
139
+ if (process.env.NODE_ENV !== 'production' || error.expose) {
140
+ ctx.body = error.message;
141
+ } else {
142
+ throw error;
143
+ }
144
+ break;
145
+ }
146
+ }
147
+ }
148
+
149
+ function alpLanguage(app) {
150
+ const config = app.context.config;
151
+ const availableLanguages = config.get('availableLanguages');
152
+ if (!availableLanguages) {
153
+ throw new Error('Missing config "availableLanguages"');
154
+ }
155
+ defineLazyProperty(app.context, 'language', function () {
156
+ return this.acceptsLanguages(availableLanguages) || availableLanguages[0];
157
+ });
158
+ defineLazyProperty(app.context, 'firstAcceptedLanguage', function () {
159
+ return this.acceptsLanguages()[0] || availableLanguages[0];
160
+ });
161
+ }
162
+
163
+ const logger$3 = new Logger('alp:listen');
164
+ const createServer = (callback, socketPath, tls, dirname = ''
165
+ // eslint-disable-next-line @typescript-eslint/max-params
166
+ ) => {
167
+ const createHttpServer = !socketPath && tls ? createServer$1 : createServer$2;
168
+ if (!tls) {
169
+ return createHttpServer(callback);
170
+ }
171
+ const options = {
172
+ key: readFileSync(`${dirname}/server.key`),
173
+ cert: readFileSync(`${dirname}/server.crt`)
174
+ };
175
+ return createHttpServer(options, callback);
176
+ };
177
+ function alpListen(config, callback, dirname) {
178
+ return new Promise(resolve => {
179
+ const socketPath = config.get('socketPath');
180
+ const port = config.get('port');
181
+ const hostname = config.get('hostname');
182
+ const tls = config.get('tls');
183
+ logger$3.info('Creating server', socketPath ? {
184
+ socketPath
185
+ } : {
186
+ port
187
+ });
188
+ const server = createServer(callback, socketPath, tls, dirname);
189
+ if (socketPath) {
190
+ try {
191
+ unlinkSync(socketPath);
192
+ } catch {}
193
+ server.listen(socketPath, () => {
194
+ if (socketPath) {
195
+ chmodSync(socketPath, '777');
196
+ }
197
+ logger$3.info('Server listening', {
198
+ socketPath
199
+ });
200
+ resolve(server);
201
+ });
202
+ } else {
203
+ server.listen(port, hostname, () => {
204
+ logger$3.info('Server listening', {
205
+ port
206
+ });
207
+ resolve(server);
208
+ });
209
+ }
210
+ });
211
+ }
212
+
213
+ class ParamValidationResult {
214
+ _error(name, key, value) {
215
+ if (!this._errors) {
216
+ this._errors = {};
217
+ }
218
+ this._errors[name] = {
219
+ error: key,
220
+ value
221
+ };
222
+ }
223
+ getErrors() {
224
+ return this._errors;
225
+ }
226
+ hasErrors() {
227
+ return this._errors !== undefined;
228
+ }
229
+ isValid() {
230
+ return this._errors === undefined;
231
+ }
232
+
233
+ // string(name: string): ParamValueStringValidator {
234
+ // return new ParamValueStringValidator(this, name, this.context.param(name));
235
+ // }
236
+ /* int(name, position) {
237
+ return new ParamValueIntValidator(this, name, this.context.param(name, position));
238
+ }
239
+ model(modelName, name) {
240
+ name = name || S.string.lcFirst(modelName);
241
+ console.log('paramvalidator model', modelName, M[modelName]);
242
+ let data = this.context.getOrPostParam(name);
243
+ return new ParamValueModelValidator(this, name, !data ? null : new M[modelName](data));
244
+ } */
245
+ }
246
+
247
+ class ParamValid extends ParamValidationResult {
248
+ constructor(context) {
249
+ super();
250
+ this.context = context;
251
+ }
252
+ _error() {
253
+ this.context.throw(400, 'Invalid params', {
254
+ validator: this
255
+ });
256
+ }
257
+ }
258
+
259
+ class ParamValueValidator {
260
+ constructor(validationResult, name, value) {
261
+ this.validationResult = validationResult;
262
+ this.name = name;
263
+ this.value = value;
264
+ }
265
+ isValid() {
266
+ return this.validationResult.isValid();
267
+ }
268
+ _error(key) {
269
+ this.validationResult._error(this.name, key, this.value);
270
+ }
271
+ }
272
+
273
+ class ParamValueStringValidator extends ParamValueValidator {
274
+ notEmpty() {
275
+ if (this.value == null || this.value.trim() === '') {
276
+ this._error('notEmpty');
277
+ }
278
+ return this;
279
+ }
280
+ }
281
+
282
+ class ParamValueFromContext {
283
+ constructor(context, validationResult) {
284
+ this.validationResult = validationResult;
285
+ this.context = context;
286
+ }
287
+ namedParam(name) {
288
+ return new ParamValueStringValidator(this.validationResult, name, this.context.namedParam(name));
289
+ }
290
+ otherParam(position) {
291
+ return new ParamValueStringValidator(this.validationResult, String(position), this.context.otherParam(position));
292
+ }
293
+ queryParam(name) {
294
+ return new ParamValueStringValidator(this.validationResult, name, this.context.queryParam(name));
295
+ }
296
+
297
+ // bodyParam: <T>(name: string): ParamValueValidator<string | undefined> {
298
+
299
+ // }
300
+ }
301
+
302
+ function alpParams(app) {
303
+ Object.assign(app.context, {
304
+ namedRouteParam(name) {
305
+ const namedParams = this.route.namedParams;
306
+ return namedParams?.get(name);
307
+ },
308
+ otherRouteParam(position) {
309
+ const otherParams = this.route.otherParams;
310
+ return otherParams?.[position - 1];
311
+ },
312
+ queryParam(name) {
313
+ const searchParams = this.request.searchParams;
314
+ return searchParams.get(name) ?? undefined;
315
+ },
316
+ bodyParam(name) {
317
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
318
+ return this.body[name];
319
+ }
320
+ });
321
+ defineLazyProperty(app.request, 'searchParams', function () {
322
+ return new URLSearchParams(this.search);
323
+ });
324
+ defineLazyProperty(app.context, 'params', function () {
325
+ return new ParamValueFromContext(this, new ParamValidationResult());
326
+ });
327
+ defineLazyProperty(app.context, 'validParams', function () {
328
+ return new ParamValueFromContext(this, new ParamValid(this));
329
+ });
330
+ }
331
+
332
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
333
+ const IntlMessageFormat =
334
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
335
+ IntlMessageFormatDefault.default || IntlMessageFormatDefault;
336
+ function load(translations, language) {
337
+ const result = new Map();
338
+ (function loadMap(map, prefix) {
339
+ map.forEach((value, key) => {
340
+ if (typeof value === 'object') {
341
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
342
+ loadMap(value, `${prefix}${key}.`);
343
+ return;
344
+ }
345
+
346
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
347
+ result.set(`${prefix}${key}`, new IntlMessageFormat(value, language));
348
+ });
349
+ })(translations, '');
350
+ return result;
351
+ }
352
+
353
+ const logger$2 = new Logger('alp:translate');
354
+ function alpTranslate(dirname) {
355
+ dirname = dirname.replace(/\/*$/, '/');
356
+ return app => {
357
+ const appTranslations = new Map();
358
+ Object.assign(app.context, {
359
+ t(id, args) {
360
+ const msg = appTranslations.get(this.language).get(id);
361
+ if (!msg) {
362
+ logger$2.warn('invalid msg', {
363
+ language: this.language,
364
+ id
365
+ });
366
+ return id;
367
+ }
368
+ return msg.format(args);
369
+ }
370
+ });
371
+ const config = app.config;
372
+ config.get('availableLanguages').forEach(language => {
373
+ const translations = app.loadConfigSync(dirname + language);
374
+ appTranslations.set(language, load(translations, language));
375
+ });
376
+ return appTranslations;
377
+ };
378
+ }
15
379
 
16
380
  const logger$1 = new Logger('alp');
17
381
  class AlpNodeApp extends Koa {
@@ -36,11 +400,11 @@ class AlpNodeApp extends Koa {
36
400
  });
37
401
  this.certPath = certPath || `${packageDirname}/config/cert`;
38
402
  this.publicPath = publicPath || `${packageDirname}/public/`;
39
- this.config = _config(this, config);
403
+ this.config = getConfig(this, config);
40
404
  this.context.config = this.config;
41
- params(this);
42
- language(this);
43
- translate('locales')(this);
405
+ alpParams(this);
406
+ alpLanguage(this);
407
+ alpTranslate('locales')(this);
44
408
  this.use(compress());
45
409
  }
46
410
  existsConfigSync(name) {
@@ -58,7 +422,7 @@ class AlpNodeApp extends Koa {
58
422
  this.use(serve(this.publicPath)); // static files
59
423
  }
60
424
  catchErrors() {
61
- this.use(errors);
425
+ this.use(alpNodeErrors);
62
426
  }
63
427
 
64
428
  // eslint-disable-next-line @typescript-eslint/class-methods-use-this
@@ -78,7 +442,7 @@ class AlpNodeApp extends Koa {
78
442
  async start(fn) {
79
443
  await fn();
80
444
  try {
81
- const server = await _listen(this.config, this.callback(), this.certPath);
445
+ const server = await alpListen(this.config, this.callback(), this.certPath);
82
446
  this._server = server;
83
447
  logger$1.success('started');
84
448
  if (process.send) process.send('ready');
@@ -92,6 +456,29 @@ class AlpNodeApp extends Koa {
92
456
  }
93
457
  }
94
458
 
459
+ const createAlpRouterBuilder = () => createRouterBuilder();
460
+ function alpRouter(router) {
461
+ return app => {
462
+ app.router = router;
463
+ app.context.urlGenerator = function (routeKey, params) {
464
+ return router.toLocalizedPath(this.language, routeKey, params);
465
+ };
466
+ app.context.redirectTo = function (to, params) {
467
+ this.redirect(router.toLocalizedPath(this.language, to, params));
468
+ };
469
+ return async ctx => {
470
+ // eslint-disable-next-line unicorn/no-array-method-this-argument
471
+ const routeMatch = router.find(ctx.request.path, ctx.language);
472
+ if (!routeMatch) {
473
+ ctx.status = 404;
474
+ throw new Error(`Route not found: ${ctx.request.path}`);
475
+ }
476
+ ctx.route = routeMatch;
477
+ await routeMatch.ref(ctx);
478
+ };
479
+ };
480
+ }
481
+
95
482
  const logger = new Logger('alp');
96
483
  const appDirname = path.resolve('build');
97
484
  const packagePath = path.resolve('package.json');
@@ -120,5 +507,5 @@ class App extends AlpNodeApp {
120
507
  }
121
508
  }
122
509
 
123
- export { appDirname, config, App as default, packageConfig, packageDirname };
510
+ export { Config, appDirname, config, createAlpRouterBuilder, App as default, packageConfig, packageDirname, alpRouter as router };
124
511
  //# sourceMappingURL=index-node18.mjs.map