vona-module-a-executor 5.0.9 → 5.0.11

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.
@@ -0,0 +1,65 @@
1
+ import type { BeanScopeUtil } from 'vona';
2
+ /** bean: end */
3
+ /** bean: begin */
4
+ import type { BeanExecutor } from '../bean/bean.executor.ts';
5
+ /** service: end */
6
+ /** service: begin */
7
+ import type { ServiceExecutor } from '../service/executor.ts';
8
+ /** service: end */
9
+ /** scope: begin */
10
+ import { BeanScopeBase } from 'vona';
11
+ /** bean: begin */
12
+ import 'vona';
13
+ /** service: end */
14
+ /** service: begin */
15
+ import 'vona';
16
+ import 'vona';
17
+ import 'vona';
18
+ import 'vona';
19
+ export * from '../bean/bean.executor.ts';
20
+ declare module 'vona' {
21
+ }
22
+ declare module 'vona-module-a-executor' {
23
+ interface BeanExecutor {
24
+ }
25
+ }
26
+ declare module 'vona' {
27
+ interface IBeanRecordGlobal {
28
+ executor: BeanExecutor;
29
+ }
30
+ }
31
+ /** bean: end */
32
+ /** service: begin */
33
+ export * from '../service/executor.ts';
34
+ declare module 'vona-module-a-web' {
35
+ interface IServiceRecord {
36
+ 'a-executor:executor': never;
37
+ }
38
+ }
39
+ declare module 'vona-module-a-executor' {
40
+ interface ServiceExecutor {
41
+ }
42
+ }
43
+ export interface IModuleService {
44
+ executor: ServiceExecutor;
45
+ }
46
+ declare module 'vona' {
47
+ interface IBeanRecordGeneral {
48
+ 'a-executor.service.executor': ServiceExecutor;
49
+ }
50
+ }
51
+ export declare class ScopeModuleAExecutor extends BeanScopeBase {
52
+ }
53
+ export interface ScopeModuleAExecutor {
54
+ util: BeanScopeUtil;
55
+ service: IModuleService;
56
+ }
57
+ declare module 'vona' {
58
+ interface IBeanScopeRecord {
59
+ 'a-executor': ScopeModuleAExecutor;
60
+ }
61
+ interface IBeanScopeContainer {
62
+ executor: ScopeModuleAExecutor;
63
+ }
64
+ }
65
+ /** scope: end */
@@ -0,0 +1,2 @@
1
+ export declare const __ThisModule__ = "a-executor";
2
+ export { ScopeModuleAExecutor as ScopeModule } from './index.ts';
@@ -0,0 +1,12 @@
1
+ import type { FunctionAsync } from 'vona';
2
+ import type { IApiPathRecordMethodMap } from 'vona-module-a-web';
3
+ import type { INewCtxOptions, IPerformActionOptions } from '../types/executor.ts';
4
+ import { BeanBase } from 'vona';
5
+ export declare class BeanExecutor extends BeanBase {
6
+ performAction<METHOD extends keyof IApiPathRecordMethodMap, PATH extends keyof IApiPathRecordMethodMap[METHOD]>(method: METHOD, path: PATH, options?: IPerformActionOptions): Promise<any>;
7
+ runInBackground(fn: FunctionAsync<void>): Promise<void>;
8
+ newCtxIsolate<RESULT>(fn: FunctionAsync<RESULT>, options?: INewCtxOptions): Promise<RESULT>;
9
+ mockCtx<RESULT>(fn: FunctionAsync<RESULT>, options?: INewCtxOptions): Promise<RESULT>;
10
+ newCtx<RESULT>(fn: FunctionAsync<RESULT>, options?: INewCtxOptions): Promise<RESULT>;
11
+ private _newCtxInner;
12
+ }
@@ -0,0 +1,2 @@
1
+ export * from './.metadata/index.ts';
2
+ export * from './types/index.ts';
package/dist/index.js ADDED
@@ -0,0 +1,291 @@
1
+ import { BeanInfo, BeanBase, cast, deepExtend, BeanScopeBase } from 'vona';
2
+ import { Bean, Scope } from 'vona-module-a-bean';
3
+ import { combineParamsAndQuery } from '@cabloy/utils';
4
+ import { Log } from 'vona-module-a-logger';
5
+ import { Service } from 'vona-module-a-web';
6
+
7
+ function __delegateProperties(ctx, ctxCaller) {
8
+ for (const property of ['state']) {
9
+ __delegateProperty(ctx, ctxCaller, property);
10
+ }
11
+ for (const property of ['headers']) {
12
+ __delegateProperty(ctx.request, ctxCaller.request, property);
13
+ // if (ctx.request[property]) req[property] = ctx.request[property];
14
+ }
15
+ }
16
+ function __delegateProperty(ctx, ctxCaller, property) {
17
+ if (!ctxCaller[property]) ctxCaller[property] = {};
18
+ ctx[property] = ctxCaller[property];
19
+ }
20
+
21
+ // export function delegateProperty(ctx, ctxCaller, property) {
22
+ // if (!ctxCaller[property]) return;
23
+ // if (!ctx[property]) ctx[property] = {};
24
+ // for (const key in ctxCaller[property]) {
25
+ // ctx[property][key] = ctxCaller[property][key];
26
+ // }
27
+ // }
28
+
29
+ // function _delegateProperty(ctx, ctxCaller, property) {
30
+ // const keyMock = `__executeBean__mock__${property}__`;
31
+ // const keyOriginal = `__executeBean__mock__${property}__original__`;
32
+ // if (['headers'].includes(property)) {
33
+ // ctx[keyOriginal] = ctx[property];
34
+ // }
35
+ // Object.defineProperty(ctx, property, {
36
+ // get() {
37
+ // const value = ctxCaller && ctxCaller[property];
38
+ // if (value) return value;
39
+ // //
40
+ // if (['headers'].includes(property)) {
41
+ // return ctx[keyOriginal];
42
+ // }
43
+ // //
44
+ // if (!ctx[keyMock]) {
45
+ // ctx[keyMock] = {};
46
+ // }
47
+ // return ctx[keyMock];
48
+ // },
49
+ // });
50
+ // }
51
+
52
+ var _dec$2, _dec2$2, _class$2;
53
+ let BeanExecutor = (_dec$2 = Bean(), _dec2$2 = BeanInfo({
54
+ module: "a-executor"
55
+ }), _dec$2(_class$2 = _dec2$2(_class$2 = class BeanExecutor extends BeanBase {
56
+ async performAction(method, path, options) {
57
+ // url
58
+ const url = this.app.util.combineApiPath(path, '', true, true);
59
+ return await this.scope.service.executor.performActionInner(method, url, options);
60
+ }
61
+ runInBackground(fn) {
62
+ return this.bean.database.newDbIsolate(() => {
63
+ return this.newCtx(fn);
64
+ });
65
+ }
66
+ async newCtxIsolate(fn, options) {
67
+ options = Object.assign({}, options);
68
+ // instanceName !== undefined means isolate
69
+ options.instanceName = options.instanceName === undefined ? this.ctx?.instanceName : options.instanceName;
70
+ return this.newCtx(fn, options);
71
+ }
72
+ async mockCtx(fn, options) {
73
+ options = Object.assign({}, options);
74
+ options.dbInfo = options.dbInfo === undefined ? true : options.dbInfo;
75
+ options.instanceName = options.instanceName === undefined ? this.ctx?.instanceName ?? '' : options.instanceName;
76
+ return this.newCtx(fn, options);
77
+ }
78
+ async newCtx(fn, options) {
79
+ if (!options?.dbInfo) return this._newCtxInner(fn, options);
80
+ const dbInfo = options.dbInfo === true ? {} : options.dbInfo;
81
+ return this.bean.database.newDb(() => {
82
+ return this._newCtxInner(fn, options);
83
+ }, dbInfo);
84
+ }
85
+ async _newCtxInner(fn, options) {
86
+ options = Object.assign({}, options);
87
+ // innerAccess
88
+ const innerAccess = options.innerAccess !== false;
89
+ // ctx ref
90
+ const ctxRef = innerAccess ? this.ctx : undefined;
91
+ // isolate
92
+ const isolate = !ctxRef || options.instanceName !== undefined;
93
+ const ctxCaller = !isolate && ctxRef ? ctxRef : undefined;
94
+ // locale/instanceName
95
+ if (ctxRef) {
96
+ options.locale = options.locale === undefined ? ctxRef.locale : options.locale;
97
+ options.instanceName = options.instanceName === undefined ? ctxRef.instanceName : options.instanceName;
98
+ }
99
+ // run
100
+ const ctx = this.app.createAnonymousContext(options.req, options.res);
101
+ return await this.app.ctxStorage.run(ctx, async () => {
102
+ // innerAccess
103
+ ctx.innerAccess = innerAccess;
104
+ // locale
105
+ if (options.locale !== undefined) {
106
+ ctx.locale = options.locale;
107
+ }
108
+ // instanceName: undefined/null is different
109
+ if (options.instanceName !== undefined) {
110
+ ctx.instanceName = options.instanceName;
111
+ }
112
+ // ctxCaller
113
+ if (ctxCaller) {
114
+ // delegateProperties
115
+ __delegateProperties(ctx, ctxCaller);
116
+ // ctxCaller
117
+ ctx.ctxCaller = ctxCaller;
118
+ } else {
119
+ // isolate: extraData
120
+ if (options.extraData) {
121
+ // delegateProperties
122
+ __delegateProperties(ctx, options.extraData);
123
+ }
124
+ }
125
+ // instance
126
+ const instanceName = ctx.instanceName; // use default instanceName when undefined
127
+ if (instanceName !== undefined && instanceName !== null) {
128
+ ctx.instance = await this.bean.instance.get(instanceName);
129
+ // start instance
130
+ if (options.instance) {
131
+ await this.$scope.instance.service.instance.checkAppReadyInstance(true);
132
+ }
133
+ }
134
+ // execute
135
+ let res;
136
+ if (options.transaction) {
137
+ res = await this.bean.database.current.transaction.begin(async () => {
138
+ return await fn();
139
+ }, options.transactionOptions);
140
+ } else {
141
+ res = await fn();
142
+ }
143
+ // commitDone
144
+ await ctx.commitDone();
145
+ // ok
146
+ return res;
147
+ });
148
+ }
149
+ }) || _class$2) || _class$2);
150
+
151
+ function _applyDecoratedDescriptor(i, e, r, n, l) {
152
+ var a = {};
153
+ return Object.keys(n).forEach(function (i) {
154
+ a[i] = n[i];
155
+ }), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = true), a = r.slice().reverse().reduce(function (r, n) {
156
+ return n(i, e, r) || r;
157
+ }, a), l && void 0 !== a.initializer && (a.value = a.initializer ? a.initializer.call(l) : void 0, a.initializer = void 0), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a;
158
+ }
159
+
160
+ const SymbolRouterMiddleware = Symbol('SymbolRouterMiddleware');
161
+
162
+ var _dec$1, _dec2$1, _dec3, _dec4, _dec5, _class$1, _class2;
163
+ let ServiceExecutor = (_dec$1 = Service(), _dec2$1 = BeanInfo({
164
+ module: "a-executor"
165
+ }), _dec3 = Log({
166
+ level: 'debug'
167
+ }), _dec4 = Reflect.metadata("design:type", Function), _dec5 = Reflect.metadata("design:paramtypes", [typeof METHOD === "undefined" ? Object : METHOD, String, typeof IPerformActionOptions === "undefined" ? Object : IPerformActionOptions]), _dec$1(_class$1 = _dec2$1(_class$1 = (_class2 = class ServiceExecutor extends BeanBase {
168
+ async performActionInner(method, url, options) {
169
+ // app
170
+ const app = this.app;
171
+ // new ctx
172
+ return await this.bean.executor.newCtx(async () => {
173
+ const ctx = this.ctx;
174
+ // default status code
175
+ ctx.res.statusCode = 404;
176
+ ctx.req.method = method.toUpperCase();
177
+ // url
178
+ ctx.req.url = combineParamsAndQuery(url, {
179
+ params: options?.params,
180
+ query: options?.query
181
+ });
182
+ // headers
183
+ ctx.req.headers = Object.assign({}, ctx.req.headers, options?.headers);
184
+ // json
185
+ if (!ctx.req.headers.accept) {
186
+ ctx.req.headers.accept = 'application/json';
187
+ }
188
+ // authToken
189
+ if (options?.authToken) {
190
+ ctx.req.headers.authorization = `Bearer ${options?.authToken}`;
191
+ }
192
+ // // query
193
+ // if (options?.query !== undefined) {
194
+ // cast(ctx.req).query = cast(ctx.request).query = options?.query;
195
+ // }
196
+ // body
197
+ cast(ctx.req).body = ctx.request.body = options?.body ?? {}; // body should set {} if undefined/null
198
+ // onion
199
+ ctx.onionsDynamic = options?.onions;
200
+ // invoke middleware
201
+ await app[SymbolRouterMiddleware](ctx);
202
+ // check result
203
+ if (ctx.status === 200) {
204
+ if (!ctx.body || ctx.body.code === undefined) {
205
+ // not check code, e.g. text/xml
206
+ return ctx.body;
207
+ }
208
+ if (ctx.body.code === 0) {
209
+ return ctx.body.data;
210
+ }
211
+ throw app.util.createError(ctx.body);
212
+ } else {
213
+ if (ctx.body && typeof ctx.body === 'object') {
214
+ throw app.util.createError(ctx.body);
215
+ } else {
216
+ throw app.util.createError({
217
+ code: ctx.status,
218
+ message: ctx.message
219
+ });
220
+ }
221
+ }
222
+ }, {
223
+ innerAccess: options?.innerAccess,
224
+ extraData: options?.extraData
225
+ });
226
+ }
227
+ prepareGeneralInfo(options) {
228
+ const current = this.bean.database.current;
229
+ const level = (options?.dbInfo?.level ?? current?.level ?? 0) + 1;
230
+ const clientName = options?.dbInfo?.clientName ?? current?.clientName;
231
+ const locale = options?.locale === undefined ? this.ctx?.locale : options.locale;
232
+ const instanceName = options?.instanceName === undefined ? this.ctx?.instanceName : options.instanceName;
233
+ options = {
234
+ dbInfo: {
235
+ level,
236
+ clientName
237
+ },
238
+ locale,
239
+ instanceName
240
+ };
241
+ if (this.ctx) {
242
+ options = deepExtend({
243
+ extraData: {
244
+ request: {
245
+ headers: {}
246
+ }
247
+ }
248
+ }, options);
249
+ // extraData: headers
250
+ const headers = options.extraData.request.headers;
251
+ for (const key in this.ctx.request.headers) {
252
+ if (key.startsWith('x-vona-data-') && !headers[key]) {
253
+ const value = this.ctx.request.headers[key];
254
+ if (value) {
255
+ headers[key] = value;
256
+ }
257
+ }
258
+ }
259
+ }
260
+ return options;
261
+ }
262
+ }, _applyDecoratedDescriptor(_class2.prototype, "performActionInner", [_dec3, _dec4, _dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "performActionInner"), _class2.prototype), _class2)) || _class$1) || _class$1);
263
+
264
+ // for (const key of ['x-clientid', 'x-scene']) {
265
+ // if (!headers[key]) {
266
+ // const value =
267
+ // key === 'x-clientid'
268
+ // ? (<any>ctx.app.bean).util.getFrontClientId()
269
+ // : (<any>ctx.app.bean).util.getFrontScene();
270
+ // if (value) {
271
+ // headers[key] = value;
272
+ // }
273
+ // }
274
+ // }
275
+ // for (const key of ['host', 'origin', 'referer', 'user-agent']) {
276
+ // if (!headers[key]) {
277
+ // const value = this.ctx.request.headers[key];
278
+ // if (value) {
279
+ // headers[key] = value;
280
+ // }
281
+ // }
282
+ // }
283
+
284
+ var _dec, _dec2, _class;
285
+ let ScopeModuleAExecutor = (_dec = Scope(), _dec2 = BeanInfo({
286
+ module: "a-executor"
287
+ }), _dec(_class = _dec2(_class = class ScopeModuleAExecutor extends BeanScopeBase {}) || _class) || _class);
288
+
289
+ /** scope: end */
290
+
291
+ export { BeanExecutor, ScopeModuleAExecutor, ServiceExecutor, SymbolRouterMiddleware };
@@ -0,0 +1,2 @@
1
+ export declare function __delegateProperties(ctx: any, ctxCaller: any): void;
2
+ export declare function __delegateProperty(ctx: any, ctxCaller: any, property: any): void;
@@ -0,0 +1,7 @@
1
+ import type { IApiPathRecordMethodMap } from 'vona-module-a-web';
2
+ import type { IGeneralInfoOptions, IPerformActionOptions } from '../types/executor.ts';
3
+ import { BeanBase } from 'vona';
4
+ export declare class ServiceExecutor extends BeanBase {
5
+ performActionInner<METHOD extends keyof IApiPathRecordMethodMap>(method: METHOD, url: string, options?: IPerformActionOptions): Promise<any>;
6
+ prepareGeneralInfo(options?: IGeneralInfoOptions): IGeneralInfoOptions;
7
+ }
@@ -0,0 +1,40 @@
1
+ import type { ContextState, ILocaleInfos, PowerPartial } from 'vona';
2
+ import type { IDbInfo, ITransactionOptions } from 'vona-module-a-database';
3
+ import type { ConfigOnions } from 'vona-module-a-onion';
4
+ export declare const SymbolRouterMiddleware: unique symbol;
5
+ export interface INewCtxExtraData {
6
+ state?: ContextState;
7
+ request?: {
8
+ headers?: Record<string, string>;
9
+ };
10
+ }
11
+ export interface INewCtxOptions extends INewCtxBaseOptions {
12
+ dbInfo?: IDbInfo | true;
13
+ }
14
+ export interface INewCtxBaseOptions {
15
+ locale?: keyof ILocaleInfos;
16
+ instanceName?: string | undefined | null;
17
+ instance?: boolean;
18
+ transaction?: boolean;
19
+ transactionOptions?: ITransactionOptions;
20
+ extraData?: INewCtxExtraData | undefined;
21
+ innerAccess?: boolean;
22
+ req?: any;
23
+ res?: any;
24
+ }
25
+ export interface IPerformActionOptions {
26
+ innerAccess?: boolean;
27
+ params?: object;
28
+ query?: object;
29
+ headers?: object;
30
+ body?: any;
31
+ onions?: PowerPartial<ConfigOnions>;
32
+ authToken?: string;
33
+ extraData?: INewCtxExtraData | undefined;
34
+ }
35
+ export interface IGeneralInfoOptions {
36
+ dbInfo?: IDbInfo;
37
+ locale?: keyof ILocaleInfos;
38
+ instanceName?: string | undefined | null;
39
+ extraData?: INewCtxExtraData;
40
+ }
@@ -0,0 +1 @@
1
+ export * from './executor.ts';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vona-module-a-executor",
3
3
  "type": "module",
4
- "version": "5.0.9",
4
+ "version": "5.0.11",
5
5
  "title": "a-executor",
6
6
  "vonaModule": {
7
7
  "dependencies": {}
@@ -28,8 +28,12 @@
28
28
  "dependencies": {
29
29
  "koa-compose": "^4.1.0"
30
30
  },
31
+ "devDependencies": {
32
+ "clean-package": "^2.2.0",
33
+ "rimraf": "^6.0.1"
34
+ },
31
35
  "scripts": {
32
- "clean": "rimraf dist tsconfig.tsbuildinfo",
33
- "tsc:publish": "npm run clean && tsc"
36
+ "clean": "rimraf dist tsconfig.build.tsbuildinfo",
37
+ "tsc:publish": "npm run clean && vona :bin:buildModule && tsc -p tsconfig.build.json"
34
38
  }
35
39
  }