nsgm-cli 2.1.41 → 2.1.42

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.
@@ -1,14 +1,14 @@
1
- import React, { useEffect, useState } from "react";
1
+ import { useEffect, useState, ReactNode, FC } from "react";
2
2
  import { ThemeProvider } from "styled-components";
3
3
  import { GlobalStyle } from "@/styled/common";
4
4
 
5
5
  interface ClientProvidersProps {
6
- children: React.ReactNode;
6
+ children: ReactNode;
7
7
  theme: any;
8
8
  whiteColor?: boolean;
9
9
  }
10
10
 
11
- const ClientProviders: React.FC<ClientProvidersProps> = ({ children, theme, whiteColor = true }) => {
11
+ const ClientProviders: FC<ClientProvidersProps> = ({ children, theme, whiteColor = true }) => {
12
12
  const [isClient, setIsClient] = useState(false);
13
13
 
14
14
  useEffect(() => {
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from "react";
1
+ import { useEffect, useState, CSSProperties, FC } from "react";
2
2
  import { Select } from "antd";
3
3
  import { useRouter } from "next/router";
4
4
  import { GlobalOutlined } from "@ant-design/icons";
@@ -6,11 +6,11 @@ import { GlobalOutlined } from "@ant-design/icons";
6
6
  const { Option } = Select;
7
7
 
8
8
  interface LanguageSwitcherProps {
9
- style?: React.CSSProperties;
9
+ style?: CSSProperties;
10
10
  size?: "small" | "middle" | "large";
11
11
  }
12
12
 
13
- const LanguageSwitcher: React.FC<LanguageSwitcherProps> = ({ style, size = "middle" }) => {
13
+ const LanguageSwitcher: FC<LanguageSwitcherProps> = ({ style, size = "middle" }) => {
14
14
  const router = useRouter();
15
15
  const [mounted, setMounted] = useState(false);
16
16
  const [currentLocale, setCurrentLocale] = useState("zh-CN");
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from "react";
1
+ import { useEffect, useState, ReactNode } from "react";
2
2
  import { Layout, Menu, Dropdown, Space } from "antd";
3
3
  import {
4
4
  Container,
@@ -28,7 +28,7 @@ interface MenuItem {
28
28
  key: string;
29
29
  text: string;
30
30
  url: string;
31
- icon?: React.ReactNode;
31
+ icon?: ReactNode;
32
32
  subMenus?: SubMenuItem[];
33
33
  }
34
34
 
@@ -27,24 +27,25 @@
27
27
  "nsgm-cli": "^2"
28
28
  },
29
29
  "devDependencies": {
30
- "@types/node": "^20",
31
- "@types/react": "^18",
32
- "@types/lodash": "^4",
33
- "typescript": "^5",
34
- "jest": "^30",
35
- "jest-environment-jsdom": "^30",
36
- "@testing-library/jest-dom": "^6",
37
- "@testing-library/react": "^14",
38
- "@testing-library/user-event": "^14",
39
- "@typescript-eslint/eslint-plugin": "^8",
40
- "@typescript-eslint/parser": "^8",
41
- "@types/jest": "^30",
42
- "eslint": "^9",
43
- "eslint-config-prettier": "^10",
44
- "eslint-plugin-prettier": "^5",
45
- "prettier": "^3",
46
- "next-i18next": "^15",
47
- "react-i18next": "^15",
48
- "i18next": "^24"
30
+ "@types/node": "^24.1.0",
31
+ "@types/react": "^18.3.23",
32
+ "@types/react-dom": "^18.3.7",
33
+ "@types/lodash": "^4.17.20",
34
+ "typescript": "^5.8.3",
35
+ "jest": "^30.0.5",
36
+ "jest-environment-jsdom": "^30.0.5",
37
+ "@testing-library/jest-dom": "^6.6.3",
38
+ "@testing-library/react": "^16.3.0",
39
+ "@testing-library/user-event": "^14.6.1",
40
+ "@types/jest": "^30.0.0",
41
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
42
+ "@typescript-eslint/parser": "^8.38.0",
43
+ "eslint": "^9.31.0",
44
+ "eslint-config-prettier": "^10.1.8",
45
+ "eslint-plugin-prettier": "^5.5.3",
46
+ "prettier": "^3.6.2",
47
+ "next-i18next": "^15.3.0",
48
+ "react-i18next": "^15.2.0",
49
+ "i18next": "^24.1.0"
49
50
  }
50
- }
51
+ }
@@ -4,6 +4,14 @@ import { BaseGenerator } from "./base-generator";
4
4
  * 自动生成对应的 DataLoader JavaScript 文件
5
5
  */
6
6
  export declare class DataLoaderGenerator extends BaseGenerator {
7
+ /**
8
+ * 可能的 JSON 字段名(需要自动解析)
9
+ */
10
+ private jsonFieldNames;
11
+ /**
12
+ * 获取可能是 JSON 的字段
13
+ */
14
+ private getJsonFields;
7
15
  generate(): string;
8
16
  /**
9
17
  * 生成外键 DataLoader
@@ -7,13 +7,66 @@ const base_generator_1 = require("./base-generator");
7
7
  * 自动生成对应的 DataLoader JavaScript 文件
8
8
  */
9
9
  class DataLoaderGenerator extends base_generator_1.BaseGenerator {
10
+ constructor() {
11
+ super(...arguments);
12
+ /**
13
+ * 可能的 JSON 字段名(需要自动解析)
14
+ */
15
+ this.jsonFieldNames = [
16
+ "images",
17
+ "photos",
18
+ "gallery",
19
+ "metadata",
20
+ "attributes",
21
+ "specs",
22
+ "options",
23
+ "settings",
24
+ "config",
25
+ "extra",
26
+ "data",
27
+ "json",
28
+ "params",
29
+ ];
30
+ }
31
+ /**
32
+ * 获取可能是 JSON 的字段
33
+ */
34
+ getJsonFields() {
35
+ return this.fields
36
+ .filter((f) => this.jsonFieldNames.some((jsonName) => f.name.toLowerCase().includes(jsonName)))
37
+ .map((f) => f.name);
38
+ }
10
39
  generate() {
11
40
  const capitalizedController = this.getCapitalizedController();
12
41
  const selectFields = this.fields.map((f) => f.name).join(", ");
42
+ const jsonFields = this.getJsonFields();
43
+ const hasJsonFields = jsonFields.length > 0;
13
44
  return `const DataLoader = require('dataloader');
14
45
  const { executeQuery } = require('../utils/common');
15
46
 
16
- /**
47
+ ${hasJsonFields
48
+ ? `/**
49
+ * 处理 ${this.controller} 行数据,将 JSON 字符串解析为对象
50
+ */
51
+ function process${capitalizedController}Row(row) {
52
+ if (!row) return row;
53
+
54
+ ${jsonFields
55
+ .map((field) => ` // 处理 ${field} 字段(JSON 字符串转对象)
56
+ if (row.${field} && typeof row.${field} === 'string') {
57
+ try {
58
+ row.${field} = JSON.parse(row.${field});
59
+ } catch (e) {
60
+ row.${field} = ${field === "images" || field === "photos" || field === "gallery" ? "[]" : "{}"};
61
+ }
62
+ }`)
63
+ .join(",\n ")}
64
+
65
+ return row;
66
+ }
67
+
68
+ `
69
+ : ""}/**
17
70
  * ${capitalizedController} DataLoader
18
71
  * 针对 ${this.controller} 表的批量数据加载器,解决 N+1 查询问题
19
72
  */
@@ -31,9 +84,7 @@ class ${capitalizedController}DataLoader {
31
84
  const results = await executeQuery(sql, [...ids]);
32
85
 
33
86
  // 确保返回顺序与输入 keys 一致,未找到的返回 null
34
- return ids.map(id =>
35
- results.find((row) => row.id === id) || null
36
- );
87
+ return ids.map(id => ${hasJsonFields ? `process${capitalizedController}Row(results.find((row) => row.id === id) || null)` : `results.find((row) => row.id === id) || null`});
37
88
  } catch (error) {
38
89
  console.error('DataLoader byId 批量加载失败:', error);
39
90
  throw error;
@@ -58,9 +109,7 @@ class ${capitalizedController}DataLoader {
58
109
  const results = await executeQuery(sql, [...names]);
59
110
 
60
111
  // 确保返回顺序与输入 keys 一致
61
- return names.map(name =>
62
- results.find((row) => row.name === name) || null
63
- );
112
+ return names.map(name => ${hasJsonFields ? `process${capitalizedController}Row(results.find((row) => row.name === name) || null)` : `results.find((row) => row.name === name) || null`});
64
113
  } catch (error) {
65
114
  console.error('DataLoader byName 批量加载失败:', error);
66
115
  throw error;
@@ -83,7 +132,8 @@ class ${capitalizedController}DataLoader {
83
132
  const results = await Promise.all(
84
133
  searchTerms.map(async (term) => {
85
134
  const sql = 'SELECT ${selectFields} FROM ${this.controller} WHERE name LIKE ?';
86
- return executeQuery(sql, [\`%\${term}%\`]);
135
+ const rows = await executeQuery(sql, [\`%\${term}%\`]);
136
+ ${hasJsonFields ? `return rows.map(process${capitalizedController}Row);` : "return rows;"}
87
137
  })
88
138
  );
89
139
 
@@ -100,7 +150,7 @@ class ${capitalizedController}DataLoader {
100
150
  }
101
151
  );
102
152
 
103
- ${this.generateForeignKeyLoaders()}
153
+ ${this.generateForeignKeyLoaders(hasJsonFields, capitalizedController)}
104
154
  }
105
155
 
106
156
  /**
@@ -170,7 +220,7 @@ module.exports = { ${capitalizedController}DataLoader, create${capitalizedContro
170
220
  /**
171
221
  * 生成外键 DataLoader
172
222
  */
173
- generateForeignKeyLoaders() {
223
+ generateForeignKeyLoaders(hasJsonFields, capitalizedController) {
174
224
  const foreignKeys = this.fields.filter((f) => f.name.endsWith("_id") && f.name !== "id");
175
225
  if (foreignKeys.length === 0) {
176
226
  return "";
@@ -193,7 +243,9 @@ module.exports = { ${capitalizedController}DataLoader, create${capitalizedContro
193
243
 
194
244
  // 按外键分组
195
245
  return ${fk.name}s.map(${fk.name} =>
196
- results.filter((row) => row.${fk.name} === ${fk.name})
246
+ results
247
+ .filter((row) => row.${fk.name} === ${fk.name})
248
+ ${hasJsonFields ? `.map(process${capitalizedController}Row)` : ""}
197
249
  );
198
250
  } catch (error) {
199
251
  console.error('DataLoader by${capitalizedRelated}Id 批量加载失败:', error);