@hywax/cms 2.0.2 → 3.0.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.
Files changed (53) hide show
  1. package/.nuxt/cms/form-panel-section.ts +2 -2
  2. package/.nuxt/cms/{input-uplora-image.ts → form-uplora-image.ts} +2 -9
  3. package/.nuxt/cms/http-statuses.ts +59 -0
  4. package/.nuxt/cms/index.ts +4 -4
  5. package/.nuxt/cms.css +3 -3
  6. package/dist/module.d.mts +5 -2
  7. package/dist/module.json +1 -1
  8. package/dist/module.mjs +77 -46
  9. package/dist/runtime/components/DatePicker.vue +13 -1
  10. package/dist/runtime/components/FormPanel.vue +2 -0
  11. package/dist/runtime/components/{InputSeo.d.vue.ts → FormSeo.d.vue.ts} +10 -8
  12. package/dist/runtime/components/{InputSeo.vue → FormSeo.vue} +18 -8
  13. package/dist/runtime/components/{InputSeo.vue.d.ts → FormSeo.vue.d.ts} +10 -8
  14. package/dist/runtime/components/{InputSlug.vue.d.ts → FormSlug.d.vue.ts} +12 -8
  15. package/dist/runtime/components/{InputSlug.vue → FormSlug.vue} +17 -8
  16. package/dist/runtime/components/{InputSlug.d.vue.ts → FormSlug.vue.d.ts} +12 -8
  17. package/dist/runtime/components/FormUploraImage.d.vue.ts +43 -0
  18. package/dist/runtime/components/FormUploraImage.vue +172 -0
  19. package/dist/runtime/components/FormUploraImage.vue.d.ts +43 -0
  20. package/dist/runtime/components/TablePreviewLink.d.vue.ts +13 -0
  21. package/dist/runtime/components/TablePreviewLink.vue +38 -0
  22. package/dist/runtime/components/TablePreviewLink.vue.d.ts +13 -0
  23. package/dist/runtime/composables/useTableColumns.d.ts +3 -2
  24. package/dist/runtime/composables/useTableColumns.js +11 -12
  25. package/dist/runtime/editor/uplora-image/EditorUploraImageNode.vue +2 -2
  26. package/dist/runtime/server/api/uplora/[id].delete.js +1 -1
  27. package/dist/runtime/server/api/uplora/index.post.js +2 -4
  28. package/dist/runtime/server/errors/HttpError.d.ts +8 -0
  29. package/dist/runtime/server/errors/HttpError.js +7 -0
  30. package/dist/runtime/server/errors/index.d.ts +1 -1
  31. package/dist/runtime/server/errors/index.js +1 -1
  32. package/dist/runtime/server/utils/http.d.ts +43 -0
  33. package/dist/runtime/server/utils/http.js +86 -0
  34. package/dist/runtime/server/utils/validation.js +6 -7
  35. package/dist/runtime/types/index.d.ts +3 -3
  36. package/dist/runtime/types/index.js +3 -3
  37. package/dist/runtime/utils/enums.d.ts +4 -0
  38. package/dist/runtime/utils/enums.js +6 -0
  39. package/dist/runtime/utils/index.d.ts +1 -0
  40. package/dist/runtime/utils/index.js +1 -0
  41. package/package.json +7 -6
  42. package/.nuxt/cms/http-codes.ts +0 -8
  43. package/dist/runtime/components/InputUploraImage.d.vue.ts +0 -40
  44. package/dist/runtime/components/InputUploraImage.vue +0 -181
  45. package/dist/runtime/components/InputUploraImage.vue.d.ts +0 -40
  46. package/dist/runtime/server/errors/InternalHttpError.d.ts +0 -8
  47. package/dist/runtime/server/errors/InternalHttpError.js +0 -7
  48. package/dist/runtime/server/utils/errors.d.ts +0 -8
  49. package/dist/runtime/server/utils/errors.js +0 -57
  50. package/dist/runtime/server/utils/httpHandler.d.ts +0 -10
  51. package/dist/runtime/server/utils/httpHandler.js +0 -15
  52. /package/.nuxt/cms/{input-seo.ts → form-seo.ts} +0 -0
  53. /package/.nuxt/cms/{input-slug.ts → form-slug.ts} +0 -0
@@ -1,9 +1,8 @@
1
- import { HTTP_CODE_BAD_REQUEST } from "#cms/http-codes";
2
1
  import { readMultipartFormData } from "h3";
3
- import { InternalHttpError } from "../errors/InternalHttpError.js";
2
+ import { createHttpError } from "./http.js";
4
3
  export function getValidatedSort(query, availableColumns) {
5
4
  if (!query.sortColumn || !availableColumns.includes(query.sortColumn)) {
6
- throw new InternalHttpError(HTTP_CODE_BAD_REQUEST);
5
+ throw createHttpError("badRequest");
7
6
  }
8
7
  const sortType = query.sortType === "asc" ? "asc" : "desc";
9
8
  const sortColumn = query.sortColumn;
@@ -15,7 +14,7 @@ export function getValidatedSort(query, availableColumns) {
15
14
  export function getValidatedPagination(query) {
16
15
  const perPage = Number(query.perPage);
17
16
  if (!Number.isInteger(perPage) || perPage < 1 || perPage > 100) {
18
- throw new InternalHttpError(HTTP_CODE_BAD_REQUEST);
17
+ throw createHttpError("badRequest");
19
18
  }
20
19
  const page = Number(query.page) || 1;
21
20
  const pageOffset = (page - 1) * perPage;
@@ -28,7 +27,7 @@ export function getValidatedPagination(query) {
28
27
  export async function readValidatedMultipartFormData(event, validate) {
29
28
  const formData = await readMultipartFormData(event);
30
29
  if (!formData) {
31
- throw new InternalHttpError(HTTP_CODE_BAD_REQUEST);
30
+ throw createHttpError("badRequest");
32
31
  }
33
32
  try {
34
33
  const transformedFormData = {};
@@ -42,13 +41,13 @@ export async function readValidatedMultipartFormData(event, validate) {
42
41
  }
43
42
  const res = await validate(transformedFormData);
44
43
  if (res === false) {
45
- throw new InternalHttpError(HTTP_CODE_BAD_REQUEST);
44
+ throw createHttpError("badRequest");
46
45
  }
47
46
  if (res === true) {
48
47
  return formData;
49
48
  }
50
49
  return res ?? formData;
51
50
  } catch (error) {
52
- throw new InternalHttpError(HTTP_CODE_BAD_REQUEST, { cause: error });
51
+ throw createHttpError("badRequest", { cause: error });
53
52
  }
54
53
  }
@@ -7,9 +7,9 @@ export * from '../components/EditorLinkPopover.vue';
7
7
  export * from '../components/FormPanel.vue';
8
8
  export * from '../components/FormPanelAsideSection.vue';
9
9
  export * from '../components/FormPanelSection.vue';
10
- export * from '../components/InputSeo.vue';
11
- export * from '../components/InputSlug.vue';
12
- export * from '../components/InputUploraImage.vue';
10
+ export * from '../components/FormSeo.vue';
11
+ export * from '../components/FormSlug.vue';
12
+ export * from '../components/FormUploraImage.vue';
13
13
  export * from '../components/Layout.vue';
14
14
  export * from '../components/ModalConfirm.vue';
15
15
  export * from '../components/prose/UploraImage.vue';
@@ -7,9 +7,9 @@ export * from "../components/EditorLinkPopover.vue";
7
7
  export * from "../components/FormPanel.vue";
8
8
  export * from "../components/FormPanelAsideSection.vue";
9
9
  export * from "../components/FormPanelSection.vue";
10
- export * from "../components/InputSeo.vue";
11
- export * from "../components/InputSlug.vue";
12
- export * from "../components/InputUploraImage.vue";
10
+ export * from "../components/FormSeo.vue";
11
+ export * from "../components/FormSlug.vue";
12
+ export * from "../components/FormUploraImage.vue";
13
13
  export * from "../components/Layout.vue";
14
14
  export * from "../components/ModalConfirm.vue";
15
15
  export * from "../components/prose/UploraImage.vue";
@@ -0,0 +1,4 @@
1
+ export declare function createEnumItems<T extends Record<any, string>>(labels: T): Array<{
2
+ value: keyof T;
3
+ label: string;
4
+ }>;
@@ -0,0 +1,6 @@
1
+ export function createEnumItems(labels) {
2
+ return Object.entries(labels).map(([value, label]) => ({
3
+ value,
4
+ label
5
+ }));
6
+ }
@@ -1,6 +1,7 @@
1
1
  export * from './auth';
2
2
  export * from './avatar';
3
3
  export * from './date';
4
+ export * from './enums';
4
5
  export * from './formatters';
5
6
  export * from './logger';
6
7
  export * from './slugify';
@@ -1,6 +1,7 @@
1
1
  export * from "./auth.js";
2
2
  export * from "./avatar.js";
3
3
  export * from "./date.js";
4
+ export * from "./enums.js";
4
5
  export * from "./formatters.js";
5
6
  export * from "./logger.js";
6
7
  export * from "./slugify.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hywax/cms",
3
3
  "type": "module",
4
- "version": "2.0.2",
4
+ "version": "3.0.0",
5
5
  "description": "Hywax CMS. ⚠️ This package is intended for internal use only.",
6
6
  "imports": {
7
7
  "#build/cms/*": "./.nuxt/cms/*.ts",
@@ -48,7 +48,8 @@
48
48
  ],
49
49
  "peerDependencies": {
50
50
  "@unovis/ts": "^1.6.2",
51
- "@unovis/vue": "^1.6.2"
51
+ "@unovis/vue": "^1.6.2",
52
+ "drizzle-orm": "^0.45.1"
52
53
  },
53
54
  "peerDependenciesMeta": {
54
55
  "@unovis/ts": {
@@ -79,16 +80,16 @@
79
80
  "scule": "^1.3.0",
80
81
  "sortablejs": "^1.15.6",
81
82
  "tinyglobby": "^0.2.15",
82
- "zod": "^4.3.4"
83
+ "zod": "^4.3.5"
83
84
  },
84
85
  "devDependencies": {
85
- "@antfu/eslint-config": "^5.4.1",
86
+ "@antfu/eslint-config": "^6.7.3",
86
87
  "@commitlint/cli": "^20.3.0",
87
88
  "@commitlint/config-conventional": "^20.3.0",
88
89
  "@nuxt/devtools": "^3.1.1",
89
90
  "@nuxt/module-builder": "^1.0.2",
90
91
  "@nuxt/schema": "^4.2.2",
91
- "@nuxt/test-utils": "^3.21.0",
92
+ "@nuxt/test-utils": "^3.23.0",
92
93
  "@types/sortablejs": "^1.15.9",
93
94
  "@vue/test-utils": "^2.4.6",
94
95
  "changelogen-monorepo": "^0.5.0",
@@ -99,7 +100,7 @@
99
100
  "nuxt": "^4.2.2",
100
101
  "typescript": "^5.9.3",
101
102
  "vitest": "^3.2.4",
102
- "vue-tsc": "^3.2.1"
103
+ "vue-tsc": "^3.2.2"
103
104
  },
104
105
  "resolutions": {
105
106
  "@hywax/cms": "workspace:*"
@@ -1,8 +0,0 @@
1
- export const HTTP_CODE_BAD_REQUEST = '400: Неверный запрос'
2
- export const HTTP_CODE_UNAUTHORIZED = '401: Не авторизован'
3
- export const HTTP_CODE_FORBIDDEN = '403: Доступ запрещен'
4
- export const HTTP_CODE_NOT_FOUND = '404: Не найдено'
5
- export const HTTP_CODE_REQUEST_TIMEOUT = '408: Время ожидания запроса истекло'
6
- export const HTTP_CODE_INTERNAL_SERVER_ERROR = '500: Внутренняя ошибка сервера'
7
- export const HTTP_CODE_BAD_GATEWAY = '502: Ошибка шлюза'
8
- export const HTTP_CODE_SERVICE_UNAVAILABLE = '503: Сервис недоступен'
@@ -1,40 +0,0 @@
1
- import type { AppConfig } from '@nuxt/schema';
2
- import type { ComponentConfig } from '../types';
3
- import theme from '#build/cms/input-uplora-image';
4
- type InputUploraImage = ComponentConfig<typeof theme, AppConfig, 'inputUploraImage'>;
5
- export interface InputUploraImageProps {
6
- showExtensions?: boolean;
7
- id?: string;
8
- name?: string;
9
- disabled?: boolean;
10
- as?: any;
11
- class?: any;
12
- ui?: InputUploraImage['slots'];
13
- }
14
- export interface InputUploraImageEmits {
15
- upload: [InputUploraImageModelValue];
16
- delete: [];
17
- }
18
- export interface InputUploraImageModelValue {
19
- image?: string;
20
- alt?: string;
21
- color?: string;
22
- lqip?: string;
23
- }
24
- declare const _default: typeof __VLS_export;
25
- export default _default;
26
- declare const __VLS_export: import("vue").DefineComponent<InputUploraImageProps & {
27
- modelValue?: InputUploraImageModelValue;
28
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
29
- delete: () => any;
30
- "update:modelValue": (value: InputUploraImageModelValue) => any;
31
- upload: (args_0: InputUploraImageModelValue) => any;
32
- }, string, import("vue").PublicProps, Readonly<InputUploraImageProps & {
33
- modelValue?: InputUploraImageModelValue;
34
- }> & Readonly<{
35
- onDelete?: (() => any) | undefined;
36
- "onUpdate:modelValue"?: ((value: InputUploraImageModelValue) => any) | undefined;
37
- onUpload?: ((args_0: InputUploraImageModelValue) => any) | undefined;
38
- }>, {
39
- showExtensions: boolean;
40
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,181 +0,0 @@
1
- <template>
2
- <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
3
- <template v-if="modelValue.image">
4
- <UPopover
5
- :content="{ align: 'center', side: 'top', sideOffset: 8 }"
6
- :ui="{ content: 'p-1' }"
7
- >
8
- <CUploraImage
9
- :image="modelValue.image"
10
- :alt="modelValue.alt"
11
- :color="modelValue.color"
12
- :lqip="modelValue.lqip"
13
- :class="ui.image({ class: [props.ui?.image] })"
14
- />
15
-
16
- <div v-if="!modelValue.alt" :class="ui.imageActionsWarning({ class: [props.ui?.imageActionsWarning] })">
17
- <UIcon :name="appConfig.ui.icons.warning" class="size-4" />
18
- </div>
19
-
20
- <template #content>
21
- <div class="flex items-center gap-0.5">
22
- <UPopover :ui="{ content: 'p-1' }" @update:open="syncState">
23
- <UButton
24
- color="neutral"
25
- size="sm"
26
- variant="ghost"
27
- :icon="appConfig.ui.icons.editLine"
28
- />
29
- <template #content>
30
- <UTextarea
31
- v-model="state.alt"
32
- placeholder="Введите описание..."
33
- autoresize
34
- variant="none"
35
- size="xs"
36
- />
37
- </template>
38
- </UPopover>
39
-
40
- <UButton
41
- color="neutral"
42
- size="sm"
43
- variant="ghost"
44
- :icon="appConfig.ui.icons.refresh"
45
- @click="resetState()"
46
- />
47
-
48
- <ButtonDeleteConfirm
49
- color="error"
50
- size="sm"
51
- variant="ghost"
52
- label=""
53
- :icon="appConfig.ui.icons.trash"
54
- @confirm="deleteExecute(modelValue.image)"
55
- />
56
- </div>
57
- </template>
58
- </UPopover>
59
- </template>
60
- <div v-else :id="id" :class="ui.uploader({ class: [props.ui?.uploader] })">
61
- <template v-if="uploadStatus === 'pending'">
62
- <UIcon :name="appConfig.ui.icons.loading" :class="ui.uploaderPendingIcon({ class: [props.ui?.uploaderPendingIcon] })" />
63
- </template>
64
- <template v-else-if="uploadStatus === 'idle'">
65
- <button
66
- type="button"
67
- :class="ui.uploaderIdleButton({ class: [props.ui?.uploaderIdleButton] })"
68
- :disabled="disabled"
69
- v-bind="ariaAttrs"
70
- @click="open"
71
- >
72
- <UAvatar :icon="appConfig.ui.icons.image" size="lg" />
73
-
74
- <p :class="ui.uploaderIdleText({ class: [props.ui?.uploaderIdleText] })">
75
- Загрузить изображение
76
- </p>
77
- <p :class="ui.uploaderIdleExtensions({ class: [props.ui?.uploaderIdleExtensions] })">
78
- {{ extensions }}
79
- </p>
80
- </button>
81
- </template>
82
- <template v-else-if="uploadStatus === 'error'">
83
- <p :class="ui.uploaderErrorText({ class: [props.ui?.uploaderErrorText] })">
84
- Произошла ошибка при загрузке изображения
85
- </p>
86
- <div :class="ui.uploaderErrorActions({ class: [props.ui?.uploaderErrorActions] })">
87
- <UButton
88
- label="Отменить"
89
- variant="ghost"
90
- color="neutral"
91
- @click="resetUpload"
92
- />
93
- <UButton
94
- label="Повторить"
95
- variant="soft"
96
- color="neutral"
97
- @click="uploadExecute"
98
- />
99
- </div>
100
- </template>
101
- </div>
102
- </Primitive>
103
- </template>
104
-
105
- <script>
106
- import theme from "#build/cms/input-uplora-image";
107
- import { useAppConfig, useFormField, useUploraDelete, useUploraUpload } from "#imports";
108
- import { imagesExtensions } from "@uplora/formats";
109
- import { Primitive } from "reka-ui";
110
- import { computed, reactive, useId } from "vue";
111
- import { tv } from "../tv";
112
- import ButtonDeleteConfirm from "./ButtonDeleteConfirm.vue";
113
- </script>
114
-
115
- <script setup>
116
- const props = defineProps({
117
- showExtensions: { type: Boolean, required: false, default: true },
118
- id: { type: String, required: false },
119
- name: { type: String, required: false },
120
- disabled: { type: Boolean, required: false },
121
- as: { type: null, required: false },
122
- class: { type: null, required: false },
123
- ui: { type: null, required: false }
124
- });
125
- const emit = defineEmits(["upload", "delete"]);
126
- const modelValue = defineModel({ type: Object, ...{
127
- default: () => ({
128
- image: void 0,
129
- alt: void 0,
130
- lqip: void 0,
131
- color: void 0
132
- })
133
- } });
134
- const appConfig = useAppConfig();
135
- const extensions = computed(() => imagesExtensions.filter((extension) => extension !== "jpeg").join(", "));
136
- const state = reactive({
137
- alt: modelValue.value.alt
138
- });
139
- const { id: _id, disabled, emitFormChange, emitFormInput, ariaAttrs } = useFormField(props);
140
- const id = _id.value ?? useId();
141
- const { open, execute: uploadExecute, status: uploadStatus, reset: resetUpload, onUploaded } = useUploraUpload({
142
- accept: "image/*"
143
- });
144
- const { execute: deleteExecute, onDeleted } = useUploraDelete();
145
- function syncState() {
146
- modelValue.value = {
147
- ...modelValue.value,
148
- alt: state.alt || void 0
149
- };
150
- }
151
- function resetState() {
152
- modelValue.value = {
153
- image: void 0,
154
- alt: void 0,
155
- lqip: void 0,
156
- color: void 0
157
- };
158
- emitFormChange();
159
- emitFormInput();
160
- }
161
- onUploaded((file) => {
162
- modelValue.value = {
163
- ...modelValue.value,
164
- image: file.id,
165
- lqip: file.lqip,
166
- color: file.color
167
- };
168
- emit("upload", modelValue.value);
169
- emitFormChange();
170
- emitFormInput();
171
- });
172
- onDeleted(() => {
173
- resetUpload();
174
- resetState();
175
- emit("delete");
176
- });
177
- const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.inputUploraImage || {} })({
178
- disabled: disabled.value,
179
- uploaded: modelValue.value.image !== ""
180
- }));
181
- </script>
@@ -1,40 +0,0 @@
1
- import type { AppConfig } from '@nuxt/schema';
2
- import type { ComponentConfig } from '../types';
3
- import theme from '#build/cms/input-uplora-image';
4
- type InputUploraImage = ComponentConfig<typeof theme, AppConfig, 'inputUploraImage'>;
5
- export interface InputUploraImageProps {
6
- showExtensions?: boolean;
7
- id?: string;
8
- name?: string;
9
- disabled?: boolean;
10
- as?: any;
11
- class?: any;
12
- ui?: InputUploraImage['slots'];
13
- }
14
- export interface InputUploraImageEmits {
15
- upload: [InputUploraImageModelValue];
16
- delete: [];
17
- }
18
- export interface InputUploraImageModelValue {
19
- image?: string;
20
- alt?: string;
21
- color?: string;
22
- lqip?: string;
23
- }
24
- declare const _default: typeof __VLS_export;
25
- export default _default;
26
- declare const __VLS_export: import("vue").DefineComponent<InputUploraImageProps & {
27
- modelValue?: InputUploraImageModelValue;
28
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
29
- delete: () => any;
30
- "update:modelValue": (value: InputUploraImageModelValue) => any;
31
- upload: (args_0: InputUploraImageModelValue) => any;
32
- }, string, import("vue").PublicProps, Readonly<InputUploraImageProps & {
33
- modelValue?: InputUploraImageModelValue;
34
- }> & Readonly<{
35
- onDelete?: (() => any) | undefined;
36
- "onUpdate:modelValue"?: ((value: InputUploraImageModelValue) => any) | undefined;
37
- onUpload?: ((args_0: InputUploraImageModelValue) => any) | undefined;
38
- }>, {
39
- showExtensions: boolean;
40
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,8 +0,0 @@
1
- interface InternalHttpErrorOptions {
2
- cause?: unknown;
3
- }
4
- export declare class InternalHttpError extends Error {
5
- httpCodeString: string;
6
- constructor(httpCodeString: string, options?: InternalHttpErrorOptions);
7
- }
8
- export {};
@@ -1,7 +0,0 @@
1
- export class InternalHttpError extends Error {
2
- constructor(httpCodeString, options) {
3
- super("Internal Error");
4
- this.httpCodeString = httpCodeString;
5
- this.cause = options?.cause;
6
- }
7
- }
@@ -1,8 +0,0 @@
1
- import type { CustomError, ErrorMapCodes } from '../types';
2
- import { H3Error } from 'h3';
3
- import { InternalHttpError } from '../errors';
4
- export declare function parseErrorString(errorString: string): CustomError;
5
- export declare function errorServerResolver(error: unknown, errorMap?: ErrorMapCodes): H3Error<{
6
- [key: string]: unknown;
7
- }>;
8
- export declare function createServerError(errorString: string): InternalHttpError;
@@ -1,57 +0,0 @@
1
- import { HTTP_CODE_BAD_REQUEST, HTTP_CODE_INTERNAL_SERVER_ERROR, HTTP_CODE_REQUEST_TIMEOUT, HTTP_CODE_UNAUTHORIZED } from "#cms/http-codes";
2
- import { consola } from "consola";
3
- import { defu } from "defu";
4
- import { createError, H3Error } from "h3";
5
- import { z } from "zod";
6
- import { InternalHttpError, TimeoutError } from "../errors/index.js";
7
- const defaultHttpCodes = {
8
- DEFAULT: HTTP_CODE_INTERNAL_SERVER_ERROR,
9
- ZOD: HTTP_CODE_BAD_REQUEST,
10
- DB: HTTP_CODE_INTERNAL_SERVER_ERROR,
11
- ERROR_UNAUTHORIZED: HTTP_CODE_UNAUTHORIZED,
12
- TIMEOUT: HTTP_CODE_REQUEST_TIMEOUT
13
- };
14
- function extractHttpCodeString(error, errorMap = {}) {
15
- errorMap = defu(errorMap, defaultHttpCodes);
16
- if (error instanceof InternalHttpError) {
17
- return error.httpCodeString;
18
- } else if (error instanceof z.ZodError) {
19
- return errorMap.ZOD;
20
- } else if (error instanceof TimeoutError) {
21
- return errorMap.TIMEOUT;
22
- } else if (error instanceof H3Error && error.cause instanceof InternalHttpError) {
23
- return error.cause.httpCodeString;
24
- } else if (error instanceof Error) {
25
- if ("query" in error && "params" in error && Array.isArray(error.params)) {
26
- const errorMaybeCode2 = `DB_${error.cause?.code}`;
27
- return errorMap[errorMaybeCode2] ?? errorMap.DB;
28
- }
29
- const normalizedMessage = error.message.trim().replaceAll(" ", "_").toUpperCase();
30
- const errorMaybeCode = `ERROR_${normalizedMessage}`;
31
- return errorMap[errorMaybeCode] ?? errorMap.DEFAULT;
32
- }
33
- return errorMap.DEFAULT;
34
- }
35
- export function parseErrorString(errorString) {
36
- const [code, message] = errorString.split(":");
37
- if (!code || !message) {
38
- throw new Error("Invalid error string");
39
- }
40
- return {
41
- statusCode: Number.parseInt(code, 10),
42
- message: message.trim()
43
- };
44
- }
45
- export function errorServerResolver(error, errorMap) {
46
- const httpCodeString = extractHttpCodeString(error, errorMap);
47
- const parsedHttpCode = parseErrorString(httpCodeString);
48
- consola.error.raw({
49
- code: parsedHttpCode.statusCode,
50
- message: parsedHttpCode.message,
51
- error
52
- });
53
- return createError(parsedHttpCode);
54
- }
55
- export function createServerError(errorString) {
56
- return new InternalHttpError(errorString);
57
- }
@@ -1,10 +0,0 @@
1
- import type { EventHandler, EventHandlerRequest, EventHandlerResponse } from 'h3';
2
- import type { ErrorMapCodes } from '../types';
3
- export interface EventHandlerOptions {
4
- errorMap?: ErrorMapCodes;
5
- }
6
- /**
7
- * Функция для определения обработчика HTTP-запросов.
8
- * Обрабатывает, H3-обработчик и ловит, обрабатывает ошибки.
9
- */
10
- export declare function defineHttpHandler<Request extends EventHandlerRequest, Response extends EventHandlerResponse>(handler: EventHandler<Request, Response | Promise<Response>>, options?: EventHandlerOptions): EventHandler<Request, Promise<Response>>;
@@ -1,15 +0,0 @@
1
- import { eventHandler } from "h3";
2
- import { errorServerResolver } from "./errors.js";
3
- export function defineHttpHandler(handler, options) {
4
- return eventHandler(async (event) => {
5
- try {
6
- return await handler(event);
7
- } catch (e) {
8
- let error = e;
9
- if (error.cause?.data instanceof Error) {
10
- error = error.cause?.data;
11
- }
12
- throw errorServerResolver(error, options?.errorMap);
13
- }
14
- });
15
- }
File without changes
File without changes