cabloy 5.1.131 → 5.1.133
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/.cabloy-version +1 -1
- package/.claude/skills/cabloy-worktree-environment/SKILL.md +6 -6
- package/.claude/skills/cabloy-worktree-environment/evals/evals.json +2 -2
- package/.github/workflows/vona-test-pg.yml +1 -1
- package/.github/workflows/vona-test-sqlite3.yml +1 -1
- package/CHANGELOG.md +28 -0
- package/cabloy-docs/backend/dto-guide.md +39 -4
- package/cabloy-docs/backend/dto-infer-generation.md +29 -0
- package/cabloy-docs/backend/openapi-guide.md +16 -0
- package/cabloy-docs/backend/validation-guide.md +45 -0
- package/cabloy-docs/frontend/environment-config-guide.md +8 -15
- package/cabloy-docs/frontend/navigation-guards-guide.md +3 -3
- package/cabloy-docs/frontend/page-route-guide.md +4 -4
- package/cabloy-docs/frontend/ssr-env.md +22 -29
- package/cabloy-docs/frontend/theme-guide.md +4 -4
- package/cabloy-docs/frontend/zova-router-under-the-hood.md +1 -1
- package/cabloy-docs/fullstack/deploy-cloudflare-docker.md +6 -6
- package/cabloy-docs/fullstack/parallel-worktree-environment.md +2 -2
- package/e2e/specs/a-commerce/commerce.spec.ts +479 -17
- package/e2e/specs/cabloy-basic/basic.spec.ts +30 -5
- package/package.json +7 -7
- package/vona/.claude/skills/detect-ssr-leak/SKILL.md +1 -1
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +120 -10
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuCreate.tsx +3 -1
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +13 -1
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuUpdate.tsx +3 -1
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuView.tsx +13 -1
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/sku.tsx +6 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/test/skuPresentation.test.ts +227 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +46 -36
- package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectResItem.tsx +5 -13
- package/vona/src/suite/a-commerce/modules/commerce-member/src/service/address.ts +16 -1
- package/vona/src/suite/a-commerce/modules/commerce-member/test/addressPresentation.test.ts +210 -0
- package/vona/src/suite/a-commerce/modules/commerce-payment/src/service/commercePayScene.ts +13 -2
- package/vona/src/suite/a-commerce/modules/commerce-payment/test/paymentAttempt.test.ts +12 -0
- package/vona/src/suite/a-commerce/modules/commerce-promotion/src/service/coupon.ts +7 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +45 -2
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +23 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +23 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/order.ts +31 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderAdminLineBase.tsx +56 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderAdminLineResItem.tsx +17 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderAdminLineView.tsx +13 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderSelectResItem.tsx +26 -2
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/orderView.tsx +197 -3
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/refundRecoveryAction.tsx +19 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/refundRecoveryView.tsx +70 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectResItem.tsx +7 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditView.tsx +21 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectResItem.tsx +7 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceView.tsx +3 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/order.tsx +12 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/order.ts +15 -2
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/order.ts +215 -3
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockAudit.ts +25 -2
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockBalance.ts +14 -3
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/checkoutReservation.test.ts +4 -4
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/orderPresentation.test.ts +358 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/orderSnapshot.test.ts +8 -8
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/paymentOutcome.test.ts +5 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/refundLifecycle.test.ts +50 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockPresentation.test.ts +324 -0
- package/vona/src/suite/a-home/modules/home-base/package.json +3 -2
- package/vona/src/suite/a-home/modules/home-base/src/.metadata/index.ts +93 -16
- package/vona/src/suite/a-home/modules/home-base/src/controller/siteCatalog.ts +21 -0
- package/vona/src/suite/a-home/modules/home-base/src/dto/siteCatalogSelectRes.ts +11 -0
- package/vona/src/suite/a-home/modules/home-base/src/dto/siteCatalogSelectResItem.ts +15 -0
- package/vona/src/suite/a-home/modules/home-base/src/service/siteCatalog.ts +29 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrSite.admin.ts +3 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/config/locale/en-us.ts +1 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/config/locale/zh-cn.ts +1 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/bean/ssrSite.web.ts +3 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/config/locale/en-us.ts +1 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/config/locale/zh-cn.ts +1 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/cli/ssrSite/boilerplate/{{sceneName}}.{{beanName}}.ts_ +1 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/env.ts +1 -3
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrSite.ts +2 -1
- package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
- package/vona/src/suite-vendor/a-pay/modules/a-pay/package.json +1 -1
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/.metadata/index.ts +67 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/bean.payProvider.ts +1 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/bean.payScene.ts +5 -4
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/meta.index.ts +8 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/meta.version.ts +22 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/bean/schedule.providerOperationDispatch.ts +1 -1
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/paymentSession.tsx +6 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/providerOperation.tsx +3 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/providerOperationRecoveryAudit.tsx +53 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/entity/refundOperation.tsx +6 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/model/providerOperationRecoveryAudit.ts +12 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/paymentSession.ts +6 -2
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/providerOperation.ts +236 -30
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/refundOperation.ts +8 -5
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/service/webhook.ts +34 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/types/payProvider.ts +4 -0
- package/vona/src/suite-vendor/a-pay/modules/a-pay/src/types/payment.ts +6 -0
- package/vona/src/suite-vendor/a-pay/modules/pay-mock/package.json +1 -1
- package/vona/src/suite-vendor/a-pay/modules/pay-mock/src/bean/payProvider.mock.ts +15 -7
- package/vona/src/suite-vendor/a-pay/modules/pay-mock/src/service/payMock.ts +9 -5
- package/vona/src/suite-vendor/a-pay/modules/pay-paypal/package.json +1 -1
- package/vona/src/suite-vendor/a-pay/modules/pay-paypal/src/bean/payProvider.paypal.ts +289 -86
- package/vona/src/suite-vendor/a-pay/modules/pay-paypal/src/lib/paypalGateway.ts +9 -1
- package/vona/src/suite-vendor/a-pay/modules/pay-stripe/package.json +1 -1
- package/vona/src/suite-vendor/a-pay/package.json +5 -5
- package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/types/rest.ts +1 -0
- package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/utils.ts +12 -0
- package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoCreate.ts +5 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoUpdate.ts +5 -1
- package/vona/src/suite-vendor/a-vona/modules/a-validation/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-validation/src/bean/bean.validator.ts +60 -1
- package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-web/src/lib/decorator/bean.ts +7 -4
- package/vona/src/suite-vendor/a-vona/modules/a-web/src/types/dto.ts +2 -1
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/env/.env +3 -5
- package/zova/env/.env.cabloyBasicAdmin +1 -4
- package/zova/env/.env.cabloyBasicWeb +1 -5
- package/zova/env/.env.cabloyCommerce +1 -5
- package/zova/env/.env.cabloyCommerceAdmin +1 -4
- package/zova/env/.env.ssr.admin +1 -4
- package/zova/env/.env.ssr.web +1 -5
- package/zova/package.original.json +1 -1
- package/zova/packages-utils/zova-jsx/package.json +2 -2
- package/zova/packages-zova/zova/package.json +3 -3
- package/zova/packages-zova/zova-core/package.json +2 -1
- package/zova/packages-zova/zova-core/src/core/component/locale.ts +10 -4
- package/zova/packages-zova/zova-core/src/core/sys/config.ts +14 -6
- package/zova/packages-zova/zova-core/src/types/utils/env.ts +4 -2
- package/zova/pnpm-lock.yaml +24 -21
- package/zova/src/front/config/config/config.ts +22 -7
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/routes.ts +2 -2
- package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/schemas.ts +16 -8
- package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/types.ts +150 -216
- package/zova/src/suite/a-commerce/modules/commerce-member/src/model/addressMine.ts +1 -2
- package/zova/src/suite/a-commerce/modules/commerce-member/src/page/address/controller.tsx +5 -8
- package/zova/src/suite/a-commerce/modules/commerce-member/src/routes.ts +1 -1
- package/zova/src/suite/a-commerce/modules/commerce-promotion/src/model/coupon.ts +1 -2
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/routes.ts +3 -1
- package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +3 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeOrder.ts +72 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +8 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +226 -16
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeOrder.ts +15 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/component/tableCellActionRefund/controller.tsx +155 -36
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +7 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +7 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +3 -4
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/order.ts +42 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/orderMine.ts +2 -4
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/cart/controller.tsx +5 -1
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/checkout/controller.tsx +14 -10
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/order/controller.tsx +5 -8
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/orders/controller.tsx +5 -8
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +151 -24
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/routes.ts +5 -5
- package/zova/src/suite/a-demo/modules/demo-basic/src/routes.ts +26 -7
- package/zova/src/suite/a-demo/modules/demo-todo/src/routes.ts +2 -2
- package/zova/src/suite/a-devui/modules/devui-adapter/src/bean/meta.themeHandler.ts +1 -1
- package/zova/src/suite/a-home/modules/home-base/package.json +1 -0
- package/zova/src/suite/a-home/modules/home-base/src/routes.ts +5 -0
- package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +1 -1
- package/zova/src/suite/a-home/modules/home-base/src/service/ssrLayout.ts +18 -14
- package/zova/src/suite/a-home/modules/home-indexadmin/src/routes.ts +1 -1
- package/zova/src/suite/a-home/modules/home-indexweb/src/routes.ts +1 -0
- package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx +12 -4
- package/zova/src/suite/a-home/modules/home-layoutadmin/src/config/config.ts +8 -0
- package/zova/src/suite/a-home/modules/home-layoutadmin/src/model/layout.ts +5 -8
- package/zova/src/suite/a-home/modules/home-layoutempty/src/.metadata/index.ts +10 -3
- package/zova/src/suite/a-home/modules/home-layoutempty/src/component/layoutEmpty/controller.tsx +9 -3
- package/zova/src/suite/a-home/modules/home-layoutempty/src/config/config.ts +12 -0
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx +13 -8
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.header.tsx +1 -1
- package/zova/src/suite/a-home/modules/home-layoutweb/src/config/config.ts +4 -0
- package/zova/src/suite/a-home/modules/home-layoutweb/src/model/layout.ts +5 -8
- package/zova/src/suite/a-home/modules/home-login/src/routes.ts +1 -0
- package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +2 -3
- package/zova/src/suite/cabloy-basic/modules/basic-metrics/src/routes.ts +3 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/routes.ts +3 -0
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-pay/modules/a-pay/package.json +1 -1
- package/zova/src/suite-vendor/a-pay/modules/a-pay/src/model/paymentSession.ts +2 -2
- package/zova/src/suite-vendor/a-pay/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-interceptor/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-interceptor/src/bean/interceptor.jwt.ts +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/config/config.ts +1 -17
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/bodyReadyObserver.ts +27 -0
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/index.ts +2 -0
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssr.ts +33 -0
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssrMetaStore.ts +3 -35
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssrProfile.ts +38 -0
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/monkey.ts +10 -0
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/types/config.ts +3 -10
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/types/ssr.ts +17 -8
- package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/src/service/ssrHandler.ts +33 -18
- package/zova/src/suite-vendor/a-zova/modules/a-style/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-style/src/bean/bean.theme.ts +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +7 -7
|
@@ -7,15 +7,15 @@ export * from '../entity/address.tsx';
|
|
|
7
7
|
import type { IEntityOptionsAddress } from '../entity/address.tsx';
|
|
8
8
|
import 'vona-module-a-orm';
|
|
9
9
|
declare module 'vona-module-a-orm' {
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
export interface IEntityRecord {
|
|
12
12
|
'commerce-member:address': IEntityOptionsAddress;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
}
|
|
17
17
|
declare module 'vona-module-commerce-member' {
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
}
|
|
20
20
|
/** entity: end */
|
|
21
21
|
/** entity: begin */
|
|
@@ -33,7 +33,7 @@ declare module 'vona-module-a-orm' {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
declare module 'vona-module-commerce-member' {
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
export interface IEntityOptionsAddress {
|
|
38
38
|
fields?: TypeEntityOptionsFields<EntityAddress, IEntityOptionsAddress[TypeSymbolKeyFieldsMore]>;
|
|
39
39
|
}
|
|
@@ -44,15 +44,15 @@ export * from '../model/address.ts';
|
|
|
44
44
|
import type { IModelOptionsAddress } from '../model/address.ts';
|
|
45
45
|
import 'vona-module-a-orm';
|
|
46
46
|
declare module 'vona-module-a-orm' {
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
export interface IModelRecord {
|
|
49
49
|
'commerce-member:address': IModelOptionsAddress;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
}
|
|
54
54
|
declare module 'vona-module-commerce-member' {
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
export interface ModelAddress {
|
|
57
57
|
/** @internal */
|
|
58
58
|
get scope(): ScopeModuleCommerceMember;
|
|
@@ -62,7 +62,7 @@ declare module 'vona-module-commerce-member' {
|
|
|
62
62
|
get $beanFullName(): 'commerce-member.model.address';
|
|
63
63
|
get $onionName(): 'commerce-member:address';
|
|
64
64
|
get $onionOptions(): IModelOptionsAddress;
|
|
65
|
-
}
|
|
65
|
+
}
|
|
66
66
|
}
|
|
67
67
|
/** model: end */
|
|
68
68
|
/** model: begin */
|
|
@@ -84,13 +84,23 @@ declare module 'vona' {
|
|
|
84
84
|
import type { IModelGetOptions, IModelMethodOptions, IModelSelectParams, TypeModelSelectAndCount, TypeModelRelationResult, TypeModelWhere, IModelInsertOptions, TypeModelMutateRelationData, IModelDeleteOptions, IModelUpdateOptions, IModelMutateOptions, IModelSelectCountParams, IModelIncrementParams, IModelSelectAggrParams, TypeModelAggrRelationResult, IModelSelectGroupParams, TypeModelGroupRelationResult } from 'vona-module-a-orm';
|
|
85
85
|
import { SymbolKeyEntity, SymbolKeyEntityMeta, SymbolKeyModelOptions } from 'vona-module-a-orm';
|
|
86
86
|
declare module 'vona-module-commerce-member' {
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
export interface ModelAddress {
|
|
89
89
|
[SymbolKeyEntity]: EntityAddress;
|
|
90
90
|
[SymbolKeyEntityMeta]: EntityAddressMeta;
|
|
91
91
|
[SymbolKeyModelOptions]: IModelOptionsAddress;
|
|
92
92
|
get<T extends IModelGetOptions<EntityAddress,ModelAddress>>(where: TypeModelWhere<EntityAddress>, options?: T): Promise<TypeModelRelationResult<EntityAddress, ModelAddress, T> | undefined>;
|
|
93
|
+
/**
|
|
94
|
+
* Retrieves one matching primary row with a pessimistic FOR UPDATE lock.
|
|
95
|
+
* Requires an active transaction. The lock is released when that transaction completes.
|
|
96
|
+
* Entity and query caches are bypassed.
|
|
97
|
+
*/
|
|
93
98
|
getForUpdate<T extends IModelGetOptions<EntityAddress,ModelAddress>>(where: TypeModelWhere<EntityAddress>, options?: T): Promise<TypeModelRelationResult<EntityAddress, ModelAddress, T> | undefined>;
|
|
99
|
+
/**
|
|
100
|
+
* Retrieves a primary row by ID with the same pessimistic FOR UPDATE lock semantics.
|
|
101
|
+
* Requires an active transaction. The lock is released when that transaction completes.
|
|
102
|
+
* Entity and query caches are bypassed.
|
|
103
|
+
*/
|
|
94
104
|
getByIdForUpdate<T extends IModelGetOptions<EntityAddress,ModelAddress>>(id: TableIdentity, options?: T): Promise<TypeModelRelationResult<EntityAddress, ModelAddress, T> | undefined>;
|
|
95
105
|
mget<T extends IModelGetOptions<EntityAddress,ModelAddress>>(ids: TableIdentity[], options?: T): Promise<TypeModelRelationResult<EntityAddress, ModelAddress, T>[]>;
|
|
96
106
|
selectAndCount<T extends IModelSelectParams<EntityAddress,ModelAddress,ModelJoins>, ModelJoins extends TypeModelsClassLikeGeneral | undefined = undefined>(params?: T, options?: IModelMethodOptions, modelJoins?: ModelJoins): Promise<TypeModelSelectAndCount<EntityAddress, ModelAddress, T>>;
|
|
@@ -124,15 +134,15 @@ export * from '../service/address.ts';
|
|
|
124
134
|
|
|
125
135
|
import 'vona-module-a-bean';
|
|
126
136
|
declare module 'vona-module-a-bean' {
|
|
127
|
-
|
|
137
|
+
|
|
128
138
|
export interface IServiceRecord {
|
|
129
139
|
'commerce-member:address': never;
|
|
130
140
|
}
|
|
131
141
|
|
|
132
|
-
|
|
142
|
+
|
|
133
143
|
}
|
|
134
144
|
declare module 'vona-module-commerce-member' {
|
|
135
|
-
|
|
145
|
+
|
|
136
146
|
export interface ServiceAddress {
|
|
137
147
|
/** @internal */
|
|
138
148
|
get scope(): ScopeModuleCommerceMember;
|
|
@@ -141,8 +151,8 @@ declare module 'vona-module-commerce-member' {
|
|
|
141
151
|
export interface ServiceAddress {
|
|
142
152
|
get $beanFullName(): 'commerce-member.service.address';
|
|
143
153
|
get $onionName(): 'commerce-member:address';
|
|
144
|
-
|
|
145
|
-
}
|
|
154
|
+
|
|
155
|
+
}
|
|
146
156
|
}
|
|
147
157
|
/** service: end */
|
|
148
158
|
/** service: begin */
|
|
@@ -166,16 +176,16 @@ export * from '../bean/meta.version.ts';
|
|
|
166
176
|
import type { IMetaOptionsIndex } from 'vona-module-a-index';
|
|
167
177
|
import 'vona-module-a-meta';
|
|
168
178
|
declare module 'vona-module-a-meta' {
|
|
169
|
-
|
|
179
|
+
|
|
170
180
|
export interface IMetaRecord {
|
|
171
181
|
'commerce-member:index': IMetaOptionsIndex;
|
|
172
182
|
'commerce-member:version': never;
|
|
173
183
|
}
|
|
174
184
|
|
|
175
|
-
|
|
185
|
+
|
|
176
186
|
}
|
|
177
187
|
declare module 'vona-module-commerce-member' {
|
|
178
|
-
|
|
188
|
+
|
|
179
189
|
export interface MetaIndex {
|
|
180
190
|
/** @internal */
|
|
181
191
|
get scope(): ScopeModuleCommerceMember;
|
|
@@ -195,8 +205,8 @@ declare module 'vona-module-commerce-member' {
|
|
|
195
205
|
export interface MetaVersion {
|
|
196
206
|
get $beanFullName(): 'commerce-member.meta.version';
|
|
197
207
|
get $onionName(): 'commerce-member:version';
|
|
198
|
-
|
|
199
|
-
}
|
|
208
|
+
|
|
209
|
+
}
|
|
200
210
|
}
|
|
201
211
|
/** meta: end */
|
|
202
212
|
/** dto: begin */
|
|
@@ -222,7 +232,7 @@ import type { IDtoOptionsAddressSelectResItem } from '../dto/addressSelectResIte
|
|
|
222
232
|
import type { IDtoOptionsAddressView } from '../dto/addressView.tsx';
|
|
223
233
|
import 'vona-module-a-web';
|
|
224
234
|
declare module 'vona-module-a-web' {
|
|
225
|
-
|
|
235
|
+
|
|
226
236
|
export interface IDtoRecord {
|
|
227
237
|
'commerce-member:addressMineCreate': IDtoOptionsAddressMineCreate;
|
|
228
238
|
'commerce-member:addressMineItem': IDtoOptionsAddressMineItem;
|
|
@@ -236,10 +246,10 @@ declare module 'vona-module-a-web' {
|
|
|
236
246
|
'commerce-member:addressView': IDtoOptionsAddressView;
|
|
237
247
|
}
|
|
238
248
|
|
|
239
|
-
|
|
249
|
+
|
|
240
250
|
}
|
|
241
251
|
declare module 'vona-module-commerce-member' {
|
|
242
|
-
|
|
252
|
+
|
|
243
253
|
}
|
|
244
254
|
/** dto: end */
|
|
245
255
|
/** dto: begin */
|
|
@@ -254,7 +264,7 @@ import type { DtoAddressSelectRes } from '../dto/addressSelectRes.tsx';
|
|
|
254
264
|
import type { DtoAddressSelectResItem } from '../dto/addressSelectResItem.tsx';
|
|
255
265
|
import type { DtoAddressView } from '../dto/addressView.tsx';
|
|
256
266
|
declare module 'vona-module-commerce-member' {
|
|
257
|
-
|
|
267
|
+
|
|
258
268
|
export interface IDtoOptionsAddressMineCreate {
|
|
259
269
|
fields?: TypeEntityOptionsFields<DtoAddressMineCreate, IDtoOptionsAddressMineCreate[TypeSymbolKeyFieldsMore]>;
|
|
260
270
|
}
|
|
@@ -301,15 +311,15 @@ export * from '../controller/address.ts';
|
|
|
301
311
|
import type { IControllerOptionsAddress } from '../controller/address.ts';
|
|
302
312
|
import 'vona-module-a-web';
|
|
303
313
|
declare module 'vona-module-a-web' {
|
|
304
|
-
|
|
314
|
+
|
|
305
315
|
export interface IControllerRecord {
|
|
306
316
|
'commerce-member:address': IControllerOptionsAddress;
|
|
307
317
|
}
|
|
308
318
|
|
|
309
|
-
|
|
319
|
+
|
|
310
320
|
}
|
|
311
321
|
declare module 'vona-module-commerce-member' {
|
|
312
|
-
|
|
322
|
+
|
|
313
323
|
export interface ControllerAddress {
|
|
314
324
|
/** @internal */
|
|
315
325
|
get scope(): ScopeModuleCommerceMember;
|
|
@@ -319,14 +329,14 @@ declare module 'vona-module-commerce-member' {
|
|
|
319
329
|
get $beanFullName(): 'commerce-member.controller.address';
|
|
320
330
|
get $onionName(): 'commerce-member:address';
|
|
321
331
|
get $onionOptions(): IControllerOptionsAddress;
|
|
322
|
-
}
|
|
332
|
+
}
|
|
323
333
|
}
|
|
324
334
|
/** controller: end */
|
|
325
335
|
/** controller: begin */
|
|
326
336
|
// @ts-ignore ignore
|
|
327
337
|
import type { ControllerAddress } from '../controller/address.ts';
|
|
328
338
|
declare module 'vona-module-commerce-member' {
|
|
329
|
-
|
|
339
|
+
|
|
330
340
|
export interface IControllerOptionsAddress {
|
|
331
341
|
actions?: TypeControllerOptionsActions<ControllerAddress>;
|
|
332
342
|
}
|
|
@@ -355,22 +365,22 @@ import 'vona-module-a-openapi';
|
|
|
355
365
|
'commerce-member:address': never;
|
|
356
366
|
}
|
|
357
367
|
}
|
|
358
|
-
|
|
368
|
+
|
|
359
369
|
/** controller: end */
|
|
360
370
|
/** ssrMenu: begin */
|
|
361
371
|
export * from '../bean/ssrMenu.address.ts';
|
|
362
372
|
import type { ISsrMenuOptionsAddress } from '../bean/ssrMenu.address.ts';
|
|
363
373
|
import 'vona-module-a-ssr';
|
|
364
374
|
declare module 'vona-module-a-ssr' {
|
|
365
|
-
|
|
375
|
+
|
|
366
376
|
export interface ISsrMenuRecord {
|
|
367
377
|
'commerce-member:address': ISsrMenuOptionsAddress;
|
|
368
378
|
}
|
|
369
379
|
|
|
370
|
-
|
|
380
|
+
|
|
371
381
|
}
|
|
372
382
|
declare module 'vona-module-commerce-member' {
|
|
373
|
-
|
|
383
|
+
|
|
374
384
|
export interface SsrMenuAddress {
|
|
375
385
|
/** @internal */
|
|
376
386
|
get scope(): ScopeModuleCommerceMember;
|
|
@@ -380,7 +390,7 @@ declare module 'vona-module-commerce-member' {
|
|
|
380
390
|
get $beanFullName(): 'commerce-member.ssrMenu.address';
|
|
381
391
|
get $onionName(): 'commerce-member:address';
|
|
382
392
|
get $onionOptions(): ISsrMenuOptionsAddress;
|
|
383
|
-
}
|
|
393
|
+
}
|
|
384
394
|
}
|
|
385
395
|
/** ssrMenu: end */
|
|
386
396
|
/** locale: begin */
|
|
@@ -410,13 +420,13 @@ declare module 'vona' {
|
|
|
410
420
|
export interface IBeanScopeContainer {
|
|
411
421
|
commerceMember: ScopeModuleCommerceMember;
|
|
412
422
|
}
|
|
413
|
-
|
|
414
|
-
|
|
423
|
+
|
|
424
|
+
|
|
415
425
|
|
|
416
426
|
export interface IBeanScopeLocale {
|
|
417
427
|
'commerce-member': (typeof locales)[TypeLocaleBase];
|
|
418
428
|
}
|
|
419
429
|
|
|
420
|
-
|
|
430
|
+
|
|
421
431
|
}
|
|
422
432
|
/** scope: end */
|
|
@@ -6,6 +6,7 @@ import { Dto } from 'vona-module-a-web';
|
|
|
6
6
|
import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
|
|
7
7
|
|
|
8
8
|
import { $locale } from '../.metadata/locales.ts';
|
|
9
|
+
import { EntityAddress } from '../entity/address.tsx';
|
|
9
10
|
import { ModelAddress } from '../model/address.ts';
|
|
10
11
|
|
|
11
12
|
export interface IDtoOptionsAddressSelectResItem extends IDecoratorDtoOptions {}
|
|
@@ -45,20 +46,11 @@ export interface IDtoOptionsAddressSelectResItem extends IDecoratorDtoOptions {}
|
|
|
45
46
|
],
|
|
46
47
|
})
|
|
47
48
|
export class DtoAddressSelectResItem extends $Dto.get(() => ModelAddress, {
|
|
48
|
-
columns: [
|
|
49
|
-
'id',
|
|
50
|
-
'recipientName',
|
|
51
|
-
'phone',
|
|
52
|
-
'countryCode',
|
|
53
|
-
'region',
|
|
54
|
-
'city',
|
|
55
|
-
'postalCode',
|
|
56
|
-
'addressLine1',
|
|
57
|
-
'addressLine2',
|
|
58
|
-
'createdAt',
|
|
59
|
-
'updatedAt',
|
|
60
|
-
],
|
|
49
|
+
columns: ['id', 'recipientName', 'phone', 'countryCode', 'city', 'createdAt'],
|
|
61
50
|
}) {
|
|
51
|
+
@Api.field(ZovaRender.order(1, 'core'), ZovaRender.cell('basic-table:actionView'))
|
|
52
|
+
declare id: EntityAddress['id'];
|
|
53
|
+
|
|
62
54
|
@Api.field(
|
|
63
55
|
v.title($locale('Operations')),
|
|
64
56
|
ZovaRender.order(1, 'max'),
|
|
@@ -19,12 +19,27 @@ export class ServiceAddress extends BeanBase {
|
|
|
19
19
|
async select(params?: IQueryParams<ModelAddress>): Promise<DtoAddressSelectRes> {
|
|
20
20
|
return await this.scope.model.address.selectAndCount({
|
|
21
21
|
...params,
|
|
22
|
+
columns: ['id', 'recipientName', 'phone', 'countryCode', 'city', 'createdAt'],
|
|
22
23
|
orders: params?.orders ?? [['id', 'asc']],
|
|
23
24
|
});
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
async view(id: TableIdentity): Promise<DtoAddressView | undefined> {
|
|
27
|
-
return await this.scope.model.address.getById(id
|
|
28
|
+
return await this.scope.model.address.getById(id, {
|
|
29
|
+
columns: [
|
|
30
|
+
'id',
|
|
31
|
+
'recipientName',
|
|
32
|
+
'phone',
|
|
33
|
+
'countryCode',
|
|
34
|
+
'region',
|
|
35
|
+
'city',
|
|
36
|
+
'postalCode',
|
|
37
|
+
'addressLine1',
|
|
38
|
+
'addressLine2',
|
|
39
|
+
'createdAt',
|
|
40
|
+
'updatedAt',
|
|
41
|
+
],
|
|
42
|
+
});
|
|
28
43
|
}
|
|
29
44
|
|
|
30
45
|
async mine(params?: IQueryParams<ModelAddress>): Promise<DtoAddressMineRes> {
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import { app } from 'vona-mock';
|
|
5
|
+
import {
|
|
6
|
+
DtoAddressMineCreate,
|
|
7
|
+
DtoAddressSelectReq,
|
|
8
|
+
DtoAddressSelectResItem,
|
|
9
|
+
DtoAddressView,
|
|
10
|
+
} from 'vona-module-commerce-member';
|
|
11
|
+
|
|
12
|
+
const actionPath = '/commerce/member/address';
|
|
13
|
+
const createMinePath = `${actionPath}/createMine`;
|
|
14
|
+
|
|
15
|
+
function findComponent(apiJson: any, predicate: (properties: any) => boolean) {
|
|
16
|
+
return Object.values(apiJson.components!.schemas as any).find(item => {
|
|
17
|
+
return predicate((item as any).properties);
|
|
18
|
+
}) as any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getListFilter(component: any) {
|
|
22
|
+
const page = component?.rest?.blocks?.[0];
|
|
23
|
+
const [filter, table, pager] = page?.options?.blocks ?? [];
|
|
24
|
+
assert.equal(page?.render, 'basic-page:blockPage');
|
|
25
|
+
assert.equal(filter?.render, 'basic-page:blockFilter');
|
|
26
|
+
assert.equal(table?.render, 'basic-page:blockTable');
|
|
27
|
+
assert.equal(pager?.render, 'basic-page:blockPager');
|
|
28
|
+
return filter;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getEntryToolbar(component: any) {
|
|
32
|
+
const pageEntry = component?.rest?.blocks?.[0];
|
|
33
|
+
const formBlock = pageEntry?.options?.blocks?.[0];
|
|
34
|
+
const toolbarBlock = pageEntry?.options?.blocks?.[1];
|
|
35
|
+
assert.equal(pageEntry?.render, 'basic-pageentry:blockPageEntry');
|
|
36
|
+
assert.equal(formBlock?.render, 'basic-pageentry:blockForm');
|
|
37
|
+
assert.equal(toolbarBlock?.render, 'basic-pageentry:blockToolbarRow');
|
|
38
|
+
return toolbarBlock;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function createAddress(suffix: string): DtoAddressMineCreate {
|
|
42
|
+
return {
|
|
43
|
+
recipientName: `Presentation Recipient ${suffix}`,
|
|
44
|
+
phone: '15555550123',
|
|
45
|
+
countryCode: 'US',
|
|
46
|
+
region: 'California',
|
|
47
|
+
city: 'San Francisco',
|
|
48
|
+
postalCode: '94105',
|
|
49
|
+
addressLine1: `1 Market Street ${suffix}`,
|
|
50
|
+
addressLine2: 'Suite 100',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function performAs(accessToken: string, method: string, path: string, options = {}) {
|
|
55
|
+
return await app.bean.executor.newCtxIsolate(async () => {
|
|
56
|
+
return await app.bean.executor.performAction(method, path, {
|
|
57
|
+
...options,
|
|
58
|
+
authToken: accessToken,
|
|
59
|
+
innerAccess: false,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe('addressPresentation.test.ts', () => {
|
|
65
|
+
it('action:address:presentationMetadata', async () => {
|
|
66
|
+
await app.bean.executor.mockCtx(async () => {
|
|
67
|
+
const listJson = await app.bean.openapi.generateJsonOfClass(DtoAddressSelectResItem);
|
|
68
|
+
const list = findComponent(
|
|
69
|
+
listJson,
|
|
70
|
+
properties =>
|
|
71
|
+
properties?._operationsRow && properties?.recipientName && properties?.countryCode,
|
|
72
|
+
);
|
|
73
|
+
assert.deepEqual(Object.keys(list.properties).sort(), [
|
|
74
|
+
'_operationsRow',
|
|
75
|
+
'city',
|
|
76
|
+
'countryCode',
|
|
77
|
+
'createdAt',
|
|
78
|
+
'id',
|
|
79
|
+
'phone',
|
|
80
|
+
'recipientName',
|
|
81
|
+
]);
|
|
82
|
+
assert.equal(list.properties.id.rest.table.render, 'basic-table:actionView');
|
|
83
|
+
assert.equal(list.properties.createdAt.rest.table.render, 'basic-date:date');
|
|
84
|
+
assert.deepEqual(
|
|
85
|
+
list.properties._operationsRow.rest.table.columnProps.actions.map(
|
|
86
|
+
(action: any) => action.render,
|
|
87
|
+
),
|
|
88
|
+
['basic-table:actionView'],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const filter = getListFilter(list);
|
|
92
|
+
const section = filter.options.blocks[0].options.formLayout.children[0];
|
|
93
|
+
assert.equal(section.type, 'section');
|
|
94
|
+
assert.equal(section.layout, 'flow');
|
|
95
|
+
assert.deepEqual(
|
|
96
|
+
section.children.slice(0, 3).map((field: any) => field.name),
|
|
97
|
+
['recipientName', 'phone', 'createdAt'],
|
|
98
|
+
);
|
|
99
|
+
assert.equal(section.children[3].block.render, 'basic-page:blockFilterActions');
|
|
100
|
+
|
|
101
|
+
const filterJson = await app.bean.openapi.generateJsonOfClass(DtoAddressSelectReq);
|
|
102
|
+
const filterComponent = findComponent(filterJson, properties => {
|
|
103
|
+
return properties?.recipientName && properties?.phone && properties?.createdAt;
|
|
104
|
+
});
|
|
105
|
+
assert.equal(
|
|
106
|
+
filterComponent.properties.createdAt.rest.form.render,
|
|
107
|
+
'basic-date:formFieldDateRange',
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const viewJson = await app.bean.openapi.generateJsonOfClass(DtoAddressView);
|
|
111
|
+
const view = findComponent(
|
|
112
|
+
viewJson,
|
|
113
|
+
properties =>
|
|
114
|
+
properties?.recipientName && properties?.addressLine1 && properties?.updatedAt,
|
|
115
|
+
);
|
|
116
|
+
assert.deepEqual(Object.keys(view.properties).sort(), [
|
|
117
|
+
'addressLine1',
|
|
118
|
+
'addressLine2',
|
|
119
|
+
'city',
|
|
120
|
+
'countryCode',
|
|
121
|
+
'createdAt',
|
|
122
|
+
'id',
|
|
123
|
+
'phone',
|
|
124
|
+
'postalCode',
|
|
125
|
+
'recipientName',
|
|
126
|
+
'region',
|
|
127
|
+
'updatedAt',
|
|
128
|
+
]);
|
|
129
|
+
assert.equal(view.properties.createdAt.rest.form.render, 'basic-date:formFieldDate');
|
|
130
|
+
assert.equal(view.properties.updatedAt.rest.form.render, 'basic-date:formFieldDate');
|
|
131
|
+
assert.deepEqual(
|
|
132
|
+
getEntryToolbar(view).options.actions.map((action: any) => action.render),
|
|
133
|
+
['basic-form:actionBack'],
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
for (const component of [list, view]) {
|
|
137
|
+
for (const field of ['userId', 'iid', 'deleted']) {
|
|
138
|
+
assert.equal(component.properties[field], undefined);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('action:address:runtimeBoundary', async () => {
|
|
145
|
+
await app.bean.executor.mockCtx(async () => {
|
|
146
|
+
let addressId: number | undefined;
|
|
147
|
+
const suffix = randomUUID().slice(0, 12);
|
|
148
|
+
const address = createAddress(suffix);
|
|
149
|
+
try {
|
|
150
|
+
await app.bean.user.register({ name: `presentation-address-${suffix}` }, true);
|
|
151
|
+
const customer = await app.bean.passport.signinMock(
|
|
152
|
+
`presentation-address-${suffix}` as any,
|
|
153
|
+
);
|
|
154
|
+
addressId = await performAs(customer.accessToken, 'post', createMinePath, {
|
|
155
|
+
body: address,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const admin = await app.bean.passport.signinMock();
|
|
159
|
+
const list: any = await performAs(admin.accessToken, 'get', actionPath, {
|
|
160
|
+
query: { recipientName: address.recipientName },
|
|
161
|
+
});
|
|
162
|
+
const item = list.list.find((entry: any) => String(entry.id) === String(addressId));
|
|
163
|
+
assert.deepEqual(Object.keys(item).sort(), [
|
|
164
|
+
'city',
|
|
165
|
+
'countryCode',
|
|
166
|
+
'createdAt',
|
|
167
|
+
'id',
|
|
168
|
+
'phone',
|
|
169
|
+
'recipientName',
|
|
170
|
+
]);
|
|
171
|
+
assert.equal(item.recipientName, address.recipientName);
|
|
172
|
+
assert.equal(item.phone, address.phone);
|
|
173
|
+
assert.equal(item.countryCode, address.countryCode);
|
|
174
|
+
assert.equal(item.city, address.city);
|
|
175
|
+
|
|
176
|
+
const view: any = await performAs(admin.accessToken, 'get', `${actionPath}/:id`, {
|
|
177
|
+
params: { id: addressId },
|
|
178
|
+
});
|
|
179
|
+
assert.deepEqual(Object.keys(view).sort(), [
|
|
180
|
+
'addressLine1',
|
|
181
|
+
'addressLine2',
|
|
182
|
+
'city',
|
|
183
|
+
'countryCode',
|
|
184
|
+
'createdAt',
|
|
185
|
+
'id',
|
|
186
|
+
'phone',
|
|
187
|
+
'postalCode',
|
|
188
|
+
'recipientName',
|
|
189
|
+
'region',
|
|
190
|
+
'updatedAt',
|
|
191
|
+
]);
|
|
192
|
+
assert.equal(view.addressLine1, address.addressLine1);
|
|
193
|
+
assert.equal(view.addressLine2, address.addressLine2);
|
|
194
|
+
assert.equal(view.region, address.region);
|
|
195
|
+
|
|
196
|
+
const permissions = await Promise.all(
|
|
197
|
+
['create', 'update', 'delete'].map(action =>
|
|
198
|
+
app.bean.permission.retrievePermissionAction('commerce-member:address', action),
|
|
199
|
+
),
|
|
200
|
+
);
|
|
201
|
+
assert.deepEqual(permissions, [false, false, false]);
|
|
202
|
+
} finally {
|
|
203
|
+
if (addressId !== undefined) {
|
|
204
|
+
await app.scope('commerce-member').model.address.deleteById(addressId);
|
|
205
|
+
}
|
|
206
|
+
await app.bean.passport.signout();
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
});
|
|
@@ -52,8 +52,9 @@ export class ServiceCommercePayScene extends BeanBase {
|
|
|
52
52
|
return { ...refundAttempt, refundOperationId };
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
@Core.transaction({ isolationLevel: 'SERIALIZABLE' })
|
|
55
56
|
async createRefundOperation(refundAttemptId: TableIdentity) {
|
|
56
|
-
const refundAttempt = await this.scope.model.refundAttempt.
|
|
57
|
+
const refundAttempt = await this.scope.model.refundAttempt.getByIdForUpdate(refundAttemptId);
|
|
57
58
|
if (!refundAttempt) this.app.throw(404, 'commerce refund attempt not found');
|
|
58
59
|
const paymentAttempt = await this.scope.model.paymentAttempt.get({
|
|
59
60
|
orderId: refundAttempt.orderId,
|
|
@@ -68,7 +69,17 @@ export class ServiceCommercePayScene extends BeanBase {
|
|
|
68
69
|
idempotencyKey: `${refundAttempt.correlationId}:refund`,
|
|
69
70
|
correlationId: refundAttempt.correlationId,
|
|
70
71
|
});
|
|
71
|
-
|
|
72
|
+
if (
|
|
73
|
+
refundAttempt.refundOperationId &&
|
|
74
|
+
String(refundAttempt.refundOperationId) !== String(refund.id)
|
|
75
|
+
) {
|
|
76
|
+
this.app.throw(409, 'commerce refund attempt is linked to another refund operation');
|
|
77
|
+
}
|
|
78
|
+
if (!refundAttempt.refundOperationId) {
|
|
79
|
+
await this.scope.model.refundAttempt.updateById(refundAttempt.id, {
|
|
80
|
+
refundOperationId: refund.id,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
72
83
|
return refund;
|
|
73
84
|
}
|
|
74
85
|
|
|
@@ -46,6 +46,18 @@ describe('paymentAttempt.test.ts', { concurrency: false }, () => {
|
|
|
46
46
|
assert.equal(session?.providerName, 'pay-mock:mock');
|
|
47
47
|
assert.equal(session?.clientName, 'default');
|
|
48
48
|
assert.equal(session?.environment, 'sandbox');
|
|
49
|
+
assert.match(
|
|
50
|
+
session?.providerInvoiceReference ?? '',
|
|
51
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
|
|
52
|
+
);
|
|
53
|
+
assert.match(
|
|
54
|
+
session?.providerCorrelationReference ?? '',
|
|
55
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
|
|
56
|
+
);
|
|
57
|
+
assert.notEqual(session?.providerInvoiceReference, session?.providerCorrelationReference);
|
|
58
|
+
const reloaded = await app.scope('a-pay').model.paymentSession.getById(paymentSessionId);
|
|
59
|
+
assert.equal(reloaded?.providerInvoiceReference, session?.providerInvoiceReference);
|
|
60
|
+
assert.equal(reloaded?.providerCorrelationReference, session?.providerCorrelationReference);
|
|
49
61
|
assert.ok((session?.expiresAt.getTime() ?? 0) > Date.now() + 29 * 60 * 1000);
|
|
50
62
|
const cancelled = await scope.service.paymentAttempt.cancel(created.orderId);
|
|
51
63
|
assert.equal(cancelled?.state, 'cancelled');
|
|
@@ -42,7 +42,13 @@ const serializationRetryOptions = {
|
|
|
42
42
|
minTimeout: 0,
|
|
43
43
|
maxTimeout: 0,
|
|
44
44
|
randomize: false,
|
|
45
|
-
errorCodes: [
|
|
45
|
+
errorCodes: [
|
|
46
|
+
'40001',
|
|
47
|
+
'ER_LOCK_DEADLOCK',
|
|
48
|
+
'ER_LOCK_WAIT_TIMEOUT',
|
|
49
|
+
'SQLITE_BUSY',
|
|
50
|
+
'SQLITE_BUSY_SNAPSHOT',
|
|
51
|
+
],
|
|
46
52
|
ownerOnly: true,
|
|
47
53
|
};
|
|
48
54
|
|