@statezero/core 0.1.92 → 0.1.93

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.
@@ -400,6 +400,7 @@ function createDateOperations(timezone = 'UTC', ModelClass = null) {
400
400
  return false;
401
401
  }
402
402
  // Convert params to Date using serializer
403
+ // The serializer now parses date strings in the backend timezone
403
404
  const paramDate = toDateObject(params, fieldName);
404
405
  if (!paramDate || isNaN(paramDate.getTime()))
405
406
  return false;
@@ -19,9 +19,10 @@ export class DateParsingHelpers {
19
19
  * @param {string|Date} value - The date value to parse
20
20
  * @param {string} fieldName - Name of the field (for schema lookup)
21
21
  * @param {Object} schema - The model schema containing format info
22
+ * @param {string} timezone - The backend timezone (defaults to 'UTC')
22
23
  * @returns {Date|null} - Parsed Date object or null if invalid
23
24
  */
24
- static parseDate(value: string | Date, fieldName: string, schema: Object): Date | null;
25
+ static parseDate(value: string | Date, fieldName: string, schema: Object, timezone?: string): Date | null;
25
26
  /**
26
27
  * Serialize a date using the field's configured format
27
28
  * @param {Date} date - The date to serialize
@@ -1,4 +1,5 @@
1
1
  import { format, parse, parseISO } from 'date-fns';
2
+ import { DateTime } from 'luxon';
2
3
  /**
3
4
  * Date parsing utilities for handling Django style date formats
4
5
  */
@@ -8,12 +9,13 @@ export class DateParsingHelpers {
8
9
  * @param {string|Date} value - The date value to parse
9
10
  * @param {string} fieldName - Name of the field (for schema lookup)
10
11
  * @param {Object} schema - The model schema containing format info
12
+ * @param {string} timezone - The backend timezone (defaults to 'UTC')
11
13
  * @returns {Date|null} - Parsed Date object or null if invalid
12
14
  */
13
- static parseDate(value, fieldName, schema) {
15
+ static parseDate(value, fieldName, schema, timezone = 'UTC') {
14
16
  if (!value)
15
17
  return null;
16
- // If already a Date object, return as-is
18
+ // If already a Date object, return as-is (it's already a specific instant in time)
17
19
  if (value instanceof Date)
18
20
  return value;
19
21
  const fieldFormat = schema.properties[fieldName].format;
@@ -33,10 +35,19 @@ export class DateParsingHelpers {
33
35
  try {
34
36
  // Handle ISO format (Django's default)
35
37
  if (!dateFormat || dateFormat === 'iso-8601') {
36
- return parseISO(value);
38
+ // Parse the string in the server timezone using Luxon
39
+ // This ensures '2022-03-15' is interpreted as midnight in the server TZ, not browser TZ
40
+ const luxonDate = DateTime.fromISO(value, { zone: timezone });
41
+ if (!luxonDate.isValid) {
42
+ console.error(`Failed to parse ISO date "${value}":`, luxonDate.invalidReason);
43
+ return null;
44
+ }
45
+ return luxonDate.toJSDate();
37
46
  }
38
47
  // Handle supported Django formats
39
48
  const dateFnsFormat = this.SUPPORTED_FORMATS[dateFormat];
49
+ // For non-ISO formats, use date-fns but we should still consider timezone
50
+ // For now, parse with date-fns and assume it's in the server timezone
40
51
  return parse(value, dateFnsFormat, new Date());
41
52
  }
42
53
  catch (error) {
@@ -1,6 +1,19 @@
1
1
  import { configInstance } from "../../config.js";
2
2
  import { isNil } from "lodash-es";
3
3
  import { DateParsingHelpers } from "./dates.js";
4
+ /**
5
+ * Gets the backend timezone for a model class
6
+ * @param {Class} ModelClass - The model class
7
+ * @returns {string} The backend timezone or 'UTC' as fallback
8
+ */
9
+ function getBackendTimezone(ModelClass) {
10
+ if (!ModelClass || !ModelClass.configKey) {
11
+ return 'UTC'; // Default fallback
12
+ }
13
+ const config = configInstance.getConfig();
14
+ const backendConfig = config.backendConfigs[ModelClass.configKey] || config.backendConfigs.default;
15
+ return backendConfig.BACKEND_TZ || 'UTC';
16
+ }
4
17
  /**
5
18
  * File field serializer - handles both camelCase (frontend) and snake_case (backend) formats
6
19
  */
@@ -73,8 +86,11 @@ export const dateFieldSerializer = {
73
86
  return value;
74
87
  const { model, field } = context;
75
88
  if (model?.schema) {
76
- // Use DateParsingHelpers like the model does
77
- return DateParsingHelpers.parseDate(value, field, model.schema);
89
+ // Get the backend timezone for this model
90
+ const timezone = getBackendTimezone(model);
91
+ // Use DateParsingHelpers with timezone awareness
92
+ // This ensures date strings are parsed in the server timezone, not browser timezone
93
+ return DateParsingHelpers.parseDate(value, field, model.schema, timezone);
78
94
  }
79
95
  // Fallback parsing if no schema context
80
96
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statezero/core",
3
- "version": "0.1.92",
3
+ "version": "0.1.93",
4
4
  "type": "module",
5
5
  "module": "ESNext",
6
6
  "description": "The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate",