@nocobase/database 2.1.0-beta.32 → 2.1.0-beta.34

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,4 +1,13 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  import { DatetimeInterface } from './datetime-interface';
2
10
  export declare class DateInterface extends DatetimeInterface {
11
+ toValue(value: any, ctx?: any): Promise<any>;
3
12
  toString(value: any, ctx?: any): any;
4
13
  }
@@ -31,7 +31,34 @@ __export(date_interface_exports, {
31
31
  });
32
32
  module.exports = __toCommonJS(date_interface_exports);
33
33
  var import_datetime_interface = require("./datetime-interface");
34
+ function pad2(value) {
35
+ return String(value).padStart(2, "0");
36
+ }
37
+ __name(pad2, "pad2");
38
+ function formatDateOnlyFromDate(date, timezone) {
39
+ const offsetMinutes = (0, import_datetime_interface.getTimeZoneOffsetMinutes)(timezone);
40
+ if (offsetMinutes == null) {
41
+ return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
42
+ }
43
+ const shifted = new Date(date.getTime() + offsetMinutes * 60 * 1e3);
44
+ return `${shifted.getUTCFullYear()}-${pad2(shifted.getUTCMonth() + 1)}-${pad2(shifted.getUTCDate())}`;
45
+ }
46
+ __name(formatDateOnlyFromDate, "formatDateOnlyFromDate");
34
47
  const _DateInterface = class _DateInterface extends import_datetime_interface.DatetimeInterface {
48
+ async toValue(value, ctx) {
49
+ const normalized = await super.toValue(value, ctx);
50
+ if (!normalized) {
51
+ return normalized;
52
+ }
53
+ if (typeof normalized === "string" && /^\d{4}-\d{2}-\d{2}$/.test(normalized)) {
54
+ return normalized;
55
+ }
56
+ const date = normalized instanceof Date ? normalized : new Date(normalized);
57
+ if (Number.isNaN(date.getTime())) {
58
+ return normalized;
59
+ }
60
+ return formatDateOnlyFromDate(date, (0, import_datetime_interface.resolveTimeZoneFromCtx)(ctx));
61
+ }
35
62
  toString(value, ctx) {
36
63
  return value;
37
64
  }
@@ -7,6 +7,8 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { BaseInterface } from './base-interface';
10
+ export declare function getTimeZoneOffsetMinutes(timezone: string | number | null | undefined): number;
11
+ export declare function resolveTimeZoneFromCtx(ctx: any): any;
10
12
  export declare class DatetimeInterface extends BaseInterface {
11
13
  protected parseDateString(value: string): {
12
14
  year: string;
@@ -30,7 +32,7 @@ export declare class DatetimeInterface extends BaseInterface {
30
32
  hour?: string;
31
33
  minute?: string;
32
34
  second?: string;
33
- }): string;
35
+ }, ctx?: any): string;
34
36
  toValue(value: any, ctx?: any): Promise<any>;
35
37
  toString(value: any, ctx?: any): any;
36
38
  }
@@ -37,7 +37,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
37
37
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
38
  var datetime_interface_exports = {};
39
39
  __export(datetime_interface_exports, {
40
- DatetimeInterface: () => DatetimeInterface
40
+ DatetimeInterface: () => DatetimeInterface,
41
+ getTimeZoneOffsetMinutes: () => getTimeZoneOffsetMinutes,
42
+ resolveTimeZoneFromCtx: () => resolveTimeZoneFromCtx
41
43
  });
42
44
  module.exports = __toCommonJS(datetime_interface_exports);
43
45
  var import_base_interface = require("./base-interface");
@@ -54,13 +56,79 @@ function isNumeric(str) {
54
56
  return !isNaN(str) && !isNaN(parseFloat(str));
55
57
  }
56
58
  __name(isNumeric, "isNumeric");
59
+ function getTimeZoneOffsetMinutes(timezone) {
60
+ if (typeof timezone === "number" && Number.isFinite(timezone)) {
61
+ return timezone;
62
+ }
63
+ if (typeof timezone !== "string") {
64
+ return null;
65
+ }
66
+ const normalized = timezone.trim().toUpperCase();
67
+ if (!normalized) {
68
+ return null;
69
+ }
70
+ if (normalized === "Z" || normalized === "UTC") {
71
+ return 0;
72
+ }
73
+ const match = normalized.match(/^([+-])(\d{2})(?::?(\d{2}))?$/);
74
+ if (!match) {
75
+ return null;
76
+ }
77
+ const [, sign, hours, minutes = "00"] = match;
78
+ const totalMinutes = Number(hours) * 60 + Number(minutes);
79
+ return sign === "+" ? totalMinutes : -totalMinutes;
80
+ }
81
+ __name(getTimeZoneOffsetMinutes, "getTimeZoneOffsetMinutes");
57
82
  function resolveTimeZoneFromCtx(ctx) {
58
- if ((ctx == null ? void 0 : ctx.get) && (ctx == null ? void 0 : ctx.get("X-Timezone"))) {
59
- return ctx.get("X-Timezone");
83
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
84
+ let timezone;
85
+ if (typeof (ctx == null ? void 0 : ctx.get) === "function") {
86
+ timezone = ctx.get("X-Timezone") || ctx.get("x-timezone");
87
+ } else if (typeof ((_a = ctx == null ? void 0 : ctx.request) == null ? void 0 : _a.get) === "function") {
88
+ timezone = ctx.request.get("X-Timezone") || ctx.request.get("x-timezone");
89
+ }
90
+ timezone = timezone || ((_c = (_b = ctx == null ? void 0 : ctx.request) == null ? void 0 : _b.headers) == null ? void 0 : _c["x-timezone"]) || ((_e = (_d = ctx == null ? void 0 : ctx.request) == null ? void 0 : _d.headers) == null ? void 0 : _e["X-Timezone"]) || ((_g = (_f = ctx == null ? void 0 : ctx.request) == null ? void 0 : _f.header) == null ? void 0 : _g["x-timezone"]) || ((_i = (_h = ctx == null ? void 0 : ctx.request) == null ? void 0 : _h.header) == null ? void 0 : _i["X-Timezone"]) || ((_k = (_j = ctx == null ? void 0 : ctx.req) == null ? void 0 : _j.headers) == null ? void 0 : _k["x-timezone"]) || ((_m = (_l = ctx == null ? void 0 : ctx.req) == null ? void 0 : _l.headers) == null ? void 0 : _m["X-Timezone"]);
91
+ if (timezone !== void 0 && timezone !== null && timezone !== "") {
92
+ return timezone;
60
93
  }
61
- return 0;
94
+ return null;
62
95
  }
63
96
  __name(resolveTimeZoneFromCtx, "resolveTimeZoneFromCtx");
97
+ function toISOWithTimezone(dateInfo, timezone) {
98
+ const offsetMinutes = getTimeZoneOffsetMinutes(timezone);
99
+ if (offsetMinutes == null) {
100
+ return null;
101
+ }
102
+ const utcMillis = Date.UTC(
103
+ Number(dateInfo.year),
104
+ Number(dateInfo.month) - 1,
105
+ Number(dateInfo.day),
106
+ Number(dateInfo.hour || "00"),
107
+ Number(dateInfo.minute || "00"),
108
+ Number(dateInfo.second || "00"),
109
+ 0
110
+ ) - offsetMinutes * 60 * 1e3;
111
+ return new Date(utcMillis).toISOString();
112
+ }
113
+ __name(toISOWithTimezone, "toISOWithTimezone");
114
+ function excelSerialToISO(value, timezone) {
115
+ const wallClockUtcDate = (0, import_excel_date_to_js.getJsDateFromExcel)(value);
116
+ const offsetMinutes = getTimeZoneOffsetMinutes(timezone);
117
+ if (offsetMinutes == null) {
118
+ return wallClockUtcDate.toISOString();
119
+ }
120
+ const utcMillis = Date.UTC(
121
+ wallClockUtcDate.getUTCFullYear(),
122
+ wallClockUtcDate.getUTCMonth(),
123
+ wallClockUtcDate.getUTCDate(),
124
+ wallClockUtcDate.getUTCHours(),
125
+ wallClockUtcDate.getUTCMinutes(),
126
+ wallClockUtcDate.getUTCSeconds(),
127
+ wallClockUtcDate.getUTCMilliseconds()
128
+ ) - offsetMinutes * 60 * 1e3;
129
+ return new Date(utcMillis).toISOString();
130
+ }
131
+ __name(excelSerialToISO, "excelSerialToISO");
64
132
  const _DatetimeInterface = class _DatetimeInterface extends import_base_interface.BaseInterface {
65
133
  parseDateString(value) {
66
134
  const dateOnlyMatch = /^(\d{4})[-/]?(\d{2})[-/]?(\d{2})$/.exec(value);
@@ -75,7 +143,12 @@ const _DatetimeInterface = class _DatetimeInterface extends import_base_interfac
75
143
  }
76
144
  return null;
77
145
  }
78
- formatDateTimeToISO(dateInfo) {
146
+ formatDateTimeToISO(dateInfo, ctx) {
147
+ const timezone = resolveTimeZoneFromCtx(ctx);
148
+ const timezoneAwareISO = toISOWithTimezone(dateInfo, timezone);
149
+ if (timezoneAwareISO) {
150
+ return timezoneAwareISO;
151
+ }
79
152
  const { year, month, day, hour = "00", minute = "00", second = "00" } = dateInfo;
80
153
  const m = (0, import_dayjs.default)(`${year}-${month}-${day} ${hour}:${minute}:${second}.000`);
81
154
  return m.toISOString();
@@ -94,7 +167,7 @@ const _DatetimeInterface = class _DatetimeInterface extends import_base_interfac
94
167
  if (typeof value === "string") {
95
168
  const dateInfo = this.parseDateString(value);
96
169
  if (dateInfo) {
97
- return this.formatDateTimeToISO(dateInfo);
170
+ return this.formatDateTimeToISO(dateInfo, ctx);
98
171
  }
99
172
  }
100
173
  if (import_dayjs.default.isDayjs(value)) {
@@ -102,7 +175,7 @@ const _DatetimeInterface = class _DatetimeInterface extends import_base_interfac
102
175
  } else if (isDate(value)) {
103
176
  return value;
104
177
  } else if (isNumeric(value)) {
105
- return (0, import_excel_date_to_js.getJsDateFromExcel)(value).toISOString();
178
+ return excelSerialToISO(value, resolveTimeZoneFromCtx(ctx));
106
179
  } else if (typeof value === "string") {
107
180
  return value;
108
181
  }
@@ -110,7 +183,7 @@ const _DatetimeInterface = class _DatetimeInterface extends import_base_interfac
110
183
  }
111
184
  toString(value, ctx) {
112
185
  var _a, _b;
113
- const utcOffset = resolveTimeZoneFromCtx(ctx);
186
+ const utcOffset = resolveTimeZoneFromCtx(ctx) ?? 0;
114
187
  const props = ((_b = (_a = this.options) == null ? void 0 : _a.uiSchema) == null ? void 0 : _b["x-component-props"]) ?? {};
115
188
  const format = (0, import_utils.getDefaultFormat)(props);
116
189
  const m = (0, import_utils.str2moment)(value, { ...props, utcOffset });
@@ -121,5 +194,7 @@ __name(_DatetimeInterface, "DatetimeInterface");
121
194
  let DatetimeInterface = _DatetimeInterface;
122
195
  // Annotate the CommonJS export names for ESM import in node:
123
196
  0 && (module.exports = {
124
- DatetimeInterface
197
+ DatetimeInterface,
198
+ getTimeZoneOffsetMinutes,
199
+ resolveTimeZoneFromCtx
125
200
  });
@@ -1,3 +1,11 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  import { DatetimeInterface } from './datetime-interface';
2
10
  export declare class DatetimeNoTzInterface extends DatetimeInterface {
3
11
  protected formatDateTimeToString(dateInfo: {
@@ -8,6 +16,7 @@ export declare class DatetimeNoTzInterface extends DatetimeInterface {
8
16
  minute?: string;
9
17
  second?: string;
10
18
  }): string;
19
+ protected formatExcelSerialToString(value: number | string): string;
11
20
  toValue(value: any, ctx?: any): Promise<any>;
12
21
  toString(value: any, ctx?: any): any;
13
22
  }
@@ -54,6 +54,10 @@ function isNumeric(str) {
54
54
  return !isNaN(str) && !isNaN(parseFloat(str));
55
55
  }
56
56
  __name(isNumeric, "isNumeric");
57
+ function pad2(value) {
58
+ return String(value).padStart(2, "0");
59
+ }
60
+ __name(pad2, "pad2");
57
61
  const _DatetimeNoTzInterface = class _DatetimeNoTzInterface extends import_datetime_interface.DatetimeInterface {
58
62
  formatDateTimeToString(dateInfo) {
59
63
  const { year, month, day, hour, minute, second } = dateInfo;
@@ -62,6 +66,17 @@ const _DatetimeNoTzInterface = class _DatetimeNoTzInterface extends import_datet
62
66
  }
63
67
  return `${year}-${month}-${day}`;
64
68
  }
69
+ formatExcelSerialToString(value) {
70
+ const date = (0, import_excel_date_to_js.getJsDateFromExcel)(value);
71
+ return this.formatDateTimeToString({
72
+ year: String(date.getUTCFullYear()),
73
+ month: pad2(date.getUTCMonth() + 1),
74
+ day: pad2(date.getUTCDate()),
75
+ hour: pad2(date.getUTCHours()),
76
+ minute: pad2(date.getUTCMinutes()),
77
+ second: pad2(date.getUTCSeconds())
78
+ });
79
+ }
65
80
  async toValue(value, ctx = {}) {
66
81
  if (!value) {
67
82
  return null;
@@ -77,8 +92,7 @@ const _DatetimeNoTzInterface = class _DatetimeNoTzInterface extends import_datet
77
92
  } else if (isDate(value)) {
78
93
  return value;
79
94
  } else if (isNumeric(value)) {
80
- const date = (0, import_excel_date_to_js.getJsDateFromExcel)(value);
81
- return date.toISOString();
95
+ return this.formatExcelSerialToString(value);
82
96
  } else if (typeof value === "string") {
83
97
  return value;
84
98
  }
@@ -44,8 +44,24 @@ var import_dayjs = __toESM(require("dayjs"));
44
44
  var import_utc = __toESM(require("dayjs/plugin/utc"));
45
45
  var import_base_interface = require("./base-interface");
46
46
  import_dayjs.default.extend(import_utc.default);
47
+ function isNumeric(value) {
48
+ return typeof value === "number" && Number.isFinite(value);
49
+ }
50
+ __name(isNumeric, "isNumeric");
51
+ function formatExcelTimeSerial(value) {
52
+ const normalized = (value % 1 + 1) % 1;
53
+ const totalSeconds = Math.round(normalized * 24 * 60 * 60) % (24 * 60 * 60);
54
+ const hours = Math.floor(totalSeconds / 3600).toString().padStart(2, "0");
55
+ const minutes = Math.floor(totalSeconds % 3600 / 60).toString().padStart(2, "0");
56
+ const seconds = (totalSeconds % 60).toString().padStart(2, "0");
57
+ return `${hours}:${minutes}:${seconds}`;
58
+ }
59
+ __name(formatExcelTimeSerial, "formatExcelTimeSerial");
47
60
  const _TimeInterface = class _TimeInterface extends import_base_interface.BaseInterface {
48
61
  toValue(value, ctx) {
62
+ if (isNumeric(value)) {
63
+ return formatExcelTimeSerial(value);
64
+ }
49
65
  if (this.validate(value)) {
50
66
  const result = (0, import_dayjs.default)(value).format("HH:mm:ss");
51
67
  return result;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@nocobase/database",
3
- "version": "2.1.0-beta.32",
3
+ "version": "2.1.0-beta.34",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
7
7
  "license": "Apache-2.0",
8
8
  "dependencies": {
9
- "@nocobase/logger": "2.1.0-beta.32",
10
- "@nocobase/utils": "2.1.0-beta.32",
9
+ "@nocobase/logger": "2.1.0-beta.34",
10
+ "@nocobase/utils": "2.1.0-beta.34",
11
11
  "async-mutex": "^0.3.2",
12
12
  "chalk": "^4.1.1",
13
13
  "cron-parser": "4.4.0",
@@ -38,5 +38,5 @@
38
38
  "url": "git+https://github.com/nocobase/nocobase.git",
39
39
  "directory": "packages/database"
40
40
  },
41
- "gitHead": "659c5efe992da7118d33c768bbd9e837a2c4716f"
41
+ "gitHead": "ca804833299c547f8d49f8d58f73273a4bfcd03c"
42
42
  }