3a-ecommerce-utils 1.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 (45) hide show
  1. package/README.md +163 -0
  2. package/dist/chunk-PEAZVBSD.mjs +597 -0
  3. package/dist/client-DYGi_pyp.d.mts +87 -0
  4. package/dist/client-DYGi_pyp.d.ts +87 -0
  5. package/dist/index.d.mts +496 -0
  6. package/dist/index.d.ts +496 -0
  7. package/dist/index.js +17707 -0
  8. package/dist/index.mjs +17043 -0
  9. package/dist/validation/server.d.mts +50 -0
  10. package/dist/validation/server.d.ts +50 -0
  11. package/dist/validation/server.js +518 -0
  12. package/dist/validation/server.mjs +168 -0
  13. package/package.json +69 -0
  14. package/src/api/address.queries.ts +96 -0
  15. package/src/api/category.queries.ts +85 -0
  16. package/src/api/coupon.queries.ts +120 -0
  17. package/src/api/dashboard.queries.ts +35 -0
  18. package/src/api/errorHandler.ts +164 -0
  19. package/src/api/graphqlClient.ts +113 -0
  20. package/src/api/index.ts +10 -0
  21. package/src/api/logger.client.ts +89 -0
  22. package/src/api/logger.ts +135 -0
  23. package/src/api/order.queries.ts +211 -0
  24. package/src/api/product.queries.ts +144 -0
  25. package/src/api/review.queries.ts +56 -0
  26. package/src/api/user.queries.ts +232 -0
  27. package/src/assets/3A.png +0 -0
  28. package/src/assets/index.ts +1 -0
  29. package/src/assets.d.ts +29 -0
  30. package/src/auth.ts +176 -0
  31. package/src/config/jest.backend.config.js +42 -0
  32. package/src/config/jest.frontend.config.js +50 -0
  33. package/src/config/postcss.config.js +6 -0
  34. package/src/config/tailwind.config.ts +70 -0
  35. package/src/config/tsconfig.base.json +36 -0
  36. package/src/config/vite.config.ts +86 -0
  37. package/src/config/vitest.base.config.ts +74 -0
  38. package/src/config/webpack.base.config.ts +126 -0
  39. package/src/constants/index.ts +312 -0
  40. package/src/cookies.ts +104 -0
  41. package/src/helpers.ts +400 -0
  42. package/src/index.ts +32 -0
  43. package/src/validation/client.ts +287 -0
  44. package/src/validation/index.ts +3 -0
  45. package/src/validation/server.ts +32 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Base Jest configuration for frontend React applications
3
+ * @type {import('jest').Config}
4
+ */
5
+ module.exports = {
6
+ preset: 'ts-jest',
7
+ testEnvironment: 'jsdom',
8
+ roots: ['<rootDir>/tests'],
9
+ setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],
10
+ moduleNameMapper: {
11
+ // Handle CSS imports
12
+ '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
13
+ // Handle @e-commerce packages - projects should override these
14
+ '^@e-commerce/utils$': '<rootDir>/tests/__mocks__/utils.ts',
15
+ '^@e-commerce/ui-library$': '<rootDir>/tests/__mocks__/ui-library.tsx',
16
+ '^@e-commerce/types$': '<rootDir>/tests/__mocks__/types.ts',
17
+ // Handle FontAwesome
18
+ '^@fortawesome/react-fontawesome$': '<rootDir>/tests/__mocks__/fontawesome.tsx',
19
+ },
20
+ transform: {
21
+ '^.+\\.tsx?$': [
22
+ 'ts-jest',
23
+ {
24
+ tsconfig: 'tsconfig.json',
25
+ },
26
+ ],
27
+ },
28
+ transformIgnorePatterns: ['/node_modules/(?!(zustand|@reduxjs/toolkit|@tanstack/react-query)/)'],
29
+ testMatch: ['**/*.test.ts', '**/*.test.tsx'],
30
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
31
+ collectCoverageFrom: [
32
+ 'src/**/*.{ts,tsx}',
33
+ '!src/**/*.d.ts',
34
+ '!src/main.tsx',
35
+ '!src/bootstrap.tsx',
36
+ '!src/vite-env.d.ts',
37
+ ],
38
+ coverageDirectory: 'coverage',
39
+ coverageReporters: ['text', 'lcov', 'html'],
40
+ coverageThreshold: {
41
+ global: {
42
+ branches: 70,
43
+ functions: 70,
44
+ lines: 70,
45
+ statements: 70,
46
+ },
47
+ },
48
+ testTimeout: 10000,
49
+ verbose: true,
50
+ };
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };
@@ -0,0 +1,70 @@
1
+ import theme from '../../../ui-library/src/theme/theme.json';
2
+ import daisyui from 'daisyui';
3
+
4
+ const baseConfig = {
5
+ darkMode: 'class',
6
+ content: ['./src*.{js,ts,jsx,tsx}'],
7
+ theme: {
8
+ extend: {
9
+ colors: {
10
+ primary: theme.colors.primary,
11
+ secondary: theme.colors.secondary,
12
+ accent: theme.colors.accent,
13
+ neutral: theme.colors.neutral,
14
+ },
15
+ fontFamily: {
16
+ sans: theme.typography.fontFamily.sans,
17
+ serif: theme.typography.fontFamily.serif,
18
+ mono: theme.typography.fontFamily.mono,
19
+ },
20
+ fontSize: theme.typography.fontSize,
21
+ fontWeight: theme.typography.fontWeight,
22
+ lineHeight: theme.typography.lineHeight,
23
+ spacing: theme.spacing,
24
+ borderRadius: theme.borderRadius,
25
+ boxShadow: theme.shadows,
26
+ screens: theme.breakpoints,
27
+ zIndex: theme.zIndex,
28
+ transitionDuration: {
29
+ fast: '150ms',
30
+ DEFAULT: '250ms',
31
+ slow: '350ms',
32
+ },
33
+ },
34
+ },
35
+ plugins: [daisyui],
36
+ daisyui: {
37
+ themes: [
38
+ {
39
+ light: {
40
+ primary: '#3b82f6',
41
+ secondary: '#10b981',
42
+ accent: '#f59e0b',
43
+ neutral: '#64748b',
44
+ 'base-100': '#ffffff',
45
+ 'base-200': '#f8fafc',
46
+ 'base-300': '#f1f5f9',
47
+ info: '#3b82f6',
48
+ success: '#10b981',
49
+ warning: '#f59e0b',
50
+ error: '#ef4444',
51
+ },
52
+ dark: {
53
+ primary: '#3b82f6',
54
+ secondary: '#10b981',
55
+ accent: '#f59e0b',
56
+ neutral: '#94a3b8',
57
+ 'base-100': '#0f172a',
58
+ 'base-200': '#1e293b',
59
+ 'base-300': '#334155',
60
+ info: '#3b82f6',
61
+ success: '#10b981',
62
+ warning: '#f59e0b',
63
+ error: '#ef4444',
64
+ },
65
+ },
66
+ ],
67
+ },
68
+ };
69
+
70
+ export default baseConfig;
@@ -0,0 +1,36 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "strict": true,
7
+ "noImplicitAny": true,
8
+ "strictNullChecks": true,
9
+ "strictFunctionTypes": true,
10
+ "strictBindCallApply": true,
11
+ "strictPropertyInitialization": true,
12
+ "noImplicitThis": true,
13
+ "alwaysStrict": true,
14
+ "noUnusedLocals": false,
15
+ "noUnusedParameters": false,
16
+ "noImplicitReturns": true,
17
+ "noFallthroughCasesInSwitch": true,
18
+ "jsx": "react-jsx",
19
+ "esModuleInterop": true,
20
+ "allowSyntheticDefaultImports": true,
21
+ "resolveJsonModule": true,
22
+ "isolatedModules": true,
23
+ "skipLibCheck": true,
24
+ "forceConsistentCasingInFileNames": true,
25
+ "baseUrl": ".",
26
+ "types": ["vite/client"],
27
+ "paths": {
28
+ "@e-commerce/types": ["../../packages/types/src"],
29
+ "@e-commerce/types/*": ["../../packages/types/src/*"],
30
+ "@e-commerce/ui-library": ["../../packages/ui-library/src"],
31
+ "@e-commerce/ui-library/*": ["../../packages/ui-library/src/*"],
32
+ "@e-commerce/utils": ["../../packages/utils/src"],
33
+ "@e-commerce/utils/*": ["../../packages/utils/src/*"]
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,86 @@
1
+ import { defineConfig, UserConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+ import * as path from 'path';
4
+
5
+ export function createBaseViteConfig(rootDir: string): UserConfig {
6
+ return defineConfig({
7
+ plugins: [react()],
8
+ css: {
9
+ postcss: path.resolve(rootDir, 'postcss.config.js'),
10
+ },
11
+ resolve: {
12
+ alias: {
13
+ '@e-commerce/ui-library': path.resolve(rootDir, '../../packages/ui-library/src'),
14
+ '@e-commerce/types': path.resolve(rootDir, '../../packages/types/src'),
15
+ '@e-commerce/utils': path.resolve(rootDir, '../../packages/utils/src'),
16
+ },
17
+ },
18
+ });
19
+ }
20
+
21
+ export async function createLibraryViteConfig(rootDir: string): Promise<UserConfig> {
22
+ const base = createBaseViteConfig(rootDir) as UserConfig;
23
+
24
+ const config: any = Object.assign({}, base);
25
+
26
+ config.build = config.build || {};
27
+ config.build.lib = {
28
+ entry: path.resolve(rootDir, 'src/index.ts'),
29
+ name: 'ui-library',
30
+ formats: ['es', 'cjs', 'umd'],
31
+ fileName: (format: string) => `ui-library.${format}.js`,
32
+ };
33
+ config.build.rollupOptions = config.build.rollupOptions || {};
34
+ config.build.rollupOptions.external = ['react', 'react-dom'];
35
+ config.build.rollupOptions.output = {
36
+ globals: {
37
+ react: 'React',
38
+ 'react-dom': 'ReactDOM',
39
+ },
40
+ };
41
+
42
+ const isVitest =
43
+ Boolean(process.env.VITEST) ||
44
+ Boolean(
45
+ process.env.npm_lifecycle_event && process.env.npm_lifecycle_event.includes('vitest')
46
+ ) ||
47
+ process.argv.join(' ').includes('vitest');
48
+
49
+ if (isVitest) {
50
+ // @ts-ignore - Dynamic import with fallback, module may not exist
51
+ const { storybookTest } = await import('@storybook/addon-vitest/vitest-plugin').catch(() => ({
52
+ storybookTest: undefined,
53
+ }));
54
+ // @ts-ignore - Dynamic import with fallback, module may not exist
55
+ const { playwright } = await import('@vitest/browser-playwright').catch(() => ({
56
+ playwright: undefined,
57
+ }));
58
+
59
+ if (storybookTest) {
60
+ config.test = {
61
+ projects: [
62
+ {
63
+ extends: true,
64
+ plugins: [
65
+ storybookTest({
66
+ configDir: path.join(rootDir, '.storybook'),
67
+ }),
68
+ ],
69
+ test: {
70
+ name: 'storybook',
71
+ browser: {
72
+ enabled: true,
73
+ headless: true,
74
+ provider: playwright ? playwright({}) : undefined,
75
+ instances: [{ browser: 'chromium' }],
76
+ },
77
+ setupFiles: ['.storybook/vitest.setup.ts'],
78
+ },
79
+ },
80
+ ],
81
+ };
82
+ }
83
+ }
84
+
85
+ return config;
86
+ }
@@ -0,0 +1,74 @@
1
+ import { defineConfig, UserConfig } from 'vitest/config';
2
+ import react from '@vitejs/plugin-react';
3
+ import * as path from 'path';
4
+
5
+ /**
6
+ * Base Vitest configuration for browser/React testing
7
+ */
8
+ export function createBrowserVitestConfig(rootDir: string, options?: {
9
+ setupFiles?: string[];
10
+ include?: string[];
11
+ coverageInclude?: string[];
12
+ coverageExclude?: string[];
13
+ }): UserConfig {
14
+ return defineConfig({
15
+ plugins: [react()],
16
+ test: {
17
+ globals: true,
18
+ environment: 'jsdom',
19
+ setupFiles: options?.setupFiles || ['./vitest.setup.ts'],
20
+ include: options?.include || ['src/**/*.test.{ts,tsx}', 'tests/**/*.test.{ts,tsx}'],
21
+ coverage: {
22
+ provider: 'v8',
23
+ reporter: ['text', 'json', 'html', 'lcov'],
24
+ include: options?.coverageInclude || ['src/**/*.{ts,tsx}'],
25
+ exclude: options?.coverageExclude || [
26
+ 'src/**/*.test.{ts,tsx}',
27
+ 'src/**/*.d.ts',
28
+ 'src/main.tsx',
29
+ 'src/bootstrap.tsx',
30
+ 'src/vite-env.d.ts',
31
+ ],
32
+ thresholds: {
33
+ lines: 80,
34
+ functions: 80,
35
+ branches: 70,
36
+ statements: 80,
37
+ },
38
+ },
39
+ },
40
+ resolve: {
41
+ alias: {
42
+ '@': path.resolve(rootDir, './src'),
43
+ '@e-commerce/ui-library': path.resolve(rootDir, '../../packages/ui-library/src'),
44
+ '@e-commerce/utils': path.resolve(rootDir, '../../packages/utils/src'),
45
+ '@e-commerce/types': path.resolve(rootDir, '../../packages/types/src'),
46
+ },
47
+ },
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Base Vitest configuration for Node.js/backend testing
53
+ */
54
+ export function createNodeVitestConfig(rootDir: string, options?: {
55
+ include?: string[];
56
+ coverageInclude?: string[];
57
+ coverageExclude?: string[];
58
+ }): UserConfig {
59
+ return defineConfig({
60
+ test: {
61
+ globals: true,
62
+ environment: 'node',
63
+ include: options?.include || ['tests/**/*.test.ts'],
64
+ coverage: {
65
+ provider: 'v8',
66
+ reporter: ['text', 'json', 'html'],
67
+ include: options?.coverageInclude || ['src/**/*.ts'],
68
+ exclude: options?.coverageExclude || ['src/**/*.d.ts'],
69
+ },
70
+ },
71
+ });
72
+ }
73
+
74
+ export { defineConfig };
@@ -0,0 +1,126 @@
1
+ import * as path from 'path';
2
+ import webpack, { Configuration } from 'webpack';
3
+ import type { Configuration as DevServerConfiguration } from 'webpack-dev-server';
4
+ import HtmlWebpackPlugin from 'html-webpack-plugin';
5
+ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
6
+
7
+ type WebpackConfiguration = Configuration & {
8
+ devServer?: DevServerConfiguration;
9
+ };
10
+
11
+ export interface WebpackBaseOptions {
12
+ rootDir: string;
13
+ entry?: string;
14
+ outputPath?: string;
15
+ publicPath?: string;
16
+ htmlTemplate?: string;
17
+ htmlTitle?: string;
18
+ devServerPort?: number;
19
+ }
20
+
21
+ /**
22
+ * Creates base Webpack configuration for shell/host applications
23
+ */
24
+ export function createBaseWebpackConfig(options: WebpackBaseOptions): WebpackConfiguration {
25
+ const {
26
+ rootDir,
27
+ entry = './src/index.tsx',
28
+ outputPath = 'dist',
29
+ publicPath = 'auto',
30
+ htmlTemplate = './public/index.html',
31
+ htmlTitle = 'E-Commerce App',
32
+ devServerPort = 3000,
33
+ } = options;
34
+
35
+ const isProduction = process.env.NODE_ENV === 'production';
36
+
37
+ return {
38
+ entry,
39
+ target: 'web',
40
+ output: {
41
+ path: path.resolve(rootDir, outputPath),
42
+ filename: 'bundle.[contenthash].js',
43
+ publicPath,
44
+ clean: true,
45
+ },
46
+ resolve: {
47
+ extensions: ['.tsx', '.ts', '.jsx', '.js'],
48
+ },
49
+ module: {
50
+ rules: [
51
+ {
52
+ test: /\.(png|jpe?g|gif|svg|webp)$/i,
53
+ type: 'asset/resource',
54
+ generator: {
55
+ filename: 'assets/images/[name].[hash][ext]',
56
+ },
57
+ },
58
+ {
59
+ test: /\.(ts|tsx)$/,
60
+ use: [
61
+ {
62
+ loader: 'babel-loader',
63
+ options: {
64
+ presets: [
65
+ '@babel/preset-react',
66
+ ['@babel/preset-typescript', { onlyRemoveTypeImports: true }],
67
+ ],
68
+ },
69
+ },
70
+ ],
71
+ exclude: /node_modules\/(?!@e-commerce)/,
72
+ },
73
+ {
74
+ test: /\.css$/,
75
+ use: [
76
+ isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
77
+ 'css-loader',
78
+ 'postcss-loader',
79
+ ],
80
+ },
81
+ ],
82
+ },
83
+ plugins: [
84
+ new HtmlWebpackPlugin({
85
+ template: htmlTemplate,
86
+ title: htmlTitle,
87
+ }),
88
+ new MiniCssExtractPlugin({
89
+ filename: '[name].[contenthash].css',
90
+ }),
91
+ ],
92
+ optimization: {
93
+ splitChunks: {
94
+ chunks: 'all',
95
+ cacheGroups: {
96
+ vendor: {
97
+ test: /[\\/]node_modules[\\/]/,
98
+ name: 'vendors',
99
+ priority: 10,
100
+ },
101
+ react: {
102
+ test: /[\\/]node_modules[\\/](react|react-dom|react-router-dom)[\\/]/,
103
+ name: 'react-vendor',
104
+ priority: 20,
105
+ },
106
+ uiLibrary: {
107
+ test: /[\\/]packages[\\/]ui-library[\\/]/,
108
+ name: 'ui-library',
109
+ priority: 15,
110
+ },
111
+ },
112
+ },
113
+ runtimeChunk: 'single',
114
+ },
115
+ performance: {
116
+ hints: false,
117
+ },
118
+ devServer: {
119
+ port: devServerPort,
120
+ hot: true,
121
+ historyApiFallback: true,
122
+ },
123
+ };
124
+ }
125
+
126
+ export { webpack, HtmlWebpackPlugin, MiniCssExtractPlugin };