@povio/openapi-codegen-cli 2.0.8-rc.9 → 2.0.8

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.
Files changed (162) hide show
  1. package/README.md +0 -63
  2. package/dist/acl.d.ts +4 -0
  3. package/dist/acl.mjs +7 -62
  4. package/dist/commands/check.command.d.ts +2 -0
  5. package/dist/commands/check.d.ts +7 -0
  6. package/dist/commands/generate.command.d.ts +2 -0
  7. package/dist/commands/generate.d.ts +8 -0
  8. package/dist/generator.d.ts +3 -0
  9. package/dist/generator.js +78 -0
  10. package/dist/generators/checkOpenAPIDoc.d.ts +3 -0
  11. package/dist/generators/const/acl.const.d.ts +13 -0
  12. package/dist/generators/const/buildConfigs.const.d.ts +1 -0
  13. package/dist/generators/const/deps.const.d.ts +38 -0
  14. package/dist/generators/const/endpoints.const.d.ts +11 -0
  15. package/dist/generators/const/js.const.d.ts +1 -0
  16. package/dist/generators/const/openapi.const.d.ts +7 -0
  17. package/dist/generators/const/options.const.d.ts +2 -0
  18. package/dist/generators/const/package.const.d.ts +2 -0
  19. package/dist/generators/const/queries.const.d.ts +8 -0
  20. package/dist/generators/const/validation.const.d.ts +53 -0
  21. package/dist/generators/const/zod.const.d.ts +19 -0
  22. package/dist/generators/core/SchemaResolver.class.d.ts +71 -0
  23. package/dist/generators/core/endpoints/getEndpointAcl.d.ts +8 -0
  24. package/dist/generators/core/endpoints/getEndpointBody.d.ts +13 -0
  25. package/dist/generators/core/endpoints/getEndpointParameter.d.ts +11 -0
  26. package/dist/generators/core/endpoints/getEndpointsFromOpenAPIDoc.d.ts +3 -0
  27. package/dist/generators/core/endpoints/getEndpointsFromOpenAPIDoc.test.d.ts +1 -0
  28. package/dist/generators/core/getDataFromOpenAPIDoc.d.ts +8 -0
  29. package/dist/generators/core/getMetadataFromOpenAPIDoc.d.ts +4 -0
  30. package/dist/generators/core/getMetadataFromOpenAPIDoc.test.d.ts +1 -0
  31. package/dist/generators/core/openapi/getOpenAPISchemaComplexity.d.ts +2 -0
  32. package/dist/generators/core/openapi/getOpenAPISchemaComplexity.test.d.ts +1 -0
  33. package/dist/generators/core/openapi/getOpenAPISchemaDependencyGraph.d.ts +6 -0
  34. package/dist/generators/core/openapi/getOpenAPISchemaDependencyGraph.test.d.ts +1 -0
  35. package/dist/generators/core/openapi/getSchemaRefObjs.d.ts +4 -0
  36. package/dist/generators/core/openapi/iterateSchema.d.ts +22 -0
  37. package/dist/generators/core/resolveConfig.d.ts +7 -0
  38. package/dist/generators/core/zod/ZodSchema.class.d.ts +26 -0
  39. package/dist/generators/core/zod/enumExtraction/resolveExtractedEnumZodSchemaNames.d.ts +2 -0
  40. package/dist/generators/core/zod/enumExtraction/resolveExtractedEnumZodSchemaTags.d.ts +2 -0
  41. package/dist/generators/core/zod/enumExtraction/updateExtractedEnumZodSchemaData.d.ts +17 -0
  42. package/dist/generators/core/zod/getZodChain.d.ts +8 -0
  43. package/dist/generators/core/zod/getZodSchema.d.ts +17 -0
  44. package/dist/generators/core/zod/getZodSchema.test.d.ts +1 -0
  45. package/dist/generators/core/zod/getZodSchemaRefs.d.ts +6 -0
  46. package/dist/generators/core/zod/getZodSchemasFromOpenAPIDoc.d.ts +6 -0
  47. package/dist/generators/core/zod/resolveZodSchemaName.d.ts +10 -0
  48. package/dist/generators/core/zod/sortZodSchemasByTopology.d.ts +4 -0
  49. package/dist/generators/generate/generateAcl.d.ts +3 -0
  50. package/dist/generators/generate/generateAclCheck.d.ts +2 -0
  51. package/dist/generators/generate/generateAppRestClient.d.ts +2 -0
  52. package/dist/generators/generate/generateConfigs.d.ts +2 -0
  53. package/dist/generators/generate/generateEndpoints.d.ts +2 -0
  54. package/dist/generators/generate/generateModels.d.ts +2 -0
  55. package/dist/generators/generate/generateQueries.d.ts +2 -0
  56. package/dist/generators/generate/generateQueryModules.d.ts +2 -0
  57. package/dist/generators/generate/generateZodExtended.d.ts +2 -0
  58. package/dist/generators/generateCodeFromOpenAPIDoc.d.ts +4 -0
  59. package/dist/generators/types/builder-config.d.ts +48 -0
  60. package/dist/generators/types/common.d.ts +27 -0
  61. package/dist/generators/types/config.d.ts +2 -0
  62. package/dist/generators/types/endpoint.d.ts +50 -0
  63. package/dist/generators/types/generate.d.ts +39 -0
  64. package/dist/generators/types/metadata.d.ts +51 -0
  65. package/dist/generators/types/openapi.d.ts +22 -0
  66. package/dist/generators/types/options.d.ts +66 -0
  67. package/dist/generators/types/validation.d.ts +5 -0
  68. package/dist/generators/utils/array.utils.d.ts +1 -0
  69. package/dist/generators/utils/endpoint.utils.d.ts +12 -0
  70. package/dist/generators/utils/endpoint.utils.test.d.ts +1 -0
  71. package/dist/generators/utils/file.utils.d.ts +8 -0
  72. package/dist/generators/utils/generate/generate.acl.utils.d.ts +23 -0
  73. package/dist/generators/utils/generate/generate.configs.utils.d.ts +15 -0
  74. package/dist/generators/utils/generate/generate.endpoints.utils.d.ts +41 -0
  75. package/dist/generators/utils/generate/generate.imports.utils.d.ts +39 -0
  76. package/dist/generators/utils/generate/generate.imports.utils.test.d.ts +1 -0
  77. package/dist/generators/utils/generate/generate.openapi.utils.d.ts +2 -0
  78. package/dist/generators/utils/generate/generate.query.utils.d.ts +6 -0
  79. package/dist/generators/utils/generate/generate.utils.d.ts +18 -0
  80. package/dist/generators/utils/generate/generate.zod.utils.d.ts +13 -0
  81. package/dist/generators/utils/generate-files.utils.d.ts +6 -0
  82. package/dist/generators/utils/hbs/hbs-template.utils.d.ts +3 -0
  83. package/dist/generators/utils/hbs/hbs.acl.utils.d.ts +2 -0
  84. package/dist/generators/utils/hbs/hbs.common.utils.d.ts +1 -0
  85. package/dist/generators/utils/hbs/hbs.endpoints.utils.d.ts +2 -0
  86. package/dist/generators/utils/hbs/hbs.imports.utils.d.ts +1 -0
  87. package/dist/generators/utils/hbs/hbs.partials.utils.d.ts +2 -0
  88. package/dist/generators/utils/hbs/hbs.query.utils.d.ts +2 -0
  89. package/dist/generators/utils/hbs/hbs.zod.utils.d.ts +2 -0
  90. package/dist/generators/utils/js.utils.d.ts +2 -0
  91. package/dist/generators/utils/js.utils.test.d.ts +1 -0
  92. package/dist/generators/utils/math.utils.d.ts +1 -0
  93. package/dist/generators/utils/namespace.utils.d.ts +7 -0
  94. package/dist/generators/utils/object.utils.d.ts +13 -0
  95. package/dist/generators/utils/object.utils.test.d.ts +1 -0
  96. package/dist/generators/utils/openapi-schema.utils.d.ts +15 -0
  97. package/dist/generators/utils/openapi.utils.d.ts +23 -0
  98. package/dist/generators/utils/openapi.utils.test.d.ts +1 -0
  99. package/dist/generators/utils/operation.utils.d.ts +22 -0
  100. package/dist/generators/utils/operation.utils.test.d.ts +1 -0
  101. package/dist/generators/utils/query.utils.d.ts +7 -0
  102. package/dist/generators/utils/sort.utils.d.ts +7 -0
  103. package/dist/generators/utils/string.utils.d.ts +14 -0
  104. package/dist/generators/utils/string.utils.test.d.ts +1 -0
  105. package/dist/generators/utils/tag.utils.d.ts +7 -0
  106. package/dist/generators/utils/ts.utils.d.ts +16 -0
  107. package/dist/generators/utils/validation.utils.d.ts +17 -0
  108. package/dist/generators/utils/zod-schema.utils.d.ts +15 -0
  109. package/dist/helpers/cli.helper.d.ts +22 -0
  110. package/dist/helpers/config.helper.d.ts +3 -0
  111. package/dist/helpers/version.helper.d.ts +4 -0
  112. package/dist/helpers/yargs.helper.d.ts +10 -0
  113. package/dist/index.d.ts +15 -0
  114. package/dist/index.mjs +22 -365
  115. package/dist/lib/acl/AclGuard.d.ts +8 -0
  116. package/dist/lib/acl/AclGuard.mjs +14 -0
  117. package/dist/lib/acl/Can.d.ts +9 -0
  118. package/dist/lib/acl/Can.mjs +11 -0
  119. package/dist/lib/acl/ability.context.d.ts +15 -0
  120. package/dist/lib/acl/ability.context.mjs +37 -0
  121. package/dist/lib/acl/appAbility.types.d.ts +3 -0
  122. package/dist/lib/assets/locales/en/translation.json.mjs +8 -0
  123. package/dist/lib/assets/locales/sl/translation.json.mjs +8 -0
  124. package/dist/lib/auth/AuthGuard.d.ts +6 -0
  125. package/dist/lib/auth/AuthGuard.mjs +26 -0
  126. package/dist/lib/auth/auth.context.d.ts +22 -0
  127. package/dist/lib/auth/auth.context.mjs +41 -0
  128. package/dist/lib/config/i18n.d.ts +32 -0
  129. package/dist/lib/config/i18n.mjs +31 -0
  130. package/dist/lib/config/queryConfig.context.d.ts +17 -0
  131. package/dist/lib/config/queryConfig.context.mjs +26 -0
  132. package/dist/lib/config/router.context.d.ts +9 -0
  133. package/dist/lib/config/router.context.mjs +20 -0
  134. package/dist/lib/react-query.types.d.ts +10 -0
  135. package/dist/lib/rest/error-handling.d.ts +30 -0
  136. package/dist/lib/rest/error-handling.mjs +132 -0
  137. package/dist/lib/rest/rest-client.d.ts +22 -0
  138. package/dist/lib/rest/rest-client.mjs +62 -0
  139. package/dist/lib/rest/rest-client.types.d.ts +23 -0
  140. package/dist/lib/rest/rest-interceptor.d.ts +8 -0
  141. package/dist/lib/rest/rest-interceptor.mjs +21 -0
  142. package/dist/lib/rest/rest.utils.d.ts +7 -0
  143. package/dist/lib/rest/rest.utils.mjs +51 -0
  144. package/dist/sh.d.ts +2 -0
  145. package/dist/sh.js +635 -0
  146. package/package.json +41 -47
  147. package/src/generators/templates/endpoints.hbs +1 -0
  148. package/src/generators/templates/partials/query-use-infinite-query.hbs +7 -5
  149. package/src/generators/templates/partials/query-use-query.hbs +4 -3
  150. package/dist/acl.d.mts +0 -48
  151. package/dist/auth.context-DKjzWiaA.mjs +0 -59
  152. package/dist/config-Cu_GYfai.d.mts +0 -6
  153. package/dist/generate.runner-CSqX4Uw7.mjs +0 -98
  154. package/dist/generateCodeFromOpenAPIDoc-BOjk_Ey8.mjs +0 -4522
  155. package/dist/generator.d.mts +0 -65
  156. package/dist/generator.mjs +0 -144
  157. package/dist/index.d.mts +0 -246
  158. package/dist/options-DBz5YE3s.d.mts +0 -90
  159. package/dist/sh.d.mts +0 -1
  160. package/dist/sh.mjs +0 -439
  161. package/dist/vite.d.mts +0 -8
  162. package/dist/vite.mjs +0 -50
@@ -0,0 +1,22 @@
1
+ import { PropsWithChildren, ReactNode } from 'react';
2
+ export declare namespace AuthContext {
3
+ export interface Routes {
4
+ authenticated?: string;
5
+ unauthenticated?: string;
6
+ }
7
+ interface Type<TUser = unknown> {
8
+ isAuthenticated: boolean;
9
+ isInitializing: boolean;
10
+ logout: () => void;
11
+ updateTokens?: (accessToken: string | null, refreshToken?: string | null) => void;
12
+ accessToken?: string | null;
13
+ user?: TUser | null;
14
+ userPromise?: () => Promise<TUser | null>;
15
+ routes?: Routes;
16
+ loadingState?: ReactNode;
17
+ }
18
+ type ProviderProps<TUser = unknown> = Type<TUser>;
19
+ export const Provider: <TUser>({ isAuthenticated, isInitializing, logout, updateTokens, accessToken, user, userPromise, routes, loadingState, children, }: PropsWithChildren<ProviderProps<TUser>>) => import("react/jsx-runtime").JSX.Element;
20
+ export const useAuth: <TUser>() => Type<TUser>;
21
+ export {};
22
+ }
@@ -0,0 +1,41 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createContext, useMemo, use } from "react";
3
+ var AuthContext;
4
+ ((AuthContext2) => {
5
+ const Context = createContext({});
6
+ AuthContext2.Provider = ({
7
+ isAuthenticated,
8
+ isInitializing,
9
+ logout,
10
+ updateTokens,
11
+ accessToken,
12
+ user,
13
+ userPromise,
14
+ routes,
15
+ loadingState,
16
+ children
17
+ }) => {
18
+ const value = useMemo(
19
+ () => ({
20
+ isAuthenticated,
21
+ isInitializing,
22
+ logout,
23
+ updateTokens,
24
+ accessToken,
25
+ user,
26
+ userPromise,
27
+ routes,
28
+ loadingState
29
+ }),
30
+ [isAuthenticated, isInitializing, logout, updateTokens, accessToken, user, userPromise, routes, loadingState]
31
+ );
32
+ return /* @__PURE__ */ jsx(Context.Provider, { value, children });
33
+ };
34
+ AuthContext2.useAuth = () => {
35
+ const auth = use(Context);
36
+ return auth;
37
+ };
38
+ })(AuthContext || (AuthContext = {}));
39
+ export {
40
+ AuthContext
41
+ };
@@ -0,0 +1,32 @@
1
+ export declare const ns = "openapi";
2
+ export declare const resources: {
3
+ readonly en: {
4
+ readonly openapi: {
5
+ openapi: {
6
+ sharedErrors: {
7
+ dataValidation: string;
8
+ internalError: string;
9
+ networkError: string;
10
+ canceledError: string;
11
+ unknownError: string;
12
+ unknownErrorWithCode: string;
13
+ };
14
+ };
15
+ };
16
+ };
17
+ readonly sl: {
18
+ readonly openapi: {
19
+ openapi: {
20
+ sharedErrors: {
21
+ dataValidation: string;
22
+ internalError: string;
23
+ networkError: string;
24
+ canceledError: string;
25
+ unknownError: string;
26
+ unknownErrorWithCode: string;
27
+ };
28
+ };
29
+ };
30
+ };
31
+ };
32
+ export declare const defaultT: import('i18next').TFunction<["translation", ...string[]], undefined>;
@@ -0,0 +1,31 @@
1
+ import i18next from "i18next";
2
+ import translationEN from "../assets/locales/en/translation.json.mjs";
3
+ import translationSL from "../assets/locales/sl/translation.json.mjs";
4
+ const ns = "openapi";
5
+ const resources = {
6
+ en: {
7
+ [ns]: translationEN
8
+ },
9
+ sl: {
10
+ [ns]: translationSL
11
+ }
12
+ };
13
+ const defaultLanguage = "en";
14
+ const i18n = i18next.createInstance();
15
+ i18n.init({
16
+ compatibilityJSON: "v4",
17
+ lng: defaultLanguage,
18
+ fallbackLng: defaultLanguage,
19
+ resources,
20
+ ns: Object.keys(resources.en),
21
+ defaultNS: ns,
22
+ interpolation: {
23
+ escapeValue: false
24
+ }
25
+ });
26
+ const defaultT = i18n.t.bind(i18n);
27
+ export {
28
+ defaultT,
29
+ ns,
30
+ resources
31
+ };
@@ -0,0 +1,17 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { QueryKey } from '@tanstack/react-query';
3
+ export type QueryModule = string | number | symbol;
4
+ export type InvalidationMapFunc<TData = any, TVariables = any> = (data: TData, variables: TVariables) => QueryKey[];
5
+ export type InvalidationMap<TData = any, TVariables = any> = Record<QueryModule, InvalidationMapFunc<TData, TVariables>>;
6
+ export declare namespace OpenApiQueryConfig {
7
+ interface Type {
8
+ preferUpdate?: boolean;
9
+ invalidateCurrentModule?: boolean;
10
+ invalidationMap?: InvalidationMap;
11
+ crossTabInvalidation?: boolean;
12
+ }
13
+ type ProviderProps = Type;
14
+ export const Provider: ({ preferUpdate, invalidateCurrentModule, invalidationMap, crossTabInvalidation, children, }: PropsWithChildren<ProviderProps>) => import("react/jsx-runtime").JSX.Element;
15
+ export const useConfig: () => Type;
16
+ export {};
17
+ }
@@ -0,0 +1,26 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createContext, useMemo, use } from "react";
3
+ var OpenApiQueryConfig;
4
+ ((OpenApiQueryConfig2) => {
5
+ const Context = createContext({});
6
+ OpenApiQueryConfig2.Provider = ({
7
+ preferUpdate,
8
+ invalidateCurrentModule,
9
+ invalidationMap,
10
+ crossTabInvalidation,
11
+ children
12
+ }) => {
13
+ const value = useMemo(
14
+ () => ({ preferUpdate, invalidateCurrentModule, invalidationMap, crossTabInvalidation }),
15
+ [preferUpdate, invalidateCurrentModule, invalidationMap, crossTabInvalidation]
16
+ );
17
+ return /* @__PURE__ */ jsx(Context.Provider, { value, children });
18
+ };
19
+ OpenApiQueryConfig2.useConfig = () => {
20
+ const context = use(Context);
21
+ return context ?? {};
22
+ };
23
+ })(OpenApiQueryConfig || (OpenApiQueryConfig = {}));
24
+ export {
25
+ OpenApiQueryConfig
26
+ };
@@ -0,0 +1,9 @@
1
+ import { PropsWithChildren } from 'react';
2
+ interface RouterProviderProps {
3
+ replace: (url: string) => void;
4
+ }
5
+ export declare namespace OpenApiRouter {
6
+ const Provider: ({ children, replace }: PropsWithChildren<RouterProviderProps>) => import("react/jsx-runtime").JSX.Element;
7
+ const useRouter: () => RouterProviderProps;
8
+ }
9
+ export {};
@@ -0,0 +1,20 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createContext, useMemo, use } from "react";
3
+ var OpenApiRouter;
4
+ ((OpenApiRouter2) => {
5
+ const Context = createContext(null);
6
+ OpenApiRouter2.Provider = ({ children, replace }) => {
7
+ const value = useMemo(() => ({ replace }), [replace]);
8
+ return /* @__PURE__ */ jsx(Context, { value, children });
9
+ };
10
+ OpenApiRouter2.useRouter = () => {
11
+ const context = use(Context);
12
+ if (!context) {
13
+ throw new Error("useRouter must be used within an OpenApiRouter.Provider");
14
+ }
15
+ return context;
16
+ };
17
+ })(OpenApiRouter || (OpenApiRouter = {}));
18
+ export {
19
+ OpenApiRouter
20
+ };
@@ -0,0 +1,10 @@
1
+ import { InfiniteData, QueryKey, UseInfiniteQueryOptions, UseMutationOptions, UseQueryOptions } from '@tanstack/react-query';
2
+ import { ApplicationException, GeneralErrorCodes } from './rest/error-handling';
3
+ type Function = (...args: any) => any;
4
+ type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;
5
+ type IsAny<T> = IfAny<T, true, never>;
6
+ type IsUnknown<T, Y, N = T> = IsAny<T> extends never ? (unknown extends T ? Y : N) : N;
7
+ export type AppQueryOptions<TFunction extends Function, TData = Awaited<ReturnType<TFunction>>, TErrorCodes = GeneralErrorCodes> = Omit<UseQueryOptions<Awaited<ReturnType<TFunction>>, ApplicationException<TErrorCodes>, IsUnknown<TData, Awaited<ReturnType<TFunction>>>>, "queryKey" | "queryFn">;
8
+ export type AppMutationOptions<TFunction extends Function, TVariables = void, TData = Awaited<ReturnType<TFunction>>, TErrorCodes = GeneralErrorCodes> = Omit<UseMutationOptions<TData, ApplicationException<TErrorCodes>, TVariables>, "mutationKey" | "mutationFn">;
9
+ export type AppInfiniteQueryOptions<TFunction extends Function, TData = InfiniteData<Awaited<ReturnType<TFunction>>>, TErrorCodes = GeneralErrorCodes, TQueryKey extends QueryKey = QueryKey, TPageParam = number> = Omit<UseInfiniteQueryOptions<Awaited<ReturnType<TFunction>>, ApplicationException<TErrorCodes>, IsUnknown<TData, InfiniteData<Awaited<ReturnType<TFunction>>>>, TQueryKey, TPageParam>, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam">;
10
+ export {};
@@ -0,0 +1,30 @@
1
+ import { TFunction } from 'i18next';
2
+ export type GeneralErrorCodes = "DATA_VALIDATION_ERROR" | "NETWORK_ERROR" | "CANCELED_ERROR" | "INTERNAL_ERROR" | "UNKNOWN_ERROR";
3
+ export declare class ApplicationException<CodeT> extends Error {
4
+ code: CodeT;
5
+ serverMessage: string | null;
6
+ constructor(message: string, code: CodeT, serverMessage: string | null);
7
+ }
8
+ export interface ErrorEntry<CodeT> {
9
+ code: CodeT;
10
+ condition?: (error: unknown) => boolean;
11
+ getMessage: (t: TFunction<string, undefined>, error: unknown) => string;
12
+ }
13
+ export interface ErrorHandlerOptions<CodeT extends string> {
14
+ entries: ErrorEntry<CodeT>[];
15
+ t?: TFunction<string, undefined>;
16
+ onRethrowError?: (error: unknown, exception: ApplicationException<CodeT | GeneralErrorCodes>) => void;
17
+ }
18
+ export declare class ErrorHandler<CodeT extends string> {
19
+ entries: ErrorEntry<CodeT | GeneralErrorCodes>[];
20
+ private t;
21
+ private onRethrowError?;
22
+ constructor({ entries, t, onRethrowError }: ErrorHandlerOptions<CodeT>);
23
+ private matchesEntry;
24
+ setTranslateFunction(t: TFunction<string, undefined>): void;
25
+ rethrowError(error: unknown): ApplicationException<CodeT | GeneralErrorCodes>;
26
+ getError(error: unknown): ApplicationException<CodeT | GeneralErrorCodes> | null;
27
+ getErrorCode(error: unknown): CodeT | GeneralErrorCodes | null;
28
+ static getErrorMessage(error: unknown, fallbackToUnknown?: boolean): string | null;
29
+ }
30
+ export declare const SharedErrorHandler: ErrorHandler<never>;
@@ -0,0 +1,132 @@
1
+ import { isAxiosError, isCancel } from "axios";
2
+ import { z } from "zod";
3
+ import { defaultT } from "../config/i18n.mjs";
4
+ import { RestUtils } from "./rest.utils.mjs";
5
+ class ApplicationException extends Error {
6
+ code;
7
+ serverMessage = null;
8
+ constructor(message, code, serverMessage) {
9
+ super(message);
10
+ this.code = code;
11
+ this.serverMessage = serverMessage;
12
+ }
13
+ }
14
+ class ErrorHandler {
15
+ entries = [];
16
+ t;
17
+ onRethrowError;
18
+ constructor({ entries, t = defaultT, onRethrowError }) {
19
+ this.t = t;
20
+ this.onRethrowError = onRethrowError;
21
+ const dataValidationError = {
22
+ code: "DATA_VALIDATION_ERROR",
23
+ condition: (e) => {
24
+ return e instanceof z.ZodError;
25
+ },
26
+ getMessage: () => this.t("openapi.sharedErrors.dataValidation")
27
+ };
28
+ const internalError = {
29
+ code: "INTERNAL_ERROR",
30
+ condition: (e) => {
31
+ if (isAxiosError(e)) {
32
+ return e.response?.status != null && e.response.status >= 500 && e.response.status < 600;
33
+ }
34
+ return false;
35
+ },
36
+ getMessage: () => this.t("openapi.sharedErrors.internalError")
37
+ };
38
+ const networkError = {
39
+ code: "NETWORK_ERROR",
40
+ condition: (e) => {
41
+ if (isAxiosError(e)) {
42
+ return e.code === "ERR_NETWORK";
43
+ }
44
+ return false;
45
+ },
46
+ getMessage: () => this.t("openapi.sharedErrors.networkError")
47
+ };
48
+ const canceledError = {
49
+ code: "CANCELED_ERROR",
50
+ condition: (e) => {
51
+ if (isCancel(e)) {
52
+ return true;
53
+ }
54
+ if (isAxiosError(e) && e.code === "ECONNABORTED") {
55
+ return true;
56
+ }
57
+ return false;
58
+ },
59
+ getMessage: () => this.t("openapi.sharedErrors.canceledError")
60
+ };
61
+ const unknownError = {
62
+ code: "UNKNOWN_ERROR",
63
+ condition: () => true,
64
+ getMessage: (_, e) => {
65
+ const code = RestUtils.extractServerResponseCode(e);
66
+ const serverMessage = RestUtils.extractServerErrorMessage(e);
67
+ if (code) {
68
+ let message = `Unknown error, message from server: ${code}`;
69
+ if (serverMessage) {
70
+ message += ` ${serverMessage}`;
71
+ }
72
+ return message;
73
+ }
74
+ return this.t("openapi.sharedErrors.unknownError");
75
+ }
76
+ };
77
+ this.entries = [...entries, dataValidationError, internalError, networkError, canceledError, unknownError];
78
+ }
79
+ matchesEntry(error, entry, code) {
80
+ if (entry.condition) {
81
+ return entry.condition(error);
82
+ }
83
+ return code === entry.code;
84
+ }
85
+ setTranslateFunction(t) {
86
+ this.t = t;
87
+ }
88
+ rethrowError(error) {
89
+ const code = RestUtils.extractServerResponseCode(error);
90
+ const errorEntry = this.entries.find((entry) => this.matchesEntry(error, entry, code));
91
+ const serverMessage = RestUtils.extractServerErrorMessage(error);
92
+ const exception = new ApplicationException(errorEntry.getMessage(this.t, error), errorEntry.code, serverMessage);
93
+ this.onRethrowError?.(error, exception);
94
+ throw exception;
95
+ }
96
+ getError(error) {
97
+ if (error instanceof ApplicationException) {
98
+ return error;
99
+ }
100
+ return null;
101
+ }
102
+ getErrorCode(error) {
103
+ if (error instanceof ApplicationException) {
104
+ return error.code;
105
+ }
106
+ return null;
107
+ }
108
+ static getErrorMessage(error, fallbackToUnknown = true) {
109
+ if (typeof error === "string") {
110
+ return error;
111
+ }
112
+ if (error instanceof Error) {
113
+ return error.message;
114
+ }
115
+ if (error instanceof ApplicationException) {
116
+ if (error.serverMessage != null) {
117
+ return error.serverMessage;
118
+ }
119
+ return error.message;
120
+ }
121
+ if (fallbackToUnknown) {
122
+ return defaultT("openapi.sharedErrors.unknownError");
123
+ }
124
+ return null;
125
+ }
126
+ }
127
+ const SharedErrorHandler = new ErrorHandler({ entries: [] });
128
+ export {
129
+ ApplicationException,
130
+ ErrorHandler,
131
+ SharedErrorHandler
132
+ };
@@ -0,0 +1,22 @@
1
+ import { AxiosRequestConfig, CreateAxiosDefaults } from 'axios';
2
+ import { ErrorHandler, GeneralErrorCodes } from './error-handling';
3
+ import { RestClient as IRestClient, RequestConfig, RequestInfo, Response } from './rest-client.types';
4
+ import { RestInterceptor } from './rest-interceptor';
5
+ export declare class RestClient implements IRestClient {
6
+ private readonly client;
7
+ private readonly errorHandler;
8
+ constructor({ config, interceptors, errorHandler, }?: {
9
+ config?: CreateAxiosDefaults;
10
+ interceptors?: RestInterceptor<any[]>[];
11
+ errorHandler?: ErrorHandler<any>;
12
+ });
13
+ attachInterceptors<T extends any[]>(interceptors?: RestInterceptor<T>[], ...args: T): void;
14
+ attachInterceptor<T extends any[]>(interceptor: RestInterceptor<T>, ...args: T): void;
15
+ ejectInterceptor<T extends any[]>(interceptor: RestInterceptor<T>): void;
16
+ get<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
17
+ post<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
18
+ patch<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
19
+ put<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
20
+ delete<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
21
+ private makeRequest;
22
+ }
@@ -0,0 +1,62 @@
1
+ import axios from "axios";
2
+ import { z } from "zod";
3
+ import { SharedErrorHandler } from "./error-handling.mjs";
4
+ class RestClient {
5
+ client;
6
+ errorHandler;
7
+ constructor({
8
+ config,
9
+ interceptors,
10
+ errorHandler
11
+ } = {}) {
12
+ this.client = axios.create(config);
13
+ this.errorHandler = errorHandler ?? SharedErrorHandler;
14
+ this.attachInterceptors(interceptors);
15
+ }
16
+ attachInterceptors(interceptors, ...args) {
17
+ if (interceptors != null) {
18
+ interceptors.forEach((interceptor) => this.attachInterceptor(interceptor, ...args));
19
+ }
20
+ }
21
+ attachInterceptor(interceptor, ...args) {
22
+ interceptor.addInterceptor(this.client, ...args);
23
+ }
24
+ ejectInterceptor(interceptor) {
25
+ interceptor.removeInterceptor(this.client);
26
+ }
27
+ async get(requestInfo, url, requestConfig) {
28
+ return this.makeRequest(requestInfo, { ...requestConfig, method: "get", url });
29
+ }
30
+ async post(requestInfo, url, data, requestConfig) {
31
+ return this.makeRequest(requestInfo, { ...requestConfig, method: "post", url, data });
32
+ }
33
+ async patch(requestInfo, url, data, requestConfig) {
34
+ return this.makeRequest(requestInfo, { ...requestConfig, method: "patch", url, data });
35
+ }
36
+ async put(requestInfo, url, data, requestConfig) {
37
+ return this.makeRequest(requestInfo, { ...requestConfig, method: "put", url, data });
38
+ }
39
+ async delete(requestInfo, url, data, requestConfig) {
40
+ return this.makeRequest(requestInfo, { ...requestConfig, method: "delete", url, data });
41
+ }
42
+ async makeRequest(requestInfo, requestConfig) {
43
+ const errorStack = new Error().stack;
44
+ try {
45
+ const { rawResponse, ...config } = requestConfig;
46
+ const res = await this.client(config);
47
+ const resData = requestInfo.resSchema.parse(res.data);
48
+ return rawResponse ? { ...res, data: resData } : resData;
49
+ } catch (error) {
50
+ if (error instanceof z.ZodError) {
51
+ error.name = "BE Response schema mismatch - ZodError";
52
+ error.stack = [error.stack, ...errorStack?.split("\n").slice(2) ?? []].join("\n");
53
+ }
54
+ const errorHandler = requestInfo.errorHandler ?? this.errorHandler;
55
+ errorHandler.rethrowError(error);
56
+ throw error;
57
+ }
58
+ }
59
+ }
60
+ export {
61
+ RestClient
62
+ };
@@ -0,0 +1,23 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
+ import { z } from 'zod';
3
+ import { ErrorHandler } from './error-handling';
4
+ import { RestInterceptor } from './rest-interceptor';
5
+ export type GeneralErrorCodes = string;
6
+ export interface RequestInfo<ZOutput, ECodes extends string> {
7
+ resSchema: z.ZodType<ZOutput>;
8
+ errorHandler?: ErrorHandler<ECodes>;
9
+ }
10
+ export interface RequestConfig<IsRawRes extends boolean = false> {
11
+ rawResponse?: IsRawRes;
12
+ }
13
+ export type Response<ZOutput, IsRawRes extends boolean = false> = IsRawRes extends true ? AxiosResponse<ZOutput> : ZOutput;
14
+ export interface RestClient {
15
+ attachInterceptors<T extends any[]>(interceptors?: RestInterceptor<T>[], ...args: T): void;
16
+ attachInterceptor<T extends any[]>(interceptor: RestInterceptor<T>, ...args: T): void;
17
+ ejectInterceptor<T extends any[]>(interceptor: RestInterceptor<T>): void;
18
+ get<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
19
+ post<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
20
+ patch<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
21
+ put<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
22
+ delete<ZOutput, ECodes extends string = GeneralErrorCodes, IsRawRes extends boolean = false>(requestInfo: RequestInfo<ZOutput, ECodes>, url: string, data?: any, requestConfig?: AxiosRequestConfig & RequestConfig<IsRawRes>): Promise<Response<ZOutput, IsRawRes>>;
23
+ }
@@ -0,0 +1,8 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export declare class RestInterceptor<T extends any[]> {
3
+ private applyInterceptor;
4
+ private interceptorIdMap;
5
+ constructor(applyInterceptor: (client: AxiosInstance, ...args: T) => number);
6
+ addInterceptor(client: AxiosInstance, ...args: T): void;
7
+ removeInterceptor(client: AxiosInstance): void;
8
+ }
@@ -0,0 +1,21 @@
1
+ class RestInterceptor {
2
+ constructor(applyInterceptor) {
3
+ this.applyInterceptor = applyInterceptor;
4
+ }
5
+ interceptorIdMap = [];
6
+ addInterceptor(client, ...args) {
7
+ this.removeInterceptor(client);
8
+ const interceptorId = this.applyInterceptor(client, ...args);
9
+ this.interceptorIdMap.push({ client, interceptorId });
10
+ }
11
+ removeInterceptor(client) {
12
+ const interceptorId = this.interceptorIdMap.find((i) => i.client === client)?.interceptorId;
13
+ if (interceptorId != null) {
14
+ client.interceptors.request.eject(interceptorId);
15
+ this.interceptorIdMap = this.interceptorIdMap.filter((i) => i.client !== client);
16
+ }
17
+ }
18
+ }
19
+ export {
20
+ RestInterceptor
21
+ };
@@ -0,0 +1,7 @@
1
+ import { AxiosError, AxiosResponseHeaders } from 'axios';
2
+ export declare namespace RestUtils {
3
+ const extractServerResponseCode: (e: unknown) => string | null;
4
+ const doesServerErrorMessageContain: (e: AxiosError, text: string) => boolean;
5
+ const extractServerErrorMessage: (e: unknown) => string | null;
6
+ const extractContentDispositionFilename: (headers: AxiosResponseHeaders) => string | undefined;
7
+ }
@@ -0,0 +1,51 @@
1
+ import { isAxiosError } from "axios";
2
+ import { z } from "zod";
3
+ var RestUtils;
4
+ ((RestUtils2) => {
5
+ RestUtils2.extractServerResponseCode = (e) => {
6
+ if (e instanceof z.ZodError) {
7
+ return "validation-exception";
8
+ }
9
+ if (!isAxiosError(e)) {
10
+ return null;
11
+ }
12
+ if (!e.response) {
13
+ return null;
14
+ }
15
+ const data = e.response.data;
16
+ if (typeof data?.code === "string") {
17
+ return data.code;
18
+ }
19
+ return null;
20
+ };
21
+ RestUtils2.doesServerErrorMessageContain = (e, text) => {
22
+ const message = (0, RestUtils2.extractServerErrorMessage)(e);
23
+ if (message === null || message === void 0) {
24
+ return false;
25
+ }
26
+ return message.toLowerCase().includes(text.toLowerCase());
27
+ };
28
+ RestUtils2.extractServerErrorMessage = (e) => {
29
+ if (e instanceof z.ZodError) {
30
+ return e.message;
31
+ }
32
+ if (!isAxiosError(e)) {
33
+ return null;
34
+ }
35
+ if (!e.response) {
36
+ return null;
37
+ }
38
+ const data = e.response.data;
39
+ if (typeof data?.message === "string") {
40
+ return data.message;
41
+ }
42
+ return null;
43
+ };
44
+ RestUtils2.extractContentDispositionFilename = (headers) => {
45
+ const contentDisposition = headers["content-disposition"];
46
+ return contentDisposition ? /filename=["']?([^"';]+)/i.exec(contentDisposition)?.[1] : void 0;
47
+ };
48
+ })(RestUtils || (RestUtils = {}));
49
+ export {
50
+ RestUtils
51
+ };
package/dist/sh.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};