@aphexcms/cms-core 0.1.17 → 0.2.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.
Files changed (120) hide show
  1. package/dist/api/client.d.ts.map +1 -1
  2. package/dist/api/client.js +7 -1
  3. package/dist/api/types.d.ts +2 -0
  4. package/dist/api/types.d.ts.map +1 -1
  5. package/dist/cli/generate-types.js +59 -16
  6. package/dist/cli/index.js +1 -1
  7. package/dist/client/index.d.ts +0 -1
  8. package/dist/client/index.d.ts.map +1 -1
  9. package/dist/client/index.js +0 -1
  10. package/dist/components/AdminApp.svelte +278 -45
  11. package/dist/components/AdminApp.svelte.d.ts +2 -0
  12. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  13. package/dist/components/admin/DocumentEditor.svelte +60 -13
  14. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  15. package/dist/components/admin/ObjectModal.svelte +15 -4
  16. package/dist/components/admin/ObjectModal.svelte.d.ts +1 -0
  17. package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -1
  18. package/dist/components/admin/SchemaField.svelte +64 -5
  19. package/dist/components/admin/SchemaField.svelte.d.ts +1 -0
  20. package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
  21. package/dist/components/admin/fields/ArrayField.svelte +72 -17
  22. package/dist/components/admin/fields/ArrayField.svelte.d.ts +1 -0
  23. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
  24. package/dist/components/admin/fields/DateField.svelte +145 -0
  25. package/dist/components/admin/fields/DateField.svelte.d.ts +14 -0
  26. package/dist/components/admin/fields/DateField.svelte.d.ts.map +1 -0
  27. package/dist/components/admin/fields/DateTimeField.svelte +225 -0
  28. package/dist/components/admin/fields/DateTimeField.svelte.d.ts +14 -0
  29. package/dist/components/admin/fields/DateTimeField.svelte.d.ts.map +1 -0
  30. package/dist/components/admin/fields/ImageField.svelte +20 -7
  31. package/dist/components/admin/fields/ImageField.svelte.d.ts +1 -0
  32. package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
  33. package/dist/components/admin/fields/ReferenceField.svelte +1 -1
  34. package/dist/components/admin/fields/SlugField.svelte +1 -3
  35. package/dist/components/admin/fields/SlugField.svelte.d.ts.map +1 -1
  36. package/dist/components/admin/fields/StringField.svelte +156 -12
  37. package/dist/components/admin/fields/StringField.svelte.d.ts +3 -2
  38. package/dist/components/admin/fields/StringField.svelte.d.ts.map +1 -1
  39. package/dist/components/admin/fields/URLField.svelte +41 -0
  40. package/dist/components/admin/fields/URLField.svelte.d.ts +14 -0
  41. package/dist/components/admin/fields/URLField.svelte.d.ts.map +1 -0
  42. package/dist/components/index.d.ts +0 -1
  43. package/dist/components/index.d.ts.map +1 -1
  44. package/dist/components/index.js +0 -1
  45. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts +1 -8
  46. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +1 -1
  47. package/dist/db/interfaces/document.d.ts +0 -2
  48. package/dist/db/interfaces/document.d.ts.map +1 -1
  49. package/dist/db/interfaces/index.d.ts +2 -1
  50. package/dist/db/interfaces/index.d.ts.map +1 -1
  51. package/dist/db/interfaces/user.d.ts +2 -0
  52. package/dist/db/interfaces/user.d.ts.map +1 -1
  53. package/dist/db/utils/reference-resolver.js +1 -1
  54. package/dist/engine.d.ts.map +1 -1
  55. package/dist/engine.js +3 -0
  56. package/dist/field-validation/date-utils.d.ts +30 -0
  57. package/dist/field-validation/date-utils.d.ts.map +1 -0
  58. package/dist/field-validation/date-utils.js +147 -0
  59. package/dist/field-validation/rule.d.ts +4 -0
  60. package/dist/field-validation/rule.d.ts.map +1 -1
  61. package/dist/field-validation/rule.js +170 -4
  62. package/dist/field-validation/utils.d.ts +7 -3
  63. package/dist/field-validation/utils.d.ts.map +1 -1
  64. package/dist/field-validation/utils.js +129 -35
  65. package/dist/hooks.d.ts.map +1 -1
  66. package/dist/hooks.js +38 -21
  67. package/dist/lib/field-validation/date-utils.js +147 -0
  68. package/dist/lib/field-validation/rule.js +170 -4
  69. package/dist/lib/field-validation/utils.js +129 -35
  70. package/dist/local-api/collection-api.d.ts +16 -4
  71. package/dist/local-api/collection-api.d.ts.map +1 -1
  72. package/dist/local-api/collection-api.js +51 -17
  73. package/dist/local-api/index.d.ts +1 -1
  74. package/dist/local-api/index.d.ts.map +1 -1
  75. package/dist/routes/assets-cdn.d.ts.map +1 -1
  76. package/dist/routes/assets-cdn.js +14 -7
  77. package/dist/routes/assets.d.ts.map +1 -1
  78. package/dist/routes/assets.js +6 -1
  79. package/dist/routes/documents-by-id.d.ts.map +1 -1
  80. package/dist/routes/documents-by-id.js +18 -7
  81. package/dist/routes/documents-publish.js +2 -2
  82. package/dist/routes/documents-query.d.ts +3 -1
  83. package/dist/routes/documents-query.d.ts.map +1 -1
  84. package/dist/routes/documents-query.js +6 -2
  85. package/dist/routes/documents.d.ts.map +1 -1
  86. package/dist/routes/documents.js +20 -4
  87. package/dist/routes/index.d.ts +1 -0
  88. package/dist/routes/index.d.ts.map +1 -1
  89. package/dist/routes/index.js +2 -0
  90. package/dist/routes/user-preferences.d.ts +4 -0
  91. package/dist/routes/user-preferences.d.ts.map +1 -0
  92. package/dist/routes/user-preferences.js +77 -0
  93. package/dist/schema-utils/utils.d.ts +4 -0
  94. package/dist/schema-utils/utils.d.ts.map +1 -1
  95. package/dist/schema-utils/utils.js +23 -2
  96. package/dist/schema-utils/validator.d.ts +4 -0
  97. package/dist/schema-utils/validator.d.ts.map +1 -1
  98. package/dist/schema-utils/validator.js +120 -0
  99. package/dist/types/filters.d.ts +13 -0
  100. package/dist/types/filters.d.ts.map +1 -1
  101. package/dist/types/organization.d.ts +3 -0
  102. package/dist/types/organization.d.ts.map +1 -1
  103. package/dist/types/schemas.d.ts +67 -7
  104. package/dist/types/schemas.d.ts.map +1 -1
  105. package/dist/utils/default-orderings.d.ts +10 -0
  106. package/dist/utils/default-orderings.d.ts.map +1 -0
  107. package/dist/utils/default-orderings.js +63 -0
  108. package/dist/utils/field-defaults.d.ts +8 -0
  109. package/dist/utils/field-defaults.d.ts.map +1 -0
  110. package/dist/utils/field-defaults.js +20 -0
  111. package/dist/utils/index.d.ts +1 -0
  112. package/dist/utils/index.d.ts.map +1 -1
  113. package/dist/utils/index.js +1 -0
  114. package/dist/utils/initial-value-helpers.d.ts +50 -0
  115. package/dist/utils/initial-value-helpers.d.ts.map +1 -0
  116. package/dist/utils/initial-value-helpers.js +70 -0
  117. package/package.json +6 -4
  118. package/dist/components/admin/DocumentTypesList.svelte +0 -97
  119. package/dist/components/admin/DocumentTypesList.svelte.d.ts +0 -14
  120. package/dist/components/admin/DocumentTypesList.svelte.d.ts.map +0 -1
@@ -1,11 +1,4 @@
1
- import { Sidebar } from '@aphexcms/ui/shadcn/sidebar';
2
- import type { SidebarData } from '../../../types/sidebar.js';
3
- import type { ComponentProps } from 'svelte';
4
- type Props = ComponentProps<typeof Sidebar> & {
5
- data: SidebarData;
6
- onSignOut?: () => void | Promise<void>;
7
- };
8
- declare const AppSidebar: import("svelte").Component<Props, {}, "">;
1
+ declare const AppSidebar: import("svelte").Component<any, {}, "">;
9
2
  type AppSidebar = ReturnType<typeof AppSidebar>;
10
3
  export default AppSidebar;
11
4
  //# sourceMappingURL=AppSidebar.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AppSidebar.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/sidebar/AppSidebar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,OAAO,EAKP,MAAM,6BAA6B,CAAC;AAItC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAG5C,KAAK,KAAK,GAAG,cAAc,CAAC,OAAO,OAAO,CAAC,GAAG;IAC7C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,CAAC;AAqDH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"AppSidebar.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/sidebar/AppSidebar.svelte.ts"],"names":[],"mappings":"AAyEA,QAAA,MAAM,UAAU,yCAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -24,8 +24,6 @@ export interface UpdateDocumentData {
24
24
  * Document adapter interface for document-specific operations
25
25
  */
26
26
  export interface DocumentAdapter {
27
- findManyDoc(organizationId: string, filters?: Omit<DocumentFilters, 'organizationId'>): Promise<Document[]>;
28
- findByDocId(organizationId: string, id: string, depth?: number): Promise<Document | null>;
29
27
  createDocument(data: CreateDocumentData): Promise<Document>;
30
28
  updateDocDraft(organizationId: string, id: string, data: any, updatedBy?: string): Promise<Document | null>;
31
29
  deleteDocById(organizationId: string, id: string): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../src/lib/db/interfaces/document.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAE/B,WAAW,CACV,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,gBAAgB,CAAC,GAC/C,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvB,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC1F,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5D,cAAc,CACb,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,GAAG,EACT,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC5B,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAGpE,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACzE,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAG3E,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAG5E;;;;;;OAMG;IACH,mBAAmB,CAClB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,mBAAmB,CAClB,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAE5B;;;;;;OAMG;IACH,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/F"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../src/lib/db/interfaces/document.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAE/B,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5D,cAAc,CACb,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,GAAG,EACT,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC5B,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAGpE,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACzE,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAG3E,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAG5E;;;;;;OAMG;IACH,mBAAmB,CAClB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,mBAAmB,CAClB,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAE5B;;;;;;OAMG;IACH,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/F"}
@@ -20,6 +20,7 @@ export interface DatabaseAdapter extends DocumentAdapter, AssetAdapter, UserProf
20
20
  * Initialize RLS (enable/disable) on tables - call after migrations
21
21
  */
22
22
  initializeRLS?(): Promise<void>;
23
+ hierarchyEnabled: boolean;
23
24
  /**
24
25
  * Execute a function within a transaction with organization context set for RLS
25
26
  * Ensures proper isolation with connection pooling
@@ -28,7 +29,7 @@ export interface DatabaseAdapter extends DocumentAdapter, AssetAdapter, UserProf
28
29
  /**
29
30
  * Get all child organizations for a parent (for hierarchy support)
30
31
  */
31
- getChildOrganizations?(parentOrganizationId: string): Promise<string[]>;
32
+ getChildOrganizations(parentOrganizationId: string): Promise<string[]>;
32
33
  /**
33
34
  * Check if any user profiles exist in the system (for first-user detection)
34
35
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/db/interfaces/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,YAAY,EACX,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACrE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,eAChB,SAAQ,eAAe,EACtB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,mBAAmB;IAEpB,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAG7B,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAG9B;;OAEG;IACH,aAAa,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;;OAGG;IACH,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE7E;;OAEG;IACH,qBAAqB,CAAC,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAExE;;OAEG;IACH,kBAAkB,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,IAAI,eAAe,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,OAAO,CAAC,EAAE;QACT,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA6B,SAAQ,eAAe;IACpE,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjD,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/db/interfaces/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,YAAY,EACX,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACrE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,eAChB,SAAQ,eAAe,EACtB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,mBAAmB;IAEpB,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAG7B,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAG9B;;OAEG;IACH,aAAa,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE7E;;OAEG;IACH,qBAAqB,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEvE;;OAEG;IACH,kBAAkB,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,IAAI,eAAe,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,OAAO,CAAC,EAAE;QACT,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA6B,SAAQ,eAAe;IACpE,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjD,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7E"}
@@ -1,4 +1,5 @@
1
1
  import type { UserProfile } from '../../types/index.js';
2
+ import type { UserSessionPreferences } from '../../types/organization.js';
2
3
  export interface NewUserProfileData {
3
4
  userId: string;
4
5
  role?: 'super_admin' | 'admin' | 'editor' | 'viewer';
@@ -11,5 +12,6 @@ export interface UserProfileAdapter {
11
12
  createUserProfile(data: NewUserProfileData): Promise<UserProfile>;
12
13
  findUserProfileById(userId: string): Promise<UserProfile | null>;
13
14
  deleteUserProfile(userId: string): Promise<boolean>;
15
+ updateUserPreferences(userId: string, preferences: Partial<UserSessionPreferences>): Promise<void>;
14
16
  }
15
17
  //# sourceMappingURL=user.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/lib/db/interfaces/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAClE,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACjE,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpD"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/lib/db/interfaces/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAClE,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACjE,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,qBAAqB,CACpB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB"}
@@ -52,7 +52,7 @@ async function resolveDataReferences(data, adapter, organizationId, options) {
52
52
  if (typeof value === 'string' && key !== '_type' && key !== '_key') {
53
53
  // Try to fetch the referenced document
54
54
  try {
55
- const referencedDoc = await adapter.findByDocId(organizationId, value);
55
+ const referencedDoc = await adapter.findByDocIdAdvanced(organizationId, value);
56
56
  if (referencedDoc) {
57
57
  // Recursively resolve nested references
58
58
  resolved[key] = await resolveReferences(referencedDoc, adapter, organizationId, options);
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/lib/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,qBAAa,SAAS;IACrB,OAAO,CAAC,EAAE,CAAkB;IACrB,MAAM,EAAE,SAAS,CAAC;gBAEb,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe;IAMzD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAUlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIvD,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAI1C,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAI9C,iBAAiB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAI1F,eAAe,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAG9F;AAKD,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,GAAG,SAAS,CAKlF;AAED,wBAAgB,MAAM,IAAI,SAAS,CAKlC"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/lib/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,qBAAa,SAAS;IACrB,OAAO,CAAC,EAAE,CAAkB;IACrB,MAAM,EAAE,SAAS,CAAC;gBAEb,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe;IAMzD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAUlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIvD,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAI1C,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAI9C,iBAAiB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAI1F,eAAe,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAG9F;AAKD,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,GAAG,SAAS,CAKlF;AAED,wBAAgB,MAAM,IAAI,SAAS,CAKlC"}
package/dist/engine.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { validateSchemaReferences } from './schema-utils/validator.js';
1
2
  export class CMSEngine {
2
3
  db;
3
4
  config;
@@ -17,6 +18,8 @@ export class CMSEngine {
17
18
  // Initialize CMS - register schema types in database
18
19
  async initialize() {
19
20
  console.log('🚀 Initializing CMS...');
21
+ // Validate schemas before syncing to database
22
+ validateSchemaReferences(this.config.schemaTypes);
20
23
  // Get existing schemas from database
21
24
  const existingSchemas = await this.db.listSchemas();
22
25
  const existingNames = new Set(existingSchemas.map((s) => s.name));
@@ -0,0 +1,30 @@
1
+ import type { SchemaType } from '../types/index.js';
2
+ /**
3
+ * Convert a date value to user format for validation
4
+ * Handles both ISO format and user format inputs
5
+ */
6
+ export declare function convertDateToUserFormat(value: string, userFormat: string): string;
7
+ /**
8
+ * Convert a date value to ISO format for storage
9
+ * Returns ISO if already valid, or original value if invalid
10
+ */
11
+ export declare function convertDateToISO(value: string, userFormat: string): string;
12
+ /**
13
+ * Convert a datetime value to user format for validation
14
+ * Handles both ISO datetime and user format inputs
15
+ */
16
+ export declare function convertDateTimeToUserFormat(value: string, dateFormat: string, timeFormat?: string): string;
17
+ /**
18
+ * Convert a datetime value to ISO UTC format for storage
19
+ * Returns ISO UTC if already valid, or original value if invalid
20
+ */
21
+ export declare function convertDateTimeToISO(value: string, dateFormat: string, timeFormat?: string): string;
22
+ /**
23
+ * Normalize date fields in data object
24
+ * Converts dates to ISO for storage and creates a parallel object with user-formatted dates for validation
25
+ */
26
+ export declare function normalizeDateFields(data: Record<string, any>, schema: SchemaType): {
27
+ normalizedData: Record<string, any>;
28
+ dataForValidation: Record<string, any>;
29
+ };
30
+ //# sourceMappingURL=date-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-utils.d.ts","sourceRoot":"","sources":["../../src/lib/field-validation/date-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA4B,MAAM,gBAAgB,CAAC;AAQ3E;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAiBjF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAiB1E;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAC1C,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,MAAgB,GAC1B,MAAM,CAmBR;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,MAAgB,GAC1B,MAAM,CA0BR;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,MAAM,EAAE,UAAU,GAChB;IACF,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACvC,CA8DA"}
@@ -0,0 +1,147 @@
1
+ import dayjs from 'dayjs';
2
+ import customParseFormat from 'dayjs/plugin/customParseFormat.js';
3
+ import utc from 'dayjs/plugin/utc.js';
4
+ dayjs.extend(customParseFormat);
5
+ dayjs.extend(utc);
6
+ /**
7
+ * Convert a date value to user format for validation
8
+ * Handles both ISO format and user format inputs
9
+ */
10
+ export function convertDateToUserFormat(value, userFormat) {
11
+ // Try parsing as ISO format first (what DateField stores)
12
+ // Use strict mode to reject invalid dates
13
+ const parsedISO = dayjs(value, 'YYYY-MM-DD', true);
14
+ if (parsedISO.isValid()) {
15
+ return parsedISO.format(userFormat);
16
+ }
17
+ // Try parsing as user format (what API might send)
18
+ // Use strict mode to reject invalid dates like Feb 31st
19
+ const parsedUser = dayjs(value, userFormat, true);
20
+ if (parsedUser.isValid()) {
21
+ return value; // Already in user format
22
+ }
23
+ // Invalid date - return as-is for validation to catch
24
+ return value;
25
+ }
26
+ /**
27
+ * Convert a date value to ISO format for storage
28
+ * Returns ISO if already valid, or original value if invalid
29
+ */
30
+ export function convertDateToISO(value, userFormat) {
31
+ // Try parsing as user format first (for API consumers)
32
+ // Use strict mode to reject invalid dates like Feb 31st
33
+ const parsedUser = dayjs(value, userFormat, true);
34
+ if (parsedUser.isValid()) {
35
+ return parsedUser.format('YYYY-MM-DD');
36
+ }
37
+ // Try parsing as ISO (for DateField component)
38
+ // Use strict mode
39
+ const parsedISO = dayjs(value, 'YYYY-MM-DD', true);
40
+ if (parsedISO.isValid()) {
41
+ return value; // Already ISO
42
+ }
43
+ // Invalid date - return as-is
44
+ return value;
45
+ }
46
+ /**
47
+ * Convert a datetime value to user format for validation
48
+ * Handles both ISO datetime and user format inputs
49
+ */
50
+ export function convertDateTimeToUserFormat(value, dateFormat, timeFormat = 'HH:mm') {
51
+ const userFormat = `${dateFormat} ${timeFormat}`;
52
+ // Try parsing as ISO datetime first (what DateTimeField stores)
53
+ // Use strict mode to reject invalid dates
54
+ const parsedISO = dayjs(value, 'YYYY-MM-DDTHH:mm:ss[Z]', true);
55
+ if (parsedISO.isValid()) {
56
+ return parsedISO.format(userFormat);
57
+ }
58
+ // Try parsing as user format (what API might send)
59
+ // Use strict mode to reject invalid dates like Feb 31st
60
+ const parsedUser = dayjs(value, userFormat, true);
61
+ if (parsedUser.isValid()) {
62
+ return value; // Already in user format
63
+ }
64
+ // Invalid datetime - return as-is for validation to catch
65
+ return value;
66
+ }
67
+ /**
68
+ * Convert a datetime value to ISO UTC format for storage
69
+ * Returns ISO UTC if already valid, or original value if invalid
70
+ */
71
+ export function convertDateTimeToISO(value, dateFormat, timeFormat = 'HH:mm') {
72
+ const userFormat = `${dateFormat} ${timeFormat}`;
73
+ console.log('[convertDateTimeToISO]', { value, userFormat });
74
+ // Try parsing as user format first (for API consumers)
75
+ // Use strict mode to reject invalid dates like Feb 31st
76
+ const parsedUser = dayjs(value, userFormat, true);
77
+ if (parsedUser.isValid()) {
78
+ const result = parsedUser.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
79
+ console.log('[convertDateTimeToISO] User format parse successful, converting to UTC:', result);
80
+ return result;
81
+ }
82
+ // Try parsing as ISO datetime (for DateTimeField component)
83
+ // Use strict mode with ISO format
84
+ const parsedISO = dayjs(value, 'YYYY-MM-DDTHH:mm:ss[Z]', true);
85
+ if (parsedISO.isValid()) {
86
+ const result = parsedISO.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
87
+ console.log('[convertDateTimeToISO] ISO parse successful:', result);
88
+ return result;
89
+ }
90
+ // Invalid datetime - return as-is
91
+ console.log('[convertDateTimeToISO] Invalid - returning as-is');
92
+ return value;
93
+ }
94
+ /**
95
+ * Normalize date fields in data object
96
+ * Converts dates to ISO for storage and creates a parallel object with user-formatted dates for validation
97
+ */
98
+ export function normalizeDateFields(data, schema) {
99
+ const normalizedData = { ...data };
100
+ const dataForValidation = { ...data };
101
+ console.log('[normalizeDateFields] Starting normalization...');
102
+ console.log('[normalizeDateFields] Input data:', data);
103
+ for (const field of schema.fields) {
104
+ if (field.type === 'date' && normalizedData[field.name]) {
105
+ const dateField = field;
106
+ const userFormat = dateField.options?.dateFormat || 'YYYY-MM-DD';
107
+ const dateValue = normalizedData[field.name];
108
+ console.log(`[normalizeDateFields] Processing DATE field "${field.name}"`, {
109
+ originalValue: dateValue,
110
+ userFormat
111
+ });
112
+ if (typeof dateValue === 'string') {
113
+ normalizedData[field.name] = convertDateToISO(dateValue, userFormat);
114
+ dataForValidation[field.name] = convertDateToUserFormat(dateValue, userFormat);
115
+ console.log(`[normalizeDateFields] Converted DATE field "${field.name}"`, {
116
+ normalizedValue: normalizedData[field.name],
117
+ validationValue: dataForValidation[field.name]
118
+ });
119
+ }
120
+ }
121
+ else if (field.type === 'datetime' && normalizedData[field.name]) {
122
+ const dateTimeField = field;
123
+ const dateFormat = dateTimeField.options?.dateFormat || 'YYYY-MM-DD';
124
+ const timeFormat = dateTimeField.options?.timeFormat || 'HH:mm';
125
+ const dateTimeValue = normalizedData[field.name];
126
+ console.log(`[normalizeDateFields] Processing DATETIME field "${field.name}"`, {
127
+ originalValue: dateTimeValue,
128
+ dateFormat,
129
+ timeFormat,
130
+ combinedFormat: `${dateFormat} ${timeFormat}`
131
+ });
132
+ if (typeof dateTimeValue === 'string') {
133
+ normalizedData[field.name] = convertDateTimeToISO(dateTimeValue, dateFormat, timeFormat);
134
+ dataForValidation[field.name] = convertDateTimeToUserFormat(dateTimeValue, dateFormat, timeFormat);
135
+ console.log(`[normalizeDateFields] Converted DATETIME field "${field.name}"`, {
136
+ normalizedValue: normalizedData[field.name],
137
+ validationValue: dataForValidation[field.name]
138
+ });
139
+ }
140
+ }
141
+ }
142
+ console.log('[normalizeDateFields] Final result:', {
143
+ normalizedData,
144
+ dataForValidation
145
+ });
146
+ return { normalizedData, dataForValidation };
147
+ }
@@ -28,6 +28,7 @@ export declare class Rule {
28
28
  min(len: number | string | FieldReference): Rule;
29
29
  max(len: number | string | FieldReference): Rule;
30
30
  length(len: number | FieldReference): Rule;
31
+ unique(): Rule;
31
32
  email(): Rule;
32
33
  uri(options?: {
33
34
  scheme?: RegExp[];
@@ -39,6 +40,8 @@ export declare class Rule {
39
40
  integer(): Rule;
40
41
  greaterThan(num: number | FieldReference): Rule;
41
42
  lessThan(num: number | FieldReference): Rule;
43
+ date(format?: string): Rule;
44
+ datetime(dateFormat?: string, timeFormat?: string): Rule;
42
45
  custom<T = unknown>(fn: CustomValidator<T>): Rule;
43
46
  error(message?: string): Rule;
44
47
  warning(message?: string): Rule;
@@ -47,5 +50,6 @@ export declare class Rule {
47
50
  validate(value: unknown, context?: ValidationContext): Promise<ValidationMarker[]>;
48
51
  private validateRule;
49
52
  isRequired(): boolean;
53
+ private normalizeForComparison;
50
54
  }
51
55
  //# sourceMappingURL=rule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../src/lib/field-validation/rule.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAEjC,QAAQ,CAAC,EAAE,GAAG,CAAC;IAEf,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC3C,CACC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,iBAAiB,GACxB,gBAAgB,EAAE,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC1F;AAED,MAAM,WAAW,cAAc;IAC9B,gBAAgB,EAAE,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,IAAI;IAChB,OAAO,CAAC,SAAS,CAAkB;IAEnC,OAAO,CAAC,MAAM,CAAmE;IACjF,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,QAAQ,CAAC,CAAS;IAE1B,MAAM,CAAC,SAAS,SAA4B;IAE5C,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc;IAO5D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc;IAIrD,QAAQ,IAAI,IAAI;IAMhB,QAAQ,IAAI,IAAI;IAMhB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,IAAI;IAMhD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,IAAI;IAMhD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAM1C,KAAK,IAAI,IAAI;IAMb,GAAG,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAMnE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAM3C,QAAQ,IAAI,IAAI;IAMhB,QAAQ,IAAI,IAAI;IAMhB,OAAO,IAAI,IAAI;IAMf,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAM/C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAM5C,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI;IAMjD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAO7B,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAO/B,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAO5B,KAAK,IAAI,IAAI;IASP,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAwC9E,YAAY;IAkF1B,UAAU,IAAI,OAAO;CAGrB"}
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../src/lib/field-validation/rule.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAEjC,QAAQ,CAAC,EAAE,GAAG,CAAC;IAEf,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC3C,CACC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,iBAAiB,GACxB,gBAAgB,EAAE,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC1F;AAED,MAAM,WAAW,cAAc;IAC9B,gBAAgB,EAAE,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,IAAI;IAChB,OAAO,CAAC,SAAS,CAAkB;IAEnC,OAAO,CAAC,MAAM,CAAmE;IACjF,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,QAAQ,CAAC,CAAS;IAE1B,MAAM,CAAC,SAAS,SAA4B;IAE5C,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc;IAO5D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc;IAIrD,QAAQ,IAAI,IAAI;IAMhB,QAAQ,IAAI,IAAI;IAMhB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,IAAI;IAMhD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,IAAI;IAMhD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAM1C,MAAM,IAAI,IAAI;IAMd,KAAK,IAAI,IAAI;IAMb,GAAG,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAMnE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAM3C,QAAQ,IAAI,IAAI;IAMhB,QAAQ,IAAI,IAAI;IAMhB,OAAO,IAAI,IAAI;IAMf,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAM/C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAM5C,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAM3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAOxD,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI;IAMjD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAO7B,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAO/B,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAO5B,KAAK,IAAI,IAAI;IASP,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAwC9E,YAAY;IAgO1B,UAAU,IAAI,OAAO;IAKrB,OAAO,CAAC,sBAAsB;CAkB9B"}
@@ -1,3 +1,8 @@
1
+ // Sanity-style validation Rule implementation
2
+ import dayjs from 'dayjs';
3
+ import customParseFormat from 'dayjs/plugin/customParseFormat.js';
4
+ // Enable strict parsing
5
+ dayjs.extend(customParseFormat);
1
6
  export class Rule {
2
7
  _required = false;
3
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -39,6 +44,11 @@ export class Rule {
39
44
  newRule._rules.push({ type: 'length', constraint: len });
40
45
  return newRule;
41
46
  }
47
+ unique() {
48
+ const newRule = this.clone();
49
+ newRule._rules.push({ type: 'unique' });
50
+ return newRule;
51
+ }
42
52
  email() {
43
53
  const newRule = this.clone();
44
54
  newRule._rules.push({ type: 'email' });
@@ -79,6 +89,17 @@ export class Rule {
79
89
  newRule._rules.push({ type: 'lessThan', constraint: num });
80
90
  return newRule;
81
91
  }
92
+ date(format) {
93
+ const newRule = this.clone();
94
+ newRule._rules.push({ type: 'date', constraint: format || 'YYYY-MM-DD' });
95
+ return newRule;
96
+ }
97
+ datetime(dateFormat, timeFormat) {
98
+ const newRule = this.clone();
99
+ const fullFormat = `${dateFormat || 'YYYY-MM-DD'} ${timeFormat || 'HH:mm'}`;
100
+ newRule._rules.push({ type: 'datetime', constraint: fullFormat });
101
+ return newRule;
102
+ }
82
103
  custom(fn) {
83
104
  const newRule = this.clone();
84
105
  newRule._rules.push({ type: 'custom', constraint: fn });
@@ -155,6 +176,9 @@ export class Rule {
155
176
  if (typeof value === 'number' && value < rule.constraint) {
156
177
  return `Must be at least ${rule.constraint}`;
157
178
  }
179
+ if (Array.isArray(value) && value.length < rule.constraint) {
180
+ return `Must have at least ${rule.constraint} item${rule.constraint === 1 ? '' : 's'}`;
181
+ }
158
182
  break;
159
183
  case 'max':
160
184
  if (typeof value === 'string' && value.length > rule.constraint) {
@@ -163,6 +187,31 @@ export class Rule {
163
187
  if (typeof value === 'number' && value > rule.constraint) {
164
188
  return `Must be at most ${rule.constraint}`;
165
189
  }
190
+ if (Array.isArray(value) && value.length > rule.constraint) {
191
+ return `Must have at most ${rule.constraint} item${rule.constraint === 1 ? '' : 's'}`;
192
+ }
193
+ break;
194
+ case 'length':
195
+ if (Array.isArray(value) && value.length !== rule.constraint) {
196
+ return `Must have exactly ${rule.constraint} item${rule.constraint === 1 ? '' : 's'}`;
197
+ }
198
+ if (typeof value === 'string' && value.length !== rule.constraint) {
199
+ return `Must be exactly ${rule.constraint} characters`;
200
+ }
201
+ break;
202
+ case 'unique':
203
+ if (Array.isArray(value)) {
204
+ const seen = new Set();
205
+ for (const item of value) {
206
+ // Deep comparison excluding _key property
207
+ const normalized = this.normalizeForComparison(item);
208
+ const serialized = JSON.stringify(normalized);
209
+ if (seen.has(serialized)) {
210
+ return 'All items must be unique';
211
+ }
212
+ seen.add(serialized);
213
+ }
214
+ }
166
215
  break;
167
216
  case 'email':
168
217
  if (typeof value === 'string' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
@@ -171,11 +220,57 @@ export class Rule {
171
220
  break;
172
221
  case 'uri':
173
222
  if (typeof value === 'string') {
174
- try {
175
- new URL(value);
223
+ const opts = rule.constraint || {};
224
+ const schemes = opts.scheme || [/^https?$/];
225
+ const allowRelative = opts.allowRelative || false;
226
+ const relativeOnly = opts.relativeOnly || false;
227
+ // Check if URL is relative (doesn't have a scheme)
228
+ const hasScheme = /^[a-z][a-z0-9+.-]*:/i.test(value);
229
+ const isProtocolRelative = value.startsWith('//');
230
+ if (relativeOnly) {
231
+ // Only allow relative URLs
232
+ if (hasScheme || isProtocolRelative) {
233
+ return 'Must be a relative URL';
234
+ }
235
+ // Validate it's a reasonable path
236
+ if (!value.startsWith('/') &&
237
+ !value.startsWith('.') &&
238
+ !value.startsWith('#') &&
239
+ !value.startsWith('?')) {
240
+ return 'Must be a relative URL starting with /, ., #, or ?';
241
+ }
176
242
  }
177
- catch {
178
- return 'Must be a valid URL';
243
+ else if (!hasScheme && !isProtocolRelative) {
244
+ // It's a relative URL
245
+ if (!allowRelative) {
246
+ return 'Must be an absolute URL';
247
+ }
248
+ // Validate it's a reasonable relative path
249
+ if (!value.startsWith('/') &&
250
+ !value.startsWith('.') &&
251
+ !value.startsWith('#') &&
252
+ !value.startsWith('?')) {
253
+ return 'Must be a valid relative URL';
254
+ }
255
+ }
256
+ else {
257
+ // It's an absolute URL, validate with URL constructor
258
+ try {
259
+ const url = new URL(value);
260
+ // Extract scheme without the trailing colon
261
+ const urlScheme = url.protocol.slice(0, -1);
262
+ // Check if scheme is allowed
263
+ const schemeMatches = schemes.some((s) => s instanceof RegExp ? s.test(urlScheme) : s === urlScheme);
264
+ if (!schemeMatches) {
265
+ const schemeList = schemes
266
+ .map((s) => (s instanceof RegExp ? s.toString() : s))
267
+ .join(', ');
268
+ return `URL scheme must be one of: ${schemeList}`;
269
+ }
270
+ }
271
+ catch {
272
+ return 'Must be a valid URL';
273
+ }
179
274
  }
180
275
  }
181
276
  break;
@@ -199,6 +294,58 @@ export class Rule {
199
294
  return 'Must be an integer';
200
295
  }
201
296
  break;
297
+ case 'date': {
298
+ if (typeof value === 'string') {
299
+ const format = rule.constraint || 'YYYY-MM-DD';
300
+ console.log('[Rule.validate] DATE validation', { value, format });
301
+ // Parse with strict mode
302
+ const parsed = dayjs(value, format, true);
303
+ console.log('[Rule.validate] DATE parsed', {
304
+ isValid: parsed.isValid(),
305
+ parsed: parsed.format()
306
+ });
307
+ if (!parsed.isValid()) {
308
+ console.log('[Rule.validate] DATE validation FAILED - invalid format');
309
+ return `Invalid date format. Expected: ${format}`;
310
+ }
311
+ // Verify the parsed date matches the input (catches invalid dates like 2025-02-31)
312
+ if (parsed.format(format) !== value) {
313
+ console.log('[Rule.validate] DATE validation FAILED - format mismatch', {
314
+ expected: value,
315
+ got: parsed.format(format)
316
+ });
317
+ return `Invalid date. Expected format: ${format}`;
318
+ }
319
+ console.log('[Rule.validate] DATE validation PASSED');
320
+ }
321
+ break;
322
+ }
323
+ case 'datetime': {
324
+ if (typeof value === 'string') {
325
+ const format = rule.constraint || 'YYYY-MM-DD HH:mm';
326
+ console.log('[Rule.validate] DATETIME validation', { value, format });
327
+ // Parse with strict mode
328
+ const parsed = dayjs(value, format, true);
329
+ console.log('[Rule.validate] DATETIME parsed', {
330
+ isValid: parsed.isValid(),
331
+ parsed: parsed.format()
332
+ });
333
+ if (!parsed.isValid()) {
334
+ console.log('[Rule.validate] DATETIME validation FAILED - invalid format');
335
+ return `Invalid datetime format. Expected: ${format}`;
336
+ }
337
+ // Verify the parsed datetime matches the input (catches invalid dates like 2025-02-31 23:59)
338
+ if (parsed.format(format) !== value) {
339
+ console.log('[Rule.validate] DATETIME validation FAILED - format mismatch', {
340
+ expected: value,
341
+ got: parsed.format(format)
342
+ });
343
+ return `Invalid datetime. Expected format: ${format}`;
344
+ }
345
+ console.log('[Rule.validate] DATETIME validation PASSED');
346
+ }
347
+ break;
348
+ }
202
349
  case 'custom': {
203
350
  const customResult = await rule.constraint(value, context);
204
351
  if (customResult === false) {
@@ -218,4 +365,23 @@ export class Rule {
218
365
  isRequired() {
219
366
  return this._required;
220
367
  }
368
+ // Helper method to normalize objects for comparison (exclude _key)
369
+ normalizeForComparison(value) {
370
+ if (value === null || value === undefined) {
371
+ return value;
372
+ }
373
+ if (Array.isArray(value)) {
374
+ return value.map((item) => this.normalizeForComparison(item));
375
+ }
376
+ if (typeof value === 'object') {
377
+ const normalized = {};
378
+ for (const [key, val] of Object.entries(value)) {
379
+ if (key !== '_key') {
380
+ normalized[key] = this.normalizeForComparison(val);
381
+ }
382
+ }
383
+ return normalized;
384
+ }
385
+ return value;
386
+ }
221
387
  }
@@ -9,6 +9,7 @@ export interface DocumentValidationResult {
9
9
  field: string;
10
10
  errors: string[];
11
11
  }>;
12
+ normalizedData: Record<string, any>;
12
13
  }
13
14
  /**
14
15
  * Check if a field is required based on its validation rules
@@ -27,13 +28,16 @@ export declare function validateField(field: Field, value: any, context?: any):
27
28
  export declare function getValidationClasses(hasErrors: boolean): string;
28
29
  /**
29
30
  * Validate an entire document's data against a schema
30
- * This function validates all fields in a schema against the provided data
31
- * and returns any validation errors found.
31
+ * This function:
32
+ * 1. Normalizes date fields (converts user format to ISO for storage)
33
+ * 2. Converts ISO dates to user format for validation
34
+ * 3. Validates all fields and returns errors
35
+ * 4. Returns normalized data (with ISO dates) for storage
32
36
  *
33
37
  * @param schema - The schema type containing field definitions
34
38
  * @param data - The document data to validate
35
39
  * @param context - Optional context to pass to field validators
36
- * @returns Validation result with isValid flag and array of field errors
40
+ * @returns Validation result with isValid flag, errors, and normalized data
37
41
  */
38
42
  export declare function validateDocumentData(schema: SchemaType, data: Record<string, any>, context?: any): Promise<DocumentValidationResult>;
39
43
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/field-validation/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGxD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAUrD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAClC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,GAAG,EACV,OAAO,GAAE,GAAQ,GACf,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC1B,CAAC,CA6CD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAO/D;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,OAAO,GAAE,GAAQ,GACf,OAAO,CAAC,wBAAwB,CAAC,CAwBnC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/field-validation/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIxD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACnD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAUrD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAClC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,GAAG,EACV,OAAO,GAAE,GAAQ,GACf,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC1B,CAAC,CA+HD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAO/D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,OAAO,GAAE,GAAQ,GACf,OAAO,CAAC,wBAAwB,CAAC,CAqDnC"}