@aromix/core 0.4.1 → 0.4.2
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/dist/index.d.ts +67 -237
- package/dist/index.js +103 -360
- package/package.json +9 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,254 +1,84 @@
|
|
|
1
1
|
import { AnySchema } from '@aromix/validator';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
2
|
+
import { Server } from 'http';
|
|
3
|
+
import { Db, MongoClient } from 'mongodb';
|
|
4
|
+
import { RedisClientType, RedisClusterType, RedisClientPoolType, RedisSentinelType } from 'redis';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
type MaybePromise<T> = T | Promise<T>
|
|
7
|
+
|
|
8
|
+
interface Builder {
|
|
7
9
|
name: string;
|
|
8
|
-
|
|
10
|
+
onRegister?(state: Record<string, any>): MaybePromise<void>;
|
|
11
|
+
onListen?(server: Server): MaybePromise<void>;
|
|
12
|
+
onShutdown?(): MaybePromise<void>;
|
|
9
13
|
}
|
|
10
|
-
declare
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
delete(key: string): Promise<void>;
|
|
17
|
-
has(key: string): Promise<boolean>;
|
|
14
|
+
declare function Builder(def: Builder): Builder;
|
|
15
|
+
|
|
16
|
+
interface ValidateEnvConfig<Schema extends Record<string, AnySchema>> {
|
|
17
|
+
path: string;
|
|
18
|
+
schema: Schema;
|
|
19
|
+
onError?(err: unknown): void;
|
|
18
20
|
}
|
|
21
|
+
declare function ValidateEnv<const Schema extends Record<string, AnySchema>>(config: ValidateEnvConfig<Schema>): readonly [Builder, <Key extends keyof Schema>(key: Key, fallback?: Schema[Key]["$base"]) => Schema[Key]["$base"]];
|
|
19
22
|
|
|
20
|
-
interface
|
|
23
|
+
interface EffectDef {
|
|
21
24
|
name: string;
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
declare class MongoEntity<Schema extends AnySchema> {
|
|
25
|
-
readonly states: MongoEntityUserInput<Schema>;
|
|
26
|
-
private readonly collection;
|
|
27
|
-
constructor(userInput: MongoEntityUserInput<Schema>, db: Db);
|
|
28
|
-
insertOne(doc: Schema['$insert'], options?: InsertOneOptions): Promise<InsertOneResult>;
|
|
29
|
-
insertMany(docs: Schema['$insert'][], options?: BulkWriteOptions): Promise<InsertManyResult>;
|
|
30
|
-
findOne(filter: Filter<Schema['$select']>, options?: FindOptions): Promise<Schema['$select'] | null>;
|
|
31
|
-
find(filter: Filter<Schema['$select']>, options?: FindOptions): Promise<Schema['$select'][]>;
|
|
32
|
-
updateOne(filter: Filter<Schema['$select']>, update: UpdateFilter<Schema['$update']>, options?: UpdateOptions): Promise<UpdateResult>;
|
|
33
|
-
updateMany(filter: Filter<Schema['$select']>, update: UpdateFilter<Schema['$update']>, options?: UpdateOptions): Promise<UpdateResult>;
|
|
34
|
-
replaceOne(filter: Filter<Schema['$select']>, replacement: Schema['$select'], options?: ReplaceOptions): Promise<UpdateResult>;
|
|
35
|
-
deleteOne(filter: Filter<Schema['$select']>, options?: DeleteOptions): Promise<DeleteResult>;
|
|
36
|
-
deleteMany(filter: Filter<Schema['$select']>, options?: DeleteOptions): Promise<DeleteResult>;
|
|
37
|
-
findOneAndUpdate(filter: Filter<Schema['$select']>, update: UpdateFilter<Schema['$update']>, options?: FindOneAndUpdateOptions): Promise<Schema['$select'] | null>;
|
|
38
|
-
findOneAndDelete(filter: Filter<Schema['$select']>, options?: FindOneAndDeleteOptions): Promise<Schema['$select'] | null>;
|
|
39
|
-
findOneAndReplace(filter: Filter<Schema['$select']>, replacement: Schema['$select'], options?: FindOneAndReplaceOptions): Promise<Schema['$select'] | null>;
|
|
40
|
-
countDocuments(filter: Filter<Schema['$select']>, options?: CountDocumentsOptions): Promise<number>;
|
|
41
|
-
estimatedDocumentCount(): Promise<number>;
|
|
42
|
-
distinct<Field extends keyof Schema['$select'] & string>(field: Field, filter: Filter<Schema['$select']>, options?: DistinctOptions): Promise<Array<Schema['$select'][Field]>>;
|
|
43
|
-
aggregate(pipeline: any[], options?: AggregateOptions): AggregationCursor;
|
|
44
|
-
bulkWrite(operations: any[], options?: BulkWriteOptions): Promise<BulkWriteResult>;
|
|
45
|
-
createIndex(indexSpec: any, options?: CreateIndexesOptions): Promise<string>;
|
|
46
|
-
dropIndex(indexName: string, options?: DropIndexesOptions): Promise<void>;
|
|
25
|
+
run(): void;
|
|
47
26
|
}
|
|
27
|
+
declare function effect(def: EffectDef): EffectDef;
|
|
48
28
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
set(key: string, value: unknown): Promise<void>;
|
|
53
|
-
delete(key: string): Promise<void>;
|
|
54
|
-
has(key: string): Promise<boolean>;
|
|
55
|
-
}
|
|
56
|
-
interface KvInput {
|
|
57
|
-
transport: 'http';
|
|
58
|
-
adapter(): KvAdapter;
|
|
59
|
-
}
|
|
60
|
-
function kv(builderInput: KvInput): {
|
|
61
|
-
entity<Schema extends AnySchema>(entityInput: KvEntityUserInput<Schema>): KvEntity<Schema>;
|
|
62
|
-
};
|
|
63
|
-
interface MongoInput {
|
|
64
|
-
adapter(): Db;
|
|
65
|
-
transport: 'http';
|
|
66
|
-
}
|
|
67
|
-
function mongo(builderInput: MongoInput): {
|
|
68
|
-
entity<Schema extends AnySchema>(entityInput: MongoEntityUserInput<Schema>): MongoEntity<Schema>;
|
|
69
|
-
};
|
|
29
|
+
interface GuardDef {
|
|
30
|
+
name: string;
|
|
31
|
+
run(): void;
|
|
70
32
|
}
|
|
33
|
+
declare function guard(def: GuardDef): GuardDef;
|
|
71
34
|
|
|
72
|
-
|
|
73
|
-
|
|
35
|
+
declare class MongoDatabase {
|
|
36
|
+
db: Db;
|
|
37
|
+
constructor();
|
|
38
|
+
/** internal attach */
|
|
39
|
+
attach(db: Db): void;
|
|
40
|
+
entity<Schema extends AnySchema>(input: MongoEntityInput<Schema>): void;
|
|
74
41
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
42
|
+
|
|
43
|
+
type ClusterResult<T extends readonly string[]> = {
|
|
44
|
+
builder: Builder;
|
|
45
|
+
client: MongoClient;
|
|
46
|
+
} & {
|
|
47
|
+
[K in T[number]]: MongoDatabase;
|
|
80
48
|
};
|
|
49
|
+
interface MongoClusterInput<Databases extends readonly string[]> {
|
|
50
|
+
name: string;
|
|
51
|
+
uri: string;
|
|
52
|
+
databases: Databases;
|
|
53
|
+
onConnect?(client: MongoClient): MaybePromise<void>;
|
|
54
|
+
onDisconnect?(client: MongoClient): MaybePromise<void>;
|
|
55
|
+
onError?(err: unknown): MaybePromise<void>;
|
|
56
|
+
}
|
|
57
|
+
interface MongoEntityInput<Schema extends AnySchema> {
|
|
58
|
+
name: string;
|
|
59
|
+
model: Schema;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare function MongoCluster<const Databases extends readonly string[]>(options: MongoClusterInput<Databases>): ClusterResult<Databases>;
|
|
81
63
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
type: string;
|
|
93
|
-
shape?: undefined;
|
|
94
|
-
};
|
|
95
|
-
output: any;
|
|
96
|
-
} | {
|
|
97
|
-
name: string;
|
|
98
|
-
route: string;
|
|
99
|
-
input: {
|
|
100
|
-
type: string;
|
|
101
|
-
shape: {
|
|
102
|
-
key: {
|
|
103
|
-
type: string;
|
|
104
|
-
};
|
|
105
|
-
value: any;
|
|
106
|
-
};
|
|
107
|
-
};
|
|
108
|
-
output: {
|
|
109
|
-
type: string;
|
|
110
|
-
};
|
|
111
|
-
})[];
|
|
112
|
-
};
|
|
113
|
-
private buildMongoMethod;
|
|
114
|
-
mongo(entity: MongoEntity<AnySchema>): {
|
|
115
|
-
name: string;
|
|
116
|
-
platform: string;
|
|
117
|
-
methods: {
|
|
118
|
-
name: string;
|
|
119
|
-
route: string;
|
|
120
|
-
input: any;
|
|
121
|
-
output: {
|
|
122
|
-
type: string;
|
|
123
|
-
shape: {
|
|
124
|
-
acknowledged: {
|
|
125
|
-
type: string;
|
|
126
|
-
};
|
|
127
|
-
matchedCount: {
|
|
128
|
-
type: string;
|
|
129
|
-
};
|
|
130
|
-
modifiedCount: {
|
|
131
|
-
type: string;
|
|
132
|
-
};
|
|
133
|
-
upsertedCount: {
|
|
134
|
-
type: string;
|
|
135
|
-
};
|
|
136
|
-
upsertedId: {
|
|
137
|
-
type: string;
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
} | {
|
|
141
|
-
type: string;
|
|
142
|
-
shape: {
|
|
143
|
-
acknowledged: {
|
|
144
|
-
type: string;
|
|
145
|
-
};
|
|
146
|
-
insertedId: {
|
|
147
|
-
type: string;
|
|
148
|
-
};
|
|
149
|
-
insertedCount?: undefined;
|
|
150
|
-
insertedIds?: undefined;
|
|
151
|
-
matchedCount?: undefined;
|
|
152
|
-
modifiedCount?: undefined;
|
|
153
|
-
upsertedCount?: undefined;
|
|
154
|
-
upsertedId?: undefined;
|
|
155
|
-
deletedCount?: undefined;
|
|
156
|
-
};
|
|
157
|
-
items?: undefined;
|
|
158
|
-
element?: undefined;
|
|
159
|
-
} | {
|
|
160
|
-
type: string;
|
|
161
|
-
shape: {
|
|
162
|
-
acknowledged: {
|
|
163
|
-
type: string;
|
|
164
|
-
};
|
|
165
|
-
insertedCount: {
|
|
166
|
-
type: string;
|
|
167
|
-
};
|
|
168
|
-
insertedIds: {
|
|
169
|
-
type: string;
|
|
170
|
-
};
|
|
171
|
-
insertedId?: undefined;
|
|
172
|
-
matchedCount?: undefined;
|
|
173
|
-
modifiedCount?: undefined;
|
|
174
|
-
upsertedCount?: undefined;
|
|
175
|
-
upsertedId?: undefined;
|
|
176
|
-
deletedCount?: undefined;
|
|
177
|
-
};
|
|
178
|
-
items?: undefined;
|
|
179
|
-
element?: undefined;
|
|
180
|
-
} | {
|
|
181
|
-
type: string;
|
|
182
|
-
items: any[];
|
|
183
|
-
shape?: undefined;
|
|
184
|
-
element?: undefined;
|
|
185
|
-
} | {
|
|
186
|
-
type: string;
|
|
187
|
-
element: any;
|
|
188
|
-
shape?: undefined;
|
|
189
|
-
items?: undefined;
|
|
190
|
-
} | {
|
|
191
|
-
type: string;
|
|
192
|
-
shape: {
|
|
193
|
-
acknowledged: {
|
|
194
|
-
type: string;
|
|
195
|
-
};
|
|
196
|
-
matchedCount: {
|
|
197
|
-
type: string;
|
|
198
|
-
};
|
|
199
|
-
modifiedCount: {
|
|
200
|
-
type: string;
|
|
201
|
-
};
|
|
202
|
-
upsertedCount: {
|
|
203
|
-
type: string;
|
|
204
|
-
};
|
|
205
|
-
upsertedId: {
|
|
206
|
-
type: string;
|
|
207
|
-
};
|
|
208
|
-
insertedId?: undefined;
|
|
209
|
-
insertedCount?: undefined;
|
|
210
|
-
insertedIds?: undefined;
|
|
211
|
-
deletedCount?: undefined;
|
|
212
|
-
};
|
|
213
|
-
items?: undefined;
|
|
214
|
-
element?: undefined;
|
|
215
|
-
} | {
|
|
216
|
-
type: string;
|
|
217
|
-
items: any[];
|
|
218
|
-
shape?: undefined;
|
|
219
|
-
element?: undefined;
|
|
220
|
-
} | {
|
|
221
|
-
type: string;
|
|
222
|
-
shape: {
|
|
223
|
-
acknowledged: {
|
|
224
|
-
type: string;
|
|
225
|
-
};
|
|
226
|
-
deletedCount: {
|
|
227
|
-
type: string;
|
|
228
|
-
};
|
|
229
|
-
insertedId?: undefined;
|
|
230
|
-
insertedCount?: undefined;
|
|
231
|
-
insertedIds?: undefined;
|
|
232
|
-
matchedCount?: undefined;
|
|
233
|
-
modifiedCount?: undefined;
|
|
234
|
-
upsertedCount?: undefined;
|
|
235
|
-
upsertedId?: undefined;
|
|
236
|
-
};
|
|
237
|
-
items?: undefined;
|
|
238
|
-
element?: undefined;
|
|
239
|
-
} | {
|
|
240
|
-
type: string;
|
|
241
|
-
shape?: undefined;
|
|
242
|
-
items?: undefined;
|
|
243
|
-
element?: undefined;
|
|
244
|
-
};
|
|
245
|
-
}[];
|
|
246
|
-
};
|
|
64
|
+
type RedisAdapter = RedisClientType | RedisClusterType | RedisClientPoolType | RedisSentinelType;
|
|
65
|
+
interface RedisInput {
|
|
66
|
+
name: string;
|
|
67
|
+
client(): RedisAdapter;
|
|
68
|
+
onConnect?(client: RedisAdapter): MaybePromise<void>;
|
|
69
|
+
onDisconnect?(client: RedisAdapter): MaybePromise<void>;
|
|
70
|
+
onError?(err: unknown): void;
|
|
71
|
+
}
|
|
72
|
+
declare class Redis {
|
|
73
|
+
constructor(input: RedisInput);
|
|
247
74
|
}
|
|
248
75
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
76
|
+
declare class Application {
|
|
77
|
+
private state;
|
|
78
|
+
private builders;
|
|
79
|
+
register(builder: Builder): void;
|
|
80
|
+
listen(port: number): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
declare function bootstrap(): Application;
|
|
253
83
|
|
|
254
|
-
export { type
|
|
84
|
+
export { Builder, type ClusterResult, type EffectDef, type GuardDef, type MaybePromise, MongoCluster, type MongoClusterInput, MongoDatabase, type MongoEntityInput, Redis, type RedisAdapter, type RedisInput, ValidateEnv, type ValidateEnvConfig, bootstrap, effect, guard };
|
package/dist/index.js
CHANGED
|
@@ -1,380 +1,123 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
constructor(userProvided, internal) {
|
|
6
|
-
this.state = userProvided;
|
|
7
|
-
this.adapter = internal;
|
|
8
|
-
}
|
|
9
|
-
async get(key) {
|
|
10
|
-
const formattedKey = `${this.state.name}:${key}`;
|
|
11
|
-
const raw = await this.adapter.get(formattedKey);
|
|
12
|
-
return raw;
|
|
13
|
-
}
|
|
14
|
-
async set(key, value) {
|
|
15
|
-
const formattedKey = `${this.state.name}:${key}`;
|
|
16
|
-
await this.adapter.set(formattedKey, value);
|
|
17
|
-
}
|
|
18
|
-
async delete(key) {
|
|
19
|
-
const formattedKey = `${this.state.name}:${key}`;
|
|
20
|
-
await this.adapter.delete(formattedKey);
|
|
21
|
-
}
|
|
22
|
-
async has(key) {
|
|
23
|
-
const formattedKey = `${this.state.name}:${key}`;
|
|
24
|
-
return this.adapter.has(formattedKey);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
1
|
+
// src/server/builder.ts
|
|
2
|
+
function Builder(def) {
|
|
3
|
+
return def;
|
|
4
|
+
}
|
|
27
5
|
|
|
28
|
-
// src/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
async findOne(filter, options) {
|
|
43
|
-
return this.collection.findOne(filter, options);
|
|
44
|
-
}
|
|
45
|
-
async find(filter, options) {
|
|
46
|
-
return this.collection.find(filter, options).toArray();
|
|
47
|
-
}
|
|
48
|
-
async updateOne(filter, update, options) {
|
|
49
|
-
return this.collection.updateOne(filter, update, options);
|
|
50
|
-
}
|
|
51
|
-
async updateMany(filter, update, options) {
|
|
52
|
-
return this.collection.updateMany(filter, update, options);
|
|
53
|
-
}
|
|
54
|
-
async replaceOne(filter, replacement, options) {
|
|
55
|
-
return this.collection.replaceOne(filter, replacement, options);
|
|
56
|
-
}
|
|
57
|
-
async deleteOne(filter, options) {
|
|
58
|
-
return this.collection.deleteOne(filter, options);
|
|
59
|
-
}
|
|
60
|
-
async deleteMany(filter, options) {
|
|
61
|
-
return this.collection.deleteMany(filter, options);
|
|
62
|
-
}
|
|
63
|
-
async findOneAndUpdate(filter, update, options) {
|
|
64
|
-
return this.collection.findOneAndUpdate(filter, update, options);
|
|
65
|
-
}
|
|
66
|
-
async findOneAndDelete(filter, options) {
|
|
67
|
-
return this.collection.findOneAndDelete(filter, options);
|
|
68
|
-
}
|
|
69
|
-
async findOneAndReplace(filter, replacement, options) {
|
|
70
|
-
return this.collection.findOneAndReplace(filter, replacement, options);
|
|
71
|
-
}
|
|
72
|
-
async countDocuments(filter, options) {
|
|
73
|
-
return this.collection.countDocuments(filter, options);
|
|
74
|
-
}
|
|
75
|
-
async estimatedDocumentCount() {
|
|
76
|
-
return this.collection.estimatedDocumentCount();
|
|
77
|
-
}
|
|
78
|
-
async distinct(field, filter, options) {
|
|
79
|
-
return this.collection.distinct(field, filter, options);
|
|
80
|
-
}
|
|
81
|
-
aggregate(pipeline, options) {
|
|
82
|
-
return this.collection.aggregate(pipeline, options);
|
|
83
|
-
}
|
|
84
|
-
async bulkWrite(operations, options) {
|
|
85
|
-
return this.collection.bulkWrite(operations, options);
|
|
86
|
-
}
|
|
87
|
-
async createIndex(indexSpec, options) {
|
|
88
|
-
return this.collection.createIndex(indexSpec, options);
|
|
89
|
-
}
|
|
90
|
-
async dropIndex(indexName, options) {
|
|
91
|
-
return this.collection.dropIndex(indexName, options);
|
|
6
|
+
// src/common/validate.env.ts
|
|
7
|
+
import { loadEnvFile } from "process";
|
|
8
|
+
function ValidateEnv(config) {
|
|
9
|
+
const builder = Builder({
|
|
10
|
+
name: "validate.env",
|
|
11
|
+
onRegister(state) {
|
|
12
|
+
loadEnvFile(config.path);
|
|
13
|
+
console.log(state);
|
|
14
|
+
console.log(process.env);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
function env(key, fallback) {
|
|
18
|
+
return process.env[key] ?? fallback;
|
|
92
19
|
}
|
|
93
|
-
|
|
20
|
+
return [builder, env];
|
|
21
|
+
}
|
|
94
22
|
|
|
95
|
-
// src/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const adapter = builderInput.adapter();
|
|
100
|
-
const result = {
|
|
101
|
-
entity(entityInput) {
|
|
102
|
-
return new KvEntity(entityInput, adapter);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
EntityBuilder2.kv = kv;
|
|
108
|
-
function mongo(builderInput) {
|
|
109
|
-
const db = builderInput.adapter();
|
|
110
|
-
const result = {
|
|
111
|
-
entity(entityInput) {
|
|
112
|
-
return new MongoEntity(entityInput, db);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
EntityBuilder2.mongo = mongo;
|
|
118
|
-
})(EntityBuilder || (EntityBuilder = {}));
|
|
23
|
+
// src/layer/effect.ts
|
|
24
|
+
function effect(def) {
|
|
25
|
+
return def;
|
|
26
|
+
}
|
|
119
27
|
|
|
120
|
-
// src/
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const fields = {};
|
|
133
|
-
for (const key in shape) {
|
|
134
|
-
if (this.isExcluded(shape[key], slot)) continue;
|
|
135
|
-
fields[key] = this.parseSchema(shape[key], slot);
|
|
136
|
-
}
|
|
137
|
-
return { type: "object", shape: fields };
|
|
138
|
-
}
|
|
139
|
-
if (state.type === "array") {
|
|
140
|
-
return { type: "array", element: this.parseSchema(state.typeMeta.arrayElement, slot) };
|
|
141
|
-
}
|
|
142
|
-
if (state.type === "tuple") {
|
|
143
|
-
return { type: "tuple", items: (state.typeMeta.tupleItems ?? []).map((s) => this.parseSchema(s, slot)) };
|
|
144
|
-
}
|
|
145
|
-
if (state.type === "union") {
|
|
146
|
-
return { type: "union", items: (state.typeMeta.unionItems ?? []).map((s) => this.parseSchema(s, slot)) };
|
|
147
|
-
}
|
|
148
|
-
if (state.type === "record") {
|
|
149
|
-
return { type: "record", element: this.parseSchema(state.typeMeta.recordElement, slot) };
|
|
150
|
-
}
|
|
151
|
-
if (state.type === "literals") {
|
|
152
|
-
return { type: "literals", values: state.typeMeta.literalValues };
|
|
153
|
-
}
|
|
154
|
-
return { type: state.type };
|
|
155
|
-
}
|
|
156
|
-
kv(entity) {
|
|
157
|
-
const name = entity.state.name;
|
|
158
|
-
const model = entity.state.model;
|
|
159
|
-
return {
|
|
160
|
-
name,
|
|
161
|
-
platform: "kv",
|
|
162
|
-
methods: [
|
|
163
|
-
{ name: "get", route: `${name}.kv.get`, input: { type: "string" }, output: this.parseSchema(model, "select") },
|
|
164
|
-
{ name: "set", route: `${name}.kv.set`, input: { type: "object", shape: { key: { type: "string" }, value: this.parseSchema(model, "insert") } }, output: { type: "null" } },
|
|
165
|
-
{ name: "delete", route: `${name}.kv.delete`, input: { type: "string" }, output: { type: "null" } },
|
|
166
|
-
{ name: "has", route: `${name}.kv.has`, input: { type: "string" }, output: { type: "boolean" } }
|
|
167
|
-
]
|
|
168
|
-
};
|
|
28
|
+
// src/layer/guard.ts
|
|
29
|
+
function guard(def) {
|
|
30
|
+
return def;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/mongo/cluster.ts
|
|
34
|
+
import { MongoClient } from "mongodb";
|
|
35
|
+
|
|
36
|
+
// src/mongo/database.ts
|
|
37
|
+
var MongoDatabase = class {
|
|
38
|
+
db;
|
|
39
|
+
constructor() {
|
|
169
40
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
if (methodName === "insertMany") {
|
|
175
|
-
return {
|
|
176
|
-
input: { type: "array", element: this.parseSchema(model, "insert") },
|
|
177
|
-
output: { type: "object", shape: { acknowledged: { type: "boolean" }, insertedCount: { type: "number" }, insertedIds: { type: "unknown" } } }
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
if (methodName === "findOne") {
|
|
181
|
-
return { input: this.parseSchema(model, "select"), output: { type: "union", items: [this.parseSchema(model, "select"), { type: "null" }] } };
|
|
182
|
-
}
|
|
183
|
-
if (methodName === "find") {
|
|
184
|
-
return { input: this.parseSchema(model, "select"), output: { type: "array", element: this.parseSchema(model, "select") } };
|
|
185
|
-
}
|
|
186
|
-
if (methodName === "updateOne" || methodName === "updateMany") {
|
|
187
|
-
return {
|
|
188
|
-
input: { type: "object", shape: { filter: this.parseSchema(model, "select"), update: this.parseSchema(model, "update") } },
|
|
189
|
-
output: {
|
|
190
|
-
type: "object",
|
|
191
|
-
shape: {
|
|
192
|
-
acknowledged: { type: "boolean" },
|
|
193
|
-
matchedCount: { type: "number" },
|
|
194
|
-
modifiedCount: { type: "number" },
|
|
195
|
-
upsertedCount: { type: "number" },
|
|
196
|
-
upsertedId: { type: "unknown" }
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
if (methodName === "replaceOne" || methodName === "findOneAndReplace") {
|
|
202
|
-
const updateResultShape = {
|
|
203
|
-
type: "object",
|
|
204
|
-
shape: { acknowledged: { type: "boolean" }, matchedCount: { type: "number" }, modifiedCount: { type: "number" }, upsertedCount: { type: "number" }, upsertedId: { type: "unknown" } }
|
|
205
|
-
};
|
|
206
|
-
return {
|
|
207
|
-
input: { type: "object", shape: { filter: this.parseSchema(model, "select"), replacement: this.parseSchema(model, "select") } },
|
|
208
|
-
output: methodName === "replaceOne" ? updateResultShape : { type: "union", items: [this.parseSchema(model, "select"), { type: "null" }] }
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
if (methodName === "deleteOne" || methodName === "deleteMany") {
|
|
212
|
-
return { input: this.parseSchema(model, "select"), output: { type: "object", shape: { acknowledged: { type: "boolean" }, deletedCount: { type: "number" } } } };
|
|
213
|
-
}
|
|
214
|
-
if (methodName === "findOneAndUpdate") {
|
|
215
|
-
return {
|
|
216
|
-
input: { type: "object", shape: { filter: this.parseSchema(model, "select"), update: this.parseSchema(model, "update") } },
|
|
217
|
-
output: { type: "union", items: [this.parseSchema(model, "select"), { type: "null" }] }
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
if (methodName === "findOneAndDelete") {
|
|
221
|
-
return { input: this.parseSchema(model, "select"), output: { type: "union", items: [this.parseSchema(model, "select"), { type: "null" }] } };
|
|
222
|
-
}
|
|
223
|
-
if (methodName === "countDocuments") {
|
|
224
|
-
return { input: this.parseSchema(model, "select"), output: { type: "number" } };
|
|
225
|
-
}
|
|
226
|
-
if (methodName === "estimatedDocumentCount") {
|
|
227
|
-
return { input: { type: "null" }, output: { type: "number" } };
|
|
228
|
-
}
|
|
229
|
-
if (methodName === "distinct") {
|
|
230
|
-
return { input: { type: "object", shape: { field: { type: "string" }, filter: this.parseSchema(model, "select") } }, output: { type: "unknown" } };
|
|
231
|
-
}
|
|
232
|
-
if (methodName === "createIndex") {
|
|
233
|
-
return { input: { type: "unknown" }, output: { type: "string" } };
|
|
234
|
-
}
|
|
235
|
-
if (methodName === "dropIndex") {
|
|
236
|
-
return { input: { type: "string" }, output: { type: "null" } };
|
|
237
|
-
}
|
|
238
|
-
return { input: { type: "unknown" }, output: { type: "unknown" } };
|
|
41
|
+
/** internal attach */
|
|
42
|
+
attach(db) {
|
|
43
|
+
this.db = db;
|
|
239
44
|
}
|
|
240
|
-
|
|
241
|
-
const name = entity.states.name;
|
|
242
|
-
const model = entity.states.model;
|
|
243
|
-
const proto = Object.getPrototypeOf(entity);
|
|
244
|
-
const methods = [];
|
|
245
|
-
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
246
|
-
if (key === "constructor") continue;
|
|
247
|
-
const shape = this.buildMongoMethod(model, key);
|
|
248
|
-
methods.push({ name: key, route: `${name}.mongo.${key}`, input: shape.input, output: shape.output });
|
|
249
|
-
}
|
|
250
|
-
return { name, platform: "mongo", methods };
|
|
45
|
+
entity(input) {
|
|
251
46
|
}
|
|
252
47
|
};
|
|
253
48
|
|
|
254
|
-
// src/
|
|
255
|
-
function
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
49
|
+
// src/mongo/cluster.ts
|
|
50
|
+
function MongoCluster(options) {
|
|
51
|
+
const client = new MongoClient(options.uri);
|
|
52
|
+
const databases = {};
|
|
53
|
+
for (const name of options.databases) {
|
|
54
|
+
databases[name] = new MongoDatabase();
|
|
55
|
+
}
|
|
56
|
+
const builder = Builder({
|
|
57
|
+
name: options.name,
|
|
58
|
+
async onListen() {
|
|
59
|
+
try {
|
|
60
|
+
await client.connect();
|
|
61
|
+
for (const name of options.databases) {
|
|
62
|
+
const db = client.db(name);
|
|
63
|
+
databases[name].attach(db);
|
|
64
|
+
}
|
|
65
|
+
await options.onConnect?.(client);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
await options.onError?.(err);
|
|
68
|
+
throw err;
|
|
272
69
|
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return {
|
|
276
|
-
get descriptor() {
|
|
277
|
-
return { entities: descriptors };
|
|
278
70
|
},
|
|
279
|
-
async
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
throw new Error(`no method registered for route "${route}"`);
|
|
283
|
-
}
|
|
284
|
-
const fn = target.entity[target.methodName];
|
|
285
|
-
return fn.call(target.entity, payload);
|
|
71
|
+
async onShutdown() {
|
|
72
|
+
await options.onDisconnect?.(client);
|
|
73
|
+
await client.close();
|
|
286
74
|
}
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
client,
|
|
78
|
+
builder,
|
|
79
|
+
...databases
|
|
287
80
|
};
|
|
288
81
|
}
|
|
289
82
|
|
|
290
|
-
// src/
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
const url = `http://${req.headers.host}${req.url}`;
|
|
294
|
-
const headers = new Headers();
|
|
295
|
-
for (const key in req.headers) {
|
|
296
|
-
const value = req.headers[key];
|
|
297
|
-
if (typeof value === "string") {
|
|
298
|
-
headers.set(key, value);
|
|
299
|
-
}
|
|
300
|
-
if (Array.isArray(value)) {
|
|
301
|
-
headers.set(key, value.join(", "));
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
if (req.method === "GET" || req.method === "HEAD") {
|
|
305
|
-
return new Request(url, { method: req.method, headers });
|
|
306
|
-
}
|
|
307
|
-
const chunks = [];
|
|
308
|
-
for await (const chunk of req) {
|
|
309
|
-
chunks.push(chunk);
|
|
310
|
-
}
|
|
311
|
-
const body = Buffer.concat(chunks);
|
|
312
|
-
return new Request(url, { method: req.method, headers, body });
|
|
313
|
-
}
|
|
314
|
-
async function writeWebResponse(webResponse, res) {
|
|
315
|
-
res.statusCode = webResponse.status;
|
|
316
|
-
webResponse.headers.forEach((value, key) => {
|
|
317
|
-
res.setHeader(key, value);
|
|
318
|
-
});
|
|
319
|
-
if (webResponse.body === null) {
|
|
320
|
-
res.end();
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
const reader = webResponse.body.getReader();
|
|
324
|
-
while (true) {
|
|
325
|
-
const next = await reader.read();
|
|
326
|
-
if (next.done) {
|
|
327
|
-
break;
|
|
328
|
-
}
|
|
329
|
-
res.write(next.value);
|
|
330
|
-
}
|
|
331
|
-
res.end();
|
|
332
|
-
}
|
|
333
|
-
async function handle(request, composed) {
|
|
334
|
-
const url = new URL(request.url);
|
|
335
|
-
if (url.pathname === "/meta") {
|
|
336
|
-
return Response.json(composed.descriptor);
|
|
83
|
+
// src/redis/redis.ts
|
|
84
|
+
var Redis = class {
|
|
85
|
+
constructor(input) {
|
|
337
86
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// src/server/application.ts
|
|
90
|
+
import { createServer } from "http";
|
|
91
|
+
var Application = class {
|
|
92
|
+
state = {};
|
|
93
|
+
builders = [];
|
|
94
|
+
register(builder) {
|
|
95
|
+
this.builders.push(builder);
|
|
96
|
+
builder.onRegister?.(this.state);
|
|
97
|
+
}
|
|
98
|
+
async listen(port) {
|
|
99
|
+
const server = createServer();
|
|
100
|
+
for (const builder of this.builders) {
|
|
101
|
+
await builder.onListen?.(server);
|
|
102
|
+
}
|
|
103
|
+
server.listen(port);
|
|
104
|
+
server.on("close", async () => {
|
|
105
|
+
for (const builder of this.builders) {
|
|
106
|
+
await builder.onShutdown?.();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
357
109
|
}
|
|
358
|
-
}
|
|
359
|
-
function
|
|
360
|
-
return
|
|
361
|
-
listen(port) {
|
|
362
|
-
const server = createServer((req, res) => {
|
|
363
|
-
toWebRequest(req).then((request) => handle(request, composed)).then((response) => writeWebResponse(response, res)).catch((error) => {
|
|
364
|
-
res.statusCode = 500;
|
|
365
|
-
res.end("internal error");
|
|
366
|
-
});
|
|
367
|
-
});
|
|
368
|
-
server.listen(port);
|
|
369
|
-
return server;
|
|
370
|
-
}
|
|
371
|
-
};
|
|
110
|
+
};
|
|
111
|
+
function bootstrap() {
|
|
112
|
+
return new Application();
|
|
372
113
|
}
|
|
373
114
|
export {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
115
|
+
Builder,
|
|
116
|
+
MongoCluster,
|
|
117
|
+
MongoDatabase,
|
|
118
|
+
Redis,
|
|
119
|
+
ValidateEnv,
|
|
120
|
+
bootstrap,
|
|
121
|
+
effect,
|
|
122
|
+
guard
|
|
380
123
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aromix/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "The Core Package For Aromix",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,9 +18,8 @@
|
|
|
18
18
|
"core",
|
|
19
19
|
"server",
|
|
20
20
|
"framework",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"node"
|
|
21
|
+
"node",
|
|
22
|
+
"rpc"
|
|
24
23
|
],
|
|
25
24
|
"files": [
|
|
26
25
|
"dist"
|
|
@@ -42,18 +41,23 @@
|
|
|
42
41
|
},
|
|
43
42
|
"peerDependencies": {
|
|
44
43
|
"@aromix/validator": "^0.3.0",
|
|
45
|
-
"mongodb": "^7.3.0"
|
|
44
|
+
"mongodb": "^7.3.0",
|
|
45
|
+
"redis": "^6.0.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@aromix/validator": "^0.3.0",
|
|
49
49
|
"@types/node": "^22.10.2",
|
|
50
50
|
"mongodb": "^7.3.0",
|
|
51
|
+
"redis": "^6.0.1",
|
|
51
52
|
"tsup": "^8.3.5",
|
|
52
53
|
"typescript": "^5.7.2"
|
|
53
54
|
},
|
|
54
55
|
"peerDependenciesMeta": {
|
|
55
56
|
"mongodb": {
|
|
56
57
|
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"redis": {
|
|
60
|
+
"optional": true
|
|
57
61
|
}
|
|
58
62
|
}
|
|
59
63
|
}
|