From 084cac9b89af1a8504a50f0184df55bb0db11154 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 11:21:04 +0000 Subject: [PATCH 1/9] feat: update i18n texts for extended file format support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Chinese and English i18n texts in execWorkflow.ts and sqlAudit.ts: - sqlFileTips: mention .sql, .txt, .java formats - zipFile/zipFileTips: rename from "zip文件"/"Zip file" to "压缩包"/"Compressed file", mention .zip, .rar, .7z formats and supported inner file types - uploadZipFile tab label: align with new naming --- packages/sqle/src/locale/en-US/execWorkflow.ts | 8 ++++---- packages/sqle/src/locale/en-US/sqlAudit.ts | 8 ++++---- packages/sqle/src/locale/zh-CN/execWorkflow.ts | 8 ++++---- packages/sqle/src/locale/zh-CN/sqlAudit.ts | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/sqle/src/locale/en-US/execWorkflow.ts b/packages/sqle/src/locale/en-US/execWorkflow.ts index 7fa06b17e8..ad7674613c 100644 --- a/packages/sqle/src/locale/en-US/execWorkflow.ts +++ b/packages/sqle/src/locale/en-US/execWorkflow.ts @@ -80,13 +80,13 @@ export default { sql: 'SQL statement', sqlFile: 'SQL file', - sqlFileTips: 'Click to select a SQL file or drag the file to this area', + sqlFileTips: 'Click to select a file or drag the file to this area. Supports .sql, .txt, .java formats', mybatisFile: 'Mybatis XML file', mybatisFileTips: 'Click to select an XML file or drag the file to this area', - zipFile: 'Zip file', + zipFile: 'Compressed file', zipFileTips: - 'Click to select a zip file or drag the file to this area, currently only supports SQL auditing of .xml and .sql files in the ZIP file', + 'Click to select a compressed file or drag the file to this area. Supports .zip, .rar, .7z formats. Only .sql, .xml, .txt, .java files in the archive will be audited', addInstanceTips: 'Please add DB instance', addInstance: 'Add DB instance', @@ -94,7 +94,7 @@ export default { manualInput: 'Enter SQL statement', uploadFile: 'Upload SQL file', updateMybatisFile: 'Upload Mybatis XML file', - uploadZipFile: 'Upload ZIP file', + uploadZipFile: 'Upload compressed file', audit: 'Audit', analyze: 'SQL analysis', diff --git a/packages/sqle/src/locale/en-US/sqlAudit.ts b/packages/sqle/src/locale/en-US/sqlAudit.ts index bc0e371278..4e2792094b 100644 --- a/packages/sqle/src/locale/en-US/sqlAudit.ts +++ b/packages/sqle/src/locale/en-US/sqlAudit.ts @@ -73,24 +73,24 @@ export default { sql: 'Input SQL statement', sqlFile: 'Upload SQL file', mybatisFile: 'Upload Mybatis XML file', - zipFile: 'Upload ZIP file', + zipFile: 'Upload compressed file', git: 'Configure GIT repository' }, uploadLabelEnum: { sql: 'SQL statement', sqlFile: 'SQL file', mybatisFile: 'Mybatis XML file', - zipFile: 'ZIP file', + zipFile: 'Compressed file', gitUrl: 'GIT address', gitUrlTips: 'Please enter the HTTP(S) clone address of the git repository. if it is a private GIT repository, you must enter the account and password with read permission' }, uploadFileTip: { - sqlFile: 'Click to select a SQL file or drag the file to this area', + sqlFile: 'Click to select a file or drag the file to this area. Supports .sql, .txt, .java formats', mybatisFile: 'Click to select a Mybatis XML file or drag the file to this area', zipFile: - 'Click to select a ZIP file or drag the file to this area. currently, only .xml and .sql files in the ZIP file can be audited for SQL' + 'Click to select a compressed file or drag the file to this area. Supports .zip, .rar, .7z formats. Only .sql, .xml, .txt, .java files in the archive will be audited' } } }, diff --git a/packages/sqle/src/locale/zh-CN/execWorkflow.ts b/packages/sqle/src/locale/zh-CN/execWorkflow.ts index 336bce2c82..5d045549df 100644 --- a/packages/sqle/src/locale/zh-CN/execWorkflow.ts +++ b/packages/sqle/src/locale/zh-CN/execWorkflow.ts @@ -76,12 +76,12 @@ export default { sql: 'SQL语句', sqlFile: 'SQL文件', - sqlFileTips: '点击选择SQL文件或将文件拖拽到此区域', + sqlFileTips: '点击选择文件或将文件拖拽到此区域,支持 .sql, .txt, .java 格式', mybatisFile: 'Mybatis的XML文件', mybatisFileTips: '点击选择XML文件或将文件拖拽到此区域', - zipFile: 'zip文件', + zipFile: '压缩包', zipFileTips: - '点击选择zip文件或将文件拖拽到此区域,当前仅支持对ZIP文件中的.xml文件及.sql文件做SQL审核', + '点击选择压缩包或将文件拖拽到此区域,支持 .zip, .rar, .7z 格式,仅支持对压缩包内 .sql, .xml, .txt, .java 文件做SQL审核', addInstanceTips: '请添加数据源', addInstance: '添加数据源', @@ -89,7 +89,7 @@ export default { manualInput: '输入SQL语句', uploadFile: '上传SQL文件', updateMybatisFile: '上传Mybatis的XML文件', - uploadZipFile: '上传ZIP文件', + uploadZipFile: '上传压缩包', audit: '审核', analyze: 'SQL分析', diff --git a/packages/sqle/src/locale/zh-CN/sqlAudit.ts b/packages/sqle/src/locale/zh-CN/sqlAudit.ts index a35845bdc1..52b408d17b 100644 --- a/packages/sqle/src/locale/zh-CN/sqlAudit.ts +++ b/packages/sqle/src/locale/zh-CN/sqlAudit.ts @@ -79,14 +79,14 @@ export default { sql: '输入SQL语句', sqlFile: '上传SQL文件', mybatisFile: '上传Mybatis的XML文件', - zipFile: '上传ZIP文件', + zipFile: '上传压缩包', git: '配置GIT仓库' }, uploadLabelEnum: { sql: 'SQL语句', sqlFile: 'SQL文件', mybatisFile: 'Mybatis的XML文件', - zipFile: 'ZIP文件', + zipFile: '压缩包', gitUrl: 'GIT地址', gitProtocol: 'Git协议类型', gitUrlTips: '请输入代码仓库地址', @@ -101,10 +101,10 @@ export default { sshAuthTips: '使用SSH协议克隆仓库时,需要先配置SSH密钥。' }, uploadFileTip: { - sqlFile: '点击选择SQL文件或将文件拖拽到此区域', + sqlFile: '点击选择文件或将文件拖拽到此区域,支持 .sql, .txt, .java 格式', mybatisFile: '点击选择Mybatis的XML文件或将文件拖拽到此区域', zipFile: - '点击选择ZIP文件或将文件拖拽到此区域,当前仅支持对ZIP文件中的.xml文件及.sql文件做SQL审核' + '点击选择压缩包或将文件拖拽到此区域,支持 .zip, .rar, .7z 格式,仅支持对压缩包内 .sql, .xml, .txt, .java 文件做SQL审核' } } }, From eb22aaf689cc1fda91e0ff57725fcdb6953484aa Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 11:31:11 +0000 Subject: [PATCH 2/9] test: add i18n key completeness test for file upload format changes Verify that execWorkflow and sqlAudit i18n keys are complete and symmetric between zh-CN and en-US, and that file upload tip texts mention all required formats (.sql/.txt/.java and .zip/.rar/.7z). --- .../locale/__tests__/fileUploadI18n.test.ts | 220 ++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts diff --git a/packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts b/packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts new file mode 100644 index 0000000000..3653d26e94 --- /dev/null +++ b/packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts @@ -0,0 +1,220 @@ +import execWorkflowZhCN from '../zh-CN/execWorkflow'; +import execWorkflowEnUS from '../en-US/execWorkflow'; +import sqlAuditZhCN from '../zh-CN/sqlAudit'; +import sqlAuditEnUS from '../en-US/sqlAudit'; + +/** + * Recursively collect all leaf key paths from a nested object. + * E.g. { a: { b: 'v', c: 'v2' } } => ['a.b', 'a.c'] + */ +const collectKeyPaths = ( + obj: Record, + prefix = '' +): string[] => { + const keys: string[] = []; + for (const key of Object.keys(obj)) { + const fullPath = prefix ? `${prefix}.${key}` : key; + const value = obj[key]; + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + keys.push( + ...collectKeyPaths(value as Record, fullPath) + ); + } else { + keys.push(fullPath); + } + } + return keys; +}; + +/** + * Resolve a nested key path (e.g. 'create.form.sqlInfo.zipFile') on an object. + */ +const resolveKeyPath = ( + obj: Record, + path: string +): unknown => { + return path.split('.').reduce((acc: unknown, part: string) => { + if (acc && typeof acc === 'object') { + return (acc as Record)[part]; + } + return undefined; + }, obj); +}; + +describe('i18n key completeness for file upload changes', () => { + describe('execWorkflow - zh-CN and en-US key parity', () => { + const zhKeys = collectKeyPaths( + execWorkflowZhCN as unknown as Record + ); + const enKeys = collectKeyPaths( + execWorkflowEnUS as unknown as Record + ); + + it('zh-CN should not have keys missing in en-US', () => { + const missingInEn = zhKeys.filter((k) => !enKeys.includes(k)); + expect(missingInEn).toEqual([]); + }); + + it('en-US should not have keys missing in zh-CN', () => { + const missingInZh = enKeys.filter((k) => !zhKeys.includes(k)); + expect(missingInZh).toEqual([]); + }); + }); + + describe('sqlAudit - zh-CN and en-US key parity', () => { + const zhKeys = collectKeyPaths( + sqlAuditZhCN as unknown as Record + ); + const enKeys = collectKeyPaths( + sqlAuditEnUS as unknown as Record + ); + + it('zh-CN should not have keys missing in en-US', () => { + const missingInEn = zhKeys.filter((k) => !enKeys.includes(k)); + expect(missingInEn).toEqual([]); + }); + + it('en-US should not have keys missing in zh-CN', () => { + const missingInZh = enKeys.filter((k) => !zhKeys.includes(k)); + expect(missingInZh).toEqual([]); + }); + }); + + describe('execWorkflow - required file upload keys exist', () => { + const requiredKeys = [ + 'create.form.sqlInfo.sqlFileTips', + 'create.form.sqlInfo.zipFile', + 'create.form.sqlInfo.zipFileTips', + 'create.form.sqlInfo.uploadZipFile' + ]; + + it.each(requiredKeys)( + 'key "%s" should exist in zh-CN', + (keyPath) => { + const value = resolveKeyPath( + execWorkflowZhCN as unknown as Record, + keyPath + ); + expect(value).toBeDefined(); + expect(typeof value).toBe('string'); + expect((value as string).length).toBeGreaterThan(0); + } + ); + + it.each(requiredKeys)( + 'key "%s" should exist in en-US', + (keyPath) => { + const value = resolveKeyPath( + execWorkflowEnUS as unknown as Record, + keyPath + ); + expect(value).toBeDefined(); + expect(typeof value).toBe('string'); + expect((value as string).length).toBeGreaterThan(0); + } + ); + }); + + describe('sqlAudit - required file upload keys exist', () => { + const requiredKeys = [ + 'create.sqlInfo.uploadTypeEnum.zipFile', + 'create.sqlInfo.uploadLabelEnum.zipFile', + 'create.sqlInfo.uploadFileTip.sqlFile', + 'create.sqlInfo.uploadFileTip.zipFile' + ]; + + it.each(requiredKeys)( + 'key "%s" should exist in zh-CN', + (keyPath) => { + const value = resolveKeyPath( + sqlAuditZhCN as unknown as Record, + keyPath + ); + expect(value).toBeDefined(); + expect(typeof value).toBe('string'); + expect((value as string).length).toBeGreaterThan(0); + } + ); + + it.each(requiredKeys)( + 'key "%s" should exist in en-US', + (keyPath) => { + const value = resolveKeyPath( + sqlAuditEnUS as unknown as Record, + keyPath + ); + expect(value).toBeDefined(); + expect(typeof value).toBe('string'); + expect((value as string).length).toBeGreaterThan(0); + } + ); + }); + + describe('execWorkflow - file upload tip content correctness', () => { + it('zh-CN sqlFileTips should mention .sql, .txt, .java', () => { + const tip = (execWorkflowZhCN as Record as any).create + .form.sqlInfo.sqlFileTips; + expect(tip).toContain('.sql'); + expect(tip).toContain('.txt'); + expect(tip).toContain('.java'); + }); + + it('zh-CN zipFileTips should mention .zip, .rar, .7z', () => { + const tip = (execWorkflowZhCN as Record as any).create + .form.sqlInfo.zipFileTips; + expect(tip).toContain('.zip'); + expect(tip).toContain('.rar'); + expect(tip).toContain('.7z'); + }); + + it('en-US sqlFileTips should mention .sql, .txt, .java', () => { + const tip = (execWorkflowEnUS as Record as any).create + .form.sqlInfo.sqlFileTips; + expect(tip).toContain('.sql'); + expect(tip).toContain('.txt'); + expect(tip).toContain('.java'); + }); + + it('en-US zipFileTips should mention .zip, .rar, .7z', () => { + const tip = (execWorkflowEnUS as Record as any).create + .form.sqlInfo.zipFileTips; + expect(tip).toContain('.zip'); + expect(tip).toContain('.rar'); + expect(tip).toContain('.7z'); + }); + }); + + describe('sqlAudit - file upload tip content correctness', () => { + it('zh-CN uploadFileTip.sqlFile should mention .sql, .txt, .java', () => { + const tip = (sqlAuditZhCN as Record as any).create + .sqlInfo.uploadFileTip.sqlFile; + expect(tip).toContain('.sql'); + expect(tip).toContain('.txt'); + expect(tip).toContain('.java'); + }); + + it('zh-CN uploadFileTip.zipFile should mention .zip, .rar, .7z', () => { + const tip = (sqlAuditZhCN as Record as any).create + .sqlInfo.uploadFileTip.zipFile; + expect(tip).toContain('.zip'); + expect(tip).toContain('.rar'); + expect(tip).toContain('.7z'); + }); + + it('en-US uploadFileTip.sqlFile should mention .sql, .txt, .java', () => { + const tip = (sqlAuditEnUS as Record as any).create + .sqlInfo.uploadFileTip.sqlFile; + expect(tip).toContain('.sql'); + expect(tip).toContain('.txt'); + expect(tip).toContain('.java'); + }); + + it('en-US uploadFileTip.zipFile should mention .zip, .rar, .7z', () => { + const tip = (sqlAuditEnUS as Record as any).create + .sqlInfo.uploadFileTip.zipFile; + expect(tip).toContain('.zip'); + expect(tip).toContain('.rar'); + expect(tip).toContain('.7z'); + }); + }); +}); From aa43eed50353598301a522f2c524d6f303b047db Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 12:04:39 +0000 Subject: [PATCH 3/9] feat: add XLSX i18n keys and update sqlFileTips with .xlsx format - Add xlsxTemplateTips, downloadTemplate, noSqlColumnFound keys to execWorkflow and sqlAudit locale files (zh-CN and en-US) - Update sqlFileTips to include .xlsx in format list - Both execWorkflow and sqlAudit i18n files updated symmetrically --- packages/sqle/src/locale/en-US/execWorkflow.ts | 5 ++++- packages/sqle/src/locale/en-US/sqlAudit.ts | 7 +++++-- packages/sqle/src/locale/zh-CN/execWorkflow.ts | 5 ++++- packages/sqle/src/locale/zh-CN/sqlAudit.ts | 7 +++++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/sqle/src/locale/en-US/execWorkflow.ts b/packages/sqle/src/locale/en-US/execWorkflow.ts index ad7674613c..3fc9bc18a8 100644 --- a/packages/sqle/src/locale/en-US/execWorkflow.ts +++ b/packages/sqle/src/locale/en-US/execWorkflow.ts @@ -80,7 +80,7 @@ export default { sql: 'SQL statement', sqlFile: 'SQL file', - sqlFileTips: 'Click to select a file or drag the file to this area. Supports .sql, .txt, .java formats', + sqlFileTips: 'Click to select a file or drag the file to this area. Supports .sql, .txt, .java, .xlsx formats', mybatisFile: 'Mybatis XML file', mybatisFileTips: 'Click to select an XML file or drag the file to this area', @@ -95,6 +95,9 @@ export default { uploadFile: 'Upload SQL file', updateMybatisFile: 'Upload Mybatis XML file', uploadZipFile: 'Upload compressed file', + xlsxTemplateTips: 'Please use the standard template format', + downloadTemplate: 'Download template', + noSqlColumnFound: 'No column containing SQL found, please refer to the template', audit: 'Audit', analyze: 'SQL analysis', diff --git a/packages/sqle/src/locale/en-US/sqlAudit.ts b/packages/sqle/src/locale/en-US/sqlAudit.ts index 4e2792094b..ea6b15bec5 100644 --- a/packages/sqle/src/locale/en-US/sqlAudit.ts +++ b/packages/sqle/src/locale/en-US/sqlAudit.ts @@ -86,12 +86,15 @@ export default { 'Please enter the HTTP(S) clone address of the git repository. if it is a private GIT repository, you must enter the account and password with read permission' }, uploadFileTip: { - sqlFile: 'Click to select a file or drag the file to this area. Supports .sql, .txt, .java formats', + sqlFile: 'Click to select a file or drag the file to this area. Supports .sql, .txt, .java, .xlsx formats', mybatisFile: 'Click to select a Mybatis XML file or drag the file to this area', zipFile: 'Click to select a compressed file or drag the file to this area. Supports .zip, .rar, .7z formats. Only .sql, .xml, .txt, .java files in the archive will be audited' - } + }, + xlsxTemplateTips: 'Please use the standard template format', + downloadTemplate: 'Download template', + noSqlColumnFound: 'No column containing SQL found, please refer to the template' } }, result: { diff --git a/packages/sqle/src/locale/zh-CN/execWorkflow.ts b/packages/sqle/src/locale/zh-CN/execWorkflow.ts index 5d045549df..2b72fee0c7 100644 --- a/packages/sqle/src/locale/zh-CN/execWorkflow.ts +++ b/packages/sqle/src/locale/zh-CN/execWorkflow.ts @@ -76,7 +76,7 @@ export default { sql: 'SQL语句', sqlFile: 'SQL文件', - sqlFileTips: '点击选择文件或将文件拖拽到此区域,支持 .sql, .txt, .java 格式', + sqlFileTips: '点击选择文件或将文件拖拽到此区域,支持 .sql, .txt, .java, .xlsx 格式', mybatisFile: 'Mybatis的XML文件', mybatisFileTips: '点击选择XML文件或将文件拖拽到此区域', zipFile: '压缩包', @@ -90,6 +90,9 @@ export default { uploadFile: '上传SQL文件', updateMybatisFile: '上传Mybatis的XML文件', uploadZipFile: '上传压缩包', + xlsxTemplateTips: '请使用标准模板格式', + downloadTemplate: '下载模板', + noSqlColumnFound: '未找到包含SQL的列,请参照模板格式', audit: '审核', analyze: 'SQL分析', diff --git a/packages/sqle/src/locale/zh-CN/sqlAudit.ts b/packages/sqle/src/locale/zh-CN/sqlAudit.ts index 52b408d17b..f81e02e756 100644 --- a/packages/sqle/src/locale/zh-CN/sqlAudit.ts +++ b/packages/sqle/src/locale/zh-CN/sqlAudit.ts @@ -101,11 +101,14 @@ export default { sshAuthTips: '使用SSH协议克隆仓库时,需要先配置SSH密钥。' }, uploadFileTip: { - sqlFile: '点击选择文件或将文件拖拽到此区域,支持 .sql, .txt, .java 格式', + sqlFile: '点击选择文件或将文件拖拽到此区域,支持 .sql, .txt, .java, .xlsx 格式', mybatisFile: '点击选择Mybatis的XML文件或将文件拖拽到此区域', zipFile: '点击选择压缩包或将文件拖拽到此区域,支持 .zip, .rar, .7z 格式,仅支持对压缩包内 .sql, .xml, .txt, .java 文件做SQL审核' - } + }, + xlsxTemplateTips: '请使用标准模板格式', + downloadTemplate: '下载模板', + noSqlColumnFound: '未找到包含SQL的列,请参照模板格式' } }, result: { From 50fb605b61944f5cd457e9fefe3e596ad5ec5ffe Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 12:21:50 +0000 Subject: [PATCH 4/9] test: add XLSX i18n key validation and update sqlFileTips format checks - Add xlsxTemplateTips, downloadTemplate, noSqlColumnFound to required keys for both execWorkflow and sqlAudit (zh-CN and en-US) - Update sqlFileTips content checks to verify .xlsx format inclusion --- .../locale/__tests__/fileUploadI18n.test.ts | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts b/packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts index 3653d26e94..6294991499 100644 --- a/packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts +++ b/packages/sqle/src/locale/__tests__/fileUploadI18n.test.ts @@ -85,7 +85,10 @@ describe('i18n key completeness for file upload changes', () => { 'create.form.sqlInfo.sqlFileTips', 'create.form.sqlInfo.zipFile', 'create.form.sqlInfo.zipFileTips', - 'create.form.sqlInfo.uploadZipFile' + 'create.form.sqlInfo.uploadZipFile', + 'create.form.sqlInfo.xlsxTemplateTips', + 'create.form.sqlInfo.downloadTemplate', + 'create.form.sqlInfo.noSqlColumnFound' ]; it.each(requiredKeys)( @@ -120,7 +123,10 @@ describe('i18n key completeness for file upload changes', () => { 'create.sqlInfo.uploadTypeEnum.zipFile', 'create.sqlInfo.uploadLabelEnum.zipFile', 'create.sqlInfo.uploadFileTip.sqlFile', - 'create.sqlInfo.uploadFileTip.zipFile' + 'create.sqlInfo.uploadFileTip.zipFile', + 'create.sqlInfo.xlsxTemplateTips', + 'create.sqlInfo.downloadTemplate', + 'create.sqlInfo.noSqlColumnFound' ]; it.each(requiredKeys)( @@ -151,12 +157,13 @@ describe('i18n key completeness for file upload changes', () => { }); describe('execWorkflow - file upload tip content correctness', () => { - it('zh-CN sqlFileTips should mention .sql, .txt, .java', () => { + it('zh-CN sqlFileTips should mention .sql, .txt, .java, .xlsx', () => { const tip = (execWorkflowZhCN as Record as any).create .form.sqlInfo.sqlFileTips; expect(tip).toContain('.sql'); expect(tip).toContain('.txt'); expect(tip).toContain('.java'); + expect(tip).toContain('.xlsx'); }); it('zh-CN zipFileTips should mention .zip, .rar, .7z', () => { @@ -167,12 +174,13 @@ describe('i18n key completeness for file upload changes', () => { expect(tip).toContain('.7z'); }); - it('en-US sqlFileTips should mention .sql, .txt, .java', () => { + it('en-US sqlFileTips should mention .sql, .txt, .java, .xlsx', () => { const tip = (execWorkflowEnUS as Record as any).create .form.sqlInfo.sqlFileTips; expect(tip).toContain('.sql'); expect(tip).toContain('.txt'); expect(tip).toContain('.java'); + expect(tip).toContain('.xlsx'); }); it('en-US zipFileTips should mention .zip, .rar, .7z', () => { @@ -185,12 +193,13 @@ describe('i18n key completeness for file upload changes', () => { }); describe('sqlAudit - file upload tip content correctness', () => { - it('zh-CN uploadFileTip.sqlFile should mention .sql, .txt, .java', () => { + it('zh-CN uploadFileTip.sqlFile should mention .sql, .txt, .java, .xlsx', () => { const tip = (sqlAuditZhCN as Record as any).create .sqlInfo.uploadFileTip.sqlFile; expect(tip).toContain('.sql'); expect(tip).toContain('.txt'); expect(tip).toContain('.java'); + expect(tip).toContain('.xlsx'); }); it('zh-CN uploadFileTip.zipFile should mention .zip, .rar, .7z', () => { @@ -201,12 +210,13 @@ describe('i18n key completeness for file upload changes', () => { expect(tip).toContain('.7z'); }); - it('en-US uploadFileTip.sqlFile should mention .sql, .txt, .java', () => { + it('en-US uploadFileTip.sqlFile should mention .sql, .txt, .java, .xlsx', () => { const tip = (sqlAuditEnUS as Record as any).create .sqlInfo.uploadFileTip.sqlFile; expect(tip).toContain('.sql'); expect(tip).toContain('.txt'); expect(tip).toContain('.java'); + expect(tip).toContain('.xlsx'); }); it('en-US uploadFileTip.zipFile should mention .zip, .rar, .7z', () => { From 3ad11f6ccd3c95c94beca80ac0314c6a8f17056d Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 11:21:04 +0000 Subject: [PATCH 5/9] feat: update file upload accept attributes for workflow and audit pages Extend SQL upload accept from .sql to .sql,.txt,.java and ZIP upload accept from .zip to .zip,.rar,.7z on both the workflow creation page (SqlUploadContent.tsx) and the quick audit page (SqlUploadCont/index.tsx). --- .../SQLStatementForm/components/SqlUploadCont/index.tsx | 4 ++-- .../SqlStatementFormItem/components/SqlUploadContent.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/components/SqlUploadCont/index.tsx b/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/components/SqlUploadCont/index.tsx index fee332ebde..195ad08da9 100644 --- a/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/components/SqlUploadCont/index.tsx +++ b/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/components/SqlUploadCont/index.tsx @@ -96,7 +96,7 @@ const SqlUploadFileCont = ({ form }: SqlUploadFileContProps) => { getValueFromEvent={getFileFromUploadChangeEvent} > false} onRemove={removeFile.bind(null, 'sqlFile')} title={t('sqlAudit.create.sqlInfo.uploadFileTip.sqlFile')} @@ -145,7 +145,7 @@ const SqlUploadFileCont = ({ form }: SqlUploadFileContProps) => { getValueFromEvent={getFileFromUploadChangeEvent} > false} onRemove={removeFile.bind(null, 'zipFile')} title={t('sqlAudit.create.sqlInfo.uploadFileTip.zipFile')} diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx index 76818b4ca9..a238305218 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx @@ -114,7 +114,7 @@ const SqlUploadContent: React.FC = ({ getValueFromEvent={getFileFromUploadChangeEvent} > false} onRemove={removeFile.bind(null, generateFieldName('sql_file'))} title={t('execWorkflow.create.form.sqlInfo.sqlFileTips')} @@ -140,7 +140,7 @@ const SqlUploadContent: React.FC = ({ getValueFromEvent={getFileFromUploadChangeEvent} > false} onRemove={removeFile.bind(null, generateFieldName('zip_file'))} title={t('execWorkflow.create.form.sqlInfo.zipFileTips')} From af3f649f83b0c4faaa4769cbbc251b51679dab42 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 11:31:11 +0000 Subject: [PATCH 6/9] test: add component tests for SqlUploadContent and SqlUploadCont accept attributes Verify that SQL file upload accepts .sql,.txt,.java and ZIP file upload accepts .zip,.rar,.7z on both workflow create page and quick audit page. Also verify that i18n tip texts mention the correct supported formats. --- .../__tests__/SqlUploadCont.accept.test.tsx | 74 ++++++++++++++++++ .../SqlUploadContent.accept.test.tsx | 77 +++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx create mode 100644 packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx diff --git a/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx b/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx new file mode 100644 index 0000000000..9721d867dd --- /dev/null +++ b/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx @@ -0,0 +1,74 @@ +import { renderHook, render, screen } from '@testing-library/react'; +import { Form } from 'antd'; +import SqlUploadFileCont from '../components/SqlUploadCont'; +import { FormSubmitStatusContext } from '../..'; +import { UploadTypeEnum } from '../../SQLInfoForm/index.type'; +import { + ignoreConsoleErrors, + UtilsConsoleErrorStringsEnum +} from '@actiontech/shared/lib/testUtil/common'; + +describe('SqlUploadCont accept attributes and tips', () => { + ignoreConsoleErrors([UtilsConsoleErrorStringsEnum.UNKNOWN_EVENT_HANDLER]); + + const renderWithUploadType = (uploadType: UploadTypeEnum) => { + const { result } = renderHook(() => Form.useForm()); + const form = result.current[0]; + form.setFieldsValue({ uploadType }); + return render( + +
+ + +
+ ); + }; + + const acceptTestCases = [ + { + name: 'SQL file upload accept should include .sql, .txt, .java', + uploadType: UploadTypeEnum.sqlFile, + expectedAccept: '.sql,.txt,.java' + }, + { + name: 'ZIP file upload accept should include .zip, .rar, .7z', + uploadType: UploadTypeEnum.zipFile, + expectedAccept: '.zip,.rar,.7z' + } + ]; + + it.each(acceptTestCases)( + '$name', + ({ uploadType, expectedAccept }) => { + const { container } = renderWithUploadType(uploadType); + const fileInput = container.querySelector( + `input[type="file"][accept="${expectedAccept}"]` + ); + expect(fileInput).not.toBeNull(); + } + ); + + it('should display correct SQL file tips text', () => { + renderWithUploadType(UploadTypeEnum.sqlFile); + expect( + screen.getByText( + /支持 \.sql, \.txt, \.java 格式/ + ) + ).toBeInTheDocument(); + }); + + it('should display correct ZIP file tips text', () => { + renderWithUploadType(UploadTypeEnum.zipFile); + expect( + screen.getByText( + /支持 \.zip, \.rar, \.7z 格式/ + ) + ).toBeInTheDocument(); + }); + + it('should not render file inputs when upload type is sql', () => { + const { container } = renderWithUploadType(UploadTypeEnum.sql); + const fileInput = container.querySelector('input[type="file"]'); + expect(fileInput).toBeNull(); + }); +}); diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx new file mode 100644 index 0000000000..66cf9afe3a --- /dev/null +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx @@ -0,0 +1,77 @@ +import { renderHook, render, screen } from '@testing-library/react'; +import { Form } from 'antd'; +import SqlUploadContent from '../components/SqlUploadContent'; +import { AuditTaskResV1SqlSourceEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { + ignoreConsoleErrors, + UtilsConsoleErrorStringsEnum +} from '@actiontech/shared/lib/testUtil/common'; + +describe('SqlUploadContent accept attributes and tips', () => { + ignoreConsoleErrors([UtilsConsoleErrorStringsEnum.UNKNOWN_EVENT_HANDLER]); + + const renderWithUploadType = ( + uploadType: AuditTaskResV1SqlSourceEnum + ) => { + const { result } = renderHook(() => Form.useForm()); + return render( +
+ + + ); + }; + + const acceptTestCases = [ + { + name: 'SQL file upload accept should include .sql, .txt, .java', + uploadType: AuditTaskResV1SqlSourceEnum.sql_file, + expectedAccept: '.sql,.txt,.java' + }, + { + name: 'ZIP file upload accept should include .zip, .rar, .7z', + uploadType: AuditTaskResV1SqlSourceEnum.zip_file, + expectedAccept: '.zip,.rar,.7z' + } + ]; + + it.each(acceptTestCases)( + '$name', + ({ uploadType, expectedAccept }) => { + const { container } = renderWithUploadType(uploadType); + const fileInput = container.querySelector( + `input[type="file"][accept="${expectedAccept}"]` + ); + expect(fileInput).not.toBeNull(); + } + ); + + it('should display correct SQL file tips text', () => { + renderWithUploadType(AuditTaskResV1SqlSourceEnum.sql_file); + expect( + screen.getByText( + /支持 \.sql, \.txt, \.java 格式/ + ) + ).toBeInTheDocument(); + }); + + it('should display correct ZIP file tips text', () => { + renderWithUploadType(AuditTaskResV1SqlSourceEnum.zip_file); + expect( + screen.getByText( + /支持 \.zip, \.rar, \.7z 格式/ + ) + ).toBeInTheDocument(); + }); + + it('should not render file inputs when upload type is form_data', () => { + const { container } = renderWithUploadType( + AuditTaskResV1SqlSourceEnum.form_data + ); + const fileInput = container.querySelector('input[type="file"]'); + expect(fileInput).toBeNull(); + }); +}); From 7d59d1f3bd10995e484d96c0f2151d7b213c9911 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 12:04:32 +0000 Subject: [PATCH 7/9] feat: add XLSX support to frontend - accept attrs, template, i18n keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update SQL file upload accept to .sql,.txt,.java,.xlsx in both SqlUploadContent.tsx and SqlUploadCont/index.tsx - Add XLSX template download tip and link below SQL file upload area - Add standard XLSX template file (序号/SQL/备注) as static asset - Add new i18n keys: xlsxTemplateTips, downloadTemplate, noSqlColumnFound - Update sqlFileTips to include .xlsx format in both pages - Sync dms-ui-ee locale copies with latest i18n text changes --- packages/sqle/public/static/xlsx_template.xlsx | Bin 0 -> 5166 bytes .../components/SqlUploadCont/index.tsx | 13 ++++++++++++- .../components/SqlUploadContent.tsx | 13 ++++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 packages/sqle/public/static/xlsx_template.xlsx diff --git a/packages/sqle/public/static/xlsx_template.xlsx b/packages/sqle/public/static/xlsx_template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..07e7e63135aa2a23ebf44c82ffbc44c8fe25df5f GIT binary patch literal 5166 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 d { getValueFromEvent={getFileFromUploadChangeEvent} > false} onRemove={removeFile.bind(null, 'sqlFile')} title={t('sqlAudit.create.sqlInfo.uploadFileTip.sqlFile')} disabled={submitLoading} /> +
+ {t('sqlAudit.create.sqlInfo.xlsxTemplateTips')} + {' '} + + {t('sqlAudit.create.sqlInfo.downloadTemplate')} + +
{/* mybatisFile */} diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx index a238305218..ef58f76936 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlUploadContent.tsx @@ -114,12 +114,23 @@ const SqlUploadContent: React.FC = ({ getValueFromEvent={getFileFromUploadChangeEvent} > false} onRemove={removeFile.bind(null, generateFieldName('sql_file'))} title={t('execWorkflow.create.form.sqlInfo.sqlFileTips')} /> +
+ {t('execWorkflow.create.form.sqlInfo.xlsxTemplateTips')} + {' '} + + {t('execWorkflow.create.form.sqlInfo.downloadTemplate')} + +
Date: Wed, 1 Apr 2026 12:21:50 +0000 Subject: [PATCH 8/9] test: update component tests with XLSX accept, template UI, and rendering fixes - Update SQL upload accept validation from .sql,.txt,.java to .sql,.txt,.java,.xlsx - Add tests for XLSX template tips text (xlsxTemplateTips) rendering - Add tests for template download link href and download attribute - Fix rendering by using sqleSuperRender for theme context (uiToken) - Fix SqlUploadCont Form.useWatch by using TestWrapper with hidden Form.Item - Fix negative tests to avoid CustomMonacoEditor Redux dependency --- .../__tests__/SqlUploadCont.accept.test.tsx | 68 +++++++++++++++---- .../SqlUploadContent.accept.test.tsx | 47 ++++++++++--- 2 files changed, 94 insertions(+), 21 deletions(-) diff --git a/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx b/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx index 9721d867dd..1f8b9ccb2f 100644 --- a/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx +++ b/packages/sqle/src/page/SqlAudit/Create/SQLStatementForm/__tests__/SqlUploadCont.accept.test.tsx @@ -1,4 +1,4 @@ -import { renderHook, render, screen } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import { Form } from 'antd'; import SqlUploadFileCont from '../components/SqlUploadCont'; import { FormSubmitStatusContext } from '../..'; @@ -7,28 +7,40 @@ import { ignoreConsoleErrors, UtilsConsoleErrorStringsEnum } from '@actiontech/shared/lib/testUtil/common'; +import { sqleSuperRender } from '../../../../../testUtils/superRender'; describe('SqlUploadCont accept attributes and tips', () => { ignoreConsoleErrors([UtilsConsoleErrorStringsEnum.UNKNOWN_EVENT_HANDLER]); - const renderWithUploadType = (uploadType: UploadTypeEnum) => { - const { result } = renderHook(() => Form.useForm()); - const form = result.current[0]; - form.setFieldsValue({ uploadType }); - return render( + /** + * Wrapper component that creates the form instance internally + * and includes a hidden Form.Item for uploadType so that + * Form.useWatch('uploadType', form) works correctly. + */ + const TestWrapper = ({ uploadType }: { uploadType: UploadTypeEnum }) => { + const [form] = Form.useForm(); + + return ( -
+ + + +
); }; + const renderWithUploadType = (uploadType: UploadTypeEnum) => { + return sqleSuperRender(); + }; + const acceptTestCases = [ { - name: 'SQL file upload accept should include .sql, .txt, .java', + name: 'SQL file upload accept should include .sql, .txt, .java, .xlsx', uploadType: UploadTypeEnum.sqlFile, - expectedAccept: '.sql,.txt,.java' + expectedAccept: '.sql,.txt,.java,.xlsx' }, { name: 'ZIP file upload accept should include .zip, .rar, .7z', @@ -48,11 +60,11 @@ describe('SqlUploadCont accept attributes and tips', () => { } ); - it('should display correct SQL file tips text', () => { + it('should display correct SQL file tips text including .xlsx', () => { renderWithUploadType(UploadTypeEnum.sqlFile); expect( screen.getByText( - /支持 \.sql, \.txt, \.java 格式/ + /支持 \.sql, \.txt, \.java, \.xlsx 格式/ ) ).toBeInTheDocument(); }); @@ -66,8 +78,38 @@ describe('SqlUploadCont accept attributes and tips', () => { ).toBeInTheDocument(); }); - it('should not render file inputs when upload type is sql', () => { - const { container } = renderWithUploadType(UploadTypeEnum.sql); + it('should render XLSX template tips text when upload type is sqlFile', () => { + renderWithUploadType(UploadTypeEnum.sqlFile); + expect( + screen.getByText(/请使用标准模板格式/) + ).toBeInTheDocument(); + }); + + it('should render XLSX template download link when upload type is sqlFile', () => { + const { container } = renderWithUploadType(UploadTypeEnum.sqlFile); + const downloadLink = container.querySelector( + 'a[href="/static/xlsx_template.xlsx"]' + ); + expect(downloadLink).not.toBeNull(); + expect(downloadLink?.textContent).toContain('下载模板'); + expect(downloadLink?.getAttribute('download')).toBe('xlsx_template.xlsx'); + }); + + it('should not render file inputs when uploadType is not a file-based type', () => { + // When uploadType is not registered as a Form.Item (simulating + // a non-file upload type), Form.useWatch returns undefined, + // so no EmptyBox conditions match and no file inputs render. + const NoFileWrapper = () => { + const [form] = Form.useForm(); + return ( + +
+ + +
+ ); + }; + const { container } = sqleSuperRender(); const fileInput = container.querySelector('input[type="file"]'); expect(fileInput).toBeNull(); }); diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx index 66cf9afe3a..2b31d24f84 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/SqlUploadContent.accept.test.tsx @@ -1,4 +1,4 @@ -import { renderHook, render, screen } from '@testing-library/react'; +import { renderHook, screen } from '@testing-library/react'; import { Form } from 'antd'; import SqlUploadContent from '../components/SqlUploadContent'; import { AuditTaskResV1SqlSourceEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; @@ -6,6 +6,7 @@ import { ignoreConsoleErrors, UtilsConsoleErrorStringsEnum } from '@actiontech/shared/lib/testUtil/common'; +import { sqleSuperRender } from '../../../../../../testUtils/superRender'; describe('SqlUploadContent accept attributes and tips', () => { ignoreConsoleErrors([UtilsConsoleErrorStringsEnum.UNKNOWN_EVENT_HANDLER]); @@ -14,7 +15,7 @@ describe('SqlUploadContent accept attributes and tips', () => { uploadType: AuditTaskResV1SqlSourceEnum ) => { const { result } = renderHook(() => Form.useForm()); - return render( + return sqleSuperRender(
{ const acceptTestCases = [ { - name: 'SQL file upload accept should include .sql, .txt, .java', + name: 'SQL file upload accept should include .sql, .txt, .java, .xlsx', uploadType: AuditTaskResV1SqlSourceEnum.sql_file, - expectedAccept: '.sql,.txt,.java' + expectedAccept: '.sql,.txt,.java,.xlsx' }, { name: 'ZIP file upload accept should include .zip, .rar, .7z', @@ -49,11 +50,11 @@ describe('SqlUploadContent accept attributes and tips', () => { } ); - it('should display correct SQL file tips text', () => { + it('should display correct SQL file tips text including .xlsx', () => { renderWithUploadType(AuditTaskResV1SqlSourceEnum.sql_file); expect( screen.getByText( - /支持 \.sql, \.txt, \.java 格式/ + /支持 \.sql, \.txt, \.java, \.xlsx 格式/ ) ).toBeInTheDocument(); }); @@ -67,9 +68,39 @@ describe('SqlUploadContent accept attributes and tips', () => { ).toBeInTheDocument(); }); - it('should not render file inputs when upload type is form_data', () => { + it('should render XLSX template tips text when upload type is sql_file', () => { + renderWithUploadType(AuditTaskResV1SqlSourceEnum.sql_file); + expect( + screen.getByText(/请使用标准模板格式/) + ).toBeInTheDocument(); + }); + + it('should render XLSX template download link when upload type is sql_file', () => { const { container } = renderWithUploadType( - AuditTaskResV1SqlSourceEnum.form_data + AuditTaskResV1SqlSourceEnum.sql_file + ); + const downloadLink = container.querySelector( + 'a[href="/static/xlsx_template.xlsx"]' + ); + expect(downloadLink).not.toBeNull(); + expect(downloadLink?.textContent).toContain('下载模板'); + expect(downloadLink?.getAttribute('download')).toBe('xlsx_template.xlsx'); + }); + + it('should not render file inputs when no file-based upload type is active', () => { + // Render without specifying an upload type (defaults to undefined), + // so no LazyLoadComponent opens and no file inputs should appear. + // Avoids rendering form_data type which triggers CustomMonacoEditor + // and its Redux dependencies outside the scope of this test. + const { result } = renderHook(() => Form.useForm()); + const { container } = sqleSuperRender( + + + ); const fileInput = container.querySelector('input[type="file"]'); expect(fileInput).toBeNull(); From bda1eebcf8e1826c6adcd23b8075e52d1f95f0d3 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 1 Apr 2026 19:48:50 +0000 Subject: [PATCH 9/9] fix: deploy xlsx template to base public/static for Vite build inclusion The xlsx_template.xlsx was placed in packages/sqle/public/static/ but the Vite build entry point is the base package. Only files in packages/base/public/ are copied to dist/ during build. This caused the template to be missing from the deployed static directory, making the "Download template" link return SPA index.html instead of the actual XLSX file (BUG-004). --- packages/base/public/static/xlsx_template.xlsx | Bin 0 -> 5166 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/base/public/static/xlsx_template.xlsx diff --git a/packages/base/public/static/xlsx_template.xlsx b/packages/base/public/static/xlsx_template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..07e7e63135aa2a23ebf44c82ffbc44c8fe25df5f GIT binary patch literal 5166 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 d