cabloy 5.1.239 → 5.1.241
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/CHANGELOG.md +19 -0
- package/package.json +1 -1
- package/repo-docs/backend/openapi-guide.md +18 -0
- package/repo-docs/backend/rate-limit-guide.md +54 -9
- package/repo-e2e/specs/home-user-account.spec.ts +53 -8
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +16 -141
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/dto/operatorContext.ts +4 -1
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/service/operator.ts +1 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/operatorAccess.test.ts +1 -0
- package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +1 -0
- package/vona/src/suite/a-home/modules/home-user/src/controller/passport.ts +1 -0
- package/vona/src/suite/a-home/modules/home-user/src/dto/accountCurrent.ts +3 -0
- package/vona/src/suite/a-home/modules/home-user/src/dto/accountProfileUpdate.ts +9 -2
- package/vona/src/suite/a-home/modules/home-user/src/dto/passportUser.ts +3 -0
- package/vona/src/suite/a-home/modules/home-user/src/entity/user.ts +3 -0
- package/vona/src/suite/a-home/modules/home-user/src/service/account.ts +7 -3
- package/vona/src/suite/a-home/modules/home-user/src/service/userAdapter.ts +1 -0
- package/vona/src/suite/a-home/modules/home-user/test/account.test.ts +133 -8
- package/vona/src/suite/a-home/modules/home-user/test/accountOpenapi.test.ts +32 -5
- package/vona/src/suite/a-home/modules/home-user/test/passport.test.ts +159 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-hmr/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-hmr/src/service/hmr.ts +5 -12
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +54 -8
- package/vona/src/suite-vendor/a-vona/modules/a-permission/test/permission.test.ts +228 -16
- package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/src/.metadata/index.ts +26 -0
- package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/src/bean/middlewareSystem.aggregate.ts +58 -0
- package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/src/service/rateLimit.ts +25 -5
- package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/src/types/rateLimit.ts +5 -0
- package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/test/aggregate.test.ts +247 -0
- package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/user.ts +1 -0
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/schemas.ts +68 -52
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/types.ts +530 -344
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/page/dashboard/controller.tsx +7 -1
- package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +6 -1
- package/zova/src/suite/a-home/modules/home-base/src/config/locale/en-us.ts +1 -0
- package/zova/src/suite/a-home/modules/home-base/src/config/locale/zh-cn.ts +1 -0
- package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.user.tsx +1 -1
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.user.tsx +3 -1
- package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +4 -0
- package/zova/src/suite/a-home/modules/home-user/src/config/locale/en-us.ts +1 -0
- package/zova/src/suite/a-home/modules/home-user/src/config/locale/zh-cn.ts +1 -0
- package/zova/src/suite/a-home/modules/home-user/src/model/account.ts +2 -1
- package/zova/src/suite/a-home/modules/home-user/src/page/account/controller.tsx +17 -3
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import type { IMiddlewareSystemOptionsAggregate, RateLimitMode } from 'vona-module-a-ratelimit';
|
|
2
|
+
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { once } from 'node:events';
|
|
6
|
+
import { createServer } from 'node:http';
|
|
7
|
+
import { describe, it } from 'node:test';
|
|
8
|
+
import { setTimeout } from 'node:timers/promises';
|
|
9
|
+
import { cast, compose } from 'vona';
|
|
10
|
+
import { app } from 'vona-mock';
|
|
11
|
+
import { MiddlewareSystemAggregate, ServiceRateLimit } from 'vona-module-a-ratelimit';
|
|
12
|
+
|
|
13
|
+
const exemptPath = '/api/test/vona/performAction/rateLimitExempt';
|
|
14
|
+
const limitedPath = '/api/test/vona/performAction/rateLimit';
|
|
15
|
+
|
|
16
|
+
type AdmitCommand = (key: string, windowMs: string) => Promise<[number, number]>;
|
|
17
|
+
|
|
18
|
+
function createService(command: AdmitCommand) {
|
|
19
|
+
const service = app.bean._newBean(ServiceRateLimit);
|
|
20
|
+
Object.defineProperty(service, 'bean', {
|
|
21
|
+
value: { redis: { get: () => ({ rateLimitAdmit: command }) } },
|
|
22
|
+
});
|
|
23
|
+
return service;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type Request = (path: string, options?: RequestInit) => Promise<Response>;
|
|
27
|
+
|
|
28
|
+
async function withGate(
|
|
29
|
+
mode: RateLimitMode,
|
|
30
|
+
limit: number,
|
|
31
|
+
command: AdmitCommand,
|
|
32
|
+
fn: (request: Request) => Promise<void>,
|
|
33
|
+
) {
|
|
34
|
+
await app.bean.executor.mockCtx(async () => {
|
|
35
|
+
const middleware = app.bean._newBean(MiddlewareSystemAggregate);
|
|
36
|
+
Object.defineProperty(middleware, 'scope', {
|
|
37
|
+
value: { service: { rateLimit: createService(command) } },
|
|
38
|
+
});
|
|
39
|
+
const policyName = `test-aggregate-${randomUUID()}`;
|
|
40
|
+
// Keep admission and its listener local; never patch the shared application chain.
|
|
41
|
+
const chain = compose([
|
|
42
|
+
(_ctx, next) => middleware.execute({ rateLimit: { mode, limit } }, next),
|
|
43
|
+
...app.middleware,
|
|
44
|
+
]);
|
|
45
|
+
const server = createServer((req, res) => {
|
|
46
|
+
void app.bean.executor
|
|
47
|
+
.newCtx(
|
|
48
|
+
() => {
|
|
49
|
+
app.ctx.onionsDynamic = {
|
|
50
|
+
interceptor: { 'a-ratelimit:rateLimit': { rateLimit: { name: policyName } } },
|
|
51
|
+
};
|
|
52
|
+
return cast(app).handleRequest(app.ctx, chain);
|
|
53
|
+
},
|
|
54
|
+
{ dbInfo: { level: 0 }, innerAccess: false, req, res },
|
|
55
|
+
)
|
|
56
|
+
.catch(error => res.destroy(error));
|
|
57
|
+
});
|
|
58
|
+
try {
|
|
59
|
+
server.listen(0, '127.0.0.1');
|
|
60
|
+
await once(server, 'listening');
|
|
61
|
+
const address = server.address();
|
|
62
|
+
assert.ok(address && typeof address !== 'string');
|
|
63
|
+
await fn((path, options) =>
|
|
64
|
+
fetch(`http://127.0.0.1:${address.port}${path}`, {
|
|
65
|
+
...options,
|
|
66
|
+
headers: { accept: 'application/json', ...options?.headers },
|
|
67
|
+
signal: AbortSignal.timeout(10_000),
|
|
68
|
+
}),
|
|
69
|
+
);
|
|
70
|
+
} finally {
|
|
71
|
+
await new Promise<void>((resolve, reject) => {
|
|
72
|
+
server.close(error => (error ? reject(error) : resolve()));
|
|
73
|
+
server.closeAllConnections();
|
|
74
|
+
});
|
|
75
|
+
const redis = app.bean.redis.get('limiter');
|
|
76
|
+
const prefix = redis.options.keyPrefix ?? '';
|
|
77
|
+
const keys = await redis.keys(`${prefix}rate-limit:v1:*:${encodeURIComponent(policyName)}:*`);
|
|
78
|
+
if (keys.length) await redis.del(...keys.map(key => key.slice(prefix.length)));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function counter(): AdmitCommand {
|
|
84
|
+
let current = 0;
|
|
85
|
+
return async () => [++current, 1_000];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
describe('aggregate.test.ts', { concurrency: false }, () => {
|
|
89
|
+
it('shares an atomic Redis budget across request contexts and expires its counter', async () => {
|
|
90
|
+
const key = `test:aggregate:${randomUUID()}`;
|
|
91
|
+
const redis = cast(app.bean.redis.get('limiter'));
|
|
92
|
+
const keys: string[] = [];
|
|
93
|
+
// Isolate this test's bucket without changing the production key dimensions or TTL.
|
|
94
|
+
const service = createService((actualKey, windowMs) => {
|
|
95
|
+
keys.push(actualKey);
|
|
96
|
+
return redis.rateLimitAdmit(key, windowMs);
|
|
97
|
+
});
|
|
98
|
+
try {
|
|
99
|
+
const results = await Promise.all(
|
|
100
|
+
[0, 1, 2, 3].map(index =>
|
|
101
|
+
app.bean.executor.mockCtx(async () => {
|
|
102
|
+
app.ctx.req.url = `/aggregate-${index}`;
|
|
103
|
+
return service.admitAggregate({
|
|
104
|
+
mode: 'enforce',
|
|
105
|
+
limit: 2,
|
|
106
|
+
});
|
|
107
|
+
}),
|
|
108
|
+
),
|
|
109
|
+
);
|
|
110
|
+
assert.equal(results.filter(result => result.allowed).length, 2);
|
|
111
|
+
assert.ok(keys.every(actualKey => /^rate-limit:aggregate:v1:\d+$/.test(actualKey)));
|
|
112
|
+
assert.equal(await redis.get(key), '4');
|
|
113
|
+
const ttl = await redis.pttl(key);
|
|
114
|
+
assert.ok(ttl > 0 && ttl <= 1_000);
|
|
115
|
+
await setTimeout(ttl + 20);
|
|
116
|
+
assert.equal(await redis.get(key), null);
|
|
117
|
+
await app.bean.executor.mockCtx(async () => {
|
|
118
|
+
const result = await service.admitAggregate({
|
|
119
|
+
mode: 'enforce',
|
|
120
|
+
limit: 2,
|
|
121
|
+
});
|
|
122
|
+
assert.equal(result.allowed, true);
|
|
123
|
+
assert.equal(result.remaining, 1);
|
|
124
|
+
});
|
|
125
|
+
} finally {
|
|
126
|
+
await redis.del(key);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('counts health, preflight, unknown paths and identity-exempt actions in one HTTP budget', async () => {
|
|
131
|
+
await withGate('enforce', 3, counter(), async request => {
|
|
132
|
+
const health = await request('/health/live');
|
|
133
|
+
assert.equal(health.status, 200);
|
|
134
|
+
await health.text();
|
|
135
|
+
const preflight = await request('/aggregate-unknown', {
|
|
136
|
+
method: 'OPTIONS',
|
|
137
|
+
headers: { 'origin': 'https://example.test', 'access-control-request-method': 'GET' },
|
|
138
|
+
});
|
|
139
|
+
assert.notEqual(preflight.status, 429);
|
|
140
|
+
await preflight.text();
|
|
141
|
+
const unknown = await request(`/aggregate-unknown-${randomUUID()}`);
|
|
142
|
+
assert.equal(unknown.status, 404);
|
|
143
|
+
await unknown.text();
|
|
144
|
+
const rejected = await request(exemptPath);
|
|
145
|
+
assert.equal(rejected.status, 429);
|
|
146
|
+
assert.equal(rejected.headers.get('retry-after'), '1');
|
|
147
|
+
assert.equal(rejected.headers.get('ratelimit-limit'), null);
|
|
148
|
+
assert.deepEqual(await rejected.json(), { code: 429, message: 'Too Many Requests' });
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('observes excess requests without rejecting or replacing identity headers', async () => {
|
|
153
|
+
await withGate('observe', 1, counter(), async request => {
|
|
154
|
+
for (let index = 0; index < 2; index++) {
|
|
155
|
+
const response = await request(exemptPath);
|
|
156
|
+
assert.equal(response.status, 200);
|
|
157
|
+
assert.equal(response.headers.get('ratelimit-limit'), null);
|
|
158
|
+
assert.equal(response.headers.get('retry-after'), null);
|
|
159
|
+
await response.text();
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
await withGate('enforce', 100, counter(), async request => {
|
|
163
|
+
for (let index = 0; index < 2; index++) {
|
|
164
|
+
const response = await request(limitedPath);
|
|
165
|
+
assert.equal(response.status, 200);
|
|
166
|
+
assert.equal(response.headers.get('ratelimit-limit'), '2');
|
|
167
|
+
await response.text();
|
|
168
|
+
}
|
|
169
|
+
const response = await request(limitedPath);
|
|
170
|
+
assert.equal(response.status, 429);
|
|
171
|
+
assert.equal(response.headers.get('ratelimit-limit'), '2');
|
|
172
|
+
await response.text();
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('fails open only in observe mode and preserves HTTP 503 for HTML callers', async () => {
|
|
177
|
+
const unavailable: AdmitCommand = async () => {
|
|
178
|
+
throw new Error('redis unavailable');
|
|
179
|
+
};
|
|
180
|
+
await withGate('observe', 1, unavailable, async request => {
|
|
181
|
+
const response = await request('/health/live');
|
|
182
|
+
assert.equal(response.status, 200);
|
|
183
|
+
await response.text();
|
|
184
|
+
});
|
|
185
|
+
await withGate('enforce', 1, unavailable, async request => {
|
|
186
|
+
const response = await request(exemptPath, { headers: { accept: 'text/html' } });
|
|
187
|
+
assert.equal(response.status, 503);
|
|
188
|
+
assert.match(response.headers.get('content-type')!, /application\/json/);
|
|
189
|
+
assert.equal(response.headers.get('retry-after'), null);
|
|
190
|
+
assert.deepEqual(await response.json(), { code: 503, message: 'Service Unavailable' });
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('keeps competing gates and the shared application listener independent', async () => {
|
|
195
|
+
await Promise.all([
|
|
196
|
+
withGate(
|
|
197
|
+
'enforce',
|
|
198
|
+
1,
|
|
199
|
+
async () => [2, 1_000],
|
|
200
|
+
async request => {
|
|
201
|
+
const response = await request('/health/live');
|
|
202
|
+
assert.equal(response.status, 429);
|
|
203
|
+
await response.text();
|
|
204
|
+
const address = app.server.address();
|
|
205
|
+
assert.ok(address && typeof address !== 'string');
|
|
206
|
+
const shared = await fetch(`http://127.0.0.1:${address.port}/health/live`, {
|
|
207
|
+
signal: AbortSignal.timeout(10_000),
|
|
208
|
+
});
|
|
209
|
+
assert.equal(shared.status, 200);
|
|
210
|
+
await shared.text();
|
|
211
|
+
},
|
|
212
|
+
),
|
|
213
|
+
withGate(
|
|
214
|
+
'enforce',
|
|
215
|
+
1,
|
|
216
|
+
async () => [1, 1_000],
|
|
217
|
+
async request => {
|
|
218
|
+
const response = await request('/health/live');
|
|
219
|
+
assert.equal(response.status, 200);
|
|
220
|
+
await response.text();
|
|
221
|
+
},
|
|
222
|
+
),
|
|
223
|
+
]);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('requires valid explicit configuration even in observe mode', async () => {
|
|
227
|
+
await app.bean.executor.mockCtx(async () => {
|
|
228
|
+
const middleware = app.bean._newBean(MiddlewareSystemAggregate);
|
|
229
|
+
let downstream = false;
|
|
230
|
+
const next = async () => {
|
|
231
|
+
downstream = true;
|
|
232
|
+
};
|
|
233
|
+
for (const options of [
|
|
234
|
+
{},
|
|
235
|
+
{ rateLimit: { mode: 'observe', limit: 0 } },
|
|
236
|
+
{ rateLimit: { mode: 'observe', limit: 1.5 } },
|
|
237
|
+
{ rateLimit: { mode: 'invalid', limit: 1 } },
|
|
238
|
+
]) {
|
|
239
|
+
await assert.rejects(
|
|
240
|
+
middleware.execute(options as IMiddlewareSystemOptionsAggregate, next),
|
|
241
|
+
/rate-limit aggregate/,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
assert.equal(downstream, false);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
@@ -6,6 +6,42 @@ export type ApiSchemaTestVonaDtoUserCreate = components['schemas']['test-vona.dt
|
|
|
6
6
|
export type ApiSchemaTestVonaDtoUserCreatePartial = Partial<ApiSchemaTestVonaDtoUserCreate>;
|
|
7
7
|
export type ApiSchemaTestVonaEntityProduct = components['schemas']['test-vona.entity.product'];
|
|
8
8
|
export type ApiSchemaTestVonaEntityProductPartial = Partial<ApiSchemaTestVonaEntityProduct>;
|
|
9
|
+
export type ApiSchemaAImageDtoImageUploadPolicyResponse =
|
|
10
|
+
components['schemas']['a-image.dto.imageUploadPolicyResponse'];
|
|
11
|
+
export type ApiSchemaAImageDtoImageUploadPolicyResponsePartial =
|
|
12
|
+
Partial<ApiSchemaAImageDtoImageUploadPolicyResponse>;
|
|
13
|
+
export type ApiSchemaAImageDtoImageUploadPolicyRequest =
|
|
14
|
+
components['schemas']['a-image.dto.imageUploadPolicyRequest'];
|
|
15
|
+
export type ApiSchemaAImageDtoImageUploadPolicyRequestPartial =
|
|
16
|
+
Partial<ApiSchemaAImageDtoImageUploadPolicyRequest>;
|
|
17
|
+
export type ApiSchemaAImageDtoImageUploadResponse =
|
|
18
|
+
components['schemas']['a-image.dto.imageUploadResponse'];
|
|
19
|
+
export type ApiSchemaAImageDtoImageUploadResponsePartial =
|
|
20
|
+
Partial<ApiSchemaAImageDtoImageUploadResponse>;
|
|
21
|
+
export type ApiSchemaAImageDtoImageDirectUploadResponse =
|
|
22
|
+
components['schemas']['a-image.dto.imageDirectUploadResponse'];
|
|
23
|
+
export type ApiSchemaAImageDtoImageDirectUploadResponsePartial =
|
|
24
|
+
Partial<ApiSchemaAImageDtoImageDirectUploadResponse>;
|
|
25
|
+
export type ApiSchemaAImageDtoImageDirectUploadRequest =
|
|
26
|
+
components['schemas']['a-image.dto.imageDirectUploadRequest'];
|
|
27
|
+
export type ApiSchemaAImageDtoImageDirectUploadRequestPartial =
|
|
28
|
+
Partial<ApiSchemaAImageDtoImageDirectUploadRequest>;
|
|
29
|
+
export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponse =
|
|
30
|
+
components['schemas']['a-image.dto.imageDirectUploadFinalizeResponse'];
|
|
31
|
+
export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponsePartial =
|
|
32
|
+
Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeResponse>;
|
|
33
|
+
export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequest =
|
|
34
|
+
components['schemas']['a-image.dto.imageDirectUploadFinalizeRequest'];
|
|
35
|
+
export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequestPartial =
|
|
36
|
+
Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeRequest>;
|
|
37
|
+
export type ApiSchemaAImageDtoImageUploadUrlRequest =
|
|
38
|
+
components['schemas']['a-image.dto.imageUploadUrlRequest'];
|
|
39
|
+
export type ApiSchemaAImageDtoImageUploadUrlRequestPartial =
|
|
40
|
+
Partial<ApiSchemaAImageDtoImageUploadUrlRequest>;
|
|
41
|
+
export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b =
|
|
42
|
+
components['schemas']['a-image.dto.imageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
|
|
43
|
+
export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
|
|
44
|
+
Partial<ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
|
|
9
45
|
export type ApiSchemaACaptchaDtoCaptchaData = components['schemas']['a-captcha.dto.captchaData'];
|
|
10
46
|
export type ApiSchemaACaptchaDtoCaptchaDataPartial = Partial<ApiSchemaACaptchaDtoCaptchaData>;
|
|
11
47
|
export type ApiSchemaAPayDtoPaymentSessionView =
|
|
@@ -43,42 +79,6 @@ export type ApiSchemaCommerceMemberDtoAddressView_2d063d28bc7243bed02ebd8bddf121
|
|
|
43
79
|
components['schemas']['commerce-member.dto.addressView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875'];
|
|
44
80
|
export type ApiSchemaCommerceMemberDtoAddressView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875Partial =
|
|
45
81
|
Partial<ApiSchemaCommerceMemberDtoAddressView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_425dbecccd52e19e24888f99e1b1670233afa875>;
|
|
46
|
-
export type ApiSchemaAImageDtoImageUploadPolicyResponse =
|
|
47
|
-
components['schemas']['a-image.dto.imageUploadPolicyResponse'];
|
|
48
|
-
export type ApiSchemaAImageDtoImageUploadPolicyResponsePartial =
|
|
49
|
-
Partial<ApiSchemaAImageDtoImageUploadPolicyResponse>;
|
|
50
|
-
export type ApiSchemaAImageDtoImageUploadPolicyRequest =
|
|
51
|
-
components['schemas']['a-image.dto.imageUploadPolicyRequest'];
|
|
52
|
-
export type ApiSchemaAImageDtoImageUploadPolicyRequestPartial =
|
|
53
|
-
Partial<ApiSchemaAImageDtoImageUploadPolicyRequest>;
|
|
54
|
-
export type ApiSchemaAImageDtoImageUploadResponse =
|
|
55
|
-
components['schemas']['a-image.dto.imageUploadResponse'];
|
|
56
|
-
export type ApiSchemaAImageDtoImageUploadResponsePartial =
|
|
57
|
-
Partial<ApiSchemaAImageDtoImageUploadResponse>;
|
|
58
|
-
export type ApiSchemaAImageDtoImageDirectUploadResponse =
|
|
59
|
-
components['schemas']['a-image.dto.imageDirectUploadResponse'];
|
|
60
|
-
export type ApiSchemaAImageDtoImageDirectUploadResponsePartial =
|
|
61
|
-
Partial<ApiSchemaAImageDtoImageDirectUploadResponse>;
|
|
62
|
-
export type ApiSchemaAImageDtoImageDirectUploadRequest =
|
|
63
|
-
components['schemas']['a-image.dto.imageDirectUploadRequest'];
|
|
64
|
-
export type ApiSchemaAImageDtoImageDirectUploadRequestPartial =
|
|
65
|
-
Partial<ApiSchemaAImageDtoImageDirectUploadRequest>;
|
|
66
|
-
export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponse =
|
|
67
|
-
components['schemas']['a-image.dto.imageDirectUploadFinalizeResponse'];
|
|
68
|
-
export type ApiSchemaAImageDtoImageDirectUploadFinalizeResponsePartial =
|
|
69
|
-
Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeResponse>;
|
|
70
|
-
export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequest =
|
|
71
|
-
components['schemas']['a-image.dto.imageDirectUploadFinalizeRequest'];
|
|
72
|
-
export type ApiSchemaAImageDtoImageDirectUploadFinalizeRequestPartial =
|
|
73
|
-
Partial<ApiSchemaAImageDtoImageDirectUploadFinalizeRequest>;
|
|
74
|
-
export type ApiSchemaAImageDtoImageUploadUrlRequest =
|
|
75
|
-
components['schemas']['a-image.dto.imageUploadUrlRequest'];
|
|
76
|
-
export type ApiSchemaAImageDtoImageUploadUrlRequestPartial =
|
|
77
|
-
Partial<ApiSchemaAImageDtoImageUploadUrlRequest>;
|
|
78
|
-
export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b =
|
|
79
|
-
components['schemas']['a-image.dto.imageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
|
|
80
|
-
export type ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
|
|
81
|
-
Partial<ApiSchemaAImageDtoImageTransformOptions_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
|
|
82
82
|
export type ApiSchemaHomeUserDtoAccountCurrent =
|
|
83
83
|
components['schemas']['home-user.dto.accountCurrent'];
|
|
84
84
|
export type ApiSchemaHomeUserDtoAccountCurrentPartial = Partial<ApiSchemaHomeUserDtoAccountCurrent>;
|
|
@@ -302,10 +302,10 @@ export type ApiSchemaCommerceTradeEntityStockBalance =
|
|
|
302
302
|
components['schemas']['commerce-trade.entity.stockBalance'];
|
|
303
303
|
export type ApiSchemaCommerceTradeEntityStockBalancePartial =
|
|
304
304
|
Partial<ApiSchemaCommerceTradeEntityStockBalance>;
|
|
305
|
-
export type
|
|
306
|
-
components['schemas']['commerce-trade.dto.
|
|
307
|
-
export type
|
|
308
|
-
Partial<
|
|
305
|
+
export type ApiSchemaCommerceTradeDtoStockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e =
|
|
306
|
+
components['schemas']['commerce-trade.dto.stockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e'];
|
|
307
|
+
export type ApiSchemaCommerceTradeDtoStockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750ePartial =
|
|
308
|
+
Partial<ApiSchemaCommerceTradeDtoStockAdjust_6a7c2f0bb21a25da3048650f263577ae4467750e>;
|
|
309
309
|
export type ApiSchemaCommerceTradeDtoStockBalanceSelectRes =
|
|
310
310
|
components['schemas']['commerce-trade.dto.stockBalanceSelectRes'];
|
|
311
311
|
export type ApiSchemaCommerceTradeDtoStockBalanceSelectResPartial =
|
|
@@ -366,10 +366,10 @@ export type ApiSchemaCommerceCatalogDtoProductPublicDetail_2d063d28bc7243bed02eb
|
|
|
366
366
|
components['schemas']['commerce-catalog.dto.productPublicDetail_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
|
|
367
367
|
export type ApiSchemaCommerceCatalogDtoProductPublicDetail_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
|
|
368
368
|
Partial<ApiSchemaCommerceCatalogDtoProductPublicDetail_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
|
|
369
|
-
export type
|
|
370
|
-
components['schemas']['commerce-catalog.dto.
|
|
371
|
-
export type
|
|
372
|
-
Partial<
|
|
369
|
+
export type ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57 =
|
|
370
|
+
components['schemas']['commerce-catalog.dto.productView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57'];
|
|
371
|
+
export type ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57Partial =
|
|
372
|
+
Partial<ApiSchemaCommerceCatalogDtoProductView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_a2f92cabb46b0630848b50414c0d4c60efb47a57>;
|
|
373
373
|
export type ApiSchemaCommerceCatalogDtoProductUpdate =
|
|
374
374
|
components['schemas']['commerce-catalog.dto.productUpdate'];
|
|
375
375
|
export type ApiSchemaCommerceCatalogDtoProductUpdatePartial =
|
|
@@ -435,10 +435,10 @@ export type ApiSchemaAImageDtoImageView = components['schemas']['a-image.dto.ima
|
|
|
435
435
|
export type ApiSchemaAImageDtoImageViewPartial = Partial<ApiSchemaAImageDtoImageView>;
|
|
436
436
|
export type ApiSchemaAFileDtoFileView = components['schemas']['a-file.dto.fileView'];
|
|
437
437
|
export type ApiSchemaAFileDtoFileViewPartial = Partial<ApiSchemaAFileDtoFileView>;
|
|
438
|
-
export type
|
|
439
|
-
components['schemas']['training-record.dto.
|
|
440
|
-
export type
|
|
441
|
-
Partial<
|
|
438
|
+
export type ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347 =
|
|
439
|
+
components['schemas']['training-record.dto.recordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347'];
|
|
440
|
+
export type ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347Partial =
|
|
441
|
+
Partial<ApiSchemaTrainingRecordDtoRecordView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_7d715789d9643740a04e8a6c0f6fb951884bc347>;
|
|
442
442
|
export type ApiSchemaTrainingRecordDtoRecordUpdate =
|
|
443
443
|
components['schemas']['training-record.dto.recordUpdate'];
|
|
444
444
|
export type ApiSchemaTrainingRecordDtoRecordUpdatePartial =
|
|
@@ -463,10 +463,10 @@ export type ApiSchemaAImageDtoImageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1
|
|
|
463
463
|
components['schemas']['a-image.dto.imageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1_2d063d28bc7243bed02ebd8bddf1212a93c6305b_efb37794d7c03c65122279f90d79919f009c34e5_1816ff740d81c738ec055c7038bbd93beb9405a7_537cd6552a384183a9457fb6a920bbae337277f6'];
|
|
464
464
|
export type ApiSchemaAImageDtoImageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1_2d063d28bc7243bed02ebd8bddf1212a93c6305b_efb37794d7c03c65122279f90d79919f009c34e5_1816ff740d81c738ec055c7038bbd93beb9405a7_537cd6552a384183a9457fb6a920bbae337277f6Partial =
|
|
465
465
|
Partial<ApiSchemaAImageDtoImageView_a83c3e638bca4b30ec8675860cdc52d66f6a16d1_2d063d28bc7243bed02ebd8bddf1212a93c6305b_efb37794d7c03c65122279f90d79919f009c34e5_1816ff740d81c738ec055c7038bbd93beb9405a7_537cd6552a384183a9457fb6a920bbae337277f6>;
|
|
466
|
-
export type
|
|
467
|
-
components['schemas']['training-student.dto.
|
|
468
|
-
export type
|
|
469
|
-
Partial<
|
|
466
|
+
export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60 =
|
|
467
|
+
components['schemas']['training-student.dto.studentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60'];
|
|
468
|
+
export type ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60Partial =
|
|
469
|
+
Partial<ApiSchemaTrainingStudentDtoStudentView_2d063d28bc7243bed02ebd8bddf1212a93c6305b_4826fc678e47603ec467782ddb0d02463792cd60>;
|
|
470
470
|
export type ApiSchemaTrainingStudentDtoStudentUpdate =
|
|
471
471
|
components['schemas']['training-student.dto.studentUpdate'];
|
|
472
472
|
export type ApiSchemaTrainingStudentDtoStudentUpdatePartial =
|
|
@@ -475,6 +475,10 @@ export type ApiSchemaTrainingStudentDtoStudentSummary_2d063d28bc7243bed02ebd8bdd
|
|
|
475
475
|
components['schemas']['training-student.dto.studentSummary_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
|
|
476
476
|
export type ApiSchemaTrainingStudentDtoStudentSummary_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
|
|
477
477
|
Partial<ApiSchemaTrainingStudentDtoStudentSummary_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
|
|
478
|
+
export type ApiSchemaTrainingStudentDtoStudentDeleteBulk =
|
|
479
|
+
components['schemas']['training-student.dto.studentDeleteBulk'];
|
|
480
|
+
export type ApiSchemaTrainingStudentDtoStudentDeleteBulkPartial =
|
|
481
|
+
Partial<ApiSchemaTrainingStudentDtoStudentDeleteBulk>;
|
|
478
482
|
export type ApiSchemaBasicMetricsDtoMetricsSnapshot =
|
|
479
483
|
components['schemas']['basic-metrics.dto.metricsSnapshot'];
|
|
480
484
|
export type ApiSchemaBasicMetricsDtoMetricsSnapshotPartial =
|
|
@@ -487,6 +491,18 @@ export type ApiSchemaBasicMetricsDtoMetricsQueue =
|
|
|
487
491
|
components['schemas']['basic-metrics.dto.metricsQueue'];
|
|
488
492
|
export type ApiSchemaBasicMetricsDtoMetricsQueuePartial =
|
|
489
493
|
Partial<ApiSchemaBasicMetricsDtoMetricsQueue>;
|
|
494
|
+
export type ApiSchemaALayoutprofileDtoLayoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305b =
|
|
495
|
+
components['schemas']['a-layoutprofile.dto.layoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305b'];
|
|
496
|
+
export type ApiSchemaALayoutprofileDtoLayoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305bPartial =
|
|
497
|
+
Partial<ApiSchemaALayoutprofileDtoLayoutProfile_2d063d28bc7243bed02ebd8bddf1212a93c6305b>;
|
|
498
|
+
export type ApiSchemaALayoutprofileDtoLayoutProfile =
|
|
499
|
+
components['schemas']['a-layoutprofile.dto.layoutProfile'];
|
|
500
|
+
export type ApiSchemaALayoutprofileDtoLayoutProfilePartial =
|
|
501
|
+
Partial<ApiSchemaALayoutprofileDtoLayoutProfile>;
|
|
502
|
+
export type ApiSchemaALayoutprofileDtoLayoutProfileSave =
|
|
503
|
+
components['schemas']['a-layoutprofile.dto.layoutProfileSave'];
|
|
504
|
+
export type ApiSchemaALayoutprofileDtoLayoutProfileSavePartial =
|
|
505
|
+
Partial<ApiSchemaALayoutprofileDtoLayoutProfileSave>;
|
|
490
506
|
export type ApiSchemaAFileDtoFileUploadPolicyResponse =
|
|
491
507
|
components['schemas']['a-file.dto.fileUploadPolicyResponse'];
|
|
492
508
|
export type ApiSchemaAFileDtoFileUploadPolicyResponsePartial =
|