mobx-tanstack-query-api 0.26.2 → 0.27.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/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as _tanstack_query_core from '@tanstack/query-core';
2
2
  import { InvalidateOptions, DefaultError, RefetchOptions, QueryObserverResult, QueryFunctionContext, InvalidateQueryFilters, InfiniteData, QueryKey } from '@tanstack/query-core';
3
3
  export * from '@tanstack/query-core';
4
+ import { HttpStatusCode, HttpSuccessStatusCode } from 'http-status-code-types';
4
5
  import { QueryClient, QueryClientConfig, Query, QueryUpdateOptionsAllVariants, QueryConfig, InfiniteQueryConfig, InfiniteQueryOptions, InfiniteQueryUpdateOptions, InfiniteQueryDynamicOptions, InfiniteQuery, MutationInvalidateQueriesOptions, MutationConfig, Mutation, IQueryClientCore } from 'mobx-tanstack-query';
5
6
  import { MaybeFalsy, AnyObject, Maybe, MaybeFn, ValueOf, Defined, IsPartial } from 'yummies/types';
6
- import { HttpStatusCode, HttpSuccessStatusCode } from 'http-status-code-types';
7
7
  import { IStringifyOptions, BooleanOptional } from 'qs';
8
8
 
9
9
  /**
@@ -303,6 +303,10 @@ declare class Endpoint<TResponse extends AnyResponse, TParams extends AnyObject,
303
303
  get operationId(): string;
304
304
  get group(): string | undefined;
305
305
  get namespace(): string | undefined;
306
+ checkResponse<TStatus extends HttpStatusCode>(response: unknown, status: TStatus): response is Extract<TResponse, {
307
+ status: TStatus;
308
+ }>;
309
+ checkResponse(response: unknown): response is TResponse;
306
310
  request(...args: IsPartial<TParams> extends true ? [params?: Maybe<TParams>] : [params: TParams]): Promise<TResponse>;
307
311
  toQueryMeta: (meta?: AnyObject) => {
308
312
  tags: string[];
@@ -328,7 +332,7 @@ declare class Endpoint<TResponse extends AnyResponse, TParams extends AnyObject,
328
332
  options?: InvalidateOptions
329
333
  ]): void;
330
334
  toMutation<TData = TResponse['data'], TMutationMeta extends AnyObject | void = void, TContext = unknown>(options: EndpointMutationOptions<this, TData, TParams, TMutationMeta, TContext>): EndpointMutation<this, TData, TParams, TMutationMeta, TContext>;
331
- toQuery<TQueryFnData = TResponse['data'], TError = DefaultError, TData = TQueryFnData, TQueryData = TQueryFnData>(options: EndpointQueryOptions<this, TQueryFnData, TError, TData, TQueryData> | (() => EndpointQueryFlattenOptions<this, TQueryFnData, TError, TData, TQueryData>)): EndpointQuery<this, TQueryFnData, TError, TData, TQueryData>;
335
+ toQuery<TQueryFnData = TResponse['data'], TError = DefaultError | Defined<TResponse['error']>, TData = TQueryFnData, TQueryData = TQueryFnData>(options: EndpointQueryOptions<this, TQueryFnData, TError, TData, TQueryData> | (() => EndpointQueryFlattenOptions<this, TQueryFnData, TError, TData, TQueryData>)): EndpointQuery<this, TQueryFnData, TError, TData, TQueryData>;
332
336
  toInfiniteQuery<TData = TResponse['data'], TError = DefaultError, TPageParam = unknown>(options: EndpointInfiniteQueryOptions<this, TData, TError, TPageParam> | (() => EndpointInfiniteQueryFlattenOptions<this, TData, TError, TPageParam>)): EndpointInfiniteQuery<this, TData, TError, TPageParam, _tanstack_query_core.InfiniteData<TData, TPageParam>>;
333
337
  }
334
338
 
package/index.js CHANGED
@@ -388,6 +388,176 @@ class EndpointMutation extends Mutation {
388
388
  this.endpoint = endpoint;
389
389
  }
390
390
  }
391
+ const isHttpResponse = (response, status) => !!response && typeof response === "object" && response instanceof Response && "data" in response && (!status || response.status === status);
392
+ const isHttpBadResponse = (response) => {
393
+ return isHttpResponse(response) && (!response.ok || !!response.error);
394
+ };
395
+ class HttpClient {
396
+ config;
397
+ fetch;
398
+ meta;
399
+ baseApiParams;
400
+ badResponse;
401
+ toQueryString;
402
+ constructor(config) {
403
+ this.config = config ?? {};
404
+ this.badResponse = null;
405
+ this.meta = config?.meta ?? null;
406
+ this.fetch = config?.fetch ?? ((...fetchParams) => globalThis.fetch(...fetchParams));
407
+ this.toQueryString = config?.toQueryString ?? ((query) => stringify(query, config?.queryStringifyOptions));
408
+ this.baseApiParams = {
409
+ credentials: "same-origin",
410
+ headers: {},
411
+ redirect: "follow",
412
+ referrerPolicy: "no-referrer"
413
+ };
414
+ this.updateConfig(this.config);
415
+ observable.ref(this, "badResponse");
416
+ observable.ref(this, "meta");
417
+ action(this, "setMeta");
418
+ action(this, "setBadResponse");
419
+ makeObservable(this);
420
+ }
421
+ get baseUrl() {
422
+ return this.config.baseUrl ?? "";
423
+ }
424
+ updateConfig(update) {
425
+ Object.assign(this.config, update);
426
+ if (update.baseApiParams) {
427
+ Object.assign(this.baseApiParams, update.baseApiParams);
428
+ }
429
+ if (update.contentFormatters) {
430
+ Object.assign(this.contentFormatters, update.contentFormatters);
431
+ }
432
+ if (update.fetch) {
433
+ this.fetch = update.fetch;
434
+ }
435
+ }
436
+ setMeta = (data) => {
437
+ this.meta = data;
438
+ };
439
+ setBadResponse = (response) => {
440
+ this.badResponse = response;
441
+ };
442
+ contentFormatters = {
443
+ "application/json": (input) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
444
+ "text/plain": (input) => input !== null && typeof input !== "string" ? JSON.stringify(input) : input,
445
+ "multipart/form-data": (input) => Object.keys(input || {}).reduce((formData, key) => {
446
+ const property = input[key];
447
+ if (property instanceof Blob) {
448
+ formData.append(key, property);
449
+ } else if (typeof property === "object" && property !== null) {
450
+ formData.append(key, JSON.stringify(property));
451
+ } else {
452
+ formData.append(key, `${property}`);
453
+ }
454
+ return formData;
455
+ }, new FormData()),
456
+ "application/x-www-form-urlencoded": (input) => this.toQueryString(input),
457
+ "application/octet-stream": (input) => input
458
+ };
459
+ mergeRequestParams(params1, params2) {
460
+ return {
461
+ ...this.baseApiParams,
462
+ ...params1,
463
+ ...params2,
464
+ headers: {
465
+ ...this.baseApiParams.headers,
466
+ ...params1.headers,
467
+ ...params2?.headers
468
+ }
469
+ };
470
+ }
471
+ async createResponse(responseFormat, raw, url, params) {
472
+ const response = raw;
473
+ response.request = {
474
+ url,
475
+ params
476
+ };
477
+ response.data = null;
478
+ response.error = null;
479
+ if (responseFormat) {
480
+ try {
481
+ const formatted = await response[responseFormat]();
482
+ if (response.ok) {
483
+ response.data = formatted;
484
+ } else {
485
+ response.error = formatted;
486
+ }
487
+ } catch (error) {
488
+ if (response.ok) {
489
+ response.error = error;
490
+ } else {
491
+ response.error = null;
492
+ }
493
+ }
494
+ }
495
+ if (!response.ok || response.error) {
496
+ this.setBadResponse(response);
497
+ }
498
+ return response;
499
+ }
500
+ buildUrl = (params) => {
501
+ const baseUrl = params.baseUrl ?? this.baseUrl ?? "";
502
+ const path = params.path;
503
+ const queryString = params.query && this.toQueryString(params.query);
504
+ const query = queryString ? `?${queryString}` : "";
505
+ if (this.config.buildUrl) {
506
+ return this.config.buildUrl(params, { baseUrl, path, query }, this.meta);
507
+ }
508
+ const url = baseUrl + path + query;
509
+ return url;
510
+ };
511
+ async request(fullParams, endpoint) {
512
+ this.setBadResponse(null);
513
+ const {
514
+ body,
515
+ contentType = "application/json",
516
+ format = "json",
517
+ ...params
518
+ } = fullParams;
519
+ let requestParams = this.mergeRequestParams(params);
520
+ if (this.config.interceptor) {
521
+ requestParams = await this.config.interceptor(requestParams, this.meta, endpoint) ?? requestParams;
522
+ }
523
+ const payloadFormatter = this.contentFormatters[contentType];
524
+ const responseFormat = format || requestParams.format;
525
+ const url = this.buildUrl(fullParams);
526
+ let headers;
527
+ if (requestParams.headers instanceof Headers) {
528
+ headers = requestParams.headers;
529
+ } else if (Array.isArray(requestParams.headers)) {
530
+ headers = new Headers(requestParams.headers);
531
+ } else {
532
+ headers = new Headers(requestParams.headers);
533
+ }
534
+ if (!headers.has("Content-Type")) {
535
+ headers.set("Content-Type", contentType);
536
+ }
537
+ const fetchUrl = url;
538
+ const fetchParams = {
539
+ ...requestParams,
540
+ headers,
541
+ body: body == null ? null : payloadFormatter(body)
542
+ };
543
+ let response;
544
+ try {
545
+ response = await this.fetch(fetchUrl, fetchParams);
546
+ } catch (error) {
547
+ response = error;
548
+ }
549
+ const httpResponse = await this.createResponse(
550
+ responseFormat,
551
+ response,
552
+ fetchUrl,
553
+ fetchParams
554
+ );
555
+ if (!httpResponse.ok || httpResponse.error) {
556
+ throw httpResponse;
557
+ }
558
+ return httpResponse;
559
+ }
560
+ }
391
561
  class Endpoint {
392
562
  constructor(configuration, queryClient, httpClient) {
393
563
  this.configuration = configuration;
@@ -443,6 +613,9 @@ class Endpoint {
443
613
  get namespace() {
444
614
  return this.configuration.namespace;
445
615
  }
616
+ checkResponse(response, status) {
617
+ return isHttpResponse(response, status);
618
+ }
446
619
  request(...args) {
447
620
  return this.httpClient.request(
448
621
  this.configuration.params(args[0] ?? {}),
@@ -584,176 +757,6 @@ const applyStringFilter = (filter, value) => {
584
757
  }
585
758
  return values.includes(filter);
586
759
  };
587
- const isHttpResponse = (response, status) => !!response && typeof response === "object" && response instanceof Response && "data" in response && (!status || response.status === status);
588
- const isHttpBadResponse = (response) => {
589
- return isHttpResponse(response) && (!response.ok || !!response.error);
590
- };
591
- class HttpClient {
592
- config;
593
- fetch;
594
- meta;
595
- baseApiParams;
596
- badResponse;
597
- toQueryString;
598
- constructor(config) {
599
- this.config = config ?? {};
600
- this.badResponse = null;
601
- this.meta = config?.meta ?? null;
602
- this.fetch = config?.fetch ?? ((...fetchParams) => globalThis.fetch(...fetchParams));
603
- this.toQueryString = config?.toQueryString ?? ((query) => stringify(query, config?.queryStringifyOptions));
604
- this.baseApiParams = {
605
- credentials: "same-origin",
606
- headers: {},
607
- redirect: "follow",
608
- referrerPolicy: "no-referrer"
609
- };
610
- this.updateConfig(this.config);
611
- observable.ref(this, "badResponse");
612
- observable.ref(this, "meta");
613
- action(this, "setMeta");
614
- action(this, "setBadResponse");
615
- makeObservable(this);
616
- }
617
- get baseUrl() {
618
- return this.config.baseUrl ?? "";
619
- }
620
- updateConfig(update) {
621
- Object.assign(this.config, update);
622
- if (update.baseApiParams) {
623
- Object.assign(this.baseApiParams, update.baseApiParams);
624
- }
625
- if (update.contentFormatters) {
626
- Object.assign(this.contentFormatters, update.contentFormatters);
627
- }
628
- if (update.fetch) {
629
- this.fetch = update.fetch;
630
- }
631
- }
632
- setMeta = (data) => {
633
- this.meta = data;
634
- };
635
- setBadResponse = (response) => {
636
- this.badResponse = response;
637
- };
638
- contentFormatters = {
639
- "application/json": (input) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
640
- "text/plain": (input) => input !== null && typeof input !== "string" ? JSON.stringify(input) : input,
641
- "multipart/form-data": (input) => Object.keys(input || {}).reduce((formData, key) => {
642
- const property = input[key];
643
- if (property instanceof Blob) {
644
- formData.append(key, property);
645
- } else if (typeof property === "object" && property !== null) {
646
- formData.append(key, JSON.stringify(property));
647
- } else {
648
- formData.append(key, `${property}`);
649
- }
650
- return formData;
651
- }, new FormData()),
652
- "application/x-www-form-urlencoded": (input) => this.toQueryString(input),
653
- "application/octet-stream": (input) => input
654
- };
655
- mergeRequestParams(params1, params2) {
656
- return {
657
- ...this.baseApiParams,
658
- ...params1,
659
- ...params2,
660
- headers: {
661
- ...this.baseApiParams.headers,
662
- ...params1.headers,
663
- ...params2?.headers
664
- }
665
- };
666
- }
667
- async createResponse(responseFormat, raw, url, params) {
668
- const response = raw;
669
- response.request = {
670
- url,
671
- params
672
- };
673
- response.data = null;
674
- response.error = null;
675
- if (responseFormat) {
676
- try {
677
- const formatted = await response[responseFormat]();
678
- if (response.ok) {
679
- response.data = formatted;
680
- } else {
681
- response.error = formatted;
682
- }
683
- } catch (error) {
684
- if (response.ok) {
685
- response.error = error;
686
- } else {
687
- response.error = null;
688
- }
689
- }
690
- }
691
- if (!response.ok || response.error) {
692
- this.setBadResponse(response);
693
- }
694
- return response;
695
- }
696
- buildUrl = (params) => {
697
- const baseUrl = params.baseUrl ?? this.baseUrl ?? "";
698
- const path = params.path;
699
- const queryString = params.query && this.toQueryString(params.query);
700
- const query = queryString ? `?${queryString}` : "";
701
- if (this.config.buildUrl) {
702
- return this.config.buildUrl(params, { baseUrl, path, query }, this.meta);
703
- }
704
- const url = baseUrl + path + query;
705
- return url;
706
- };
707
- async request(fullParams, endpoint) {
708
- this.setBadResponse(null);
709
- const {
710
- body,
711
- contentType = "application/json",
712
- format = "json",
713
- ...params
714
- } = fullParams;
715
- let requestParams = this.mergeRequestParams(params);
716
- if (this.config.interceptor) {
717
- requestParams = await this.config.interceptor(requestParams, this.meta, endpoint) ?? requestParams;
718
- }
719
- const payloadFormatter = this.contentFormatters[contentType];
720
- const responseFormat = format || requestParams.format;
721
- const url = this.buildUrl(fullParams);
722
- let headers;
723
- if (requestParams.headers instanceof Headers) {
724
- headers = requestParams.headers;
725
- } else if (Array.isArray(requestParams.headers)) {
726
- headers = new Headers(requestParams.headers);
727
- } else {
728
- headers = new Headers(requestParams.headers);
729
- }
730
- if (!headers.has("Content-Type")) {
731
- headers.set("Content-Type", contentType);
732
- }
733
- const fetchUrl = url;
734
- const fetchParams = {
735
- ...requestParams,
736
- headers,
737
- body: body == null ? null : payloadFormatter(body)
738
- };
739
- let response;
740
- try {
741
- response = await this.fetch(fetchUrl, fetchParams);
742
- } catch (error) {
743
- response = error;
744
- }
745
- const httpResponse = await this.createResponse(
746
- responseFormat,
747
- response,
748
- fetchUrl,
749
- fetchParams
750
- );
751
- if (!httpResponse.ok || httpResponse.error) {
752
- throw httpResponse;
753
- }
754
- return httpResponse;
755
- }
756
- }
757
760
  export {
758
761
  Endpoint,
759
762
  EndpointMutation,