@cyberskill/shared 3.11.0 → 3.12.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/dist/config/commitlint/index.d.ts +1 -5
- package/dist/config/env/index.d.ts +1 -3
- package/dist/config/eslint/index.d.ts +1 -1198
- package/dist/config/graphql-codegen/index.d.ts +1 -2
- package/dist/config/index.d.ts +1 -2
- package/dist/config/lint-staged/index.d.ts +1 -5
- package/dist/config/storybook/index.d.ts +1 -2
- package/dist/config/vitest/index.d.ts +1 -3
- package/dist/config/vitest/vitest.e2e.d.ts +1 -20
- package/dist/config/vitest/vitest.e2e.js +1 -1
- package/dist/config/vitest/vitest.unit.d.ts +1 -22
- package/dist/config/vitest/vitest.unit.js +1 -1
- package/dist/constant/index.d.ts +1 -5
- package/dist/node/apollo-server/index.d.ts +1 -2
- package/dist/node/cli/index.d.ts +1 -2
- package/dist/node/command/index.d.ts +1 -2
- package/dist/node/express/index.d.ts +1 -2
- package/dist/node/fs/index.d.ts +1 -2
- package/dist/node/log/index.d.ts +1 -2
- package/dist/node/mongo/index.d.ts +1 -6
- package/dist/node/package/index.d.ts +1 -2
- package/dist/node/path/index.d.ts +1 -2
- package/dist/node/storage/index.d.ts +1 -3
- package/dist/node/upload/index.d.ts +1 -3
- package/dist/node/upload/upload.util.js.map +1 -1
- package/dist/node/ws/index.d.ts +1 -2
- package/dist/node_modules/.pnpm/vitest@4.1.2_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.3_@types_nod_0827261ede788764a5d99ac6bdf44bde/node_modules/vitest/dist/config.js +8 -0
- package/dist/node_modules/.pnpm/{vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.1_@types_nod_5f6c16f4d4385f16c87b17afc93c851f → vitest@4.1.2_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.3_@types_nod_0827261ede788764a5d99ac6bdf44bde}/node_modules/vitest/dist/config.js.map +1 -1
- package/dist/react/apollo-client/index.d.ts +1 -9
- package/dist/react/apollo-client/links/index.d.ts +1 -1
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.rsc.d.ts +1 -16
- package/dist/react/apollo-client-nextjs/index.d.ts +1 -2
- package/dist/react/apollo-error/apollo-error.component.js +6 -2
- package/dist/react/apollo-error/apollo-error.component.js.map +1 -1
- package/dist/react/apollo-error/index.d.ts +1 -6
- package/dist/react/i18next/index.d.ts +1 -2
- package/dist/react/loading/index.d.ts +1 -5
- package/dist/react/log/index.d.ts +1 -2
- package/dist/react/next-intl/index.d.ts +1 -6
- package/dist/react/storage/index.d.ts +1 -2
- package/dist/react/toast/index.d.ts +1 -1
- package/dist/react/userback/index.d.ts +1 -2
- package/dist/src/config/commitlint/index.d.ts +5 -0
- package/dist/{config → src/config}/config.type.d.ts +1 -1
- package/dist/{config → src/config}/config.util.d.ts +1 -1
- package/dist/src/config/env/index.d.ts +3 -0
- package/dist/src/config/eslint/index.d.ts +1198 -0
- package/dist/src/config/graphql-codegen/index.d.ts +2 -0
- package/dist/src/config/index.d.ts +2 -0
- package/dist/src/config/lint-staged/index.d.ts +5 -0
- package/dist/src/config/storybook/index.d.ts +2 -0
- package/dist/src/config/vitest/index.d.ts +3 -0
- package/dist/src/config/vitest/vitest.e2e.d.ts +20 -0
- package/dist/src/config/vitest/vitest.unit.d.ts +22 -0
- package/dist/src/constant/index.d.ts +5 -0
- package/dist/src/node/apollo-server/index.d.ts +2 -0
- package/dist/src/node/cli/index.d.ts +2 -0
- package/dist/src/node/command/index.d.ts +2 -0
- package/dist/src/node/express/index.d.ts +2 -0
- package/dist/src/node/fs/index.d.ts +2 -0
- package/dist/src/node/log/index.d.ts +2 -0
- package/dist/{node → src/node}/log/log.type.d.ts +2 -2
- package/dist/{node → src/node}/log/log.util.d.ts +1 -1
- package/dist/src/node/mongo/index.d.ts +6 -0
- package/dist/{node → src/node}/mongo/mongo.controller.helpers.d.ts +1 -1
- package/dist/{node → src/node}/mongo/mongo.controller.mongoose.d.ts +1 -1
- package/dist/{node → src/node}/mongo/mongo.controller.native.d.ts +1 -1
- package/dist/{node → src/node}/mongo/mongo.controller.type.d.ts +1 -1
- package/dist/src/node/package/index.d.ts +2 -0
- package/dist/{node → src/node}/package/package.util.d.ts +1 -1
- package/dist/src/node/path/index.d.ts +2 -0
- package/dist/src/node/storage/index.d.ts +3 -0
- package/dist/src/node/upload/index.d.ts +3 -0
- package/dist/{node → src/node}/upload/upload.util.d.ts +1 -1
- package/dist/src/node/ws/index.d.ts +2 -0
- package/dist/{react → src/react}/apollo-client/apollo-client.type.d.ts +1 -1
- package/dist/src/react/apollo-client/index.d.ts +9 -0
- package/dist/src/react/apollo-client/links/index.d.ts +1 -0
- package/dist/src/react/apollo-client-nextjs/apollo-client-nextjs.rsc.d.ts +16 -0
- package/dist/src/react/apollo-client-nextjs/index.d.ts +2 -0
- package/dist/src/react/apollo-error/index.d.ts +6 -0
- package/dist/src/react/i18next/index.d.ts +2 -0
- package/dist/src/react/loading/index.d.ts +5 -0
- package/dist/{react → src/react}/loading/loading.provider.d.ts +1 -1
- package/dist/src/react/log/index.d.ts +2 -0
- package/dist/src/react/log/log.type.d.ts +1 -0
- package/dist/{react → src/react}/log/log.util.d.ts +1 -1
- package/dist/src/react/next-intl/index.d.ts +6 -0
- package/dist/{react → src/react}/next-intl/next-intl.hoc.d.ts +1 -1
- package/dist/{react → src/react}/next-intl/next-intl.type.d.ts +1 -1
- package/dist/src/react/storage/index.d.ts +2 -0
- package/dist/{react → src/react}/storage/storage.hook.d.ts +1 -1
- package/dist/src/react/toast/index.d.ts +1 -0
- package/dist/src/react/userback/index.d.ts +2 -0
- package/dist/src/typescript/index.d.ts +5 -0
- package/dist/src/util/common/index.d.ts +5 -0
- package/dist/src/util/index.d.ts +9 -0
- package/dist/src/util/log/index.d.ts +2 -0
- package/dist/{util → src/util}/log/log.util.d.ts +1 -1
- package/dist/src/util/object/index.d.ts +4 -0
- package/dist/src/util/serializer/index.d.ts +2 -0
- package/dist/src/util/string/index.d.ts +5 -0
- package/dist/src/util/validate/index.d.ts +4 -0
- package/dist/typescript/index.d.ts +1 -5
- package/dist/util/common/index.d.ts +1 -5
- package/dist/util/index.d.ts +1 -9
- package/dist/util/log/index.d.ts +1 -2
- package/dist/util/object/index.d.ts +1 -4
- package/dist/util/object/object.util.js +5 -3
- package/dist/util/object/object.util.js.map +1 -1
- package/dist/util/serializer/index.d.ts +1 -2
- package/dist/util/serializer/serializer.util.js +10 -10
- package/dist/util/serializer/serializer.util.js.map +1 -1
- package/dist/util/string/index.d.ts +1 -5
- package/dist/util/validate/index.d.ts +1 -4
- package/package.json +21 -21
- package/dist/node_modules/.pnpm/vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.1_@types_nod_5f6c16f4d4385f16c87b17afc93c851f/node_modules/vitest/dist/config.js +0 -8
- package/dist/react/log/log.type.d.ts +0 -1
- /package/dist/{config → src/config}/env/env.constant.d.ts +0 -0
- /package/dist/{config → src/config}/env/env.type.d.ts +0 -0
- /package/dist/{config → src/config}/env/env.util.d.ts +0 -0
- /package/dist/{config → src/config}/graphql-codegen/graphql-codegen.type.d.ts +0 -0
- /package/dist/{config → src/config}/graphql-codegen/graphql-codegen.util.d.ts +0 -0
- /package/dist/{config → src/config}/storybook/storybook.main.d.ts +0 -0
- /package/dist/{config → src/config}/storybook/storybook.preview.d.ts +0 -0
- /package/dist/{config → src/config}/vitest/vitest.unit.setup.d.ts +0 -0
- /package/dist/{constant → src/constant}/common.d.ts +0 -0
- /package/dist/{constant → src/constant}/response-status.d.ts +0 -0
- /package/dist/{node → src/node}/apollo-server/apollo-server.type.d.ts +0 -0
- /package/dist/{node → src/node}/apollo-server/apollo-server.util.d.ts +0 -0
- /package/dist/{node → src/node}/command/command.type.d.ts +0 -0
- /package/dist/{node → src/node}/command/command.util.d.ts +0 -0
- /package/dist/{node → src/node}/express/express.type.d.ts +0 -0
- /package/dist/{node → src/node}/express/express.util.d.ts +0 -0
- /package/dist/{node → src/node}/fs/fs.type.d.ts +0 -0
- /package/dist/{node → src/node}/fs/fs.util.d.ts +0 -0
- /package/dist/{node → src/node}/mongo/mongo.constant.d.ts +0 -0
- /package/dist/{node → src/node}/mongo/mongo.controller.d.ts +0 -0
- /package/dist/{node → src/node}/mongo/mongo.dynamic-populate.d.ts +0 -0
- /package/dist/{node → src/node}/mongo/mongo.internal-types.d.ts +0 -0
- /package/dist/{node → src/node}/mongo/mongo.populate.d.ts +0 -0
- /package/dist/{node → src/node}/mongo/mongo.type.d.ts +0 -0
- /package/dist/{node → src/node}/mongo/mongo.util.d.ts +0 -0
- /package/dist/{node → src/node}/package/package.type.d.ts +0 -0
- /package/dist/{node → src/node}/path/path.constant.d.ts +0 -0
- /package/dist/{node → src/node}/path/path.util.d.ts +0 -0
- /package/dist/{node → src/node}/storage/storage.constant.d.ts +0 -0
- /package/dist/{node → src/node}/storage/storage.type.d.ts +0 -0
- /package/dist/{node → src/node}/storage/storage.util.d.ts +0 -0
- /package/dist/{node → src/node}/upload/upload.constant.d.ts +0 -0
- /package/dist/{node → src/node}/upload/upload.type.d.ts +0 -0
- /package/dist/{node → src/node}/ws/ws.type.d.ts +0 -0
- /package/dist/{node → src/node}/ws/ws.util.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client/apollo-client.component.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client/apollo-client.constant.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client/apollo-client.context.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client/apollo-client.hook.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client/apollo-client.util.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client/links/upload.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client-nextjs/apollo-client-nextjs.component.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-client-nextjs/apollo-client-nextjs.util.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-error/apollo-error.component.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-error/apollo-error.context.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-error/apollo-error.hook.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-error/apollo-error.provider.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-error/apollo-error.type.d.ts +0 -0
- /package/dist/{react → src/react}/apollo-error/apollo-error.util.d.ts +0 -0
- /package/dist/{react → src/react}/i18next/i18next.hook.d.ts +0 -0
- /package/dist/{react → src/react}/i18next/i18next.util.d.ts +0 -0
- /package/dist/{react → src/react}/loading/loading.component.d.ts +0 -0
- /package/dist/{react → src/react}/loading/loading.context.d.ts +0 -0
- /package/dist/{react → src/react}/loading/loading.hook.d.ts +0 -0
- /package/dist/{react → src/react}/loading/loading.type.d.ts +0 -0
- /package/dist/{react → src/react}/next-intl/next-intl.constant.d.ts +0 -0
- /package/dist/{react → src/react}/next-intl/next-intl.context.d.ts +0 -0
- /package/dist/{react → src/react}/next-intl/next-intl.hook.d.ts +0 -0
- /package/dist/{react → src/react}/next-intl/next-intl.provider.d.ts +0 -0
- /package/dist/{react → src/react}/storage/storage.util.d.ts +0 -0
- /package/dist/{react → src/react}/userback/userback.component.d.ts +0 -0
- /package/dist/{react → src/react}/userback/userback.type.d.ts +0 -0
- /package/dist/{typescript → src/typescript}/common.type.d.ts +0 -0
- /package/dist/{typescript → src/typescript}/react.type.d.ts +0 -0
- /package/dist/{util → src/util}/common/common.type.d.ts +0 -0
- /package/dist/{util → src/util}/common/common.util.d.ts +0 -0
- /package/dist/{util → src/util}/log/log.type.d.ts +0 -0
- /package/dist/{util → src/util}/object/object.util.d.ts +0 -0
- /package/dist/{util → src/util}/serializer/serializer.type.d.ts +0 -0
- /package/dist/{util → src/util}/serializer/serializer.util.d.ts +0 -0
- /package/dist/{util → src/util}/string/string.type.d.ts +0 -0
- /package/dist/{util → src/util}/string/string.util.d.ts +0 -0
- /package/dist/{util → src/util}/validate/validate.util.d.ts +0 -0
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './graphql-codegen.util.js';
|
|
1
|
+
export {}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './config.util.js';
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './storybook.preview.js';
|
|
1
|
+
export {}
|
|
@@ -1,20 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Creates a Vitest configuration for end-to-end testing with browser automation.
|
|
4
|
-
* This function generates a Vitest configuration specifically designed for E2E testing
|
|
5
|
-
* using Playwright with multiple browser instances. It includes React support and
|
|
6
|
-
* browser automation capabilities for comprehensive end-to-end testing.
|
|
7
|
-
*
|
|
8
|
-
* The configuration includes:
|
|
9
|
-
* - React SWC plugin for fast React compilation
|
|
10
|
-
* - Browser automation with Playwright provider
|
|
11
|
-
* - Multiple browser instances (Chromium, Firefox, WebKit)
|
|
12
|
-
* - E2E test file pattern matching
|
|
13
|
-
* - Configurable options merging
|
|
14
|
-
*
|
|
15
|
-
* @param options - Additional Vite configuration options to merge with the E2E config.
|
|
16
|
-
* @returns A Vitest configuration object optimized for end-to-end testing with browser automation.
|
|
17
|
-
*/
|
|
18
|
-
export declare function vitestE2E(options: UserConfig): UserConfig;
|
|
19
|
-
declare const _default: UserConfig;
|
|
20
|
-
export default _default;
|
|
1
|
+
export {}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { deepMerge as e } from "../../util/object/object.util.js";
|
|
2
|
-
import { defineConfig as t } from "../../node_modules/.pnpm/vitest@4.1.
|
|
2
|
+
import { defineConfig as t } from "../../node_modules/.pnpm/vitest@4.1.2_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.3_@types_nod_0827261ede788764a5d99ac6bdf44bde/node_modules/vitest/dist/config.js";
|
|
3
3
|
import n from "@vitejs/plugin-react";
|
|
4
4
|
//#region src/config/vitest/vitest.e2e.ts
|
|
5
5
|
function r(r) {
|
|
@@ -1,22 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Creates a Vitest configuration for unit testing with React support.
|
|
4
|
-
* This function generates a Vitest configuration specifically designed for unit testing
|
|
5
|
-
* React components and JavaScript/TypeScript modules. It includes JSDOM environment
|
|
6
|
-
* for DOM simulation and comprehensive testing setup.
|
|
7
|
-
*
|
|
8
|
-
* The configuration includes:
|
|
9
|
-
* - React SWC plugin for fast React compilation
|
|
10
|
-
* - JSDOM environment for DOM simulation
|
|
11
|
-
* - Global test functions availability
|
|
12
|
-
* - VM threads pool for parallel test execution
|
|
13
|
-
* - Unit test file pattern matching
|
|
14
|
-
* - Setup files for testing library configuration
|
|
15
|
-
* - Configurable options merging
|
|
16
|
-
*
|
|
17
|
-
* @param options - Additional Vite configuration options to merge with the unit test config.
|
|
18
|
-
* @returns A Vitest configuration object optimized for unit testing with React and DOM support.
|
|
19
|
-
*/
|
|
20
|
-
export declare function vitestUnit(options: UserConfig): UserConfig;
|
|
21
|
-
declare const _default: UserConfig;
|
|
22
|
-
export default _default;
|
|
1
|
+
export {}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { deepMerge as e } from "../../util/object/object.util.js";
|
|
2
|
-
import { defineConfig as t } from "../../node_modules/.pnpm/vitest@4.1.
|
|
2
|
+
import { defineConfig as t } from "../../node_modules/.pnpm/vitest@4.1.2_@types_node@25.5.0_jsdom@29.0.1_@noble_hashes@1.8.0__vite@8.0.3_@types_nod_0827261ede788764a5d99ac6bdf44bde/node_modules/vitest/dist/config.js";
|
|
3
3
|
import n from "@vitejs/plugin-react";
|
|
4
4
|
//#region src/config/vitest/vitest.unit.ts
|
|
5
5
|
function r(r) {
|
package/dist/constant/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './apollo-server.util.js';
|
|
1
|
+
export {}
|
package/dist/node/cli/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export {};
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './command.util.js';
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './express.util.js';
|
|
1
|
+
export {}
|
package/dist/node/fs/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './fs.util.js';
|
|
1
|
+
export {}
|
package/dist/node/log/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './log.util.js';
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './package.util.js';
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './path.util.js';
|
|
1
|
+
export {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.util.js","names":[],"sources":["../../../src/node/upload/upload.util.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport nodePath from 'node:path';\nimport { Transform } from 'node:stream';\nimport { ReadableStream } from 'node:stream/web';\n\nimport type { I_Return } from '#typescript/index.js';\n\nimport { RESPONSE_STATUS } from '#constant/index.js';\n\nimport type { I_UploadConfig, I_UploadFile, I_UploadFileData, I_UploadOptions, I_UploadTypeConfig, I_UploadValidationConfig } from './upload.type.js';\n\nimport { createWriteStream, mkdirSync, pathExistsSync } from '../fs/index.js';\nimport { dirname } from '../path/index.js';\nimport { BYTES_PER_MB, DEFAULT_UPLOAD_CONFIG } from './upload.constant.js';\nimport { E_UploadType } from './upload.type.js';\n\n/**\n * Calculates the size of a file from a readable stream.\n * This function reads through the entire stream to determine the total byte size\n * by accumulating the length of each data chunk.\n *\n * @param stream - The readable stream to calculate the size for.\n * @returns A promise that resolves to the total size of the stream in bytes.\n */\nexport async function getFileSizeFromStream(stream: NodeJS.ReadableStream): Promise<number> {\n return new Promise((resolve, reject) => {\n let size = 0;\n stream.on('data', (chunk) => {\n size += chunk.length;\n });\n stream.on('end', () => resolve(size));\n stream.on('error', reject);\n });\n}\n\n/**\n * Extracts and validates file data from an upload file.\n * This function processes upload files by:\n * - Extracting file metadata and creating a readable stream\n * - Calculating the file size from the stream\n * - Validating file size and extension against upload configuration\n * - Returning a standardized response with success status and error codes\n * - Providing validated file data for further processing\n *\n * @param type - The type of upload being processed (IMAGE, VIDEO, DOCUMENT, OTHER).\n * @param file - The upload file object containing file metadata and stream creation method.\n * @param config - Optional upload configuration. If not provided, uses default configuration.\n * @returns A promise that resolves to a standardized response containing validated file data or error information.\n */\nexport async function getAndValidateFile(type: E_UploadType, file: I_UploadFile, config?: I_UploadConfig): Promise<I_Return<I_UploadFileData>> {\n const fileData = await (await file).file;\n const stream = fileData.createReadStream();\n // Stream is consumed here for validation; callers use createReadStream() again for the actual write.\n // This is intentional — createReadStream() is a factory that yields a new stream per call.\n const fileSize = await getFileSizeFromStream(stream);\n const uploadConfig = config ?? createUploadConfig();\n\n const validationResult = validateUpload(\n { filename: fileData.filename, fileSize },\n uploadConfig,\n type,\n );\n\n if (!validationResult.isValid) {\n return {\n success: false,\n message: validationResult.error || 'File validation failed',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n return {\n success: true,\n result: fileData,\n message: 'File validated successfully',\n };\n}\n\n/**\n * Creates a validated web-readable stream from an upload file with size validation.\n * This function processes file uploads for web environments by:\n * - Validating file data using getAndValidateFile function\n * - Creating a size validation transform stream to monitor upload progress\n * - Returning a web-compatible ReadableStream with real-time validation\n * - Providing standardized error responses for validation failures\n * - Wrapping the stream in a standardized response format\n *\n * @param type - The type of upload being processed (IMAGE, VIDEO, DOCUMENT, OTHER).\n * @param file - The upload file object containing file metadata and stream creation method.\n * @param config - Optional upload configuration. If not provided, uses default configuration.\n * @returns A promise that resolves to a standardized response containing either a web ReadableStream or error information.\n */\nexport async function getFileWebStream(type: E_UploadType, file: I_UploadFile, config?: I_UploadConfig): Promise<I_Return<ReadableStream<Uint8Array>>> {\n const uploadConfig = config ?? createUploadConfig();\n const typeConfig = uploadConfig[type];\n\n const fileData = await getAndValidateFile(type, file, config);\n\n if (!fileData.success) {\n return fileData;\n }\n\n const { createReadStream } = fileData.result;\n\n let remainingBytes = typeConfig.sizeLimit;\n\n const sizeValidationStream = new Transform({\n transform(chunk: Buffer, _enc: BufferEncoding, cb) {\n remainingBytes -= chunk.length;\n\n if (remainingBytes < 0) {\n cb(new Error(`File size exceeds limit of ${typeConfig.sizeLimit / BYTES_PER_MB}MB`));\n }\n else {\n cb(null, chunk);\n }\n },\n });\n const originalStream = createReadStream();\n const validatedStream = originalStream.pipe(sizeValidationStream);\n\n return {\n success: true,\n result: new ReadableStream<Uint8Array>({\n start(controller) {\n validatedStream.on('data', (chunk: Buffer | string) => {\n controller.enqueue(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n });\n validatedStream.on('end', () => controller.close());\n validatedStream.on('error', (err: unknown) => controller.error(err));\n },\n }),\n };\n}\n\n/**\n * Validates if a file has an allowed extension.\n * This function extracts the file extension from the filename and checks if it's\n * included in the list of allowed extensions (case-insensitive comparison).\n *\n * @param filename - The filename to check for valid extension.\n * @param allowedExtensions - An array of allowed file extensions (without dots).\n * @returns True if the file extension is allowed, false otherwise.\n */\nexport function validateFileExtension(filename: string, allowedExtensions: string[]): boolean {\n const lastDotIndex = filename.lastIndexOf('.');\n\n if (lastDotIndex === -1) {\n return false;\n }\n\n const extension = filename.substring(lastDotIndex + 1).toLowerCase();\n\n return allowedExtensions.includes(extension);\n}\n\n/**\n * Validates an upload against the specified configuration.\n * This function performs comprehensive validation including:\n * - File extension validation against allowed extensions\n * - File size validation against size limits\n * - Returns detailed error messages for validation failures\n *\n * @param config - The validation configuration including filename and optional file size.\n * @param uploadConfig - The upload configuration containing allowed extensions and size limits.\n * @param uploadType - The type of upload being validated.\n * @returns An object indicating validation success and optional error message.\n */\nexport function validateUpload(\n config: I_UploadValidationConfig,\n uploadConfig: I_UploadConfig,\n uploadType: E_UploadType,\n): { isValid: boolean; error?: string } {\n const { filename, fileSize } = config;\n const typeConfig: I_UploadTypeConfig = uploadConfig[uploadType];\n\n const { allowedExtensions, sizeLimit } = typeConfig;\n\n if (!validateFileExtension(filename, allowedExtensions)) {\n return {\n isValid: false,\n error: `File extension not allowed for ${uploadType.toLowerCase()} files. Allowed extensions: ${allowedExtensions.join(', ')}`,\n };\n }\n\n if (fileSize !== undefined && fileSize > sizeLimit) {\n const maxSizeMB = Math.round(sizeLimit / (1024 * 1024));\n\n return {\n isValid: false,\n error: `File size exceeds limit for ${uploadType.toLowerCase()} files. Maximum size: ${maxSizeMB}MB`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Creates a default upload configuration with predefined settings for different file types.\n * This function provides sensible defaults for image, video, document, and other file types,\n * including allowed extensions and size limits. The configuration can be customized with overrides.\n *\n * @param overrides - Optional configuration overrides to merge with the default configuration.\n * @returns A complete upload configuration object with defaults and any provided overrides.\n */\nexport function createUploadConfig(overrides?: Partial<I_UploadConfig>): I_UploadConfig {\n return { ...DEFAULT_UPLOAD_CONFIG, ...overrides };\n}\n\n/**\n * Uploads a file with comprehensive validation and error handling.\n * This function processes file uploads with the following features:\n * - Input validation for path and file parameters\n * - Configuration validation for all upload types\n * - File validation using getAndValidateFile function\n * - Automatic directory creation\n * - Stream-based file writing\n * - Comprehensive error handling with standardized response codes\n *\n * @param options - Upload configuration including file, path, type, and optional validation config.\n * @returns A promise that resolves to a standardized response with success status, message, file path, and response codes.\n */\nexport async function upload(options: I_UploadOptions): Promise<I_Return<string>> {\n const { path, file, config, type, baseDir } = options;\n\n if (!path || typeof path !== 'string') {\n return {\n success: false,\n message: 'Invalid path provided',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n // Security: Validate path is within allowed base directory to prevent path traversal.\n // When baseDir is provided, the resolved path must start with it.\n // When baseDir is not provided, reject any path containing \"..\" segments.\n const resolvedPath = nodePath.resolve(path);\n\n if (baseDir) {\n const resolvedBase = nodePath.resolve(baseDir) + nodePath.sep;\n if (!resolvedPath.startsWith(resolvedBase) && resolvedPath !== nodePath.resolve(baseDir)) {\n return {\n success: false,\n message: 'Path traversal detected: path resolves outside the allowed base directory',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n }\n else if (path.includes('..')) {\n return {\n success: false,\n message: 'Path traversal detected: \"..\" segments are not allowed',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n if (!file || typeof file !== 'object') {\n return {\n success: false,\n message: 'Invalid file provided',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n if (config) {\n const requiredTypes = [E_UploadType.IMAGE, E_UploadType.VIDEO, E_UploadType.DOCUMENT, E_UploadType.OTHER];\n\n for (const requiredType of requiredTypes) {\n if (!config[requiredType] || !Array.isArray(config[requiredType].allowedExtensions) || config[requiredType].allowedExtensions.length === 0) {\n return {\n success: false,\n message: `Invalid config for ${requiredType.toLowerCase()} files`,\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n if (typeof config[requiredType].sizeLimit !== 'number' || config[requiredType].sizeLimit <= 0) {\n return {\n success: false,\n message: `Invalid size limit for ${requiredType.toLowerCase()} files`,\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n }\n }\n\n try {\n const fileData = await getAndValidateFile(type, await file, config);\n\n if (!fileData.success) {\n return fileData;\n }\n\n const { createReadStream } = fileData.result;\n\n const dir = dirname(path);\n\n if (!pathExistsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const writeStream = createReadStream();\n const out = createWriteStream(path);\n writeStream.pipe(out);\n\n await new Promise<void>((resolve, reject) => {\n out.on('finish', () => resolve());\n out.on('error', reject);\n writeStream.on('error', reject);\n });\n\n return {\n success: true,\n result: path,\n message: 'File uploaded successfully',\n code: RESPONSE_STATUS.OK.CODE,\n };\n }\n catch (error) {\n return {\n success: false,\n message: error instanceof Error ? error.message : 'File upload failed',\n code: RESPONSE_STATUS.INTERNAL_SERVER_ERROR.CODE,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upload.util.js","names":[],"sources":["../../../src/node/upload/upload.util.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport nodePath from 'node:path';\nimport { Transform } from 'node:stream';\nimport { ReadableStream } from 'node:stream/web';\n\nimport type { I_Return } from '#typescript/index.js';\n\nimport { RESPONSE_STATUS } from '#constant/index.js';\n\nimport type { I_UploadConfig, I_UploadFile, I_UploadFileData, I_UploadOptions, I_UploadTypeConfig, I_UploadValidationConfig } from './upload.type.js';\n\nimport { createWriteStream, mkdirSync, pathExistsSync } from '../fs/index.js';\nimport { dirname } from '../path/index.js';\nimport { BYTES_PER_MB, DEFAULT_UPLOAD_CONFIG } from './upload.constant.js';\nimport { E_UploadType } from './upload.type.js';\n\n/**\n * Calculates the size of a file from a readable stream.\n * This function reads through the entire stream to determine the total byte size\n * by accumulating the length of each data chunk.\n *\n * @param stream - The readable stream to calculate the size for.\n * @returns A promise that resolves to the total size of the stream in bytes.\n */\nexport async function getFileSizeFromStream(stream: NodeJS.ReadableStream): Promise<number> {\n return new Promise((resolve, reject) => {\n let size = 0;\n stream.on('data', (chunk) => {\n size += chunk.length;\n });\n stream.on('end', () => resolve(size));\n stream.on('error', reject);\n });\n}\n\n/**\n * Extracts and validates file data from an upload file.\n * This function processes upload files by:\n * - Extracting file metadata and creating a readable stream\n * - Calculating the file size from the stream\n * - Validating file size and extension against upload configuration\n * - Returning a standardized response with success status and error codes\n * - Providing validated file data for further processing\n *\n * @param type - The type of upload being processed (IMAGE, VIDEO, DOCUMENT, OTHER).\n * @param file - The upload file object containing file metadata and stream creation method.\n * @param config - Optional upload configuration. If not provided, uses default configuration.\n * @returns A promise that resolves to a standardized response containing validated file data or error information.\n */\nexport async function getAndValidateFile(type: E_UploadType, file: I_UploadFile, config?: I_UploadConfig): Promise<I_Return<I_UploadFileData>> {\n const fileData = await (await file).file;\n const stream = fileData.createReadStream();\n // Stream is consumed here for validation; callers use createReadStream() again for the actual write.\n // This is intentional — createReadStream() is a factory that yields a new stream per call.\n const fileSize = await getFileSizeFromStream(stream);\n const uploadConfig = config ?? createUploadConfig();\n\n const validationResult = validateUpload(\n { filename: fileData.filename, fileSize },\n uploadConfig,\n type,\n );\n\n if (!validationResult.isValid) {\n return {\n success: false,\n message: validationResult.error || 'File validation failed',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n return {\n success: true,\n result: fileData,\n message: 'File validated successfully',\n };\n}\n\n/**\n * Creates a validated web-readable stream from an upload file with size validation.\n * This function processes file uploads for web environments by:\n * - Validating file data using getAndValidateFile function\n * - Creating a size validation transform stream to monitor upload progress\n * - Returning a web-compatible ReadableStream with real-time validation\n * - Providing standardized error responses for validation failures\n * - Wrapping the stream in a standardized response format\n *\n * @param type - The type of upload being processed (IMAGE, VIDEO, DOCUMENT, OTHER).\n * @param file - The upload file object containing file metadata and stream creation method.\n * @param config - Optional upload configuration. If not provided, uses default configuration.\n * @returns A promise that resolves to a standardized response containing either a web ReadableStream or error information.\n */\nexport async function getFileWebStream(type: E_UploadType, file: I_UploadFile, config?: I_UploadConfig): Promise<I_Return<ReadableStream<Uint8Array>>> {\n const uploadConfig = config ?? createUploadConfig();\n const typeConfig = uploadConfig[type];\n\n const fileData = await getAndValidateFile(type, file, config);\n\n if (!fileData.success) {\n return fileData;\n }\n\n const { createReadStream } = fileData.result;\n\n let remainingBytes = typeConfig.sizeLimit;\n\n const sizeValidationStream = new Transform({\n transform(chunk: Buffer, _enc: BufferEncoding, cb) {\n remainingBytes -= chunk.length;\n\n if (remainingBytes < 0) {\n cb(new Error(`File size exceeds limit of ${typeConfig.sizeLimit / BYTES_PER_MB}MB`));\n }\n else {\n cb(null, chunk);\n }\n },\n });\n const originalStream = createReadStream();\n const validatedStream = originalStream.pipe(sizeValidationStream);\n\n return {\n success: true,\n result: new ReadableStream<Uint8Array>({\n start(controller) {\n validatedStream.on('data', (chunk: Buffer | string) => {\n controller.enqueue(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n });\n validatedStream.on('end', () => controller.close());\n validatedStream.on('error', (err: unknown) => controller.error(err));\n },\n }),\n };\n}\n\n/**\n * Validates if a file has an allowed extension.\n * This function extracts the file extension from the filename and checks if it's\n * included in the list of allowed extensions (case-insensitive comparison).\n *\n * @param filename - The filename to check for valid extension.\n * @param allowedExtensions - An array of allowed file extensions (without dots).\n * @returns True if the file extension is allowed, false otherwise.\n */\nexport function validateFileExtension(filename: string, allowedExtensions: string[]): boolean {\n const lastDotIndex = filename.lastIndexOf('.');\n\n if (lastDotIndex === -1) {\n return false;\n }\n\n const extension = filename.substring(lastDotIndex + 1).toLowerCase();\n\n return allowedExtensions.includes(extension);\n}\n\n/**\n * Validates an upload against the specified configuration.\n * This function performs comprehensive validation including:\n * - File extension validation against allowed extensions\n * - File size validation against size limits\n * - Returns detailed error messages for validation failures\n *\n * @param config - The validation configuration including filename and optional file size.\n * @param uploadConfig - The upload configuration containing allowed extensions and size limits.\n * @param uploadType - The type of upload being validated.\n * @returns An object indicating validation success and optional error message.\n */\nexport function validateUpload(\n config: I_UploadValidationConfig,\n uploadConfig: I_UploadConfig,\n uploadType: E_UploadType,\n): { isValid: boolean; error?: string } {\n const { filename, fileSize } = config;\n const typeConfig: I_UploadTypeConfig = uploadConfig[uploadType];\n\n const { allowedExtensions, sizeLimit } = typeConfig;\n\n if (!validateFileExtension(filename, allowedExtensions)) {\n return {\n isValid: false,\n error: `File extension not allowed for ${uploadType.toLowerCase()} files. Allowed extensions: ${allowedExtensions.join(', ')}`,\n };\n }\n\n if (fileSize !== undefined && fileSize > sizeLimit) {\n const maxSizeMB = Math.round(sizeLimit / (1024 * 1024));\n\n return {\n isValid: false,\n error: `File size exceeds limit for ${uploadType.toLowerCase()} files. Maximum size: ${maxSizeMB}MB`,\n };\n }\n\n return { isValid: true };\n}\n\n/**\n * Creates a default upload configuration with predefined settings for different file types.\n * This function provides sensible defaults for image, video, document, and other file types,\n * including allowed extensions and size limits. The configuration can be customized with overrides.\n *\n * @param overrides - Optional configuration overrides to merge with the default configuration.\n * @returns A complete upload configuration object with defaults and any provided overrides.\n */\nexport function createUploadConfig(overrides?: Partial<I_UploadConfig>): I_UploadConfig {\n return { ...DEFAULT_UPLOAD_CONFIG, ...overrides };\n}\n\n/**\n * Uploads a file with comprehensive validation and error handling.\n * This function processes file uploads with the following features:\n * - Input validation for path and file parameters\n * - Configuration validation for all upload types\n * - File validation using getAndValidateFile function\n * - Automatic directory creation\n * - Stream-based file writing\n * - Comprehensive error handling with standardized response codes\n *\n * @param options - Upload configuration including file, path, type, and optional validation config.\n * @returns A promise that resolves to a standardized response with success status, message, file path, and response codes.\n */\nexport async function upload(options: I_UploadOptions): Promise<I_Return<string>> {\n const { path, file, config, type, baseDir } = options;\n\n if (!path || typeof path !== 'string') {\n return {\n success: false,\n message: 'Invalid path provided',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n // Security: Validate path is within allowed base directory to prevent path traversal.\n // When baseDir is provided, the resolved path must start with it.\n // When baseDir is not provided, reject any path containing \"..\" segments.\n const resolvedPath = nodePath.resolve(path);\n\n if (baseDir) {\n const resolvedBase = nodePath.resolve(baseDir) + nodePath.sep;\n if (!resolvedPath.startsWith(resolvedBase) && resolvedPath !== nodePath.resolve(baseDir)) {\n return {\n success: false,\n message: 'Path traversal detected: path resolves outside the allowed base directory',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n }\n else if (path.includes('..')) {\n return {\n success: false,\n message: 'Path traversal detected: \"..\" segments are not allowed',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n if (!file || typeof file !== 'object') {\n return {\n success: false,\n message: 'Invalid file provided',\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n\n if (config) {\n const requiredTypes = [E_UploadType.IMAGE, E_UploadType.VIDEO, E_UploadType.DOCUMENT, E_UploadType.OTHER];\n\n for (const requiredType of requiredTypes) {\n if (!config[requiredType] || !Array.isArray(config[requiredType].allowedExtensions) || config[requiredType].allowedExtensions.length === 0) {\n return {\n success: false,\n message: `Invalid config for ${requiredType.toLowerCase()} files`,\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n if (typeof config[requiredType].sizeLimit !== 'number' || config[requiredType].sizeLimit <= 0) {\n return {\n success: false,\n message: `Invalid size limit for ${requiredType.toLowerCase()} files`,\n code: RESPONSE_STATUS.BAD_REQUEST.CODE,\n };\n }\n }\n }\n\n try {\n const fileData = await getAndValidateFile(type, await file, config);\n\n if (!fileData.success) {\n return fileData;\n }\n\n const { createReadStream } = fileData.result;\n\n const dir = dirname(path);\n\n if (!pathExistsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const writeStream = createReadStream();\n const out = createWriteStream(path);\n writeStream.pipe(out);\n\n await new Promise<void>((resolve, reject) => {\n out.on('finish', () => resolve());\n out.on('error', reject);\n writeStream.on('error', reject);\n });\n\n return {\n success: true,\n result: path,\n message: 'File uploaded successfully',\n code: RESPONSE_STATUS.OK.CODE,\n };\n }\n catch (error) {\n return {\n success: false,\n message: error instanceof Error ? error.message : 'File upload failed',\n code: RESPONSE_STATUS.INTERNAL_SERVER_ERROR.CODE,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/node/ws/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './ws.util.js';
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region node_modules/.pnpm/vitest@4.1.2_@types+node@25.5.0_jsdom@29.0.1_@noble+hashes@1.8.0__vite@8.0.3_@types+nod_0827261ede788764a5d99ac6bdf44bde/node_modules/vitest/dist/config.js
|
|
2
|
+
function e(e) {
|
|
3
|
+
return e;
|
|
4
|
+
}
|
|
5
|
+
//#endregion
|
|
6
|
+
export { e as defineConfig };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../../../../../../../node_modules/.pnpm/vitest@4.1.
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../../../../../../node_modules/.pnpm/vitest@4.1.2_@types+node@25.5.0_jsdom@29.0.1_@noble+hashes@1.8.0__vite@8.0.3_@types+nod_0827261ede788764a5d99ac6bdf44bde/node_modules/vitest/dist/config.js"],"sourcesContent":["export { c as configDefaults, a as coverageConfigDefaults, d as defaultExclude, b as defaultInclude } from './chunks/defaults.9aQKnqFk.js';\nexport { mergeConfig } from 'vite';\nexport { d as defaultBrowserPort } from './chunks/constants.CPYnjOGj.js';\nimport 'node:os';\nimport './chunks/env.D4Lgay0q.js';\nimport 'std-env';\n\nfunction defineConfig(config) {\n\treturn config;\n}\nfunction defineProject(config) {\n\treturn config;\n}\n\nexport { defineConfig, defineProject };\n"],"x_google_ignoreList":[0],"mappings":";AAOA,SAAS,EAAa,GAAQ;AAC7B,QAAO"}
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './apollo-client.constant.js';
|
|
3
|
-
export * from './apollo-client.context.js';
|
|
4
|
-
export * from './apollo-client.hook.js';
|
|
5
|
-
export * from './apollo-client.type.js';
|
|
6
|
-
export * from './apollo-client.util.js';
|
|
7
|
-
export * from './links/index.js';
|
|
8
|
-
export { makeVar } from '@apollo/client/cache';
|
|
9
|
-
export { useApolloClient, useBackgroundQuery, useFragment, useLazyQuery, useLoadableQuery, useMutation, useQuery, useQueryRefHandlers, useReactiveVar, useReadQuery, useSubscription, useSuspenseFragment, useSuspenseQuery } from '@apollo/client/react';
|
|
1
|
+
export {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {}
|
|
@@ -1,16 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Creates a registered Apollo Client factory for Next.js server components.
|
|
4
|
-
* This function creates a client factory that is registered with Next.js for
|
|
5
|
-
* proper server-side rendering support. The factory function ensures that
|
|
6
|
-
* each request gets its own Apollo Client instance, which is essential for
|
|
7
|
-
* SSR compatibility and preventing client state leakage between requests.
|
|
8
|
-
*
|
|
9
|
-
* @param options - Configuration options for the Apollo Client including URI, WebSocket URL, and custom links.
|
|
10
|
-
* @returns A registered Apollo Client factory function that can be used with Next.js server components.
|
|
11
|
-
*/
|
|
12
|
-
export declare const makeClient: (options?: I_ApolloOptions) => {
|
|
13
|
-
getClient: () => import('@apollo/client-integration-nextjs').ApolloClient;
|
|
14
|
-
query: <TData = unknown, TVariables extends import('@apollo/client').OperationVariables = import('@apollo/client').OperationVariables>(options: import("@apollo/client").ApolloClient.QueryOptions<TData, TVariables>) => Promise<import("@apollo/client").ApolloClient.QueryResult<import('@apollo/client').MaybeMasked<TData>>>;
|
|
15
|
-
PreloadQuery: import('@apollo/client-integration-nextjs').PreloadQueryComponent;
|
|
16
|
-
};
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './apollo-client-nextjs.util.js';
|
|
1
|
+
export {}
|
|
@@ -27,7 +27,10 @@ function c() {
|
|
|
27
27
|
};
|
|
28
28
|
if (!c) return null;
|
|
29
29
|
let p = "locations" in c || "path" in c || "extensions" in c, m = "message" in c ? c.message : "Unknown error occurred";
|
|
30
|
-
return /* @__PURE__ */ r.createElement("div", {
|
|
30
|
+
return /* @__PURE__ */ r.createElement("div", {
|
|
31
|
+
className: n["modal-backdrop"],
|
|
32
|
+
onClick: l
|
|
33
|
+
}, /* @__PURE__ */ r.createElement("div", {
|
|
31
34
|
ref: u,
|
|
32
35
|
className: n["modal-content"],
|
|
33
36
|
role: "dialog",
|
|
@@ -35,7 +38,8 @@ function c() {
|
|
|
35
38
|
"aria-labelledby": "apollo-error-title",
|
|
36
39
|
"aria-describedby": "apollo-error-details",
|
|
37
40
|
tabIndex: -1,
|
|
38
|
-
onKeyDown: f
|
|
41
|
+
onKeyDown: f,
|
|
42
|
+
onClick: (e) => e.stopPropagation()
|
|
39
43
|
}, /* @__PURE__ */ r.createElement("button", {
|
|
40
44
|
type: "button",
|
|
41
45
|
className: n["btn-close"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apollo-error.component.js","names":[],"sources":["../../../src/react/apollo-error/apollo-error.component.tsx"],"sourcesContent":["import * as React from 'react';\nimport { use, useEffect, useRef } from 'react';\n\nimport { validate } from '#util/validate/validate.util.js';\n\nimport { ApolloErrorContext } from './apollo-error.context.js';\nimport style from './apollo-error.module.scss';\n\nconst FOCUSABLE_SELECTORS = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Apollo Error Component that displays detailed error information in a modal.\n * This component provides a comprehensive error display interface that shows\n * GraphQL errors and other error types with detailed information for debugging purposes.\n *\n * Features:\n * - Modal overlay with backdrop for focus\n * - Detailed error categorization and display\n * - Reload functionality for error recovery\n * - Close button to dismiss the error modal\n * - Structured display of different error types\n * - Extra information display for debugging\n *\n * @returns A modal component displaying Apollo error details, or null if no error is present.\n */\nexport function ApolloErrorComponent() {\n const context = use(ApolloErrorContext);\n const { error, hideError } = context ?? {};\n const dialogRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!error || !hideError)\n return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n hideError();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [error, hideError]);\n\n useEffect(() => {\n if (error && dialogRef.current) {\n previousFocusRef.current = document.activeElement as HTMLElement;\n dialogRef.current.focus();\n }\n else if (!error && previousFocusRef.current) {\n previousFocusRef.current.focus();\n previousFocusRef.current = null;\n }\n }, [error]);\n\n const handleFocusTrap = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Tab' || !dialogRef.current)\n return;\n\n const focusableElements = [...dialogRef.current.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTORS)].filter(el => !el.hasAttribute('disabled'));\n\n if (focusableElements.length === 0)\n return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements.at(-1);\n\n if (!firstElement || !lastElement)\n return;\n\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n }\n else if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n };\n\n if (!error) {\n return null;\n }\n\n const isGraphQLError = 'locations' in error || 'path' in error || 'extensions' in error;\n const errorMessage = 'message' in error ? error.message : 'Unknown error occurred';\n\n return (\n <div className={style['modal-backdrop']}>\n <div\n ref={dialogRef}\n className={style['modal-content']}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"apollo-error-title\"\n aria-describedby=\"apollo-error-details\"\n tabIndex={-1}\n onKeyDown={handleFocusTrap}\n >\n <button\n type=\"button\"\n className={style['btn-close']}\n onClick={hideError}\n aria-label=\"Close error details (Esc)\"\n aria-keyshortcuts=\"Escape\"\n title=\"Close error details (Esc)\"\n >\n ✕\n </button>\n <div className={style['error-title']}>\n <button\n type=\"button\"\n className={style['btn-retry']}\n onClick={() => window.location.reload()}\n aria-label=\"Reload page\"\n >\n Reload\n </button>\n {' '}\n <span id=\"apollo-error-title\">\n {errorMessage || 'Error details'}\n </span>\n </div>\n <div id=\"apollo-error-details\" className={style['error-details']}>\n {isGraphQLError && 'locations' in error && error.locations && (\n <pre className=\"locations\">\n <strong>Locations:</strong>\n {' '}\n {JSON.stringify(error.locations, null, 4)}\n </pre>\n )}\n {isGraphQLError && 'path' in error && error.path && (\n <pre className=\"path\">\n <strong>Path:</strong>\n {' '}\n {JSON.stringify(error.path, null, 4)}\n </pre>\n )}\n {isGraphQLError && 'extensions' in error && error.extensions && (\n <pre className=\"extensions\">\n <strong>Extensions:</strong>\n {' '}\n {JSON.stringify(error.extensions, null, 4)}\n </pre>\n )}\n {!isGraphQLError && (\n <pre className=\"error-details\">\n <strong>Error Details:</strong>\n {' '}\n {validate.isEmpty(error) ? errorMessage : JSON.stringify(error, null, 4)}\n </pre>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;AAQA,IAAM,IAAsB;AAiB5B,SAAgB,IAAuB;CAEnC,IAAM,EAAE,UAAO,iBADC,EAAI,EAAmB,IACC,EAAE,EACpC,IAAY,EAAuB,KAAK,EACxC,IAAmB,EAA2B,KAAK;AAmBzD,CAjBA,QAAgB;AACZ,MAAI,CAAC,KAAS,CAAC,EACX;EAEJ,IAAM,KAAiB,MAAyB;AAC5C,GAAI,EAAM,QAAQ,YACd,GAAW;;AAMnB,SAFA,OAAO,iBAAiB,WAAW,EAAc,QAEpC;AACT,UAAO,oBAAoB,WAAW,EAAc;;IAEzD,CAAC,GAAO,EAAU,CAAC,EAEtB,QAAgB;AACZ,EAAI,KAAS,EAAU,WACnB,EAAiB,UAAU,SAAS,eACpC,EAAU,QAAQ,OAAO,IAEpB,CAAC,KAAS,EAAiB,YAChC,EAAiB,QAAQ,OAAO,EAChC,EAAiB,UAAU;IAEhC,CAAC,EAAM,CAAC;CAEX,IAAM,KAAmB,MAA+C;AACpE,MAAI,EAAM,QAAQ,SAAS,CAAC,EAAU,QAClC;EAEJ,IAAM,IAAoB,CAAC,GAAG,EAAU,QAAQ,iBAA8B,EAAoB,CAAC,CAAC,QAAO,MAAM,CAAC,EAAG,aAAa,WAAW,CAAC;AAE9I,MAAI,EAAkB,WAAW,EAC7B;EAEJ,IAAM,IAAe,EAAkB,IACjC,IAAc,EAAkB,GAAG,GAAG;AAExC,GAAC,KAAgB,CAAC,MAGlB,EAAM,WACF,SAAS,kBAAkB,MAC3B,EAAM,gBAAgB,EACtB,EAAY,OAAO,IAGlB,SAAS,kBAAkB,MAChC,EAAM,gBAAgB,EACtB,EAAa,OAAO;;AAI5B,KAAI,CAAC,EACD,QAAO;CAGX,IAAM,IAAiB,eAAe,KAAS,UAAU,KAAS,gBAAgB,GAC5E,IAAe,aAAa,IAAQ,EAAM,UAAU;AAE1D,QACI,kBAAA,cAAC,OAAD
|
|
1
|
+
{"version":3,"file":"apollo-error.component.js","names":[],"sources":["../../../src/react/apollo-error/apollo-error.component.tsx"],"sourcesContent":["import * as React from 'react';\nimport { use, useEffect, useRef } from 'react';\n\nimport { validate } from '#util/validate/validate.util.js';\n\nimport { ApolloErrorContext } from './apollo-error.context.js';\nimport style from './apollo-error.module.scss';\n\nconst FOCUSABLE_SELECTORS = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Apollo Error Component that displays detailed error information in a modal.\n * This component provides a comprehensive error display interface that shows\n * GraphQL errors and other error types with detailed information for debugging purposes.\n *\n * Features:\n * - Modal overlay with backdrop for focus\n * - Detailed error categorization and display\n * - Reload functionality for error recovery\n * - Close button to dismiss the error modal\n * - Structured display of different error types\n * - Extra information display for debugging\n *\n * @returns A modal component displaying Apollo error details, or null if no error is present.\n */\nexport function ApolloErrorComponent() {\n const context = use(ApolloErrorContext);\n const { error, hideError } = context ?? {};\n const dialogRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!error || !hideError)\n return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n hideError();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [error, hideError]);\n\n useEffect(() => {\n if (error && dialogRef.current) {\n previousFocusRef.current = document.activeElement as HTMLElement;\n dialogRef.current.focus();\n }\n else if (!error && previousFocusRef.current) {\n previousFocusRef.current.focus();\n previousFocusRef.current = null;\n }\n }, [error]);\n\n const handleFocusTrap = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Tab' || !dialogRef.current)\n return;\n\n const focusableElements = [...dialogRef.current.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTORS)].filter(el => !el.hasAttribute('disabled'));\n\n if (focusableElements.length === 0)\n return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements.at(-1);\n\n if (!firstElement || !lastElement)\n return;\n\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n }\n else if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n };\n\n if (!error) {\n return null;\n }\n\n const isGraphQLError = 'locations' in error || 'path' in error || 'extensions' in error;\n const errorMessage = 'message' in error ? error.message : 'Unknown error occurred';\n\n return (\n <div className={style['modal-backdrop']} onClick={hideError}>\n <div\n ref={dialogRef}\n className={style['modal-content']}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"apollo-error-title\"\n aria-describedby=\"apollo-error-details\"\n tabIndex={-1}\n onKeyDown={handleFocusTrap}\n onClick={e => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className={style['btn-close']}\n onClick={hideError}\n aria-label=\"Close error details (Esc)\"\n aria-keyshortcuts=\"Escape\"\n title=\"Close error details (Esc)\"\n >\n ✕\n </button>\n <div className={style['error-title']}>\n <button\n type=\"button\"\n className={style['btn-retry']}\n onClick={() => window.location.reload()}\n aria-label=\"Reload page\"\n >\n Reload\n </button>\n {' '}\n <span id=\"apollo-error-title\">\n {errorMessage || 'Error details'}\n </span>\n </div>\n <div id=\"apollo-error-details\" className={style['error-details']}>\n {isGraphQLError && 'locations' in error && error.locations && (\n <pre className=\"locations\">\n <strong>Locations:</strong>\n {' '}\n {JSON.stringify(error.locations, null, 4)}\n </pre>\n )}\n {isGraphQLError && 'path' in error && error.path && (\n <pre className=\"path\">\n <strong>Path:</strong>\n {' '}\n {JSON.stringify(error.path, null, 4)}\n </pre>\n )}\n {isGraphQLError && 'extensions' in error && error.extensions && (\n <pre className=\"extensions\">\n <strong>Extensions:</strong>\n {' '}\n {JSON.stringify(error.extensions, null, 4)}\n </pre>\n )}\n {!isGraphQLError && (\n <pre className=\"error-details\">\n <strong>Error Details:</strong>\n {' '}\n {validate.isEmpty(error) ? errorMessage : JSON.stringify(error, null, 4)}\n </pre>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './apollo-error.context.js';
|
|
3
|
-
export * from './apollo-error.hook.js';
|
|
4
|
-
export * from './apollo-error.provider.js';
|
|
5
|
-
export * from './apollo-error.type.js';
|
|
6
|
-
export * from './apollo-error.util.js';
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './i18next.util.js';
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './log.util.js';
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './storage.util.js';
|
|
1
|
+
export {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from './userback.type.js';
|
|
1
|
+
export {}
|