nsgm-cli 2.0.25 → 2.1.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.
@@ -0,0 +1,18 @@
1
+ module.exports = {
2
+ presets: [
3
+ ['next/babel', {
4
+ 'preset-env': {
5
+ targets: {
6
+ node: '18'
7
+ }
8
+ }
9
+ }]
10
+ ],
11
+ plugins: [
12
+ ['styled-components', {
13
+ ssr: true,
14
+ displayName: true,
15
+ preprocess: false
16
+ }]
17
+ ]
18
+ }
@@ -0,0 +1,8 @@
1
+ // src/components/Button.js
2
+ import React from 'react';
3
+
4
+ const Button = ({ onClick, children }) => (
5
+ <button onClick={onClick}>{children}</button>
6
+ );
7
+
8
+ export default Button;
@@ -0,0 +1,15 @@
1
+ // src/components/Button.test.js
2
+ import { render, screen, fireEvent } from '@testing-library/react';
3
+ import Button from '../Button';
4
+
5
+ test('renders button with text', () => {
6
+ render(<Button>Click me</Button>);
7
+ expect(screen.getByText('Click me')).toBeInTheDocument();
8
+ });
9
+
10
+ test('calls onClick when clicked', () => {
11
+ const handleClick = jest.fn();
12
+ render(<Button onClick={handleClick}>Click me</Button>);
13
+ fireEvent.click(screen.getByText('Click me'));
14
+ expect(handleClick).toHaveBeenCalledTimes(1);
15
+ });
@@ -1,15 +1,13 @@
1
1
  import { useMemo } from 'react'
2
2
  import { combineReducers } from 'redux'
3
- import { configureStore, Tuple } from '@reduxjs/toolkit'
4
- import { thunk } from 'redux-thunk'
3
+ import { configureStore, type EnhancedStore } from '@reduxjs/toolkit'
5
4
  import reducers from './reducers'
6
- import _ from 'lodash'
7
5
 
8
- let store: any
6
+ let store: EnhancedStore | undefined
9
7
 
10
- const reducersKeysLen = _.keys(reducers).length
8
+ const reducersKeysLen = Object.keys(reducers).length
11
9
 
12
- let combineReducer: any = function () { }
10
+ let combineReducer: any = () => ({})
13
11
 
14
12
  if (reducersKeysLen > 0) {
15
13
  combineReducer = combineReducers({ ...reducers })
@@ -17,17 +15,21 @@ if (reducersKeysLen > 0) {
17
15
 
18
16
  export type RootState = ReturnType<typeof combineReducer>
19
17
 
20
- function initStore(initialState: any) {
18
+ function initStore(initialState?: any): EnhancedStore {
21
19
  return configureStore({
22
20
  reducer: combineReducer,
23
21
  preloadedState: initialState,
24
- devTools: true,
22
+ devTools: process.env.NODE_ENV !== 'production',
25
23
  middleware: (getDefaultMiddleware) =>
26
- getDefaultMiddleware().concat(thunk),
24
+ getDefaultMiddleware({
25
+ serializableCheck: {
26
+ ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE'],
27
+ },
28
+ }),
27
29
  })
28
30
  }
29
31
 
30
- export const initializeStore = (preloadedState: any) => {
32
+ export const initializeStore = (preloadedState?: any): EnhancedStore => {
31
33
  let _store = store ?? initStore(preloadedState)
32
34
 
33
35
  if (preloadedState && store) {
@@ -45,7 +47,7 @@ export const initializeStore = (preloadedState: any) => {
45
47
  return _store
46
48
  }
47
49
 
48
- export function useStore(initialState: any) {
50
+ export function useStore(initialState?: any): EnhancedStore {
49
51
  const store = useMemo(() => initializeStore(initialState), [initialState])
50
52
  return store
51
53
  }
@@ -1,25 +1,54 @@
1
1
  import axios from 'axios'
2
2
  import { getLocalApiPrefix } from './common'
3
3
 
4
- export const getLocalGraphql = (query: string, variables: any = {}) => {
4
+ // 添加缓存机制
5
+ const queryCache = new Map<string, { data: any; timestamp: number }>()
6
+ const CACHE_DURATION = 5 * 60 * 1000 // 5分钟缓存
7
+
8
+ export const getLocalGraphql = (query: string, variables: any = {}, useCache = false) => {
5
9
  return new Promise((resolve, reject) => {
10
+ // 生成缓存键
11
+ const cacheKey = `${query}:${JSON.stringify(variables)}`
12
+
13
+ // 检查缓存
14
+ if (useCache && queryCache.has(cacheKey)) {
15
+ const cached = queryCache.get(cacheKey)!
16
+ if (Date.now() - cached.timestamp < CACHE_DURATION) {
17
+ resolve(cached.data)
18
+ return
19
+ }
20
+ }
21
+
6
22
  axios
7
23
  .post(getLocalApiPrefix() + '/graphql', {
8
24
  query,
9
25
  variables
10
26
  })
11
27
  .then((res) => {
12
- // console.log('axios_res', res)
13
28
  if (res) {
14
29
  const { data } = res
30
+
31
+ // 缓存结果
32
+ if (useCache && data && !data.errors) {
33
+ queryCache.set(cacheKey, {
34
+ data,
35
+ timestamp: Date.now()
36
+ })
37
+ }
38
+
15
39
  resolve(data)
16
40
  } else {
17
- reject()
41
+ reject(new Error('No data received'))
18
42
  }
19
43
  })
20
- .catch((_e) => {
21
- // console.error('axios_e', _e)
22
- reject(_e)
44
+ .catch((error) => {
45
+ console.error('GraphQL query failed:', error)
46
+ reject(error)
23
47
  })
24
48
  })
25
49
  }
50
+
51
+ // 清除缓存
52
+ export const clearGraphqlCache = () => {
53
+ queryCache.clear()
54
+ }
@@ -0,0 +1,87 @@
1
+ const js = require('@eslint/js');
2
+ const typescript = require('@typescript-eslint/eslint-plugin');
3
+ const typescriptParser = require('@typescript-eslint/parser');
4
+ const prettier = require('eslint-plugin-prettier');
5
+
6
+ module.exports = [
7
+ js.configs.recommended,
8
+ {
9
+ files: ['src/**/*.{ts,tsx}'],
10
+ languageOptions: {
11
+ parser: typescriptParser,
12
+ parserOptions: {
13
+ ecmaVersion: 2022,
14
+ sourceType: 'module',
15
+ project: './tsconfig.json'
16
+ },
17
+ globals: {
18
+ __dirname: 'readonly',
19
+ __filename: 'readonly',
20
+ process: 'readonly',
21
+ Buffer: 'readonly',
22
+ console: 'readonly',
23
+ setTimeout: 'readonly',
24
+ clearTimeout: 'readonly',
25
+ setInterval: 'readonly',
26
+ clearInterval: 'readonly'
27
+ }
28
+ },
29
+ plugins: {
30
+ '@typescript-eslint': typescript,
31
+ 'prettier': prettier
32
+ },
33
+ rules: {
34
+ 'no-console': 'off', // 允许 console 语句用于调试
35
+ 'no-eval': 'off',
36
+ 'no-undef': 'off',
37
+ 'no-unused-vars': 'off', // 关闭原生规则,使用 TypeScript 版本
38
+ 'no-case-declarations': 'off',
39
+ 'no-fallthrough': 'off',
40
+ 'prefer-const': 'warn',
41
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
42
+ 'no-unreachable': 'error',
43
+ 'no-duplicate-imports': 'error',
44
+ 'prefer-template': 'warn',
45
+ 'prefer-arrow-callback': 'warn',
46
+ '@typescript-eslint/no-var-requires': 'off', // 允许 require
47
+ '@typescript-eslint/no-explicit-any': 'warn', // 警告但不报错
48
+ '@typescript-eslint/no-unused-vars': ['warn', {
49
+ argsIgnorePattern: '^_',
50
+ varsIgnorePattern: '^_'
51
+ }],
52
+ '@typescript-eslint/no-inferrable-types': 'warn',
53
+ '@typescript-eslint/prefer-optional-chain': 'warn',
54
+ '@typescript-eslint/no-explicit-any': 'off',
55
+ 'prettier/prettier': 'error'
56
+ }
57
+ },
58
+ {
59
+ files: ['**/*.js'],
60
+ languageOptions: {
61
+ ecmaVersion: 2022,
62
+ sourceType: 'commonjs',
63
+ globals: {
64
+ require: 'readonly',
65
+ module: 'readonly',
66
+ exports: 'readonly',
67
+ __dirname: 'readonly',
68
+ __filename: 'readonly',
69
+ process: 'readonly',
70
+ Buffer: 'readonly',
71
+ console: 'readonly'
72
+ }
73
+ },
74
+ rules: {
75
+ 'no-console': 'off'
76
+ }
77
+ },
78
+ {
79
+ ignores: [
80
+ 'node_modules/**',
81
+ 'lib/**',
82
+ '.next/**',
83
+ 'coverage/**',
84
+ '*.config.js'
85
+ ]
86
+ }
87
+ ];
@@ -0,0 +1,16 @@
1
+ module.exports = {
2
+ env: {
3
+ node: true,
4
+ es2022: true
5
+ },
6
+ extends: [
7
+ 'eslint:recommended'
8
+ ],
9
+ parserOptions: {
10
+ ecmaVersion: 2022,
11
+ sourceType: 'module'
12
+ },
13
+ rules: {
14
+ 'no-console': 'off'
15
+ }
16
+ };
@@ -1,5 +1,5 @@
1
1
  const express = require('express')
2
- const moment = require('moment')
2
+ const dayjs = require('dayjs')
3
3
  const sso = require('./apis/sso')
4
4
  //const template = require('./apis/template')
5
5
 
@@ -7,7 +7,7 @@ const router = express.Router()
7
7
 
8
8
  router.use((req, res, next) => {
9
9
  const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl
10
- console.log(moment().format('YYYY-MM-DD HH:mm:ss') + ' ' + fullUrl)
10
+ console.log(dayjs().format('YYYY-MM-DD HH:mm:ss') + ' ' + fullUrl)
11
11
  next()
12
12
  })
13
13
 
@@ -1,7 +1,9 @@
1
1
  const { serverDB } = require('nsgm-cli')
2
2
 
3
- const { getConnection } = serverDB
3
+ const { getConnection, executeQuery, executePaginatedQuery } = serverDB
4
4
 
5
5
  module.exports = {
6
- getConnection
6
+ getConnection, // 兼容旧版本
7
+ executeQuery, // 新的查询方法
8
+ executePaginatedQuery // 新的分页查询方法
7
9
  }
@@ -20,7 +20,8 @@
20
20
  "incremental": true
21
21
  },
22
22
  "include": [
23
- "next-env.d.ts"
23
+ "**/*.ts",
24
+ "**/*.tsx"
24
25
  ],
25
26
  "exclude": [
26
27
  "node_modules"
package/jest.config.js ADDED
@@ -0,0 +1,29 @@
1
+ module.exports = {
2
+ testEnvironment: 'jsdom',
3
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
4
+ transform: {
5
+ '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }]
6
+ },
7
+ testMatch: [
8
+ '**/__tests__/**/*.(ts|tsx|js)',
9
+ '**/*.(test|spec).(ts|tsx|js)'
10
+ ],
11
+ collectCoverage: true,
12
+ collectCoverageFrom: [
13
+ 'client/**/*.{js,jsx,ts,tsx}',
14
+ 'pages/**/*.{js,jsx,ts,tsx}',
15
+ 'server/**/*.{js,jsx,ts,tsx}',
16
+ 'src/**/*.{js,jsx,ts,tsx}',
17
+ '!**/*.d.ts',
18
+ '!**/node_modules/**',
19
+ '!**/.next/**'
20
+ ],
21
+ coverageDirectory: 'coverage',
22
+ coverageReporters: ['json', 'lcov', 'text', 'clover'],
23
+ extensionsToTreatAsEsm: ['.ts', '.tsx'],
24
+ globals: {
25
+ 'ts-jest': {
26
+ useESM: true
27
+ }
28
+ }
29
+ }
package/lib/args.js CHANGED
@@ -4,24 +4,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getProcessArgvs = void 0;
7
- var lodash_1 = __importDefault(require("lodash"));
8
- var getProcessArgvs = function (removeItems) {
9
- if (removeItems === void 0) { removeItems = 2; }
10
- var args = process.argv.slice(removeItems);
11
- var result = {
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const getProcessArgvs = (removeItems = 2) => {
9
+ const args = process.argv.slice(removeItems);
10
+ const result = {
12
11
  command: '', // dev, start, build, export, create, delete, init, help
13
12
  dictionary: '', // export/init dictionary=${dictionary}
14
13
  controller: '',
15
14
  action: '' // create/delete controller=${controller} action=${action}
16
15
  };
17
- lodash_1.default.each(args, function (item, index) {
16
+ lodash_1.default.each(args, (item, index) => {
18
17
  if (item.indexOf('=') !== -1) {
19
- var itemArr = item.split('=');
20
- var key = itemArr[0].toLowerCase();
18
+ const itemArr = item.split('=');
19
+ const key = itemArr[0].toLowerCase();
21
20
  result[key] = itemArr[1];
22
21
  }
23
22
  else {
24
- var command = result.command;
23
+ const { command } = result;
25
24
  switch (index) {
26
25
  case 0:
27
26
  result.command = item;