@qlover/create-app 0.0.1

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 (144) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/bin/create-app.js +28 -0
  3. package/dist/cjs/index.d.ts +67 -0
  4. package/dist/cjs/index.js +1 -0
  5. package/dist/es/index.d.ts +67 -0
  6. package/dist/es/index.js +1 -0
  7. package/package.json +60 -0
  8. package/templates/fe-react/.env +3 -0
  9. package/templates/fe-react/README.md +50 -0
  10. package/templates/fe-react/config/app.common.ts +52 -0
  11. package/templates/fe-react/config/app.router.json +150 -0
  12. package/templates/fe-react/config/feapi.mock.json +14 -0
  13. package/templates/fe-react/config/i18n.ts +21 -0
  14. package/templates/fe-react/config/theme.json +90 -0
  15. package/templates/fe-react/eslint.config.js +31 -0
  16. package/templates/fe-react/index.html +13 -0
  17. package/templates/fe-react/lib/fe-react-controller/FeController.ts +15 -0
  18. package/templates/fe-react/lib/fe-react-controller/index.ts +2 -0
  19. package/templates/fe-react/lib/fe-react-controller/useController.ts +71 -0
  20. package/templates/fe-react/lib/fe-react-theme/ThemeController.ts +40 -0
  21. package/templates/fe-react/lib/fe-react-theme/ThemeStateGetter.ts +53 -0
  22. package/templates/fe-react/lib/fe-react-theme/index.ts +3 -0
  23. package/templates/fe-react/lib/fe-react-theme/tw-generator.js +239 -0
  24. package/templates/fe-react/lib/fe-react-theme/type.ts +21 -0
  25. package/templates/fe-react/lib/openAiApi/OpenAIAuthPlugin.ts +29 -0
  26. package/templates/fe-react/lib/openAiApi/OpenAIClient.ts +51 -0
  27. package/templates/fe-react/lib/openAiApi/StreamProcessor.ts +81 -0
  28. package/templates/fe-react/lib/openAiApi/index.ts +3 -0
  29. package/templates/fe-react/lib/request-common-plugin/index.ts +169 -0
  30. package/templates/fe-react/lib/tw-root10px/index.css +4 -0
  31. package/templates/fe-react/lib/tw-root10px/index.js +178 -0
  32. package/templates/fe-react/package.json +49 -0
  33. package/templates/fe-react/postcss.config.js +6 -0
  34. package/templates/fe-react/public/locales/en/about.json +3 -0
  35. package/templates/fe-react/public/locales/en/common.json +6 -0
  36. package/templates/fe-react/public/locales/en/executor.json +6 -0
  37. package/templates/fe-react/public/locales/en/home.json +10 -0
  38. package/templates/fe-react/public/locales/en/jsonStorage.json +11 -0
  39. package/templates/fe-react/public/locales/en/login.json +7 -0
  40. package/templates/fe-react/public/locales/en/request.json +15 -0
  41. package/templates/fe-react/public/locales/zh/about.json +3 -0
  42. package/templates/fe-react/public/locales/zh/common.json +7 -0
  43. package/templates/fe-react/public/locales/zh/executor.json +7 -0
  44. package/templates/fe-react/public/locales/zh/home.json +10 -0
  45. package/templates/fe-react/public/locales/zh/jsonStorage.json +11 -0
  46. package/templates/fe-react/public/locales/zh/login.json +8 -0
  47. package/templates/fe-react/public/locales/zh/request.json +15 -0
  48. package/templates/fe-react/public/logo.svg +1 -0
  49. package/templates/fe-react/src/App.tsx +20 -0
  50. package/templates/fe-react/src/assets/react.svg +1 -0
  51. package/templates/fe-react/src/components/Loading.tsx +41 -0
  52. package/templates/fe-react/src/components/LocaleLink.tsx +42 -0
  53. package/templates/fe-react/src/components/ProcessProvider.tsx +41 -0
  54. package/templates/fe-react/src/components/ThemeSwitcher.tsx +29 -0
  55. package/templates/fe-react/src/containers/context/BaseRouteContext.ts +27 -0
  56. package/templates/fe-react/src/containers/context/BaseRouteProvider.tsx +11 -0
  57. package/templates/fe-react/src/containers/globals.ts +31 -0
  58. package/templates/fe-react/src/containers/index.ts +71 -0
  59. package/templates/fe-react/src/hooks/useLanguageGuard.ts +25 -0
  60. package/templates/fe-react/src/hooks/useStrictEffect.ts +29 -0
  61. package/templates/fe-react/src/main.tsx +15 -0
  62. package/templates/fe-react/src/pages/404.tsx +14 -0
  63. package/templates/fe-react/src/pages/500.tsx +14 -0
  64. package/templates/fe-react/src/pages/auth/Layout.tsx +14 -0
  65. package/templates/fe-react/src/pages/auth/Login.tsx +62 -0
  66. package/templates/fe-react/src/pages/auth/Register.tsx +3 -0
  67. package/templates/fe-react/src/pages/base/About.tsx +12 -0
  68. package/templates/fe-react/src/pages/base/Executor.tsx +38 -0
  69. package/templates/fe-react/src/pages/base/Home.tsx +78 -0
  70. package/templates/fe-react/src/pages/base/JSONStorage.tsx +124 -0
  71. package/templates/fe-react/src/pages/base/Layout.tsx +17 -0
  72. package/templates/fe-react/src/pages/base/RedirectPathname.tsx +15 -0
  73. package/templates/fe-react/src/pages/base/Request.tsx +91 -0
  74. package/templates/fe-react/src/pages/base/components/BaseHeader.tsx +19 -0
  75. package/templates/fe-react/src/pages/index.tsx +108 -0
  76. package/templates/fe-react/src/services/controllers/ExecutorController.ts +56 -0
  77. package/templates/fe-react/src/services/controllers/JSONStorageController.ts +42 -0
  78. package/templates/fe-react/src/services/controllers/RequestController.ts +105 -0
  79. package/templates/fe-react/src/services/controllers/RouterController.ts +90 -0
  80. package/templates/fe-react/src/services/controllers/UserController.ts +146 -0
  81. package/templates/fe-react/src/services/feApi/FeApi.ts +51 -0
  82. package/templates/fe-react/src/services/feApi/FeApiMockPlugin.ts +42 -0
  83. package/templates/fe-react/src/services/feApi/FeApiType.ts +55 -0
  84. package/templates/fe-react/src/services/feApi/index.ts +2 -0
  85. package/templates/fe-react/src/services/i18n/index.ts +50 -0
  86. package/templates/fe-react/src/services/pageProcesser/PageProcesser.ts +29 -0
  87. package/templates/fe-react/src/services/pageProcesser/index.ts +1 -0
  88. package/templates/fe-react/src/styles/css/index.css +2 -0
  89. package/templates/fe-react/src/styles/css/page.css +3 -0
  90. package/templates/fe-react/src/styles/css/tailwind.css +3 -0
  91. package/templates/fe-react/src/types/Page.ts +49 -0
  92. package/templates/fe-react/src/types/UIDependenciesInterface.ts +31 -0
  93. package/templates/fe-react/src/types/global.d.ts +7 -0
  94. package/templates/fe-react/src/utils/RequestLogger.ts +34 -0
  95. package/templates/fe-react/src/utils/datetime.ts +25 -0
  96. package/templates/fe-react/src/utils/thread.ts +3 -0
  97. package/templates/fe-react/src/vite-env.d.ts +1 -0
  98. package/templates/fe-react/tailwind.config.js +18 -0
  99. package/templates/fe-react/tsconfig.app.json +29 -0
  100. package/templates/fe-react/tsconfig.json +7 -0
  101. package/templates/fe-react/tsconfig.node.json +22 -0
  102. package/templates/fe-react/vite.config.ts +32 -0
  103. package/templates/pack-app/.editorconfig +23 -0
  104. package/templates/pack-app/.env +5 -0
  105. package/templates/pack-app/.env.template +6 -0
  106. package/templates/pack-app/.gitattributes +2 -0
  107. package/templates/pack-app/.github/workflows/general-check.yml +50 -0
  108. package/templates/pack-app/.github/workflows/release.yml.template +110 -0
  109. package/templates/pack-app/.prettierignore +5 -0
  110. package/templates/pack-app/.prettierrc.js +3 -0
  111. package/templates/pack-app/CHANGELOG.md +0 -0
  112. package/templates/pack-app/README.md +1 -0
  113. package/templates/pack-app/eslint.config.js +77 -0
  114. package/templates/pack-app/fe-config.json +10 -0
  115. package/templates/pack-app/jest.config.js +31 -0
  116. package/templates/pack-app/package.json +66 -0
  117. package/templates/pack-app/packages/browser/__tests__/calc.test.ts +9 -0
  118. package/templates/pack-app/packages/browser/package.json +11 -0
  119. package/templates/pack-app/packages/browser/rollup.config.js +70 -0
  120. package/templates/pack-app/packages/browser/src/calc.ts +3 -0
  121. package/templates/pack-app/packages/browser/src/index.ts +1 -0
  122. package/templates/pack-app/packages/browser/tsconfig.json +15 -0
  123. package/templates/pack-app/packages/node/__tests__/readJson.test.ts +25 -0
  124. package/templates/pack-app/packages/node/package.json +11 -0
  125. package/templates/pack-app/packages/node/rollup.config.js +89 -0
  126. package/templates/pack-app/packages/node/src/index.ts +7 -0
  127. package/templates/pack-app/packages/node/src/readJson.ts +6 -0
  128. package/templates/pack-app/packages/node/tsconfig.json +17 -0
  129. package/templates/pack-app/packages/react-vite-lib/README.md +50 -0
  130. package/templates/pack-app/packages/react-vite-lib/__tests__/Sum.test.ts +9 -0
  131. package/templates/pack-app/packages/react-vite-lib/__tests__/Text.test.tsx +11 -0
  132. package/templates/pack-app/packages/react-vite-lib/eslint.config.js +28 -0
  133. package/templates/pack-app/packages/react-vite-lib/index.html +13 -0
  134. package/templates/pack-app/packages/react-vite-lib/package.json +30 -0
  135. package/templates/pack-app/packages/react-vite-lib/public/vite.svg +1 -0
  136. package/templates/pack-app/packages/react-vite-lib/src/calc.ts +3 -0
  137. package/templates/pack-app/packages/react-vite-lib/src/commponents/Text.tsx +7 -0
  138. package/templates/pack-app/packages/react-vite-lib/src/index.ts +2 -0
  139. package/templates/pack-app/packages/react-vite-lib/src/vite-env.d.ts +1 -0
  140. package/templates/pack-app/packages/react-vite-lib/tsconfig.json +25 -0
  141. package/templates/pack-app/packages/react-vite-lib/vite.config.ts +24 -0
  142. package/templates/pack-app/pnpm-workspace.yaml +2 -0
  143. package/templates/pack-app/tsconfig.json +9 -0
  144. package/templates/pack-app/tsconfig.test.json +10 -0
@@ -0,0 +1,51 @@
1
+ import {
2
+ RequestAdapterFetch,
3
+ RequestAdapterConfig,
4
+ RequestScheduler,
5
+ FetchAbortPlugin,
6
+ RequestAdapterFetchConfig
7
+ } from '@qlover/fe-utils';
8
+ import {
9
+ FeApiGetIpInfo,
10
+ FeApiGetRandomUser,
11
+ FeApiGetUserInfo,
12
+ FeApiLogin
13
+ } from './FeApiType';
14
+
15
+ export class FeApi extends RequestScheduler<RequestAdapterConfig> {
16
+ private abortPlugin: FetchAbortPlugin;
17
+
18
+ constructor({
19
+ abortPlugin,
20
+ config
21
+ }: {
22
+ abortPlugin: FetchAbortPlugin;
23
+ config?: Partial<RequestAdapterFetchConfig>;
24
+ }) {
25
+ super(new RequestAdapterFetch(config));
26
+ this.abortPlugin = abortPlugin;
27
+ }
28
+
29
+ stop(config: RequestAdapterConfig): void {
30
+ this.abortPlugin.abort(config);
31
+ }
32
+
33
+ async getIpInfo(): Promise<FeApiGetIpInfo['response']> {
34
+ return this.get('http://ip-api.com/json/');
35
+ }
36
+
37
+ async getRandomUser(): Promise<FeApiGetRandomUser['response']> {
38
+ return this.get('https://randomuser.me/api/');
39
+ }
40
+
41
+ async getUserInfo(): Promise<FeApiGetUserInfo['response']> {
42
+ return this.get('/api/userinfo');
43
+ }
44
+
45
+ async login(params: FeApiLogin['request']): Promise<FeApiLogin['response']> {
46
+ return this.post('/api/login', {
47
+ // FIXME: RequestAdapterResponse response type error
48
+ data: params as unknown as FeApiLogin['response']['data']
49
+ });
50
+ }
51
+ }
@@ -0,0 +1,42 @@
1
+ import {
2
+ ExecutorContext,
3
+ ExecutorPlugin,
4
+ RequestAdapterFetchConfig,
5
+ RequestAdapterResponse
6
+ } from '@qlover/fe-utils';
7
+ import { sleep } from '@/utils/thread';
8
+
9
+ export class FeApiMockPlugin implements ExecutorPlugin {
10
+ readonly pluginName = 'FeApiMockPlugin';
11
+
12
+ constructor(private readonly mockDataJson: typeof import('@config/feapi.mock.json')) {}
13
+
14
+ async onExec({
15
+ parameters
16
+ }: ExecutorContext<RequestAdapterFetchConfig>): Promise<RequestAdapterResponse> {
17
+ const { method = 'GET', url = '', headers } = parameters;
18
+ const key = `${method.toUpperCase()} ${url}`;
19
+ const mockData = url
20
+ ? this.mockDataJson[key as keyof typeof this.mockDataJson] ||
21
+ this.mockDataJson._default
22
+ : this.mockDataJson._default;
23
+
24
+ const response = new Response(JSON.stringify(mockData), {
25
+ status: 200,
26
+ statusText: 'OK'
27
+ });
28
+
29
+ console.log('jj [mock]', key, mockData, headers);
30
+
31
+ await sleep(1000);
32
+
33
+ return {
34
+ status: response.status,
35
+ statusText: response.statusText,
36
+ headers: Object.fromEntries(response.headers.entries()),
37
+ data: mockData,
38
+ config: parameters,
39
+ response
40
+ };
41
+ }
42
+ }
@@ -0,0 +1,55 @@
1
+ import { RequestAdapterResponse } from '@qlover/fe-utils';
2
+
3
+ export type FeApiType<Request, Response> = {
4
+ request: Request;
5
+ response: RequestAdapterResponse<Request, Response>;
6
+ };
7
+ export type FeApiGetIpInfo = FeApiType<
8
+ undefined,
9
+ {
10
+ status: string;
11
+ country: string;
12
+ countryCode: string;
13
+ region: string;
14
+ regionName: string;
15
+ city: string;
16
+ zip: string;
17
+ lat: number;
18
+ lon: number;
19
+ timezone: string;
20
+ isp: string;
21
+ org: string;
22
+ as: string;
23
+ query: string;
24
+ }
25
+ >;
26
+
27
+ export type FeApiGetRandomUser = FeApiType<
28
+ undefined,
29
+ {
30
+ results: unknown[];
31
+ info: {
32
+ seed: string;
33
+ results: number;
34
+ page: number;
35
+ version: string;
36
+ };
37
+ }
38
+ >;
39
+
40
+
41
+ export type FeApiGetUserInfo = FeApiType<
42
+ string,
43
+ {
44
+ name: string;
45
+ email: string;
46
+ picture: string;
47
+ }
48
+ >;
49
+
50
+ export type FeApiLogin = FeApiType<
51
+ { username: string; password: string },
52
+ {
53
+ token: string;
54
+ }
55
+ >;
@@ -0,0 +1,2 @@
1
+ export * from './FeApiMockPlugin';
2
+ export * from './FeApi';
@@ -0,0 +1,50 @@
1
+ import i18n from 'i18next';
2
+ import { initReactI18next } from 'react-i18next';
3
+ import LanguageDetector from 'i18next-browser-languagedetector';
4
+ import HttpApi from 'i18next-http-backend';
5
+ import merge from 'lodash/merge';
6
+ import { i18nConfig, I18nServiceLocale } from '@config/i18n';
7
+
8
+ // custom language detector
9
+ const pathLanguageDetector = {
10
+ name: 'pathLanguageDetector',
11
+ lookup() {
12
+ const path = window.location.pathname.split('/');
13
+ const language = path[1];
14
+ return I18nService.isValidLanguage(language)
15
+ ? language
16
+ : i18nConfig.fallbackLng;
17
+ },
18
+ cacheUserLanguage() {
19
+ // no cache, because we get language from URL
20
+ }
21
+ };
22
+
23
+ export class I18nService {
24
+ static init(): void {
25
+ i18n
26
+ .use(HttpApi)
27
+ .use(LanguageDetector)
28
+ .use(initReactI18next)
29
+ .init(
30
+ merge({}, i18nConfig, {
31
+ detection: {
32
+ order: ['pathLanguageDetector', 'navigator'], // use custom detector
33
+ caches: []
34
+ }
35
+ })
36
+ );
37
+
38
+ // add custom detector
39
+ i18n.services.languageDetector.addDetector(pathLanguageDetector);
40
+ }
41
+
42
+ /**
43
+ * check if the language is supported
44
+ * @param language - language to check
45
+ * @returns true if the language is supported, false otherwise
46
+ */
47
+ static isValidLanguage(language: string): language is I18nServiceLocale {
48
+ return i18nConfig.supportedLngs.includes(language as I18nServiceLocale);
49
+ }
50
+ }
@@ -0,0 +1,29 @@
1
+ import { AsyncExecutor, ExecutorPlugin, Logger } from '@qlover/fe-utils';
2
+
3
+ export interface PageProcesserOptions {
4
+ logger: Logger;
5
+ }
6
+
7
+ export class PageProcesser {
8
+ private executor: AsyncExecutor;
9
+ constructor(private options: PageProcesserOptions) {
10
+ this.executor = new AsyncExecutor();
11
+ }
12
+
13
+ usePlugin(plugin: ExecutorPlugin): this {
14
+ this.executor.use(plugin);
15
+ return this;
16
+ }
17
+
18
+ handler(): Promise<{ success: boolean }> {
19
+ return Promise.resolve({
20
+ success: true,
21
+ });
22
+ }
23
+
24
+ init(): Promise<unknown> {
25
+ return this.executor.exec(this.handler).catch(() => {
26
+ this.options.logger.error('PageProcesser init failed');
27
+ });
28
+ }
29
+ }
@@ -0,0 +1 @@
1
+ export * from './PageProcesser';
@@ -0,0 +1,2 @@
1
+ @import './tailwind.css';
2
+ @import './page.css';
@@ -0,0 +1,3 @@
1
+ html {
2
+ @apply bg-white;
3
+ }
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -0,0 +1,49 @@
1
+ import { LazyExoticComponent, PropsWithChildren } from 'react';
2
+ import { RouteObject } from 'react-router-dom';
3
+
4
+ import { TFunction } from 'i18next';
5
+ import { UseTranslationResponse } from 'react-i18next';
6
+
7
+ export interface BasePageProvider {
8
+ meta: RouteMeta;
9
+ i18n: UseTranslationResponse<string, string>;
10
+ t: TFunction<string, string>;
11
+ }
12
+
13
+ export type RouteCategory = 'main' | 'auth' | 'common';
14
+
15
+ export interface RouteMeta {
16
+ category?: RouteCategory;
17
+ /**
18
+ * from app.router.json
19
+ */
20
+ title?: string;
21
+ icon?: string;
22
+ /**
23
+ * from app.router.json
24
+ *
25
+ * @default 'common'
26
+ */
27
+ localNamespace?: string;
28
+ }
29
+
30
+ export type RouteType = RouteObject & {
31
+ meta?: RouteMeta;
32
+ };
33
+
34
+ export type RouteConfig = {
35
+ routes: RouteType[];
36
+ };
37
+
38
+ export type PagesMaps = Record<
39
+ string,
40
+ | (() => LazyExoticComponent<React.ComponentType<unknown>>)
41
+ | (() => React.ComponentType<unknown>)
42
+ >;
43
+
44
+ export type LoadProps = {
45
+ pagesMaps: PagesMaps;
46
+ componentPath: string;
47
+ route: RouteType;
48
+ Provider?: React.ComponentType<PropsWithChildren<RouteMeta>>;
49
+ };
@@ -0,0 +1,31 @@
1
+ export interface UIDependenciesInterface<Dep = unknown> {
2
+ /**
3
+ * Represents the dependencies required by the UI component.
4
+ *
5
+ * @type {Dep}
6
+ * @description This allows for partial updates to the dependencies if `Dep` is an object, enabling flexibility in dependency management.
7
+ *
8
+ * @example
9
+ * const uiDependencies: UIDependenciesInterface<{ api: string, token: string }> = {
10
+ * dependencies: { api: 'https://api.example.com' }
11
+ * };
12
+ *
13
+ * const simpleDependencies: UIDependenciesInterface<string> = {
14
+ * dependencies: 'simple-dependency'
15
+ * };
16
+ */
17
+ dependencies?: Dep;
18
+
19
+ /**
20
+ * Sets the dependencies for the UI component.
21
+ *
22
+ * @param {Dep} dependencies - The dependencies to be set, allowing partial updates if `Dep` is an object.
23
+ * @description This method allows updating the dependencies, supporting partial updates if `Dep` is an object.
24
+ *
25
+ * @example
26
+ * uiDependencies.setDependencies({ token: 'new-token' });
27
+ *
28
+ * simpleDependencies.setDependencies('new-simple-dependency');
29
+ */
30
+ setDependencies(dependencies: Dep): void;
31
+ }
@@ -0,0 +1,7 @@
1
+ import * as feGlobals from '@/containers/globals';
2
+
3
+ declare global {
4
+ interface Window {
5
+ feGlobals: Readonly<typeof feGlobals>;
6
+ }
7
+ }
@@ -0,0 +1,34 @@
1
+ import {
2
+ ExecutorPlugin,
3
+ ExecutorContext,
4
+ RequestAdapterFetchConfig,
5
+ Logger
6
+ } from '@qlover/fe-utils';
7
+
8
+ export class RequestLogger
9
+ implements ExecutorPlugin<RequestAdapterFetchConfig>
10
+ {
11
+ readonly pluginName = 'RequestLogger';
12
+
13
+ constructor(public logger: Logger) {}
14
+
15
+ async onSuccess({
16
+ parameters,
17
+ returnValue
18
+ }: ExecutorContext<RequestAdapterFetchConfig>): Promise<void> {
19
+ this.logger.info(
20
+ `Request [${new Date().toLocaleString()}] ${parameters.method} ${parameters.url} [success] `,
21
+ returnValue
22
+ );
23
+ }
24
+
25
+ onError({
26
+ parameters,
27
+ error
28
+ }: ExecutorContext<RequestAdapterFetchConfig>): void {
29
+ this.logger.error(
30
+ `Request [${new Date().toLocaleString()}] ${parameters.method} ${parameters.url} [error] `,
31
+ error
32
+ );
33
+ }
34
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Adjusts the expiration time based on the provided `expiresIn` value.
3
+ *
4
+ * @param {number} baseTime - The base time in milliseconds to adjust.
5
+ * @returns {number} - The adjusted time in milliseconds.
6
+ *
7
+ * @example
8
+ * const adjustedTime = userController.adjustExpirationTime(Date.now());
9
+ */
10
+ export function adjustExpirationTime(baseTime: number, expiresIn: number | 'day' | 'week' | 'month' | 'year'): number {
11
+ const dayInMs = 24 * 60 * 60 * 1000;
12
+
13
+ switch (expiresIn) {
14
+ case 'day':
15
+ return baseTime + dayInMs;
16
+ case 'week':
17
+ return baseTime + 7 * dayInMs;
18
+ case 'month':
19
+ return baseTime + 30 * dayInMs; // Approximation
20
+ case 'year':
21
+ return baseTime + 365 * dayInMs; // Approximation
22
+ default:
23
+ return baseTime + (typeof expiresIn === 'number' ? expiresIn : 30 * dayInMs);
24
+ }
25
+ }
@@ -0,0 +1,3 @@
1
+ export function sleep(ms: number = 100): Promise<void> {
2
+ return new Promise((resolve) => setTimeout(resolve, ms));
3
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,18 @@
1
+ import root10px from './lib/tw-root10px';
2
+ import themeCreate from './lib/fe-react-theme/tw-generator';
3
+ import themeConfig from './config/theme.json';
4
+
5
+ const theme = themeCreate(themeConfig.override);
6
+
7
+ /** @type {import('tailwindcss').Config} */
8
+ export default {
9
+ darkMode: 'class',
10
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
11
+ theme: {
12
+ extend: {
13
+ ...root10px.themes,
14
+ colors: theme.colors
15
+ }
16
+ },
17
+ plugins: [root10px.plugin, theme.plugin]
18
+ };
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "isolatedModules": true,
12
+ "moduleDetection": "force",
13
+ "noEmit": true,
14
+ "jsx": "react-jsx",
15
+
16
+ "strict": true,
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "noFallthroughCasesInSwitch": true,
20
+ "baseUrl": ".",
21
+ "paths": {
22
+ "@/*": ["./src/*"],
23
+ "@lib/*": ["./lib/*"],
24
+ "@config/*": ["./config/*"],
25
+ "packages/*": ["../../packages/*"]
26
+ }
27
+ },
28
+ "include": ["src", "config", "lib"]
29
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2023"],
5
+ "module": "ESNext",
6
+ "skipLibCheck": true,
7
+
8
+ /* Bundler mode */
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "isolatedModules": true,
12
+ "moduleDetection": "force",
13
+ "noEmit": true,
14
+
15
+ /* Linting */
16
+ "strict": true,
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "noFallthroughCasesInSwitch": true
20
+ },
21
+ "include": ["vite.config.ts"]
22
+ }
@@ -0,0 +1,32 @@
1
+ import { defineConfig } from 'vite';
2
+ import alias from '@rollup/plugin-alias';
3
+ // import react from '@vitejs/plugin-react-swc';
4
+ import react from '@vitejs/plugin-react';
5
+ import path from 'node:path';
6
+ import tsappconfig from './tsconfig.app.json';
7
+ import { searchEnv } from '@qlover/fe-scripts';
8
+
9
+ searchEnv({});
10
+
11
+ const tsAppPaths = tsappconfig.compilerOptions.paths || {};
12
+
13
+ const entries = Object.entries(tsAppPaths).map(([key, value]) => {
14
+ return {
15
+ find: key.replace('/*', ''),
16
+ replacement: path.resolve(__dirname, value[0].replace('/*', ''))
17
+ };
18
+ });
19
+
20
+ // https://vite.dev/config/
21
+ export default defineConfig({
22
+ plugins: [
23
+ react(),
24
+ alias({
25
+ entries
26
+ })
27
+ ],
28
+ publicDir: 'public',
29
+ server: {
30
+ port: Number(process.env.VITE_SERVER_PORT || 3100)
31
+ }
32
+ });
@@ -0,0 +1,23 @@
1
+ # EditorConfig helps developers define and maintain consistent
2
+ # coding styles between different editors and IDEs
3
+ # editorconfig.org
4
+
5
+ root = true
6
+
7
+ [*]
8
+
9
+ # We recommend you to keep these unchanged
10
+ end_of_line = lf
11
+ charset = utf-8
12
+ trim_trailing_whitespace = true
13
+ insert_final_newline = true
14
+
15
+ # Change these settings to your own preference
16
+ indent_style = space
17
+ indent_size = 2
18
+
19
+ [*.{ts,tsx,js,jsx,json,css,scss,yml,yaml,html,vue,md}]
20
+ indent_size = 2
21
+
22
+ [*.md]
23
+ trim_trailing_whitespace = false
@@ -0,0 +1,5 @@
1
+ NODE_ENV=production
2
+ NPM_TOKEN=
3
+ GITHUB_TOKEN=
4
+ FE_RELEASE_BRANCH=master
5
+ FE_RELEASE=false
@@ -0,0 +1,6 @@
1
+ NODE_ENV=production
2
+ NPM_TOKEN=
3
+ GITHUB_TOKEN=
4
+ FE_RELEASE_BRANCH=master
5
+ FE_RELEASE=false
6
+ FE_RELEASE_ENV=production
@@ -0,0 +1,2 @@
1
+ * text=auto
2
+ * eol=lf
@@ -0,0 +1,50 @@
1
+ name: General check
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - master
7
+ types: [opened, synchronize, reopened]
8
+
9
+ jobs:
10
+ check-code:
11
+ if: |
12
+ !contains(github.event.pull_request.title, 'chore(tag):') &&
13
+ !contains(join(github.event.pull_request.commits.*.message, ' '), 'chore(tag):')
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ # - name: Print GitHub Event Information
18
+ # run: echo "${{ toJson(github.event) }}" > event.json
19
+ - name: Checkout repository
20
+ uses: actions/checkout@v3
21
+ with:
22
+ fetch-depth: 0
23
+
24
+ - name: Install Node.js
25
+ uses: actions/setup-node@v2
26
+ with:
27
+ node-version: '18.19.0'
28
+
29
+ - name: Install dependencies
30
+ run: |
31
+ npm install -g yarn
32
+ yarn
33
+
34
+ - name: Lint
35
+ run: yarn lint
36
+
37
+ - name: Test
38
+ run: yarn test
39
+
40
+ - name: Build dist
41
+ run: yarn build
42
+
43
+ # check packages
44
+ # - name: Check packages
45
+ # run: |
46
+ # git fetch origin ${{ github.base_ref }}
47
+ # npm run check-packages -- -r ${{ github.repository }} -b ${{ github.base_ref }} -n ${{ github.event.pull_request.number }}
48
+ # env:
49
+ # GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
50
+ # PAT_TOKEN: ${{ secrets.PAT_TOKEN }}