Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
54a7c82
feat: Migrate date handling utilities from date-fns to Luxon
YufJi Feb 5, 2026
bbce7bc
feat: 补充与老版本一致性验证的测试用例
YufJi Feb 6, 2026
64973dc
chore: old-basic
YufJi Feb 6, 2026
beb75ac
chore: 删除 Luxon 迁移总结文档
YufJi Feb 6, 2026
583de92
feat(tests): enhance compatibility tests for date-time utilities
YufJi Feb 6, 2026
26cab47
chore: 移除不再使用的 date-fns 依赖
YufJi Feb 6, 2026
f01d5fe
chore(tests): 添加快照测试以增强与老版本的一致性验证
YufJi Feb 6, 2026
c54174a
fix: 接受AI code review的建议
YufJi Feb 6, 2026
65b898d
chore: 移除不再使用的 date-fns 依赖
YufJi Feb 6, 2026
d014595
fix: 接受AI code review的建议
YufJi Feb 6, 2026
1e649c1
chore: 更新包名称为 @lcap/basic-template-old-fixture
YufJi Feb 6, 2026
da86463
test: 更新 CurrTime 测试并添加 CurrDateTime 测试以增强一致性验证
YufJi Feb 6, 2026
1d71c82
修复: 移除 CurrDate 测试中的快照匹配以提高一致性
YufJi Feb 6, 2026
8290046
Merge remote-tracking branch 'origin/test' into chore/luxon
YufJi Feb 6, 2026
c5af4b4
chore: 标记 AddDays、AddMonths 和 SubDays 方法为已弃用
YufJi Feb 6, 2026
4f2dbe4
chore: 更新日期时间相关测试
YufJi Feb 6, 2026
d64b45d
chore: 更新 GetDateCount 测试以包含更多度量标准并改进快照匹配
YufJi Feb 6, 2026
b5a8700
chore: 更新日期处理逻辑以支持不同格式的日期字符串并增强快照测试
YufJi Feb 6, 2026
bf504ba
chore: 更新日期和日期时间处理逻辑,增强测试覆盖率和快照一致性
YufJi Feb 6, 2026
6b7813f
feat(tests): add date utility tests for consistency with date-fns
YufJi Feb 9, 2026
e105dd4
chore: 移除不必要的 ISO 字符串格式化测试,简化日期格式化测试逻辑
YufJi Feb 9, 2026
83110f6
chore: 移除冗余测试注释,简化日期时间测试代码
YufJi Feb 9, 2026
25fc2cc
fix: 接受AI code review的建议
YufJi Feb 9, 2026
08180f2
Merge remote-tracking branch 'origin/test' into chore/luxon
YufJi Feb 9, 2026
4ae1ede
refactor: enhance date-time tests for consistency with old version
YufJi Feb 9, 2026
16effa8
Merge remote-tracking branch 'origin/test' into chore/luxon
YufJi Feb 11, 2026
6be289a
refactor: 删除不友好文案(zirun写的~
YufJi Feb 11, 2026
f9ac73c
Merge remote-tracking branch 'origin/test' into chore/luxon
YufJi Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions packages/basic/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
const fc = require('fast-check');
fc.configureGlobal({ numRuns: 100 });

const { default: NaslSDK, Helpers } = require('./src/sdk');
const { toString, fromString } = require('./src/init/dataTypes/tools');
const Basic = require('./src/index');
const { Helpers } = require('./src/sdk');

try {
const utils = NaslSDK.initUtils({
Basic.initDataTypes({
dataTypesMap: {
'nasl.core.DateTime': { typeName: 'DateTime' },
'nasl.core.Date': { typeName: 'Date' },
},
});
Comment thread
YufJi marked this conversation as resolved.
const { utils } = Basic.initUtils({
typeDefinitionMap: new Map(),
enumsMap: {},
dataTypesMap: {},

toString,
fromString,
toString: Basic.Tools.toString,
fromString: Basic.Tools.fromString,
});

// 全局变量
global.sdkUtils = utils;
global.sdkHelpers = Helpers;
global.Utils = utils;
global.Helpers = Helpers;
} catch (error) {
console.log('Error initializing NaslSDK:', error);
console.log('Error initializing Basic:', error);
}
8 changes: 4 additions & 4 deletions packages/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"zip": "node scripts/zip.js",
"prepublish": "npm run clean && npm run build && npm run test",
"test": "jest --coverage",
"test:update": "jest --updateSnapshot",
"prebuild": "npm run clean",
"postbuild": "npm run zip",
"clean": "rm -rf dist cjs esm typings",
Expand All @@ -31,13 +32,10 @@
"axios": "0.21.4",
"bignumber.js": "9.1.2",
"crypto-js": "4.2.0",
"date-fns": "2.30.0",
"date-fns-tz": "2.0.0",
"decimal.js": "10.4.3",
"lodash": "4.17.21",
"luxon": "^3.7.2",
"mockjs": "1.1.0",
"moment": "2.30.1",
"moment-timezone": "0.5.45",
"qs": "6.11.2",
"safe-json-stringify": "^1.2.0"
},
Expand All @@ -51,8 +49,10 @@
"@rollup/plugin-typescript": "^11.1.6",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.17.13",
"@types/luxon": "^3.7.1",
"@types/node": "^20.11.16",
"@types/safe-json-stringify": "^1.1.5",
"date-fns": "2.30.0",
"fast-check": "^3.14.0",
"is-ci": "^4.1.0",
"jest": "^29.7.0",
Expand Down
25 changes: 11 additions & 14 deletions packages/basic/src/init/dataTypes/tools.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { format } from 'date-fns';
import momentTZ from 'moment-timezone';
import moment from 'moment';
import { DateTime } from 'luxon';
import { flatMap, difference } from 'lodash';
import { Helpers } from '../../sdk';

Expand Down Expand Up @@ -694,7 +692,7 @@ export const genInitData = (typeKey, defaultValue, parentLevel?) => {
}
if (typeName === 'DateTime' && parsedValue !== undefined) {
if (parsedValue instanceof Date) {
parsedValue = moment(new Date()).format('YYYY-MM-DDTHH:mm:ss.SSSZ');
parsedValue = DateTime.fromJSDate(parsedValue).toFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
}
return parsedValue;
} else if (['nasl.io.File'].includes(typeKey)) {
Expand Down Expand Up @@ -769,7 +767,7 @@ export const toString = (typeKey, variable, tz?, tabSize = 0, collection = new S

// 日期时间处理
if (typeKey === 'nasl.core.Date') {
str = momentTZ.tz(safeNewDate(variable), getAppTimezone(tz)).format('YYYY-MM-DD');
str = DateTime.fromJSDate(safeNewDate(variable)).setZone(getAppTimezone(tz)).toFormat('yyyy-MM-dd');
} else if (typeKey === 'nasl.core.Time') {
const timeRegex = /^([01]?\d|2[0-3])(?::([0-5]?\d)(?::([0-5]?\d))?)?$/;
// 纯时间 12:30:00
Expand Down Expand Up @@ -797,14 +795,14 @@ export const toString = (typeKey, variable, tz?, tabSize = 0, collection = new S
}
varArr.push(varItem || '00');
});
str = momentTZ
.tz(safeNewDate('2022-01-01 ' + varArr.join(':')), getAppTimezone(tz))
.format(formatArr.join(':'));
str = DateTime.fromJSDate(safeNewDate('2022-01-01 ' + varArr.join(':')))
.setZone(getAppTimezone(tz))
.toFormat(formatArr.join(':'));
} else {
str = momentTZ.tz(safeNewDate(variable), getAppTimezone(tz)).format('HH:mm:ss');
str = DateTime.fromJSDate(safeNewDate(variable)).setZone(getAppTimezone(tz)).toFormat('HH:mm:ss');
}
} else if (typeKey === 'nasl.core.DateTime') {
str = momentTZ.tz(safeNewDate(variable), getAppTimezone(tz)).format('YYYY-MM-DD HH:mm:ss');
str = DateTime.fromJSDate(safeNewDate(variable)).setZone(getAppTimezone(tz)).toFormat('yyyy-MM-dd HH:mm:ss');
}
if (tabSize > 0) {
if (['nasl.core.String', 'nasl.core.Text'].includes(typeKey)) {
Expand Down Expand Up @@ -1032,13 +1030,12 @@ export const fromString = (variable, typeKey) => {
// 日期
if (typeName === 'DateTime') {
const date = safeNewDate(variable);
const outputDate = format(date, "yyyy-MM-dd'T'HH:mm:ss.SSSxxx");
const outputDate = DateTime.fromJSDate(date).toFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
return outputDate;
} else if (typeName === 'Date') {
return moment(safeNewDate(variable)).format('YYYY-MM-DD');
return DateTime.fromJSDate(safeNewDate(variable)).toFormat('yyyy-MM-dd');
} else if (typeName === 'Time' && TimeReg.test(variable)) {
// ???
return moment(safeNewDate('2022-01-01 ' + variable)).format('HH:mm:ss');
return DateTime.fromJSDate(safeNewDate('2022-01-01 ' + variable)).toFormat('HH:mm:ss');
}
// 浮点数
else if (['Decimal', 'Double'].includes(typeName) && FloatNumberReg.test(variable)) {
Expand Down
11 changes: 9 additions & 2 deletions packages/basic/src/sdk/Formatters/DateFormatter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { format } from 'date-fns';
import { DateTime } from 'luxon';
import Formatter from './Formatter';

/**
Expand Down Expand Up @@ -53,7 +53,14 @@ export class DateFormatter extends Formatter {
pattern = pattern || this.pattern;

if (pattern === `yyyy-MM-dd'T'HH:mm:ss.SSSxxx`) {
return format(value, pattern);
let dt =
value instanceof Date
? DateTime.fromJSDate(value)
: typeof value === 'string' && value?.includes('T')
? DateTime.fromISO(value)
: DateTime.fromJSDate(new Date(value));

return dt.toFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
Comment thread
YufJi marked this conversation as resolved.
}

if (value && !isNaN(value)) value = +value;
Expand Down
62 changes: 46 additions & 16 deletions packages/basic/src/sdk/helper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import moment from 'moment';
import momentTZ from 'moment-timezone';
import { DateTime } from 'luxon';
import { isObject } from 'lodash';

export const findAsync = async (arr, callback) => {
Expand Down Expand Up @@ -67,16 +66,26 @@ export const sortRule = (valueA, valueB, sort) => {
}
};

export const getAppTimezone = (inputTz) => {
const _appTimeZone = window?.appInfo?.appTimeZone;
const tz = inputTz === 'global' ? _appTimeZone : inputTz;

if (tz && tz !== 'user') {
// 指定的固定的时区
return tz;
} else {
// 用户本地时区,包括 tz 是 null 的场景
return Intl.DateTimeFormat().resolvedOptions().timeZone;
/**
* 获取应用的时区
* 逻辑:
* 1. 如果输入的时区是 'global',则使用应用配置的时区(window.appInfo.appTimeZone)
* 2. 如果输入的时区是其他非 'user' 的值,则使用该值作为时区
* 3. 如果输入的时区是 'user' 或者没有输入,则使用用户本地的时区(Intl.DateTimeFormat().resolvedOptions().timeZone)
*/
export const getAppTimezone = (tz?: string) => {
const userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const globalTimeZone =
(window?.appInfo?.appTimeZone === 'user' ? userTimeZone : window?.appInfo?.appTimeZone) ?? userTimeZone;

tz = tz ?? 'user';
switch (tz) {
case 'global':
return globalTimeZone;
case 'user':
return userTimeZone;
default:
return tz;
}
Comment thread
YufJi marked this conversation as resolved.
};

Expand All @@ -95,12 +104,33 @@ export function isValidTimezoneIANAString(timezoneString) {

export function naslDateToLocalDate(date) {
const localTZ = Intl.DateTimeFormat().resolvedOptions().timeZone;
const localDate = momentTZ.tz(date, 'YYYY-MM-DD', localTZ);
return safeNewDate(localDate.format('YYYY-MM-DD HH:mm:ss'));
// 仅日期部分
if (/^\d{4}-\d{2}-\d{2}$/.test(date)) {
const localDate = DateTime.fromFormat(date, 'yyyy-MM-dd', { zone: localTZ });
return safeNewDate(localDate.toFormat('yyyy-MM-dd HH:mm:ss'));
}

// 日期时间
if (/^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}$/.test(date)) {
const localDate = DateTime.fromFormat(date, 'yyyy-MM-dd HH:mm:ss', { zone: localTZ });
return safeNewDate(localDate.toFormat('yyyy-MM-dd HH:mm:ss'));
}

// ISO 字符串
if (typeof date === 'string' && date.includes('T')) {
const localDate = DateTime.fromISO(date, { zone: localTZ });
return safeNewDate(localDate.toFormat('yyyy-MM-dd HH:mm:ss'));
}

// 其他情况直接转换
const localDate = DateTime.fromJSDate(safeNewDate(date), { zone: localTZ });
return safeNewDate(localDate.toFormat('yyyy-MM-dd HH:mm:ss'));
}

export function convertJSDateInTargetTimeZone(date, tz) {
return safeNewDate(momentTZ.tz(safeNewDate(date), getAppTimezone(tz)).format('YYYY-MM-DD HH:mm:ss'));
return safeNewDate(
DateTime.fromJSDate(safeNewDate(date)).setZone(getAppTimezone(tz)).toFormat('yyyy-MM-dd HH:mm:ss'),
);
}

export const safeNewDate = (dateStr) => {
Expand Down Expand Up @@ -198,7 +228,7 @@ export function isInputValidNaslDateTime(input) {
export function toValue(date, typeKey) {
if (!date) return date;
if (typeKey === 'format')
return moment(date).format('YYYY-MM-DD'); // value 的真实格式
return DateTime.fromJSDate(date).toFormat('yyyy-MM-dd'); // value 的真实格式
else if (typeKey === 'json') return this.JsonSerialize(date);
else if (typeKey === 'timestamp') return date.getTime();
else return date;
Expand Down
Loading