@isi-ui7/bos7-shared 0.4.1 → 0.4.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isi-ui7/bos7-shared",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Shared auth7 and layout primitives for bos7 applications.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -70,7 +70,7 @@
70
70
  "peerDependencies": {
71
71
  "@carbon/icons-react": "^11.71.0",
72
72
  "@carbon/react": "^1.97.0",
73
- "@isi-ui7/corporate-themes": ">=0.2.11",
73
+ "@isi-ui7/corporate-themes": ">=0.2.12",
74
74
  "@isi-ui7/data-table": ">=0.2.5",
75
75
  "@isi-ui7/editable-table": ">=0.2.3",
76
76
  "@isi-ui7/i18n": ">=0.2.3",
@@ -106,14 +106,14 @@
106
106
  "vite": "^5.0.0",
107
107
  "vite-plugin-dts": "^3.6.0",
108
108
  "vitest": "^1.0.0",
109
- "@isi-ui7/corporate-themes": "0.2.11",
109
+ "@isi-ui7/corporate-themes": "0.2.12",
110
+ "@isi-ui7/data-table": "0.2.5",
110
111
  "@isi-ui7/editable-table": "0.2.3",
111
112
  "@isi-ui7/i18n": "0.2.3",
112
113
  "@isi-ui7/lookup-input": "0.2.4",
113
- "@isi-ui7/ui-shell": "0.2.8",
114
+ "@isi-ui7/modal-manager": "0.2.2",
114
115
  "@isi-ui7/realtime": "0.2.3",
115
- "@isi-ui7/data-table": "0.2.5",
116
- "@isi-ui7/modal-manager": "0.2.2"
116
+ "@isi-ui7/ui-shell": "0.2.8"
117
117
  },
118
118
  "dependencies": {
119
119
  "@carbon/icons-react": "^11.71.0",
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { toLocalISODate, collectPageFields, runFieldValidation } from "./form-renderer-utils";
2
+ import { toLocalISODate, fromLocalISODate, collectPageFields, runFieldValidation } from "./form-renderer-utils";
3
3
  import { Rules } from "./form-rules";
4
4
  import type { FormLayout, FormSection } from "./form-types";
5
5
 
@@ -44,6 +44,48 @@ describe("toLocalISODate", () => {
44
44
  });
45
45
  });
46
46
 
47
+ // ─────────────────────────────────────────────────────────────────────────────
48
+ // fromLocalISODate — tiga bentuk yang genuinely dikirim backend (PM, 2026-08-31:
49
+ // core7-service-cif FT-573/574 mengirim RFC3339 penuh dari *time.Time Go,
50
+ // bukan cuma "YYYY-MM-DD" polos — field date tampak KOSONG diam-diam sebelum
51
+ // perbaikan ini, ditemukan lewat verifikasi browser sungguhan).
52
+ // ─────────────────────────────────────────────────────────────────────────────
53
+ describe("fromLocalISODate", () => {
54
+ it("YYYY-MM-DD polos", () => {
55
+ const d = fromLocalISODate("2029-12-31");
56
+ expect(d).toBeInstanceOf(Date);
57
+ expect(d && toLocalISODate(d)).toBe("2029-12-31");
58
+ });
59
+
60
+ it("RFC3339 dengan 'Z' — TIDAK boleh tergeser (kelas bug yang SAMA dgn ce1573c9)", () => {
61
+ const d = fromLocalISODate("2029-12-31T00:00:00Z");
62
+ expect(d).toBeInstanceOf(Date);
63
+ expect(d && toLocalISODate(d)).toBe("2029-12-31");
64
+ });
65
+
66
+ it("RFC3339 dengan offset non-UTC — tanggalnya diambil dari digit, bukan dikonversi zona", () => {
67
+ const d = fromLocalISODate("2029-12-31T23:30:00+07:00");
68
+ expect(d).toBeInstanceOf(Date);
69
+ expect(d && toLocalISODate(d)).toBe("2029-12-31");
70
+ });
71
+
72
+ it("kontrol: string bukan tanggal → undefined, bukan Invalid Date", () => {
73
+ expect(fromLocalISODate("bukan tanggal")).toBeUndefined();
74
+ expect(fromLocalISODate("")).toBeUndefined();
75
+ expect(fromLocalISODate(undefined)).toBeUndefined();
76
+ expect(fromLocalISODate(null)).toBeUndefined();
77
+ });
78
+
79
+ it("kontrol sabotase: regex TANPA jangkar akhir memang disengaja — versi lama ($ di akhir) HARUS gagal utk RFC3339", () => {
80
+ // Membuktikan test di atas genuinely mengukur perbaikan ini, bukan
81
+ // kebetulan lolos: pola LAMA (sebelum perbaikan PM 2026-08-31) menolak
82
+ // RFC3339 sepenuhnya.
83
+ const polaLama = /^(\d{4})-(\d{2})-(\d{2})$/;
84
+ expect(polaLama.test("2029-12-31T00:00:00Z")).toBe(false);
85
+ expect(polaLama.test("2029-12-31")).toBe(true);
86
+ });
87
+ });
88
+
47
89
  // ─────────────────────────────────────────────────────────────────────────────
48
90
  // Rules.date — tanggal kalender yang sungguh ada
49
91
  // ─────────────────────────────────────────────────────────────────────────────
@@ -198,7 +198,22 @@ export function toLocalISODate(date: Date | undefined | null): string {
198
198
  */
199
199
  export function fromLocalISODate(iso: string | undefined | null): Date | undefined {
200
200
  if (!iso) return undefined;
201
- const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(iso);
201
+ // Regex TIDAK ber-akhiran `$` dengan sengaja: field "date" (bukan
202
+ // "datetime") menerima "YYYY-MM-DD" polos MAUPUN RFC3339 penuh
203
+ // ("2029-12-31T00:00:00Z" atau ber-offset) — keduanya nyata dikirim
204
+ // backend, tergantung tipe kolom Go di sisi server (time.Time vs string
205
+ // yang sudah diformat). Sebelum perbaikan ini, RFC3339 gagal match diam-
206
+ // diam dan DatePicker menerima `undefined` — field tampak KOSONG tanpa
207
+ // satu pun galat (laporan PM, ditemukan lewat verifikasi browser
208
+ // sungguhan atas core7-service-cif FT-573/574, 2026-08-31).
209
+ //
210
+ // Ambil HANYA digit tanggalnya, JANGAN `new Date(iso)` — itu persis bug
211
+ // asli yang diperbaiki lewat fungsi ini (lihat komentar di atas):
212
+ // `new Date("2029-12-31T00:00:00Z")` mem-parse sbg UTC, dan di zona
213
+ // timur UTC (WIB) itu bisa MUNDUR sehari. Regex + konstruktor
214
+ // komponen-lokal di bawah membaca digitnya apa adanya, sama seperti
215
+ // jalur "YYYY-MM-DD" polos.
216
+ const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso);
202
217
  if (!m) return undefined;
203
218
  const [, y, mo, d] = m;
204
219
  const date = new Date(Number(y), Number(mo) - 1, Number(d));