akanjs 3.0.0-alpha.45 → 3.0.0-alpha.46
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/base/primitiveRegistry.ts +14 -10
- package/common/index.ts +1 -0
- package/common/routeConvention.ts +22 -12
- package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
- package/package.json +1 -1
- package/service/adapt.ts +4 -4
- package/service/serve.ts +7 -6
- package/signal/intercept.ts +4 -4
- package/types/base/primitiveRegistry.d.ts +6 -6
- package/types/common/index.d.ts +1 -1
- package/types/common/routeConvention.d.ts +6 -0
- package/types/service/adapt.d.ts +2 -2
- package/types/service/serve.d.ts +2 -2
- package/types/signal/intercept.d.ts +2 -2
|
@@ -209,12 +209,12 @@ declare global {
|
|
|
209
209
|
[DEFAULT_VALUE]: boolean;
|
|
210
210
|
[PURIFIED_VALUE]: boolean;
|
|
211
211
|
[EXAMPLE_VALUE]: boolean;
|
|
212
|
-
validate(value: boolean | number): boolean;
|
|
213
|
-
parseValue(input: boolean | number): boolean | number;
|
|
214
|
-
serializeValue(value: boolean | number): boolean | number;
|
|
215
|
-
_parse(input: boolean | number): boolean;
|
|
216
|
-
_serialize(value: boolean | number): boolean;
|
|
217
|
-
_checkValue(value: boolean | number): void;
|
|
212
|
+
validate(value: boolean | number | string): boolean;
|
|
213
|
+
parseValue(input: boolean | number | string): boolean | number | string;
|
|
214
|
+
serializeValue(value: boolean | number | string): boolean | number | string;
|
|
215
|
+
_parse(input: boolean | number | string): boolean;
|
|
216
|
+
_serialize(value: boolean | number | string): boolean;
|
|
217
|
+
_checkValue(value: boolean | number | string): void;
|
|
218
218
|
}
|
|
219
219
|
interface DateConstructor {
|
|
220
220
|
refName: "Date";
|
|
@@ -305,10 +305,14 @@ Object.assign(String, scalarPrimitiveStatics, {
|
|
|
305
305
|
});
|
|
306
306
|
PrimitiveRegistry.register(String);
|
|
307
307
|
|
|
308
|
-
const normalizeBooleanPrimitiveValue = (value: boolean | number): boolean | null => {
|
|
308
|
+
const normalizeBooleanPrimitiveValue = (value: boolean | number | string): boolean | null => {
|
|
309
309
|
if (typeof value === "boolean") return value;
|
|
310
310
|
if (value === 1) return true;
|
|
311
311
|
if (value === 0) return false;
|
|
312
|
+
if (typeof value !== "string") return null;
|
|
313
|
+
const text = value.trim().toLowerCase();
|
|
314
|
+
if (text === "true" || text === "1") return true;
|
|
315
|
+
if (text === "false" || text === "0") return false;
|
|
312
316
|
return null;
|
|
313
317
|
};
|
|
314
318
|
|
|
@@ -317,13 +321,13 @@ Object.assign(Boolean, {
|
|
|
317
321
|
refName: "Boolean",
|
|
318
322
|
[DEFAULT_VALUE]: false,
|
|
319
323
|
[EXAMPLE_VALUE]: true,
|
|
320
|
-
validate(value: boolean | number) {
|
|
324
|
+
validate(value: boolean | number | string) {
|
|
321
325
|
return normalizeBooleanPrimitiveValue(value) !== null;
|
|
322
326
|
},
|
|
323
|
-
parseValue(input: boolean | number) {
|
|
327
|
+
parseValue(input: boolean | number | string) {
|
|
324
328
|
return normalizeBooleanPrimitiveValue(input) ?? input;
|
|
325
329
|
},
|
|
326
|
-
serializeValue(value: boolean | number) {
|
|
330
|
+
serializeValue(value: boolean | number | string) {
|
|
327
331
|
return normalizeBooleanPrimitiveValue(value) ?? value;
|
|
328
332
|
},
|
|
329
333
|
});
|
package/common/index.ts
CHANGED
|
@@ -67,27 +67,37 @@ export function isRouteSourceFile(filePath: string): boolean {
|
|
|
67
67
|
return tryParseRouteModuleKey(key) !== null;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Why a `page/` file breaks the route convention, or null when it is fine. Null also covers a non-source
|
|
72
|
+
* asset, which `page/` tolerates. `akan sync <lib>` reports these alongside its other layout violations,
|
|
73
|
+
* so the rule stays in one place instead of being restated where it cannot afford to throw.
|
|
74
|
+
*/
|
|
75
|
+
export function getPageSourceFileViolation(filePath: string): string | null {
|
|
76
|
+
if (!SOURCE_EXT_RE.test(filePath)) return null;
|
|
72
77
|
|
|
73
78
|
const key = filePath.startsWith("./") ? filePath : `./${filePath.split(/[\\/]/).join("/")}`;
|
|
74
79
|
const match = ROUTE_SOURCE_RE.exec(key);
|
|
75
|
-
|
|
76
|
-
if (!match) throw new Error(`[route-convention] invalid page source file: ${displayPath}`);
|
|
80
|
+
if (!match) return "invalid page source file";
|
|
77
81
|
|
|
78
82
|
const file = match[1] as string;
|
|
79
83
|
const ext = match[2] as string;
|
|
80
84
|
const leaf = file.split("/").filter(Boolean).at(-1);
|
|
81
|
-
if (!leaf)
|
|
85
|
+
if (!leaf) return "invalid page source file";
|
|
82
86
|
|
|
83
|
-
if (ext !== "tsx")
|
|
87
|
+
if (ext !== "tsx") return "route source files under page/ must use .tsx";
|
|
84
88
|
if (leaf.startsWith("_") && !RESERVED_ROUTE_FILES.has(leaf) && leaf !== INTERNAL_ROOT_LAYOUT_LEAF)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
return "only _index.tsx, _layout.tsx and _overrides.tsx are allowed as reserved route files under page/";
|
|
90
|
+
if (/^[A-Z]/.test(leaf)) return "route page filenames must not start with an uppercase letter";
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function validatePageSourceFile(filePath: string, options: ValidatePageSourceFileOptions = {}): boolean {
|
|
95
|
+
if (!SOURCE_EXT_RE.test(filePath)) return false;
|
|
96
|
+
|
|
97
|
+
const violation = getPageSourceFileViolation(filePath);
|
|
98
|
+
if (!violation) return true;
|
|
99
|
+
const key = filePath.startsWith("./") ? filePath : `./${filePath.split(/[\\/]/).join("/")}`;
|
|
100
|
+
throw new Error(`[route-convention] ${violation}: ${options.filePath ?? key}`);
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
export function validateSubRoutePageKey(
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/service/adapt.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { type ExtractInjectInfoObject, type InjectBuilder, type InjectInfo, inje
|
|
|
4
4
|
|
|
5
5
|
export interface Adaptor {
|
|
6
6
|
readonly logger: Logger;
|
|
7
|
-
onInit(): Promise<void
|
|
8
|
-
onDestroy(): Promise<void
|
|
7
|
+
onInit(): Promise<void> | void;
|
|
8
|
+
onDestroy(): Promise<void> | void;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export type AdaptorCls<
|
|
@@ -30,9 +30,9 @@ export function adapt(name: string, injectBuilder?: InjectBuilder) {
|
|
|
30
30
|
readonly logger = new Logger(name);
|
|
31
31
|
static readonly [INJECT_META] = injectInfoMap;
|
|
32
32
|
static readonly refName = name;
|
|
33
|
-
|
|
33
|
+
onInit(): Promise<void> | void {
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
onDestroy(): Promise<void> | void {
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
return Adaptor;
|
package/service/serve.ts
CHANGED
|
@@ -43,9 +43,9 @@ const avoidKeys = new Set([
|
|
|
43
43
|
export interface Service {
|
|
44
44
|
readonly logger: Logger;
|
|
45
45
|
|
|
46
|
-
onInit(): Promise<void
|
|
46
|
+
onInit(): Promise<void> | void;
|
|
47
47
|
_libsOnInit(): Promise<void>;
|
|
48
|
-
onDestroy(): Promise<void
|
|
48
|
+
onDestroy(): Promise<void> | void;
|
|
49
49
|
_libsOnDestroy(): Promise<void>;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -121,9 +121,9 @@ export function serve(
|
|
|
121
121
|
}
|
|
122
122
|
static [INJECT_META] = {};
|
|
123
123
|
readonly logger = new Logger(this.constructor.name);
|
|
124
|
-
|
|
124
|
+
onInit(): Promise<void> | void {
|
|
125
125
|
}
|
|
126
|
-
|
|
126
|
+
onDestroy(): Promise<void> | void {
|
|
127
127
|
}
|
|
128
128
|
};
|
|
129
129
|
applyMixins(srvRef, extSrvs, avoidKeys);
|
|
@@ -132,10 +132,11 @@ export function serve(
|
|
|
132
132
|
const onDestroyFns = extSrvs.map((srv) => srv.prototype.onDestroy);
|
|
133
133
|
Object.assign(srvRef.prototype, {
|
|
134
134
|
async _libsOnInit(this: Service) {
|
|
135
|
-
|
|
135
|
+
|
|
136
|
+
await Promise.all([...onInitFns, this.onInit].map(async (onInit) => await onInit?.call(this)));
|
|
136
137
|
},
|
|
137
138
|
async _libsOnDestroy(this: Service) {
|
|
138
|
-
await Promise.all([...onDestroyFns.map((onDestroy) => onDestroy?.call(this))
|
|
139
|
+
await Promise.all([...onDestroyFns, this.onDestroy].map(async (onDestroy) => await onDestroy?.call(this)));
|
|
139
140
|
},
|
|
140
141
|
});
|
|
141
142
|
|
package/signal/intercept.ts
CHANGED
|
@@ -7,8 +7,8 @@ export type InterceptorCls<Methods = {}, InjectMap extends { [key: string]: Inje
|
|
|
7
7
|
Methods &
|
|
8
8
|
ExtractInjectInfoObject<InjectMap> & {
|
|
9
9
|
readonly logger: Logger;
|
|
10
|
-
onInit(): Promise<void
|
|
11
|
-
onDestroy(): Promise<void
|
|
10
|
+
onInit(): Promise<void> | void;
|
|
11
|
+
onDestroy(): Promise<void> | void;
|
|
12
12
|
intercept(context: SignalContext): AsyncGenerator<unknown> | Promise<unknown>;
|
|
13
13
|
},
|
|
14
14
|
{ readonly [INJECT_META]: InjectMap; readonly refName: string }
|
|
@@ -31,9 +31,9 @@ export function intercept(refName: string, injectBuilder?: InjectBuilder) {
|
|
|
31
31
|
intercept(context: SignalContext): AsyncGenerator | Promise<(res: Response) => Promise<Response>> {
|
|
32
32
|
return Promise.resolve((res: Response) => Promise.resolve(res));
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
onInit(): Promise<void> | void {
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
onDestroy(): Promise<void> | void {
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
}
|
|
@@ -114,12 +114,12 @@ declare global {
|
|
|
114
114
|
[DEFAULT_VALUE]: boolean;
|
|
115
115
|
[PURIFIED_VALUE]: boolean;
|
|
116
116
|
[EXAMPLE_VALUE]: boolean;
|
|
117
|
-
validate(value: boolean | number): boolean;
|
|
118
|
-
parseValue(input: boolean | number): boolean | number;
|
|
119
|
-
serializeValue(value: boolean | number): boolean | number;
|
|
120
|
-
_parse(input: boolean | number): boolean;
|
|
121
|
-
_serialize(value: boolean | number): boolean;
|
|
122
|
-
_checkValue(value: boolean | number): void;
|
|
117
|
+
validate(value: boolean | number | string): boolean;
|
|
118
|
+
parseValue(input: boolean | number | string): boolean | number | string;
|
|
119
|
+
serializeValue(value: boolean | number | string): boolean | number | string;
|
|
120
|
+
_parse(input: boolean | number | string): boolean;
|
|
121
|
+
_serialize(value: boolean | number | string): boolean;
|
|
122
|
+
_checkValue(value: boolean | number | string): void;
|
|
123
123
|
}
|
|
124
124
|
interface DateConstructor {
|
|
125
125
|
refName: "Date";
|
package/types/common/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export { pathGet } from "./pathGet.d.ts";
|
|
|
24
24
|
export { pathSet } from "./pathSet.d.ts";
|
|
25
25
|
export { randomPick } from "./randomPick.d.ts";
|
|
26
26
|
export { randomPicks } from "./randomPicks.d.ts";
|
|
27
|
-
export { assertUniqueRoutePatterns, compareRouteSpecificity, getRouteExports, isRouteSourceFile, isSpecialRouteLeaf, LAYOUT_ROUTE_EXPORTS, matchRoutePattern, normalizeRoutePattern, PAGE_ROUTE_EXPORTS, type ParsedRouteModuleKey, parseRouteModuleKey, RESERVED_ROUTE_CONFIG_EXPORTS, ROOT_LAYOUT_ROUTE_EXPORTS, type RouteModuleKind, routeSegmentToPatternPart, routeSegmentToTreePath, tryParseRouteModuleKey, type ValidatePageSourceFileOptions, type ValidateSubRoutePageKeyOptions, validatePageSourceFile, validateSubRoutePageKey, } from "./routeConvention.d.ts";
|
|
27
|
+
export { assertUniqueRoutePatterns, compareRouteSpecificity, getPageSourceFileViolation, getRouteExports, isRouteSourceFile, isSpecialRouteLeaf, LAYOUT_ROUTE_EXPORTS, matchRoutePattern, normalizeRoutePattern, PAGE_ROUTE_EXPORTS, type ParsedRouteModuleKey, parseRouteModuleKey, RESERVED_ROUTE_CONFIG_EXPORTS, ROOT_LAYOUT_ROUTE_EXPORTS, type RouteModuleKind, routeSegmentToPatternPart, routeSegmentToTreePath, tryParseRouteModuleKey, type ValidatePageSourceFileOptions, type ValidateSubRoutePageKeyOptions, validatePageSourceFile, validateSubRoutePageKey, } from "./routeConvention.d.ts";
|
|
28
28
|
export { sleep } from "./sleep.d.ts";
|
|
29
29
|
export { splitVersion } from "./splitVersion.d.ts";
|
|
30
30
|
export { getBasePathFromPathname, parseBasePaths, parseSubRouteHosts, resolveSubRouteHosts } from "./subRoute.d.ts";
|
|
@@ -27,6 +27,12 @@ export interface ValidatePageSourceFileOptions {
|
|
|
27
27
|
filePath?: string;
|
|
28
28
|
}
|
|
29
29
|
export declare function isRouteSourceFile(filePath: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Why a `page/` file breaks the route convention, or null when it is fine. Null also covers a non-source
|
|
32
|
+
* asset, which `page/` tolerates. `akan sync <lib>` reports these alongside its other layout violations,
|
|
33
|
+
* so the rule stays in one place instead of being restated where it cannot afford to throw.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getPageSourceFileViolation(filePath: string): string | null;
|
|
30
36
|
export declare function validatePageSourceFile(filePath: string, options?: ValidatePageSourceFileOptions): boolean;
|
|
31
37
|
export declare function validateSubRoutePageKey(key: string, basePaths: Iterable<string>, options?: ValidateSubRoutePageKeyOptions): void;
|
|
32
38
|
export declare function parseRouteModuleKey(key: string): ParsedRouteModuleKey;
|
package/types/service/adapt.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { Logger } from "akanjs/common";
|
|
|
3
3
|
import { type ExtractInjectInfoObject, type InjectBuilder, type InjectInfo } from "./injectInfo.d.ts";
|
|
4
4
|
export interface Adaptor {
|
|
5
5
|
readonly logger: Logger;
|
|
6
|
-
onInit(): Promise<void
|
|
7
|
-
onDestroy(): Promise<void
|
|
6
|
+
onInit(): Promise<void> | void;
|
|
7
|
+
onDestroy(): Promise<void> | void;
|
|
8
8
|
}
|
|
9
9
|
export type AdaptorCls<Methods = any, InjectMap extends Record<string, InjectInfo> = {}> = Cls<Methods & ExtractInjectInfoObject<InjectMap> & Adaptor, {
|
|
10
10
|
readonly [INJECT_META]: InjectMap;
|
package/types/service/serve.d.ts
CHANGED
|
@@ -10,9 +10,9 @@ interface ServiceOptions {
|
|
|
10
10
|
export type ServiceType = "database" | "plain";
|
|
11
11
|
export interface Service {
|
|
12
12
|
readonly logger: Logger;
|
|
13
|
-
onInit(): Promise<void
|
|
13
|
+
onInit(): Promise<void> | void;
|
|
14
14
|
_libsOnInit(): Promise<void>;
|
|
15
|
-
onDestroy(): Promise<void
|
|
15
|
+
onDestroy(): Promise<void> | void;
|
|
16
16
|
_libsOnDestroy(): Promise<void>;
|
|
17
17
|
}
|
|
18
18
|
export type ServiceCls<RefName extends string = string, Methods = {}, InjectMap extends {
|
|
@@ -6,8 +6,8 @@ export type InterceptorCls<Methods = {}, InjectMap extends {
|
|
|
6
6
|
[key: string]: InjectInfo;
|
|
7
7
|
} = {}> = Cls<Methods & ExtractInjectInfoObject<InjectMap> & {
|
|
8
8
|
readonly logger: Logger;
|
|
9
|
-
onInit(): Promise<void
|
|
10
|
-
onDestroy(): Promise<void
|
|
9
|
+
onInit(): Promise<void> | void;
|
|
10
|
+
onDestroy(): Promise<void> | void;
|
|
11
11
|
intercept(context: SignalContext): AsyncGenerator<unknown> | Promise<unknown>;
|
|
12
12
|
}, {
|
|
13
13
|
readonly [INJECT_META]: InjectMap;
|