Skip to content

Commit 8ff2a07

Browse files
authored
Merge pull request #40 from jsonjoy-com/fn-value
Fn value
2 parents 06dfbe8 + ed75672 commit 8ff2a07

File tree

10 files changed

+262
-222
lines changed

10 files changed

+262
-222
lines changed

src/type/classes/FnType.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {AbsType} from './AbsType';
44
import type {SchemaOf, Type} from '../types';
55
import type {ResolveType} from '../../system';
66
import type {Observable} from 'rxjs';
7+
import {Value} from '../../value';
78

89
const fnNotImplemented: schema.FunctionValue<any, any> = async () => {
910
throw new Error('NOT_IMPLEMENTED');
@@ -40,28 +41,40 @@ export class FnType<Req extends Type, Res extends Type, Ctx = unknown> extends A
4041
} as any;
4142
}
4243

43-
public request<T extends Type>(req: T): FnType<T, Res> {
44+
public input<T extends Type>(req: T): FnType<T, Res> {
45+
return this.inp(req);
46+
}
47+
48+
public inp<T extends Type>(req: T): FnType<T, Res> {
4449
(this as any).req = req;
4550
return this as any;
4651
}
4752

48-
public inp<T extends Type>(req: T): FnType<T, Res> {
49-
return this.request(req);
53+
public output<T extends Type>(res: T): FnType<Req, T> {
54+
return this.out(res);
5055
}
5156

52-
public response<T extends Type>(res: T): FnType<Req, T> {
57+
public out<T extends Type>(res: T): FnType<Req, T> {
5358
(this as any).res = res;
5459
return this as any;
5560
}
5661

57-
public out<T extends Type>(res: T): FnType<Req, T> {
58-
return this.response(res);
62+
public io<I extends Type, O extends Type>(request: I, response: O): FnType<I, O, Ctx> {
63+
return this.inp(request).out(response) as FnType<I, O, Ctx>;
64+
}
65+
66+
public signature<I extends Type, O extends Type>(request: I, response: O): FnType<I, O, Ctx> {
67+
return this.io(request, response) as FnType<I, O, Ctx>;
5968
}
6069

6170
public ctx<T>(): FnType<Req, Res, T> {
6271
return this as any;
6372
}
6473

74+
public value(data: ResolveType<FnType<Req, Res, Ctx>>) {
75+
return new Value<FnType<Req, Res, Ctx>>(this, data);
76+
}
77+
6578
public getSchema(): schema.FunctionSchema<SchemaOf<Req>, SchemaOf<Res>, Ctx> {
6679
return {
6780
...this.schema,
@@ -70,13 +83,6 @@ export class FnType<Req extends Type, Res extends Type, Ctx = unknown> extends A
7083
};
7184
}
7285

73-
public singleton?: FunctionImpl<Req, Res, Ctx> = undefined;
74-
75-
public implement(singleton: FunctionImpl<Req, Res, Ctx>): this {
76-
this.singleton = singleton;
77-
return this;
78-
}
79-
8086
public toString(tab: string = ''): string {
8187
return super.toString(tab) + toStringTree(tab, this);
8288
}
@@ -131,13 +137,6 @@ export class FnRxType<Req extends Type, Res extends Type, Ctx = unknown> extends
131137
};
132138
}
133139

134-
public singleton?: FunctionStreamingImpl<Req, Res, Ctx> = undefined;
135-
136-
public implement(singleton: FunctionStreamingImpl<Req, Res, Ctx>): this {
137-
this.singleton = singleton;
138-
return this;
139-
}
140-
141140
public toString(tab: string = ''): string {
142141
return super.toString(tab) + toStringTree(tab, this);
143142
}

src/typescript/converter.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type * as ts from './types';
22
import type * as schema from '../schema';
3+
import type {ObjType} from '../type/classes';
34

45
/**
56
* Main router function that converts any Schema to TypeScript AST.
@@ -242,3 +243,23 @@ export function toTypeScriptAst(schema: schema.Schema): ts.TsType {
242243
}
243244
}
244245
}
246+
247+
export const objToModule = (obj: ObjType<any>): ts.TsModuleDeclaration => {
248+
const node: ts.TsModuleDeclaration = {
249+
node: 'ModuleDeclaration',
250+
name: 'Router',
251+
export: true,
252+
statements: [
253+
{
254+
node: 'TypeAliasDeclaration',
255+
name: 'Routes',
256+
type: toTypeScriptAst(obj.getSchema()),
257+
export: true,
258+
},
259+
],
260+
};
261+
const system = obj.system;
262+
if (!system) throw new Error('system is undefined');
263+
for (const alias of system.aliases.values()) node.statements.push({...alias.toTypeScriptAst(), export: true});
264+
return node;
265+
};

src/value/ObjValue.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {Value} from './Value';
2+
import {TypeSystem} from '../system/TypeSystem';
3+
import {printTree} from 'tree-dump/lib/printTree';
4+
import type * as classes from '../type';
5+
import type {TypeBuilder} from '../type/TypeBuilder';
6+
import type {Printable} from 'tree-dump/lib/types';
7+
import type {ResolveType} from '../system/types';
8+
9+
export type UnObjType<T> = T extends classes.ObjType<infer U> ? U : never;
10+
export type UnObjValue<T> = T extends ObjValue<infer U> ? U : never;
11+
export type UnObjFieldTypeVal<T> = T extends classes.ObjectFieldType<any, infer U> ? U : never;
12+
export type ObjFieldToTuple<F> = F extends classes.ObjectFieldType<infer K, infer V> ? [K, V] : never;
13+
export type ToObject<T> = T extends [string, unknown][] ? {[K in T[number] as K[0]]: K[1]} : never;
14+
export type ObjValueToTypeMap<F> = ToObject<{
15+
[K in keyof F]: ObjFieldToTuple<F[K]>;
16+
}>;
17+
18+
export class ObjValue<T extends classes.ObjType<any>> extends Value<T> implements Printable {
19+
public static new = (system: TypeSystem = new TypeSystem()) => new ObjValue(system.t.obj, {});
20+
21+
public get system(): TypeSystem {
22+
return (this.type as T).getSystem();
23+
}
24+
25+
public get t(): TypeBuilder {
26+
return this.system.t;
27+
}
28+
29+
public keys(): string[] {
30+
const type = this.type as T;
31+
return type.fields.map((field: classes.ObjectFieldType<string, any>) => field.key);
32+
}
33+
34+
public get<K extends keyof ObjValueToTypeMap<UnObjType<T>>>(
35+
key: K,
36+
): Value<
37+
ObjValueToTypeMap<UnObjType<T>>[K] extends classes.Type ? ObjValueToTypeMap<UnObjType<T>>[K] : classes.Type
38+
> {
39+
const field = this.type.getField(<string>key);
40+
if (!field) throw new Error('NO_FIELD');
41+
const type = field.value;
42+
const data = this.data[<string>key];
43+
return new Value(type, data) as any;
44+
}
45+
46+
public field<F extends classes.ObjectFieldType<any, any>>(
47+
field: F | ((t: TypeBuilder) => F),
48+
data: ResolveType<UnObjFieldTypeVal<F>>,
49+
): ObjValue<classes.ObjType<[...UnObjType<T>, F]>> {
50+
field = typeof field === 'function' ? field((this.type as classes.ObjType<any>).getSystem().t) : field;
51+
this.data[field.key] = data;
52+
const type = this.type;
53+
const system = type.system;
54+
if (!system) throw new Error('NO_SYSTEM');
55+
type.fields.push(field);
56+
return this as any;
57+
}
58+
59+
public add<K extends string, V extends classes.Type>(
60+
key: K,
61+
type: V | ((t: TypeBuilder) => V),
62+
data: ResolveType<V>,
63+
) {
64+
const system = (this.type as classes.ObjType<any>).getSystem();
65+
const t = system.t;
66+
type = typeof type === 'function' ? type(t) : type;
67+
return this.field(t.prop(key, type), data);
68+
}
69+
70+
public set<K extends string, V extends classes.Type>(key: K, value: Value<V>) {
71+
return this.add(key, value.type, value.data);
72+
}
73+
74+
public merge<O extends ObjValue<any>>(obj: O): ObjValue<classes.ObjType<[...UnObjType<T>, ...UnObjType<O['type']>]>> {
75+
Object.assign(this.data as object, obj.data);
76+
const type = this.type;
77+
const system = type.system;
78+
if (!system) throw new Error('NO_SYSTEM');
79+
type.fields.push(...type.fields);
80+
return this as any;
81+
}
82+
83+
public toString(tab: string = ''): string {
84+
return 'ObjValue' + printTree(tab, [(tab) => this.type.toString(tab)]);
85+
}
86+
}

src/value/ObjectValue.ts

Lines changed: 0 additions & 150 deletions
This file was deleted.

0 commit comments

Comments
 (0)