@supersoniks/concorde 4.7.4 → 4.8.0
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/README.md +1 -1
- package/ai/cursor/rules/concorde.mdc +1 -1
- package/ai/skills/concorde-scope/SKILL.md +2 -2
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +289 -289
- package/concorde-core.es.js +4837 -4544
- package/dist/concorde-core.bundle.js +289 -289
- package/dist/concorde-core.es.js +4837 -4544
- package/dist/docs-mock-api-sw.js +19 -0
- package/dist/docs-mock-api-sw.js.map +2 -2
- package/docs/assets/index-wyNMyWT9.js +11196 -0
- package/docs/docs-mock-api-sw.js +19 -0
- package/docs/docs-mock-api-sw.js.map +2 -2
- package/docs/index.html +1 -1
- package/package.json +9 -1
- package/public/docs-mock-api-sw.js +19 -0
- package/public/docs-mock-api-sw.js.map +2 -2
- package/src/core/components/functional/example/example.ts +3 -3
- package/src/core/components/ui/icon/icon.ts +17 -2
- package/src/core/components/ui/menu/menu.ts +12 -3
- package/src/core/decorators/api.post.spec.ts +293 -0
- package/src/core/decorators/api.spec.ts +6 -6
- package/src/core/decorators/api.ts +643 -12
- package/src/core/decorators/subscriber/bind.ts +13 -5
- package/src/core/decorators/subscriber/dynamicPath.spec.ts +53 -0
- package/src/core/decorators/subscriber/dynamicPath.ts +23 -1
- package/src/core/decorators/subscriber/handle.ts +3 -1
- package/src/core/decorators/subscriber/onAssign.ts +10 -2
- package/src/core/decorators/subscriber/publish.ts +12 -2
- package/src/core/utils/PublisherProxy.ts +95 -11
- package/src/core/utils/api.ts +72 -3
- package/src/core/utils/dpOptions.spec.ts +56 -0
- package/src/core/utils/endpoint.ts +3 -3
- package/src/decorators.ts +17 -1
- package/src/docs/_core-concept/dataFlow.md +9 -3
- package/src/docs/_decorators/bind.md +2 -2
- package/src/docs/_decorators/get.md +13 -4
- package/src/docs/_decorators/handle.md +5 -1
- package/src/docs/_decorators/on-assign.md +2 -0
- package/src/docs/_decorators/patch.md +45 -0
- package/src/docs/_decorators/post.md +93 -0
- package/src/docs/_decorators/publish.md +1 -1
- package/src/docs/_decorators/put.md +43 -0
- package/src/docs/_decorators/subscribe.md +4 -1
- package/src/docs/_directives/sub.md +1 -1
- package/src/docs/_getting-started/my-first-component.md +1 -1
- package/src/docs/_misc/api-configuration.md +3 -1
- package/src/docs/_misc/dataProviderKey.md +2 -2
- package/src/docs/_misc/dynamic-path.md +71 -0
- package/src/docs/_misc/endpoint.md +5 -3
- package/src/docs/components/docs-demo-sources.ts +102 -3
- package/src/docs/components/docs-lit-demo-raw.ts +2 -26
- package/src/docs/components/docs-lit-demo.ts +9 -42
- package/src/docs/components/docs-source-excerpt.ts +53 -0
- package/src/docs/components/docs-source-link.ts +24 -8
- package/src/docs/components/docs-source-raw.ts +34 -0
- package/src/docs/example/decorators-demo-geo.ts +2 -2
- package/src/docs/example/decorators-demo-post.ts +249 -0
- package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +5 -5
- package/src/docs/example/decorators-demo.ts +1 -0
- package/src/docs/example/docs-api-config-demos.ts +5 -5
- package/src/docs/mock-api/router.ts +20 -0
- package/src/docs/navigation/navigation.ts +16 -0
- package/src/docs/search/docs-search.json +540 -15
- package/src/tsconfig.json +24 -0
- package/src/tsconfig.tsbuildinfo +1 -1
- package/vite.config.mts +1 -1
- package/docs/assets/index-CwtPzTFq.js +0 -7508
- package/docs/src/core/components/functional/date/date.md +0 -290
- package/docs/src/core/components/functional/fetch/fetch.md +0 -125
- package/docs/src/core/components/functional/if/if.md +0 -9
- package/docs/src/core/components/functional/list/list.md +0 -65
- package/docs/src/core/components/functional/mix/mix.md +0 -41
- package/docs/src/core/components/functional/queue/queue.md +0 -72
- package/docs/src/core/components/functional/router/router.md +0 -94
- package/docs/src/core/components/functional/sdui/default-library.json +0 -108
- package/docs/src/core/components/functional/sdui/example.json +0 -99
- package/docs/src/core/components/functional/sdui/sdui.md +0 -356
- package/docs/src/core/components/functional/states/states.md +0 -87
- package/docs/src/core/components/functional/submit/submit.md +0 -114
- package/docs/src/core/components/functional/subscriber/subscriber.md +0 -91
- package/docs/src/core/components/functional/value/value.md +0 -35
- package/docs/src/core/components/ui/alert/alert.md +0 -121
- package/docs/src/core/components/ui/alert-messages/alert-messages.md +0 -0
- package/docs/src/core/components/ui/badge/badge.md +0 -127
- package/docs/src/core/components/ui/button/button.md +0 -182
- package/docs/src/core/components/ui/captcha/captcha.md +0 -12
- package/docs/src/core/components/ui/card/card.md +0 -97
- package/docs/src/core/components/ui/divider/divider.md +0 -35
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -77
- package/docs/src/core/components/ui/form/fieldset/fieldset.md +0 -129
- package/docs/src/core/components/ui/form/form-actions/form-actions.md +0 -77
- package/docs/src/core/components/ui/form/form-layout/form-layout.md +0 -44
- package/docs/src/core/components/ui/form/input/input.md +0 -142
- package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -133
- package/docs/src/core/components/ui/form/radio/radio.md +0 -57
- package/docs/src/core/components/ui/form/select/select.md +0 -71
- package/docs/src/core/components/ui/form/switch/switch.md +0 -57
- package/docs/src/core/components/ui/form/textarea/textarea.md +0 -65
- package/docs/src/core/components/ui/group/group.md +0 -75
- package/docs/src/core/components/ui/icon/icon.md +0 -125
- package/docs/src/core/components/ui/icon/icons.json +0 -1
- package/docs/src/core/components/ui/image/image.md +0 -107
- package/docs/src/core/components/ui/link/link.md +0 -43
- package/docs/src/core/components/ui/loader/loader.md +0 -55
- package/docs/src/core/components/ui/menu/menu.md +0 -329
- package/docs/src/core/components/ui/modal/modal.md +0 -119
- package/docs/src/core/components/ui/pop/pop.md +0 -96
- package/docs/src/core/components/ui/progress/progress.md +0 -63
- package/docs/src/core/components/ui/table/table.md +0 -455
- package/docs/src/core/components/ui/toast/toast.md +0 -166
- package/docs/src/core/components/ui/tooltip/tooltip.md +0 -82
- package/docs/src/docs/_core-concept/dataFlow.md +0 -73
- package/docs/src/docs/_core-concept/overview.md +0 -57
- package/docs/src/docs/_core-concept/subscriber.md +0 -75
- package/docs/src/docs/_decorators/ancestor-attribute.md +0 -79
- package/docs/src/docs/_decorators/auto-subscribe.md +0 -202
- package/docs/src/docs/_decorators/bind.md +0 -167
- package/docs/src/docs/_decorators/get.md +0 -68
- package/docs/src/docs/_decorators/handle.md +0 -171
- package/docs/src/docs/_decorators/on-assign.md +0 -388
- package/docs/src/docs/_decorators/publish.md +0 -55
- package/docs/src/docs/_decorators/subscribe.md +0 -97
- package/docs/src/docs/_decorators/wait-for-ancestors.md +0 -163
- package/docs/src/docs/_directives/sub.md +0 -91
- package/docs/src/docs/_getting-started/ai-agents.md +0 -56
- package/docs/src/docs/_getting-started/concorde-manual-install.md +0 -133
- package/docs/src/docs/_getting-started/concorde-outside.md +0 -33
- package/docs/src/docs/_getting-started/create-a-component.md +0 -139
- package/docs/src/docs/_getting-started/my-first-component.md +0 -236
- package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -120
- package/docs/src/docs/_getting-started/pubsub.md +0 -37
- package/docs/src/docs/_getting-started/start.md +0 -47
- package/docs/src/docs/_getting-started/theming.md +0 -91
- package/docs/src/docs/_misc/api-configuration.md +0 -79
- package/docs/src/docs/_misc/dataProviderKey.md +0 -168
- package/docs/src/docs/_misc/docs-mock-api.md +0 -60
- package/docs/src/docs/_misc/endpoint.md +0 -43
- package/docs/src/docs/_misc/html-integration.md +0 -13
- package/docs/src/docs/search/docs-search.json +0 -8532
- package/docs/src/tag-list.json +0 -1
- package/docs/src/tsconfig-model.json +0 -23
- package/docs/src/tsconfig.json +0 -1095
|
@@ -8,11 +8,12 @@ import HTML, {
|
|
|
8
8
|
} from "@supersoniks/concorde/core/utils/HTML";
|
|
9
9
|
import API, {
|
|
10
10
|
APIConfiguration,
|
|
11
|
-
type
|
|
11
|
+
type ApiResult,
|
|
12
12
|
} from "@supersoniks/concorde/core/utils/api";
|
|
13
13
|
import DataProvider from "../utils/PublisherProxy";
|
|
14
14
|
import { ConnectedComponent, setSubscribable } from "./subscriber/common";
|
|
15
15
|
import {
|
|
16
|
+
type DynamicPathOptions,
|
|
16
17
|
extractDynamicDependencies,
|
|
17
18
|
resolveDynamicPath,
|
|
18
19
|
} from "./subscriber/dynamicPath";
|
|
@@ -77,6 +78,22 @@ function isLitHost(component: unknown): component is LitHost {
|
|
|
77
78
|
);
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Regroupe plusieurs déclencheurs synchrones (mutations `onInternalMutation`,
|
|
83
|
+
* `rebindAll`, etc.) en un seul appel par frame — même principe que
|
|
84
|
+
* `dynamicPropertyWatch.ts` (`scheduleObservedPropertyChanges`).
|
|
85
|
+
*/
|
|
86
|
+
function createAnimationFrameCoalescedRunner(run: () => void): () => void {
|
|
87
|
+
let frameId: number | null = null;
|
|
88
|
+
return () => {
|
|
89
|
+
if (frameId !== null) return;
|
|
90
|
+
frameId = requestAnimationFrame(() => {
|
|
91
|
+
frameId = null;
|
|
92
|
+
run();
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
80
97
|
function scheduleAfterHostReady(
|
|
81
98
|
component: unknown,
|
|
82
99
|
callback: () => void,
|
|
@@ -163,7 +180,7 @@ function detachConfigPublisher(state: ApiGetState): void {
|
|
|
163
180
|
|
|
164
181
|
/**
|
|
165
182
|
* Décorateur **`@get`** : charge des données via `API.getDetailed` et assigne un
|
|
166
|
-
* `
|
|
183
|
+
* `ApiResult<T>` (`request`, `response`, `result` typé `T`) ou `null`.
|
|
167
184
|
* Le path est un `Endpoint<T, Ue>` ; les placeholders `${nomPropriété}` sont résolus sur l'instance (`Ue` contraint l’hôte).
|
|
168
185
|
*
|
|
169
186
|
* **Scoped (défaut)** : `HTML.getApiConfiguration(host)` avec `host` = l’élément connecté
|
|
@@ -176,19 +193,19 @@ function detachConfigPublisher(state: ApiGetState): void {
|
|
|
176
193
|
*
|
|
177
194
|
* @example
|
|
178
195
|
* @get(new Endpoint<User, { userId: string }>("users/${userId}"))
|
|
179
|
-
* payload?:
|
|
196
|
+
* payload?: ApiResult<User>;
|
|
180
197
|
*
|
|
181
198
|
* @example
|
|
182
199
|
* const apiConf = new DataProviderKey<APIConfiguration>("myApiConf");
|
|
183
200
|
* PublisherManager.get("myApiConf").set({ serviceURL: "...", token: null, ... });
|
|
184
201
|
* @get(new Endpoint<Thing, { id: string }>("things/${id}"), apiConf)
|
|
185
|
-
* payload?:
|
|
202
|
+
* payload?: ApiResult<Thing>;
|
|
186
203
|
*/
|
|
187
204
|
export function get<T, Ue = any>(
|
|
188
205
|
endpoint: Endpoint<T, Ue>,
|
|
189
206
|
): <K extends string>(
|
|
190
207
|
target: DataProviderKeyHost<Ue> & {
|
|
191
|
-
[P in K]?:
|
|
208
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
192
209
|
},
|
|
193
210
|
propertyKey: K,
|
|
194
211
|
) => void;
|
|
@@ -198,18 +215,50 @@ export function get<T, Ue = any, Uk = any>(
|
|
|
198
215
|
): <K extends string>(
|
|
199
216
|
target: DataProviderKeyHost<Ue> &
|
|
200
217
|
DataProviderKeyHost<Uk> & {
|
|
201
|
-
[P in K]?:
|
|
218
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
202
219
|
},
|
|
203
220
|
propertyKey: K,
|
|
204
221
|
) => void;
|
|
205
222
|
export function get<T, Ue = any, Uk = any>(
|
|
206
223
|
endpoint: Endpoint<T, Ue>,
|
|
207
|
-
|
|
224
|
+
options: GetOptions,
|
|
208
225
|
): <K extends string>(
|
|
209
|
-
target:
|
|
226
|
+
target: DataProviderKeyHost<Ue> & {
|
|
227
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
228
|
+
},
|
|
229
|
+
propertyKey: K,
|
|
230
|
+
) => void;
|
|
231
|
+
export function get<T, Ue = any, Uk = any, Ut = any>(
|
|
232
|
+
endpoint: Endpoint<T, Ue>,
|
|
233
|
+
configurationKey: DataProviderKey<APIConfiguration, Uk>,
|
|
234
|
+
options: GetOptions,
|
|
235
|
+
): <K extends string>(
|
|
236
|
+
target: DataProviderKeyHost<Ue> &
|
|
237
|
+
DataProviderKeyHost<Uk> & {
|
|
238
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
239
|
+
},
|
|
240
|
+
propertyKey: K,
|
|
241
|
+
) => void;
|
|
242
|
+
export function get<T, Ue = any, Uk = any, _Ut = any>(
|
|
243
|
+
endpoint: Endpoint<T, Ue>,
|
|
244
|
+
configurationKeyOrOptions?:
|
|
245
|
+
| DataProviderKey<APIConfiguration, Uk>
|
|
246
|
+
| GetOptions,
|
|
247
|
+
maybeOptions?: GetOptions,
|
|
248
|
+
): <K extends string>(
|
|
249
|
+
target: object & { [P in K]?: ApiResult<T> | null | undefined },
|
|
210
250
|
propertyKey: K,
|
|
211
251
|
) => void {
|
|
212
252
|
const pathTemplate = endpoint.path;
|
|
253
|
+
const configurationKey = isGetOptions(configurationKeyOrOptions)
|
|
254
|
+
? undefined
|
|
255
|
+
: configurationKeyOrOptions;
|
|
256
|
+
const options = isGetOptions(configurationKeyOrOptions)
|
|
257
|
+
? configurationKeyOrOptions
|
|
258
|
+
: maybeOptions;
|
|
259
|
+
const pathOptions: DynamicPathOptions = {
|
|
260
|
+
skipEmptyPlaceholder: options?.skipEmptyPlaceholder,
|
|
261
|
+
};
|
|
213
262
|
const configurationKeyPath = configurationKey?.path;
|
|
214
263
|
const endpointDynamicDependencies = extractDynamicDependencies(pathTemplate);
|
|
215
264
|
const configKeyDynamicDependencies = configurationKeyPath
|
|
@@ -249,7 +298,7 @@ export function get<T, Ue = any, Uk = any>(
|
|
|
249
298
|
|
|
250
299
|
const runFetch = () => {
|
|
251
300
|
const resolution = isDynamicPath
|
|
252
|
-
? resolveDynamicPath(component, pathTemplate)
|
|
301
|
+
? resolveDynamicPath(component, pathTemplate, pathOptions)
|
|
253
302
|
: { ready: true, path: pathTemplate };
|
|
254
303
|
if (!resolution.ready || !resolution.path) {
|
|
255
304
|
comp[propertyKey] = undefined;
|
|
@@ -257,7 +306,11 @@ export function get<T, Ue = any, Uk = any>(
|
|
|
257
306
|
}
|
|
258
307
|
let config: APIConfiguration | null = null;
|
|
259
308
|
if (usesPublisherConfig && configurationKeyPath) {
|
|
260
|
-
const configRes = resolveDynamicPath(
|
|
309
|
+
const configRes = resolveDynamicPath(
|
|
310
|
+
component,
|
|
311
|
+
configurationKeyPath,
|
|
312
|
+
pathOptions,
|
|
313
|
+
);
|
|
261
314
|
if (!configRes.ready || !configRes.path) {
|
|
262
315
|
comp[propertyKey] = undefined;
|
|
263
316
|
return;
|
|
@@ -282,7 +335,7 @@ export function get<T, Ue = any, Uk = any>(
|
|
|
282
335
|
const api = new API(config);
|
|
283
336
|
void api
|
|
284
337
|
.getDetailed<T>(resolution.path)
|
|
285
|
-
.then((payload?:
|
|
338
|
+
.then((payload?: ApiResult<T>) => {
|
|
286
339
|
if (generation !== state.requestGeneration) return;
|
|
287
340
|
comp[propertyKey] = payload;
|
|
288
341
|
});
|
|
@@ -291,7 +344,11 @@ export function get<T, Ue = any, Uk = any>(
|
|
|
291
344
|
const rebindPublisherConfig = () => {
|
|
292
345
|
if (!usesPublisherConfig || !configurationKeyPath) return;
|
|
293
346
|
detachConfigPublisher(state);
|
|
294
|
-
const configRes = resolveDynamicPath(
|
|
347
|
+
const configRes = resolveDynamicPath(
|
|
348
|
+
component,
|
|
349
|
+
configurationKeyPath,
|
|
350
|
+
pathOptions,
|
|
351
|
+
);
|
|
295
352
|
if (!configRes.ready || !configRes.path) {
|
|
296
353
|
comp[propertyKey] = undefined;
|
|
297
354
|
return;
|
|
@@ -355,3 +412,577 @@ export function get<T, Ue = any, Uk = any>(
|
|
|
355
412
|
});
|
|
356
413
|
};
|
|
357
414
|
}
|
|
415
|
+
|
|
416
|
+
export type GetOptions = DynamicPathOptions;
|
|
417
|
+
|
|
418
|
+
export type ApiSendOptions<Uk = any> = DynamicPathOptions & {
|
|
419
|
+
/** Intervalle de renvoi automatique (ms). 0 ou absent = pas de polling. */
|
|
420
|
+
refetchEveryMs?: number;
|
|
421
|
+
/** Ne pas envoyer si le body publisher est null/undefined (défaut: true). */
|
|
422
|
+
skipIfBodyMissing?: boolean;
|
|
423
|
+
/**
|
|
424
|
+
* Relancer l'envoi quand le body publisher mute (défaut: true).
|
|
425
|
+
* `false` : le body est lu au moment de l'envoi ; déclencher via `triggerKey.invalidate()`.
|
|
426
|
+
*/
|
|
427
|
+
autoPostOnBodyMutation?: boolean;
|
|
428
|
+
/** Publisher dont `invalidate()` relance l'envoi (relit le body courant). */
|
|
429
|
+
triggerKey?: DataProviderKey<unknown, Uk>;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
/** @deprecated Alias — préférer `ApiSendOptions`. */
|
|
433
|
+
export type PostOptions<Uk = any> = ApiSendOptions<Uk>;
|
|
434
|
+
export type PutOptions<Uk = any> = ApiSendOptions<Uk>;
|
|
435
|
+
export type PatchOptions<Uk = any> = ApiSendOptions<Uk>;
|
|
436
|
+
|
|
437
|
+
function isGetOptions(value: unknown): value is GetOptions {
|
|
438
|
+
if (!value || typeof value !== "object") return false;
|
|
439
|
+
return "skipEmptyPlaceholder" in value;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function isApiSendOptions(value: unknown): value is ApiSendOptions {
|
|
443
|
+
if (!value || typeof value !== "object") return false;
|
|
444
|
+
return (
|
|
445
|
+
"refetchEveryMs" in value ||
|
|
446
|
+
"skipIfBodyMissing" in value ||
|
|
447
|
+
"autoPostOnBodyMutation" in value ||
|
|
448
|
+
"skipEmptyPlaceholder" in value ||
|
|
449
|
+
"triggerKey" in value
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
type ApiSendState = ApiGetState & {
|
|
454
|
+
bodyPublisher: DataProvider | null;
|
|
455
|
+
bodyMutationHandler: (() => void) | null;
|
|
456
|
+
triggerPublisher: DataProvider | null;
|
|
457
|
+
triggerInvalidateHandler: (() => void) | null;
|
|
458
|
+
refetchTimeoutId: ReturnType<typeof setTimeout> | null;
|
|
459
|
+
refetchEveryMs: number;
|
|
460
|
+
skipIfBodyMissing: boolean;
|
|
461
|
+
autoPostOnBodyMutation: boolean;
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
function detachBodyPublisher(state: ApiSendState): void {
|
|
465
|
+
if (state.bodyPublisher && state.bodyMutationHandler) {
|
|
466
|
+
state.bodyPublisher.offInternalMutation(state.bodyMutationHandler);
|
|
467
|
+
}
|
|
468
|
+
state.bodyPublisher = null;
|
|
469
|
+
state.bodyMutationHandler = null;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function detachTriggerPublisher(state: ApiSendState): void {
|
|
473
|
+
if (state.triggerPublisher && state.triggerInvalidateHandler) {
|
|
474
|
+
state.triggerPublisher.offInvalidate(state.triggerInvalidateHandler);
|
|
475
|
+
}
|
|
476
|
+
state.triggerPublisher = null;
|
|
477
|
+
state.triggerInvalidateHandler = null;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function clearSendRefetch(state: ApiSendState): void {
|
|
481
|
+
if (state.refetchTimeoutId) {
|
|
482
|
+
clearTimeout(state.refetchTimeoutId);
|
|
483
|
+
state.refetchTimeoutId = null;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function readBodyFromPublisher(publisher: DataProvider | null): unknown {
|
|
488
|
+
if (!publisher || typeof publisher.get !== "function") return undefined;
|
|
489
|
+
return publisher.get();
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
type ApiSendMethod = "POST" | "PUT" | "PATCH";
|
|
493
|
+
|
|
494
|
+
type ApiSendDetailedCaller = (
|
|
495
|
+
api: API,
|
|
496
|
+
path: string,
|
|
497
|
+
body: unknown,
|
|
498
|
+
) => Promise<ApiResult<unknown> | undefined>;
|
|
499
|
+
|
|
500
|
+
function createApiSendDecorator<T, B, Ue = any, Uk = any, Ut = any>(
|
|
501
|
+
method: ApiSendMethod,
|
|
502
|
+
callDetailed: ApiSendDetailedCaller,
|
|
503
|
+
) {
|
|
504
|
+
return function (
|
|
505
|
+
endpoint: Endpoint<T, Ue>,
|
|
506
|
+
bodyKey: DataProviderKey<B>,
|
|
507
|
+
configurationKeyOrOptions?:
|
|
508
|
+
| DataProviderKey<APIConfiguration, Uk>
|
|
509
|
+
| ApiSendOptions<Ut>,
|
|
510
|
+
maybeOptions?: ApiSendOptions<Ut>,
|
|
511
|
+
): <K extends string>(
|
|
512
|
+
target: object & { [P in K]?: ApiResult<T> | null | undefined },
|
|
513
|
+
propertyKey: K,
|
|
514
|
+
) => void {
|
|
515
|
+
const pathTemplate = endpoint.path;
|
|
516
|
+
const bodyKeyPath = bodyKey.path;
|
|
517
|
+
const configurationKey = isApiSendOptions(configurationKeyOrOptions)
|
|
518
|
+
? undefined
|
|
519
|
+
: configurationKeyOrOptions;
|
|
520
|
+
const options = isApiSendOptions(configurationKeyOrOptions)
|
|
521
|
+
? configurationKeyOrOptions
|
|
522
|
+
: maybeOptions;
|
|
523
|
+
const configurationKeyPath = configurationKey?.path;
|
|
524
|
+
const triggerKeyPath = options?.triggerKey?.path;
|
|
525
|
+
const endpointDynamicDependencies = extractDynamicDependencies(pathTemplate);
|
|
526
|
+
const bodyKeyDynamicDependencies = extractDynamicDependencies(bodyKeyPath);
|
|
527
|
+
const configKeyDynamicDependencies = configurationKeyPath
|
|
528
|
+
? extractDynamicDependencies(configurationKeyPath)
|
|
529
|
+
: [];
|
|
530
|
+
const triggerKeyDynamicDependencies = triggerKeyPath
|
|
531
|
+
? extractDynamicDependencies(triggerKeyPath)
|
|
532
|
+
: [];
|
|
533
|
+
const mergedDynamicDependencies = [
|
|
534
|
+
...new Set([
|
|
535
|
+
...endpointDynamicDependencies,
|
|
536
|
+
...bodyKeyDynamicDependencies,
|
|
537
|
+
...configKeyDynamicDependencies,
|
|
538
|
+
...triggerKeyDynamicDependencies,
|
|
539
|
+
]),
|
|
540
|
+
];
|
|
541
|
+
const isDynamicPath = endpointDynamicDependencies.length > 0;
|
|
542
|
+
const usesPublisherConfig = Boolean(configurationKeyPath);
|
|
543
|
+
const refetchEveryMs = options?.refetchEveryMs ?? 0;
|
|
544
|
+
const skipIfBodyMissing = options?.skipIfBodyMissing ?? true;
|
|
545
|
+
const autoPostOnBodyMutation = options?.autoPostOnBodyMutation ?? true;
|
|
546
|
+
const pathOptions: DynamicPathOptions = {
|
|
547
|
+
skipEmptyPlaceholder: options?.skipEmptyPlaceholder,
|
|
548
|
+
};
|
|
549
|
+
const stateKeyPrefix = `__${method.toLowerCase()}_state_`;
|
|
550
|
+
|
|
551
|
+
return function (target: object, propertyKey: string) {
|
|
552
|
+
if (!target) return;
|
|
553
|
+
setSubscribable(target);
|
|
554
|
+
const stateKey = `${stateKeyPrefix}${propertyKey}`;
|
|
555
|
+
|
|
556
|
+
(target as ConnectedComponent).__onConnected__((component) => {
|
|
557
|
+
const comp = component as Record<string, unknown>;
|
|
558
|
+
let state = comp[stateKey] as ApiSendState | undefined;
|
|
559
|
+
if (!state) {
|
|
560
|
+
state = {
|
|
561
|
+
cleanupWatchers: [],
|
|
562
|
+
requestGeneration: 0,
|
|
563
|
+
configPublisher: null,
|
|
564
|
+
configMutationHandler: null,
|
|
565
|
+
scopeWatchCleanup: null,
|
|
566
|
+
bodyPublisher: null,
|
|
567
|
+
bodyMutationHandler: null,
|
|
568
|
+
triggerPublisher: null,
|
|
569
|
+
triggerInvalidateHandler: null,
|
|
570
|
+
refetchTimeoutId: null,
|
|
571
|
+
refetchEveryMs,
|
|
572
|
+
skipIfBodyMissing,
|
|
573
|
+
autoPostOnBodyMutation,
|
|
574
|
+
};
|
|
575
|
+
comp[stateKey] = state;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
state.cleanupWatchers.forEach((cleanup) => cleanup());
|
|
579
|
+
state.cleanupWatchers = [];
|
|
580
|
+
state.requestGeneration++;
|
|
581
|
+
state.refetchEveryMs = refetchEveryMs;
|
|
582
|
+
state.skipIfBodyMissing = skipIfBodyMissing;
|
|
583
|
+
state.autoPostOnBodyMutation = autoPostOnBodyMutation;
|
|
584
|
+
clearSendRefetch(state);
|
|
585
|
+
|
|
586
|
+
const scheduleRefetch = () => {
|
|
587
|
+
clearSendRefetch(state);
|
|
588
|
+
if (!state.refetchEveryMs || state.refetchEveryMs <= 0) return;
|
|
589
|
+
state.refetchTimeoutId = setTimeout(() => {
|
|
590
|
+
state.refetchTimeoutId = null;
|
|
591
|
+
runSend();
|
|
592
|
+
}, state.refetchEveryMs);
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
const runSend = () => {
|
|
596
|
+
const resolution = isDynamicPath
|
|
597
|
+
? resolveDynamicPath(component, pathTemplate, pathOptions)
|
|
598
|
+
: { ready: true, path: pathTemplate };
|
|
599
|
+
if (!resolution.ready || !resolution.path) {
|
|
600
|
+
comp[propertyKey] = undefined;
|
|
601
|
+
scheduleRefetch();
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const bodyResolution = resolveDynamicPath(
|
|
606
|
+
component,
|
|
607
|
+
bodyKeyPath,
|
|
608
|
+
pathOptions,
|
|
609
|
+
);
|
|
610
|
+
if (!bodyResolution.ready || !bodyResolution.path) {
|
|
611
|
+
comp[propertyKey] = undefined;
|
|
612
|
+
scheduleRefetch();
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const bodyPublisher = getPublisherFromPath(bodyResolution.path);
|
|
617
|
+
const body = readBodyFromPublisher(bodyPublisher);
|
|
618
|
+
if (
|
|
619
|
+
state.skipIfBodyMissing &&
|
|
620
|
+
(body === null || body === undefined)
|
|
621
|
+
) {
|
|
622
|
+
scheduleRefetch();
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
let config: APIConfiguration | null = null;
|
|
627
|
+
if (usesPublisherConfig && configurationKeyPath) {
|
|
628
|
+
const configRes = resolveDynamicPath(
|
|
629
|
+
component,
|
|
630
|
+
configurationKeyPath,
|
|
631
|
+
pathOptions,
|
|
632
|
+
);
|
|
633
|
+
if (!configRes.ready || !configRes.path) {
|
|
634
|
+
comp[propertyKey] = undefined;
|
|
635
|
+
scheduleRefetch();
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
const configPublisher = getPublisherFromPath(configRes.path);
|
|
639
|
+
config = readApiConfigurationFromPublisher(configPublisher);
|
|
640
|
+
} else {
|
|
641
|
+
config = resolveScopedConfiguration(component);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (!isScopedConfigurationReady(config)) {
|
|
645
|
+
if (!usesPublisherConfig && !state.scopeWatchCleanup) {
|
|
646
|
+
const scopeWatch = watchScopedConfiguration(component, runSend);
|
|
647
|
+
state.scopeWatchCleanup = scopeWatch;
|
|
648
|
+
state.cleanupWatchers.push(() => {
|
|
649
|
+
scopeWatch();
|
|
650
|
+
state.scopeWatchCleanup = null;
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
scheduleRefetch();
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const generation = ++state.requestGeneration;
|
|
658
|
+
const api = new API(config);
|
|
659
|
+
void callDetailed(api, resolution.path, body).then(
|
|
660
|
+
(payload?: ApiResult<unknown>) => {
|
|
661
|
+
if (generation !== state.requestGeneration) return;
|
|
662
|
+
comp[propertyKey] = payload;
|
|
663
|
+
scheduleRefetch();
|
|
664
|
+
},
|
|
665
|
+
);
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
const scheduleSend = createAnimationFrameCoalescedRunner(runSend);
|
|
669
|
+
|
|
670
|
+
const rebindBodyPublisher = () => {
|
|
671
|
+
detachBodyPublisher(state);
|
|
672
|
+
if (!state.autoPostOnBodyMutation) {
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
const bodyResolution = resolveDynamicPath(
|
|
676
|
+
component,
|
|
677
|
+
bodyKeyPath,
|
|
678
|
+
pathOptions,
|
|
679
|
+
);
|
|
680
|
+
if (!bodyResolution.ready || !bodyResolution.path) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
const publisher = getPublisherFromPath(bodyResolution.path);
|
|
684
|
+
if (!publisher) return;
|
|
685
|
+
const mutationHandler = () => scheduleSend();
|
|
686
|
+
publisher.onInternalMutation(mutationHandler);
|
|
687
|
+
state.bodyPublisher = publisher;
|
|
688
|
+
state.bodyMutationHandler = mutationHandler;
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
const rebindTriggerPublisher = () => {
|
|
692
|
+
detachTriggerPublisher(state);
|
|
693
|
+
if (!triggerKeyPath) return;
|
|
694
|
+
const triggerResolution = resolveDynamicPath(
|
|
695
|
+
component,
|
|
696
|
+
triggerKeyPath,
|
|
697
|
+
pathOptions,
|
|
698
|
+
);
|
|
699
|
+
if (!triggerResolution.ready || !triggerResolution.path) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
const publisher = getPublisherFromPath(triggerResolution.path);
|
|
703
|
+
if (!publisher) return;
|
|
704
|
+
const invalidateHandler = () => scheduleSend();
|
|
705
|
+
publisher.onInvalidate(invalidateHandler);
|
|
706
|
+
state.triggerPublisher = publisher;
|
|
707
|
+
state.triggerInvalidateHandler = invalidateHandler;
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
const rebindPublisherConfig = () => {
|
|
711
|
+
if (!usesPublisherConfig || !configurationKeyPath) return;
|
|
712
|
+
detachConfigPublisher(state);
|
|
713
|
+
const configRes = resolveDynamicPath(
|
|
714
|
+
component,
|
|
715
|
+
configurationKeyPath,
|
|
716
|
+
pathOptions,
|
|
717
|
+
);
|
|
718
|
+
if (!configRes.ready || !configRes.path) {
|
|
719
|
+
comp[propertyKey] = undefined;
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
const publisher = getPublisherFromPath(configRes.path);
|
|
723
|
+
if (!publisher) {
|
|
724
|
+
comp[propertyKey] = undefined;
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
const mutationHandler = () => scheduleSend();
|
|
728
|
+
publisher.onInternalMutation(mutationHandler);
|
|
729
|
+
state.configPublisher = publisher;
|
|
730
|
+
state.configMutationHandler = mutationHandler;
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
const rebindAll = () => {
|
|
734
|
+
rebindBodyPublisher();
|
|
735
|
+
rebindTriggerPublisher();
|
|
736
|
+
rebindPublisherConfig();
|
|
737
|
+
if (state.autoPostOnBodyMutation) {
|
|
738
|
+
scheduleSend();
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
if (
|
|
743
|
+
usesPublisherConfig ||
|
|
744
|
+
bodyKeyDynamicDependencies.length ||
|
|
745
|
+
triggerKeyDynamicDependencies.length
|
|
746
|
+
) {
|
|
747
|
+
for (const dependency of mergedDynamicDependencies) {
|
|
748
|
+
const unsubscribe = observeDynamicProperty(
|
|
749
|
+
getDynamicWatchKeys.watcherStore,
|
|
750
|
+
getDynamicWatchKeys.hooked,
|
|
751
|
+
component,
|
|
752
|
+
dependency,
|
|
753
|
+
() => rebindAll(),
|
|
754
|
+
);
|
|
755
|
+
state.cleanupWatchers.push(unsubscribe);
|
|
756
|
+
}
|
|
757
|
+
rebindAll();
|
|
758
|
+
} else {
|
|
759
|
+
const startScopedSend = () => {
|
|
760
|
+
if (isDynamicPath) {
|
|
761
|
+
for (const dependency of endpointDynamicDependencies) {
|
|
762
|
+
const unsubscribe = observeDynamicProperty(
|
|
763
|
+
getDynamicWatchKeys.watcherStore,
|
|
764
|
+
getDynamicWatchKeys.hooked,
|
|
765
|
+
component,
|
|
766
|
+
dependency,
|
|
767
|
+
() => scheduleSend(),
|
|
768
|
+
);
|
|
769
|
+
state.cleanupWatchers.push(unsubscribe);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
rebindBodyPublisher();
|
|
773
|
+
rebindTriggerPublisher();
|
|
774
|
+
if (state.autoPostOnBodyMutation) {
|
|
775
|
+
scheduleSend();
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
state.cleanupWatchers.push(
|
|
779
|
+
scheduleAfterHostReady(component, startScopedSend),
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
(target as ConnectedComponent).__onDisconnected__((component) => {
|
|
785
|
+
const comp = component as Record<string, unknown>;
|
|
786
|
+
const state = comp[stateKey] as ApiSendState | undefined;
|
|
787
|
+
if (!state) return;
|
|
788
|
+
detachConfigPublisher(state);
|
|
789
|
+
detachBodyPublisher(state);
|
|
790
|
+
detachTriggerPublisher(state);
|
|
791
|
+
clearSendRefetch(state);
|
|
792
|
+
state.cleanupWatchers.forEach((cleanup) => cleanup());
|
|
793
|
+
state.cleanupWatchers = [];
|
|
794
|
+
state.requestGeneration++;
|
|
795
|
+
comp[propertyKey] = undefined;
|
|
796
|
+
});
|
|
797
|
+
};
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Décorateur **`@post`** : envoie des données via `API.postDetailed` et assigne un
|
|
803
|
+
* `ApiResult<T>` (`request`, `response`, `result` typé `T`).
|
|
804
|
+
*
|
|
805
|
+
* Le body est lu depuis un `DataProviderKey` (mutations et assignations relancent le POST).
|
|
806
|
+
*
|
|
807
|
+
* @example
|
|
808
|
+
* @post(new Endpoint<SyncResult, { sessionId: string }>("sessions/${sessionId}/sync"), syncRequestKey)
|
|
809
|
+
* payload?: ApiResult<SyncResult>;
|
|
810
|
+
*/
|
|
811
|
+
export function post<T, B, Ue = any>(
|
|
812
|
+
endpoint: Endpoint<T, Ue>,
|
|
813
|
+
bodyKey: DataProviderKey<B>,
|
|
814
|
+
): <K extends string>(
|
|
815
|
+
target: DataProviderKeyHost<Ue> & {
|
|
816
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
817
|
+
},
|
|
818
|
+
propertyKey: K,
|
|
819
|
+
) => void;
|
|
820
|
+
export function post<T, B, Ue = any, Uk = any>(
|
|
821
|
+
endpoint: Endpoint<T, Ue>,
|
|
822
|
+
bodyKey: DataProviderKey<B>,
|
|
823
|
+
configurationKey: DataProviderKey<APIConfiguration, Uk>,
|
|
824
|
+
): <K extends string>(
|
|
825
|
+
target: DataProviderKeyHost<Ue> &
|
|
826
|
+
DataProviderKeyHost<Uk> & {
|
|
827
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
828
|
+
},
|
|
829
|
+
propertyKey: K,
|
|
830
|
+
) => void;
|
|
831
|
+
export function post<T, B, Ue = any, Uk = any>(
|
|
832
|
+
endpoint: Endpoint<T, Ue>,
|
|
833
|
+
bodyKey: DataProviderKey<B>,
|
|
834
|
+
options: PostOptions<Uk>,
|
|
835
|
+
): <K extends string>(
|
|
836
|
+
target: DataProviderKeyHost<Ue> & {
|
|
837
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
838
|
+
},
|
|
839
|
+
propertyKey: K,
|
|
840
|
+
) => void;
|
|
841
|
+
export function post<T, B, Ue = any, Uk = any, Ut = any>(
|
|
842
|
+
endpoint: Endpoint<T, Ue>,
|
|
843
|
+
bodyKey: DataProviderKey<B>,
|
|
844
|
+
configurationKey: DataProviderKey<APIConfiguration, Uk>,
|
|
845
|
+
options: PostOptions<Ut>,
|
|
846
|
+
): <K extends string>(
|
|
847
|
+
target: DataProviderKeyHost<Ue> &
|
|
848
|
+
DataProviderKeyHost<Uk> & {
|
|
849
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
850
|
+
},
|
|
851
|
+
propertyKey: K,
|
|
852
|
+
) => void;
|
|
853
|
+
export function post<T, B, Ue = any, Uk = any, Ut = any>(
|
|
854
|
+
endpoint: Endpoint<T, Ue>,
|
|
855
|
+
bodyKey: DataProviderKey<B>,
|
|
856
|
+
configurationKeyOrOptions?:
|
|
857
|
+
| DataProviderKey<APIConfiguration, Uk>
|
|
858
|
+
| PostOptions<Ut>,
|
|
859
|
+
maybeOptions?: PostOptions<Ut>,
|
|
860
|
+
): <K extends string>(
|
|
861
|
+
target: object & { [P in K]?: ApiResult<T> | null | undefined },
|
|
862
|
+
propertyKey: K,
|
|
863
|
+
) => void {
|
|
864
|
+
return createApiSendDecorator<T, B, Ue, Uk, Ut>(
|
|
865
|
+
"POST",
|
|
866
|
+
(api, path, body) => api.postDetailed<T, B>(path, body as B),
|
|
867
|
+
)(endpoint, bodyKey, configurationKeyOrOptions, maybeOptions);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/** `@put` — même modèle que `@post` via `API.putDetailed`. */
|
|
871
|
+
export function put<T, B, Ue = any>(
|
|
872
|
+
endpoint: Endpoint<T, Ue>,
|
|
873
|
+
bodyKey: DataProviderKey<B>,
|
|
874
|
+
): <K extends string>(
|
|
875
|
+
target: DataProviderKeyHost<Ue> & {
|
|
876
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
877
|
+
},
|
|
878
|
+
propertyKey: K,
|
|
879
|
+
) => void;
|
|
880
|
+
export function put<T, B, Ue = any, Uk = any>(
|
|
881
|
+
endpoint: Endpoint<T, Ue>,
|
|
882
|
+
bodyKey: DataProviderKey<B>,
|
|
883
|
+
configurationKey: DataProviderKey<APIConfiguration, Uk>,
|
|
884
|
+
): <K extends string>(
|
|
885
|
+
target: DataProviderKeyHost<Ue> &
|
|
886
|
+
DataProviderKeyHost<Uk> & {
|
|
887
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
888
|
+
},
|
|
889
|
+
propertyKey: K,
|
|
890
|
+
) => void;
|
|
891
|
+
export function put<T, B, Ue = any, Uk = any>(
|
|
892
|
+
endpoint: Endpoint<T, Ue>,
|
|
893
|
+
bodyKey: DataProviderKey<B>,
|
|
894
|
+
options: PutOptions<Uk>,
|
|
895
|
+
): <K extends string>(
|
|
896
|
+
target: DataProviderKeyHost<Ue> & {
|
|
897
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
898
|
+
},
|
|
899
|
+
propertyKey: K,
|
|
900
|
+
) => void;
|
|
901
|
+
export function put<T, B, Ue = any, Uk = any, Ut = any>(
|
|
902
|
+
endpoint: Endpoint<T, Ue>,
|
|
903
|
+
bodyKey: DataProviderKey<B>,
|
|
904
|
+
configurationKey: DataProviderKey<APIConfiguration, Uk>,
|
|
905
|
+
options: PutOptions<Ut>,
|
|
906
|
+
): <K extends string>(
|
|
907
|
+
target: DataProviderKeyHost<Ue> &
|
|
908
|
+
DataProviderKeyHost<Uk> & {
|
|
909
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
910
|
+
},
|
|
911
|
+
propertyKey: K,
|
|
912
|
+
) => void;
|
|
913
|
+
export function put<T, B, Ue = any, Uk = any, Ut = any>(
|
|
914
|
+
endpoint: Endpoint<T, Ue>,
|
|
915
|
+
bodyKey: DataProviderKey<B>,
|
|
916
|
+
configurationKeyOrOptions?:
|
|
917
|
+
| DataProviderKey<APIConfiguration, Uk>
|
|
918
|
+
| PutOptions<Ut>,
|
|
919
|
+
maybeOptions?: PutOptions<Ut>,
|
|
920
|
+
): <K extends string>(
|
|
921
|
+
target: object & { [P in K]?: ApiResult<T> | null | undefined },
|
|
922
|
+
propertyKey: K,
|
|
923
|
+
) => void {
|
|
924
|
+
return createApiSendDecorator<T, B, Ue, Uk, Ut>(
|
|
925
|
+
"PUT",
|
|
926
|
+
(api, path, body) => api.putDetailed<T, B>(path, body as B),
|
|
927
|
+
)(endpoint, bodyKey, configurationKeyOrOptions, maybeOptions);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/** `@patch` — même modèle que `@post` via `API.patchDetailed`. */
|
|
931
|
+
export function patch<T, B, Ue = any>(
|
|
932
|
+
endpoint: Endpoint<T, Ue>,
|
|
933
|
+
bodyKey: DataProviderKey<B>,
|
|
934
|
+
): <K extends string>(
|
|
935
|
+
target: DataProviderKeyHost<Ue> & {
|
|
936
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
937
|
+
},
|
|
938
|
+
propertyKey: K,
|
|
939
|
+
) => void;
|
|
940
|
+
export function patch<T, B, Ue = any, Uk = any>(
|
|
941
|
+
endpoint: Endpoint<T, Ue>,
|
|
942
|
+
bodyKey: DataProviderKey<B>,
|
|
943
|
+
configurationKey: DataProviderKey<APIConfiguration, Uk>,
|
|
944
|
+
): <K extends string>(
|
|
945
|
+
target: DataProviderKeyHost<Ue> &
|
|
946
|
+
DataProviderKeyHost<Uk> & {
|
|
947
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
948
|
+
},
|
|
949
|
+
propertyKey: K,
|
|
950
|
+
) => void;
|
|
951
|
+
export function patch<T, B, Ue = any, Uk = any>(
|
|
952
|
+
endpoint: Endpoint<T, Ue>,
|
|
953
|
+
bodyKey: DataProviderKey<B>,
|
|
954
|
+
options: PatchOptions<Uk>,
|
|
955
|
+
): <K extends string>(
|
|
956
|
+
target: DataProviderKeyHost<Ue> & {
|
|
957
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
958
|
+
},
|
|
959
|
+
propertyKey: K,
|
|
960
|
+
) => void;
|
|
961
|
+
export function patch<T, B, Ue = any, Uk = any, Ut = any>(
|
|
962
|
+
endpoint: Endpoint<T, Ue>,
|
|
963
|
+
bodyKey: DataProviderKey<B>,
|
|
964
|
+
configurationKey: DataProviderKey<APIConfiguration, Uk>,
|
|
965
|
+
options: PatchOptions<Ut>,
|
|
966
|
+
): <K extends string>(
|
|
967
|
+
target: DataProviderKeyHost<Ue> &
|
|
968
|
+
DataProviderKeyHost<Uk> & {
|
|
969
|
+
[P in K]?: ApiResult<T> | null | undefined;
|
|
970
|
+
},
|
|
971
|
+
propertyKey: K,
|
|
972
|
+
) => void;
|
|
973
|
+
export function patch<T, B, Ue = any, Uk = any, Ut = any>(
|
|
974
|
+
endpoint: Endpoint<T, Ue>,
|
|
975
|
+
bodyKey: DataProviderKey<B>,
|
|
976
|
+
configurationKeyOrOptions?:
|
|
977
|
+
| DataProviderKey<APIConfiguration, Uk>
|
|
978
|
+
| PatchOptions<Ut>,
|
|
979
|
+
maybeOptions?: PatchOptions<Ut>,
|
|
980
|
+
): <K extends string>(
|
|
981
|
+
target: object & { [P in K]?: ApiResult<T> | null | undefined },
|
|
982
|
+
propertyKey: K,
|
|
983
|
+
) => void {
|
|
984
|
+
return createApiSendDecorator<T, B, Ue, Uk, Ut>(
|
|
985
|
+
"PATCH",
|
|
986
|
+
(api, path, body) => api.patchDetailed<T, B>(path, body as B),
|
|
987
|
+
)(endpoint, bodyKey, configurationKeyOrOptions, maybeOptions);
|
|
988
|
+
}
|