@donotdev/crud 0.0.6 → 0.0.8

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 (306) hide show
  1. package/README.md +18 -2
  2. package/dist/CrudService.d.ts +91 -8
  3. package/dist/CrudService.d.ts.map +1 -1
  4. package/dist/CrudService.js +1 -1
  5. package/dist/CrudStore.d.ts +45 -2
  6. package/dist/CrudStore.d.ts.map +1 -1
  7. package/dist/CrudStore.js +1 -1
  8. package/dist/FieldRegistry.d.ts +56 -20
  9. package/dist/FieldRegistry.d.ts.map +1 -1
  10. package/dist/FieldRegistry.js +1 -1
  11. package/dist/adapters/FirestoreAdapter.d.ts +4 -4
  12. package/dist/adapters/FirestoreAdapter.d.ts.map +1 -1
  13. package/dist/adapters/FirestoreAdapter.js +1 -1
  14. package/dist/adapters/FunctionsAdapter.d.ts +3 -2
  15. package/dist/adapters/FunctionsAdapter.d.ts.map +1 -1
  16. package/dist/adapters/FunctionsAdapter.js +1 -1
  17. package/dist/builtinFieldTypes.d.ts +4 -0
  18. package/dist/builtinFieldTypes.d.ts.map +1 -1
  19. package/dist/builtinFieldTypes.js +1 -1
  20. package/dist/components/CrudButton.d.ts +1 -1
  21. package/dist/components/CrudButton.d.ts.map +1 -1
  22. package/dist/components/CrudButton.js +1 -1
  23. package/dist/components/DisplayFieldRenderer.d.ts +15 -11
  24. package/dist/components/DisplayFieldRenderer.d.ts.map +1 -1
  25. package/dist/components/DisplayFieldRenderer.js +1 -1
  26. package/dist/components/EntityCardList.d.ts +27 -0
  27. package/dist/components/EntityCardList.d.ts.map +1 -0
  28. package/dist/components/EntityCardList.js +1 -0
  29. package/dist/components/EntityDisplayRenderer.d.ts +43 -0
  30. package/dist/components/EntityDisplayRenderer.d.ts.map +1 -0
  31. package/dist/components/EntityDisplayRenderer.js +1 -0
  32. package/dist/components/EntityFormRenderer.d.ts +21 -26
  33. package/dist/components/EntityFormRenderer.d.ts.map +1 -1
  34. package/dist/components/EntityFormRenderer.js +1 -5
  35. package/dist/components/EntityList.d.ts +24 -0
  36. package/dist/components/EntityList.d.ts.map +1 -0
  37. package/dist/components/EntityList.js +1 -0
  38. package/dist/components/FormFieldRenderer.d.ts +3 -10
  39. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  40. package/dist/components/FormFieldRenderer.js +1 -1
  41. package/dist/components/FormLayout.d.ts +1 -9
  42. package/dist/components/FormLayout.d.ts.map +1 -1
  43. package/dist/components/controlled/complex/ControlledAddressField.d.ts +8 -0
  44. package/dist/components/controlled/complex/ControlledAddressField.d.ts.map +1 -0
  45. package/dist/components/controlled/complex/ControlledAddressField.js +1 -0
  46. package/dist/components/controlled/complex/ControlledDateField.d.ts +8 -0
  47. package/dist/components/controlled/complex/ControlledDateField.d.ts.map +1 -0
  48. package/dist/components/controlled/complex/ControlledDateField.js +1 -0
  49. package/dist/components/controlled/complex/ControlledGeoPointField.d.ts +8 -0
  50. package/dist/components/controlled/complex/ControlledGeoPointField.d.ts.map +1 -0
  51. package/dist/components/controlled/complex/ControlledGeoPointField.js +1 -0
  52. package/dist/components/controlled/complex/ControlledMapField.d.ts +8 -0
  53. package/dist/components/controlled/complex/ControlledMapField.d.ts.map +1 -0
  54. package/dist/components/controlled/complex/ControlledMapField.js +1 -0
  55. package/dist/components/controlled/complex/ControlledMultiInputField.d.ts +8 -0
  56. package/dist/components/controlled/complex/ControlledMultiInputField.d.ts.map +1 -0
  57. package/dist/components/controlled/complex/ControlledMultiInputField.js +1 -0
  58. package/dist/components/controlled/complex/ControlledRichTextField.d.ts +8 -0
  59. package/dist/components/controlled/complex/ControlledRichTextField.d.ts.map +1 -0
  60. package/dist/components/controlled/complex/ControlledRichTextField.js +1 -0
  61. package/dist/components/controlled/complex/ControlledTimestampField.d.ts +8 -0
  62. package/dist/components/controlled/complex/ControlledTimestampField.d.ts.map +1 -0
  63. package/dist/components/controlled/complex/ControlledTimestampField.js +1 -0
  64. package/dist/components/controlled/complex/index.d.ts +8 -0
  65. package/dist/components/controlled/complex/index.d.ts.map +1 -0
  66. package/dist/components/controlled/complex/index.js +1 -0
  67. package/dist/components/controlled/file/ControlledDocumentField.d.ts +8 -0
  68. package/dist/components/controlled/file/ControlledDocumentField.d.ts.map +1 -0
  69. package/dist/components/controlled/file/ControlledDocumentField.js +1 -0
  70. package/dist/components/controlled/file/ControlledFileField.d.ts +8 -0
  71. package/dist/components/controlled/file/ControlledFileField.d.ts.map +1 -0
  72. package/dist/components/controlled/file/ControlledFileField.js +1 -0
  73. package/dist/components/controlled/file/ControlledImageField.d.ts +8 -0
  74. package/dist/components/controlled/file/ControlledImageField.d.ts.map +1 -0
  75. package/dist/components/controlled/file/ControlledImageField.js +1 -0
  76. package/dist/components/controlled/file/ControlledMultiDocumentField.d.ts +8 -0
  77. package/dist/components/controlled/file/ControlledMultiDocumentField.d.ts.map +1 -0
  78. package/dist/components/controlled/file/ControlledMultiDocumentField.js +1 -0
  79. package/dist/components/controlled/file/ControlledMultiFileField.d.ts +8 -0
  80. package/dist/components/controlled/file/ControlledMultiFileField.d.ts.map +1 -0
  81. package/dist/components/controlled/file/ControlledMultiFileField.js +1 -0
  82. package/dist/components/controlled/file/ControlledMultiImageField.d.ts +8 -0
  83. package/dist/components/controlled/file/ControlledMultiImageField.d.ts.map +1 -0
  84. package/dist/components/controlled/file/ControlledMultiImageField.js +1 -0
  85. package/dist/components/controlled/file/index.d.ts +7 -0
  86. package/dist/components/controlled/file/index.d.ts.map +1 -0
  87. package/dist/components/controlled/file/index.js +1 -0
  88. package/dist/components/controlled/index.d.ts +12 -0
  89. package/dist/components/controlled/index.d.ts.map +1 -0
  90. package/dist/components/controlled/index.js +1 -0
  91. package/dist/components/controlled/input/ControlledCheckboxField.d.ts +8 -0
  92. package/dist/components/controlled/input/ControlledCheckboxField.d.ts.map +1 -0
  93. package/dist/components/controlled/input/ControlledCheckboxField.js +1 -0
  94. package/dist/components/controlled/input/ControlledNumberField.d.ts +8 -0
  95. package/dist/components/controlled/input/ControlledNumberField.d.ts.map +1 -0
  96. package/dist/components/controlled/input/ControlledNumberField.js +1 -0
  97. package/dist/components/controlled/input/ControlledPasswordField.d.ts +8 -0
  98. package/dist/components/controlled/input/ControlledPasswordField.d.ts.map +1 -0
  99. package/dist/components/controlled/input/ControlledPasswordField.js +1 -0
  100. package/dist/components/controlled/input/ControlledPhoneField.d.ts +8 -0
  101. package/dist/components/controlled/input/ControlledPhoneField.d.ts.map +1 -0
  102. package/dist/components/controlled/input/ControlledPhoneField.js +1 -0
  103. package/dist/components/controlled/input/ControlledRangeField.d.ts +8 -0
  104. package/dist/components/controlled/input/ControlledRangeField.d.ts.map +1 -0
  105. package/dist/components/controlled/input/ControlledRangeField.js +1 -0
  106. package/dist/components/controlled/input/ControlledSwitchField.d.ts +8 -0
  107. package/dist/components/controlled/input/ControlledSwitchField.d.ts.map +1 -0
  108. package/dist/components/controlled/input/ControlledSwitchField.js +1 -0
  109. package/dist/components/controlled/input/ControlledTextField.d.ts +8 -0
  110. package/dist/components/controlled/input/ControlledTextField.d.ts.map +1 -0
  111. package/dist/components/controlled/input/ControlledTextField.js +1 -0
  112. package/dist/components/controlled/input/ControlledTextareaField.d.ts +8 -0
  113. package/dist/components/controlled/input/ControlledTextareaField.d.ts.map +1 -0
  114. package/dist/components/controlled/input/ControlledTextareaField.js +1 -0
  115. package/dist/components/controlled/input/index.d.ts +9 -0
  116. package/dist/components/controlled/input/index.d.ts.map +1 -0
  117. package/dist/components/controlled/input/index.js +1 -0
  118. package/dist/components/controlled/select/ControlledComboboxField.d.ts +9 -0
  119. package/dist/components/controlled/select/ControlledComboboxField.d.ts.map +1 -0
  120. package/dist/components/controlled/select/ControlledComboboxField.js +1 -0
  121. package/dist/components/controlled/select/ControlledDropdownField.d.ts +9 -0
  122. package/dist/components/controlled/select/ControlledDropdownField.d.ts.map +1 -0
  123. package/dist/components/controlled/select/ControlledDropdownField.js +1 -0
  124. package/dist/components/controlled/select/ControlledMultiDropdownField.d.ts +9 -0
  125. package/dist/components/controlled/select/ControlledMultiDropdownField.d.ts.map +1 -0
  126. package/dist/components/controlled/select/ControlledMultiDropdownField.js +1 -0
  127. package/dist/components/controlled/select/ControlledRadioField.d.ts +9 -0
  128. package/dist/components/controlled/select/ControlledRadioField.d.ts.map +1 -0
  129. package/dist/components/controlled/select/ControlledRadioField.js +1 -0
  130. package/dist/components/controlled/select/index.d.ts +5 -0
  131. package/dist/components/controlled/select/index.d.ts.map +1 -0
  132. package/dist/components/controlled/select/index.js +1 -0
  133. package/dist/components/controlled/types.d.ts +23 -0
  134. package/dist/components/controlled/types.d.ts.map +1 -0
  135. package/dist/components/controlled/types.js +1 -0
  136. package/dist/components/form/fields/AddressFieldComponent.d.ts.map +1 -1
  137. package/dist/components/form/fields/AddressFieldComponent.js +1 -1
  138. package/dist/components/form/fields/AvatarFieldComponent.d.ts +2 -2
  139. package/dist/components/form/fields/BadgeFieldComponent.d.ts +2 -2
  140. package/dist/components/form/fields/ButtonFieldComponent.d.ts +1 -9
  141. package/dist/components/form/fields/ButtonFieldComponent.d.ts.map +1 -1
  142. package/dist/components/form/fields/ButtonFieldComponent.js +1 -1
  143. package/dist/components/form/fields/ComboboxComponent.d.ts.map +1 -1
  144. package/dist/components/form/fields/CurrencyFieldComponent.d.ts +1 -9
  145. package/dist/components/form/fields/CurrencyFieldComponent.d.ts.map +1 -1
  146. package/dist/components/form/fields/CurrencyFieldComponent.js +1 -1
  147. package/dist/components/form/fields/DateFieldComponent.d.ts.map +1 -1
  148. package/dist/components/form/fields/DateFieldComponent.js +1 -1
  149. package/dist/components/form/fields/DocumentFieldComponent.d.ts +47 -0
  150. package/dist/components/form/fields/DocumentFieldComponent.d.ts.map +1 -0
  151. package/dist/components/form/fields/DocumentFieldComponent.js +1 -0
  152. package/dist/components/form/fields/DropdownComponent.d.ts.map +1 -1
  153. package/dist/components/form/fields/DropdownComponent.js +1 -1
  154. package/dist/components/form/fields/FileFieldComponent.d.ts +31 -15
  155. package/dist/components/form/fields/FileFieldComponent.d.ts.map +1 -1
  156. package/dist/components/form/fields/FileFieldComponent.js +1 -1
  157. package/dist/components/form/fields/GeoPointFieldComponent.d.ts.map +1 -1
  158. package/dist/components/form/fields/GeoPointFieldComponent.js +1 -1
  159. package/dist/components/form/fields/HiddenFieldComponent.d.ts +1 -1
  160. package/dist/components/form/fields/HiddenFieldComponent.d.ts.map +1 -1
  161. package/dist/components/form/fields/HiddenFieldComponent.js +1 -1
  162. package/dist/components/form/fields/ImageFieldComponent.d.ts +9 -15
  163. package/dist/components/form/fields/ImageFieldComponent.d.ts.map +1 -1
  164. package/dist/components/form/fields/ImageFieldComponent.js +1 -1
  165. package/dist/components/form/fields/MapFieldComponent.d.ts.map +1 -1
  166. package/dist/components/form/fields/MapFieldComponent.js +1 -1
  167. package/dist/components/form/fields/MultiDropdownComponent.js +1 -1
  168. package/dist/components/form/fields/MultiInputTextFieldComponent.d.ts +1 -9
  169. package/dist/components/form/fields/MultiInputTextFieldComponent.d.ts.map +1 -1
  170. package/dist/components/form/fields/MultiInputTextFieldComponent.js +1 -1
  171. package/dist/components/form/fields/NumberFieldComponent.d.ts +2 -0
  172. package/dist/components/form/fields/NumberFieldComponent.d.ts.map +1 -1
  173. package/dist/components/form/fields/NumberFieldComponent.js +1 -1
  174. package/dist/components/form/fields/PasswordFieldComponent.d.ts +1 -9
  175. package/dist/components/form/fields/PasswordFieldComponent.d.ts.map +1 -1
  176. package/dist/components/form/fields/PhoneNumberComponent.d.ts +1 -9
  177. package/dist/components/form/fields/PhoneNumberComponent.d.ts.map +1 -1
  178. package/dist/components/form/fields/PhoneNumberComponent.js +1 -1
  179. package/dist/components/form/fields/RadioFieldComponent.d.ts +1 -9
  180. package/dist/components/form/fields/RadioFieldComponent.d.ts.map +1 -1
  181. package/dist/components/form/fields/ReferenceFieldComponent.d.ts +33 -12
  182. package/dist/components/form/fields/ReferenceFieldComponent.d.ts.map +1 -1
  183. package/dist/components/form/fields/ReferenceFieldComponent.js +1 -1
  184. package/dist/components/form/fields/RichTextComponent.d.ts +32 -0
  185. package/dist/components/form/fields/RichTextComponent.d.ts.map +1 -0
  186. package/dist/components/form/fields/RichTextComponent.js +1 -0
  187. package/dist/components/form/fields/SwitchFieldComponent.d.ts.map +1 -1
  188. package/dist/components/form/fields/TextAreaComponent.d.ts +1 -9
  189. package/dist/components/form/fields/TextAreaComponent.d.ts.map +1 -1
  190. package/dist/components/form/fields/TextAreaComponent.js +1 -1
  191. package/dist/components/form/fields/TextFieldComponent.d.ts +1 -9
  192. package/dist/components/form/fields/TextFieldComponent.d.ts.map +1 -1
  193. package/dist/components/form/fields/index.d.ts +4 -2
  194. package/dist/components/form/fields/index.d.ts.map +1 -1
  195. package/dist/components/form/fields/index.js +1 -1
  196. package/dist/components/form/fields/internal/TiptapEditor.d.ts +13 -0
  197. package/dist/components/form/fields/internal/TiptapEditor.d.ts.map +1 -0
  198. package/dist/components/form/fields/internal/TiptapEditor.js +52 -0
  199. package/dist/components/form/index.d.ts +10 -0
  200. package/dist/components/form/index.d.ts.map +1 -0
  201. package/dist/components/form/index.js +1 -0
  202. package/dist/components/form/internal/ImageViewerDialog.d.ts +1 -1
  203. package/dist/components/form/internal/ImageViewerDialog.d.ts.map +1 -1
  204. package/dist/components/index.d.ts +8 -2
  205. package/dist/components/index.d.ts.map +1 -1
  206. package/dist/components/index.js +1 -1
  207. package/dist/contexts/UploadContext.d.ts +16 -0
  208. package/dist/contexts/UploadContext.d.ts.map +1 -0
  209. package/dist/contexts/UploadContext.js +1 -0
  210. package/dist/contexts/index.d.ts +3 -0
  211. package/dist/contexts/index.d.ts.map +1 -0
  212. package/dist/contexts/index.js +1 -0
  213. package/dist/forms/hooks/index.d.ts +2 -0
  214. package/dist/forms/hooks/index.d.ts.map +1 -1
  215. package/dist/forms/hooks/index.js +1 -1
  216. package/dist/forms/hooks/useController.d.ts +29 -0
  217. package/dist/forms/hooks/useController.d.ts.map +1 -0
  218. package/dist/forms/hooks/useController.js +1 -0
  219. package/dist/forms/hooks/useEntityField.d.ts.map +1 -1
  220. package/dist/forms/hooks/useEntityField.js +1 -1
  221. package/dist/forms/hooks/useEntityForm.d.ts +8 -76
  222. package/dist/forms/hooks/useEntityForm.d.ts.map +1 -1
  223. package/dist/forms/hooks/useEntityForm.js +1 -1
  224. package/dist/forms/index.d.ts +6 -4
  225. package/dist/forms/index.d.ts.map +1 -1
  226. package/dist/forms/index.js +1 -1
  227. package/dist/forms/types.d.ts +31 -5
  228. package/dist/forms/types.d.ts.map +1 -1
  229. package/dist/forms/utils/getFieldsForOperation.d.ts +5 -5
  230. package/dist/forms/utils/getFieldsForOperation.d.ts.map +1 -1
  231. package/dist/forms/utils/getFieldsForOperation.js +1 -1
  232. package/dist/forms/utils/index.d.ts +9 -5
  233. package/dist/forms/utils/index.d.ts.map +1 -1
  234. package/dist/forms/utils/index.js +1 -1
  235. package/dist/forms/utils/isFieldEditable.d.ts +0 -8
  236. package/dist/forms/utils/isFieldEditable.d.ts.map +1 -1
  237. package/dist/forms/utils/optionHelpers.d.ts +54 -0
  238. package/dist/forms/utils/optionHelpers.d.ts.map +1 -0
  239. package/dist/forms/utils/optionHelpers.js +1 -0
  240. package/dist/forms/utils/translateFieldLabel.d.ts +70 -0
  241. package/dist/forms/utils/translateFieldLabel.d.ts.map +1 -0
  242. package/dist/forms/utils/translateFieldLabel.js +1 -0
  243. package/dist/forms/utils/validateEntity.d.ts +5 -2
  244. package/dist/forms/utils/validateEntity.d.ts.map +1 -1
  245. package/dist/forms/utils/validateEntity.js +1 -1
  246. package/dist/hooks/index.d.ts +3 -0
  247. package/dist/hooks/index.d.ts.map +1 -0
  248. package/dist/hooks/index.js +1 -0
  249. package/dist/hooks/useFileUpload.d.ts +67 -0
  250. package/dist/hooks/useFileUpload.d.ts.map +1 -0
  251. package/dist/hooks/useFileUpload.js +1 -0
  252. package/dist/index.d.ts +15 -5
  253. package/dist/index.d.ts.map +1 -1
  254. package/dist/index.js +1 -1
  255. package/dist/stores/FormStore.d.ts +78 -0
  256. package/dist/stores/FormStore.d.ts.map +1 -0
  257. package/dist/stores/FormStore.js +1 -0
  258. package/dist/stores/UploadStore.d.ts +105 -0
  259. package/dist/stores/UploadStore.d.ts.map +1 -0
  260. package/dist/stores/UploadStore.js +1 -0
  261. package/dist/stores/index.d.ts +11 -0
  262. package/dist/stores/index.d.ts.map +1 -0
  263. package/dist/stores/index.js +1 -0
  264. package/dist/tsconfig.tsbuildinfo +1 -1
  265. package/dist/useCrud.d.ts +32 -74
  266. package/dist/useCrud.d.ts.map +1 -1
  267. package/dist/useCrud.js +1 -1
  268. package/dist/useCrudCardList.d.ts +62 -0
  269. package/dist/useCrudCardList.d.ts.map +1 -0
  270. package/dist/useCrudCardList.js +1 -0
  271. package/dist/useCrudList.d.ts +61 -0
  272. package/dist/useCrudList.d.ts.map +1 -0
  273. package/dist/useCrudList.js +1 -0
  274. package/dist/utils/fileStorage.d.ts +58 -0
  275. package/dist/utils/fileStorage.d.ts.map +1 -0
  276. package/dist/utils/fileStorage.js +1 -0
  277. package/dist/utils/imageProcessing.d.ts +1 -1
  278. package/dist/utils/imageProcessing.d.ts.map +1 -1
  279. package/dist/utils/imageProcessing.js +1 -1
  280. package/dist/utils/imageStorage.d.ts +2 -11
  281. package/dist/utils/imageStorage.d.ts.map +1 -1
  282. package/dist/utils/imageStorage.js +1 -1
  283. package/dist/utils/imageUtils.d.ts +1 -1
  284. package/dist/utils/imageUtils.d.ts.map +1 -1
  285. package/dist/utils/mergeWithOptimistic.d.ts +27 -0
  286. package/dist/utils/mergeWithOptimistic.d.ts.map +1 -0
  287. package/dist/utils/mergeWithOptimistic.js +1 -0
  288. package/dist/utils/uploadValidation.d.ts +37 -0
  289. package/dist/utils/uploadValidation.d.ts.map +1 -0
  290. package/dist/utils/uploadValidation.js +1 -0
  291. package/package.json +22 -5
  292. package/dist/components/ControlledFields.d.ts +0 -49
  293. package/dist/components/ControlledFields.d.ts.map +0 -1
  294. package/dist/components/ControlledFields.js +0 -1
  295. package/dist/context/FormUploadContext.d.ts +0 -36
  296. package/dist/context/FormUploadContext.d.ts.map +0 -1
  297. package/dist/context/FormUploadContext.js +0 -1
  298. package/dist/context/index.d.ts +0 -2
  299. package/dist/context/index.d.ts.map +0 -1
  300. package/dist/context/index.js +0 -1
  301. package/dist/forms/utils/createEntitySchema.d.ts +0 -53
  302. package/dist/forms/utils/createEntitySchema.d.ts.map +0 -1
  303. package/dist/forms/utils/createEntitySchema.js +0 -1
  304. package/dist/forms/utils/normalizeToFieldConfig.d.ts +0 -47
  305. package/dist/forms/utils/normalizeToFieldConfig.d.ts.map +0 -1
  306. package/dist/forms/utils/normalizeToFieldConfig.js +0 -1
package/README.md CHANGED
@@ -130,8 +130,24 @@ const UserEntity = {
130
130
 
131
131
  ### FirestoreAdapter
132
132
 
133
- Direct Firestore SDK operations with real-time subscriptions.
133
+ **ONLY for:** `backend: 'firestore'` mode (direct client access, no functions)
134
+
135
+ Direct Firestore SDK operations with real-time subscriptions. Use for simple client-side data
136
+ like user preferences or settings. Adds technical fields client-side (no server to generate them).
137
+
138
+ **When to use:**
139
+ - User preferences, settings, client-only data
140
+ - Simple data that doesn't require server-side security
141
+ - Prototyping without functions
142
+
143
+ **When NOT to use:**
144
+ - Production data requiring server-side security
145
+ - Sensitive data needing admin checks
146
+ - When functions are available (use `FunctionsAdapter` instead)
134
147
 
135
148
  ### FunctionsAdapter
136
149
 
137
- Firebase Functions HTTP endpoints for CRUD operations.
150
+ **ONLY for:** `backend: 'functions'` mode (server-side security)
151
+
152
+ Firebase Functions HTTP endpoints for CRUD operations. Server generates technical fields and
153
+ enforces security rules. Use for production data requiring validation, auth checks, and audit logs.
@@ -1,27 +1,60 @@
1
+ import type { dndevSchema, QueryClient } from '@donotdev/core';
1
2
  import type { QueryOptions } from './adapters/FirestoreAdapter';
2
3
  import type { BackendType, CrudState, CrudActions } from './CrudStore';
3
4
  /** Store API type for CrudService - typed instead of any */
4
5
  type CrudStoreApi = {
5
6
  getState: () => CrudState & CrudActions;
6
7
  };
8
+ /** Cache options for read operations */
9
+ export interface CacheOptions {
10
+ /** Bypass cache and fetch directly from adapter */
11
+ noCache?: boolean;
12
+ /** Custom stale time in ms (default: Infinity) */
13
+ staleTime?: number;
14
+ }
7
15
  export type { QueryOptions };
8
- import type { dndevSchema } from '@donotdev/core';
9
16
  export interface CrudServiceInterface {
10
17
  initialize(backend: BackendType): Promise<void>;
11
- get<T>(collection: string, id: string, schema: dndevSchema<T>): Promise<T | null>;
18
+ setStore(store: CrudStoreApi): void;
19
+ /** Schema accepts unknown since OperationSchemas stores dndevSchema<unknown>. T is for return type. */
20
+ getListQueryOptions<T>(collection: string, queryOptions: QueryOptions, schema: dndevSchema<unknown>, cacheOptions?: CacheOptions, schemaType?: 'list' | 'listCard'): {
21
+ queryKey: readonly string[];
22
+ queryFn: () => Promise<T[]>;
23
+ staleTime: number;
24
+ };
25
+ /** Schema accepts unknown since OperationSchemas stores dndevSchema<unknown>. T is for return type. */
26
+ getDocQueryOptions<T>(collection: string, id: string, schema: dndevSchema<unknown>, cacheOptions?: CacheOptions): {
27
+ queryKey: readonly string[];
28
+ queryFn: () => Promise<T | null>;
29
+ staleTime: number;
30
+ };
31
+ get<T>(collection: string, id: string, schema: dndevSchema<T>, options?: CacheOptions): Promise<T | null>;
32
+ query<T>(collection: string, options: QueryOptions, schema: dndevSchema<T>, cacheOptions?: CacheOptions, schemaType?: 'list' | 'listCard'): Promise<T[]>;
12
33
  set<T>(collection: string, id: string, data: T, schema: dndevSchema<T>): Promise<void>;
13
34
  update<T>(collection: string, id: string, data: Partial<T>): Promise<void>;
14
35
  delete(collection: string, id: string): Promise<void>;
15
36
  add<T>(collection: string, data: T, schema: dndevSchema<T>): Promise<string>;
16
- query<T>(collection: string, options: QueryOptions, schema: dndevSchema<T>): Promise<T[]>;
17
37
  subscribe<T>(collection: string, id: string, callback: (data: T | null, error?: Error) => void, schema: dndevSchema<T>): () => void;
18
38
  subscribeToCollection<T>(collection: string, options: QueryOptions, callback: (data: T[], error?: Error) => void, schema: dndevSchema<T>): () => void;
19
- setStore(store: CrudStoreApi): void;
39
+ /** Add with optimistic update - shows item immediately, confirms/rolls back after server */
40
+ addOptimistic<T extends {
41
+ id?: string;
42
+ }>(collection: string, data: T, schema: dndevSchema<T>): Promise<T & {
43
+ id: string;
44
+ }>;
45
+ /** Update with optimistic update - shows change immediately, confirms/rolls back after server */
46
+ updateOptimistic<T>(collection: string, id: string, data: Partial<T>, schema: dndevSchema<T>): Promise<T>;
47
+ /** Delete with optimistic update - hides item immediately, confirms/restores after server */
48
+ deleteOptimistic(collection: string, id: string): Promise<void>;
49
+ /** Invalidate all cached queries for a collection */
50
+ invalidateCollection(collection: string): Promise<void>;
51
+ /** Get the shared QueryClient instance from @donotdev/core */
52
+ getQueryClient(): QueryClient;
20
53
  }
21
54
  /**
22
- * Complete CRUD orchestrator
55
+ * Complete CRUD orchestrator with TanStack Query caching
23
56
  *
24
- * @version 0.0.1
57
+ * @version 0.0.4
25
58
  * @since 0.0.1
26
59
  * @author AMBROISE PARK Consulting
27
60
  */
@@ -31,14 +64,64 @@ declare class CrudService implements CrudServiceInterface {
31
64
  private store;
32
65
  setStore(store: CrudStoreApi): void;
33
66
  initialize(backend: BackendType): Promise<void>;
34
- get<T>(collection: string, id: string, schema: dndevSchema<T>): Promise<T | null>;
67
+ /**
68
+ * Get shared QueryClient instance from @donotdev/core.
69
+ * Uses singleton on client, new instance per request on server (SSR-safe).
70
+ */
71
+ getQueryClient(): QueryClient;
72
+ /**
73
+ * Get query options for list queries. Use with useQuery() in hooks.
74
+ * Returns reactive loading states via TanStack Query.
75
+ * @param schema - Accepts dndevSchema<unknown> since OperationSchemas uses unknown. T is for return type.
76
+ */
77
+ getListQueryOptions<T>(collection: string, queryOptions: QueryOptions, schema: dndevSchema<unknown>, cacheOptions?: CacheOptions, schemaType?: 'list' | 'listCard'): {
78
+ queryKey: readonly ["crud", string, "query", "list" | "listCard", string];
79
+ queryFn: () => Promise<T[]>;
80
+ staleTime: number;
81
+ };
82
+ /**
83
+ * Get query options for single document queries. Use with useQuery() in hooks.
84
+ * Returns reactive loading states via TanStack Query.
85
+ * @param schema - Accepts dndevSchema<unknown> since OperationSchemas uses unknown. T is for return type.
86
+ */
87
+ getDocQueryOptions<T>(collection: string, id: string, schema: dndevSchema<unknown>, cacheOptions?: CacheOptions): {
88
+ queryKey: readonly ["crud", string, "get", string];
89
+ queryFn: () => Promise<T | null>;
90
+ staleTime: number;
91
+ };
92
+ /**
93
+ * Update single document GET cache after mutation.
94
+ * Key format: ['crud', collection, 'get', id]
95
+ */
96
+ private _updateGetCache;
97
+ /**
98
+ * Update all caches after mutation (list queries + single document GET cache).
99
+ * Automatically syncs both list and document caches for consistency.
100
+ */
101
+ private _updateListCaches;
102
+ /**
103
+ * Invalidate all cached queries for a collection
104
+ */
105
+ invalidateCollection(collection: string): Promise<void>;
106
+ get<T>(collection: string, id: string, schema: dndevSchema<T>, options?: CacheOptions): Promise<T | null>;
107
+ /** Internal: fetch from adapter with store updates */
108
+ private _getFromAdapter;
109
+ query<T>(collection: string, options: QueryOptions, schema: dndevSchema<T>, cacheOptions?: CacheOptions, schemaType?: 'list' | 'listCard'): Promise<T[]>;
110
+ /** Internal: query from adapter with store updates */
111
+ private _queryFromAdapter;
35
112
  set<T>(collection: string, id: string, data: T, schema: dndevSchema<T>): Promise<void>;
36
113
  update<T>(collection: string, id: string, data: Partial<T>): Promise<void>;
37
114
  delete(collection: string, id: string): Promise<void>;
38
115
  add<T>(collection: string, data: T, schema: dndevSchema<T>): Promise<string>;
39
- query<T>(collection: string, options: QueryOptions, schema: dndevSchema<T>): Promise<T[]>;
40
116
  subscribe<T>(collection: string, id: string, callback: (data: T | null, error?: Error) => void, schema: dndevSchema<T>): () => void;
41
117
  subscribeToCollection<T>(collection: string, options: QueryOptions, callback: (data: T[], error?: Error) => void, schema: dndevSchema<T>): () => void;
118
+ addOptimistic<T extends {
119
+ id?: string;
120
+ }>(collection: string, data: T, schema: dndevSchema<T>): Promise<T & {
121
+ id: string;
122
+ }>;
123
+ updateOptimistic<T>(collection: string, id: string, data: Partial<T>, schema: dndevSchema<T>): Promise<T>;
124
+ deleteOptimistic(collection: string, id: string): Promise<void>;
42
125
  }
43
126
  /**
44
127
  * Get or create CrudService singleton instance
@@ -1 +1 @@
1
- {"version":3,"file":"CrudService.d.ts","sourceRoot":"","sources":["../src/CrudService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CrudService.d.ts","sourceRoot":"","sources":["../src/CrudService.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- import{toast as d}from"@donotdev/components";import{createSingleton as u,handleError as h}from"@donotdev/core";import{FirestoreAdapter as g}from"./adapters/FirestoreAdapter";import{FunctionsAdapter as p}from"./adapters/FunctionsAdapter";class w{adapter=null;backend=null;store=null;setStore(t){this.store=t}async initialize(t){if(!(this.backend===t&&this.adapter)){if(this.backend=t,t==="functions")this.adapter=new p;else if(t==="firestore")this.adapter=new g;else throw new Error(`Unknown backend: ${t}`);this.store&&(this.store.getState().setBackend(t),this.store.getState().setCrudService(this))}}async get(t,s,i){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");const e=await this.adapter.get(t,s,i);return this.store&&e&&this.store.getState().setData(t,s,e),e}catch(e){const r=h(e,{userMessage:`Failed to fetch ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,r),r}finally{this.store&&this.store.getState().setLoading(t,!1)}}async set(t,s,i,e){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.set(t,s,i,e),this.store&&this.store.getState().setData(t,s,i),d("success",`${t} saved successfully`)}catch(r){const a=h(r,{userMessage:`Failed to save ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,a),a}finally{this.store&&this.store.getState().setLoading(t,!1)}}async update(t,s,i){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));let e=null;this.store&&(e=this.store.getState().getData(t,s)),this.store&&e&&this.store.getState().setData(t,s,{...e,...i});try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.update(t,s,i),d("success",`${t} updated successfully`)}catch(r){this.store&&e&&this.store.getState().setData(t,s,e);const a=h(r,{userMessage:`Failed to update ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,a),a}finally{this.store&&this.store.getState().setLoading(t,!1)}}async delete(t,s){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.delete(t,s),this.store&&this.store.getState().removeData(t,s),d("success",`${t} deleted successfully`)}catch(i){const e=h(i,{userMessage:`Failed to delete ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,e),e}finally{this.store&&this.store.getState().setLoading(t,!1)}}async add(t,s,i){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");const e=await this.adapter.add(t,s,i);return this.store&&e&&this.store.getState().setData(t,e,{...s,id:e}),d("success",`${t} created successfully`),e}catch(e){const r=h(e,{userMessage:`Failed to create ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,r),r}finally{this.store&&this.store.getState().setLoading(t,!1)}}async query(t,s,i){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");const e=await this.adapter.query(t,s,i);if(this.store){const r=[];for(const a of e){const o=a;o.id&&r.push({id:o.id,data:a})}r.length>0&&this.store.getState().setDataBatch(t,r)}return e}catch(e){const r=h(e,{userMessage:`Failed to query ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,r),r}finally{this.store&&this.store.getState().setLoading(t,!1)}}subscribe(t,s,i,e){this.adapter||this.initialize("firestore").catch(()=>{});try{return this.adapter?this.adapter.subscribe(t,s,(r,a)=>{r&&this.store&&this.store.getState().setData(t,s,r),i(r,a)},e):(i(null,new Error("Adapter not initialized")),()=>{})}catch(r){return i(null,h(r)),()=>{}}}subscribeToCollection(t,s,i,e){this.adapter||this.initialize("firestore").catch(()=>{});try{return this.adapter?this.adapter.subscribeToCollection(t,s,(r,a)=>{if(r&&this.store){const o=[];for(const f of r){const n=f;n.id&&o.push({id:n.id,data:f})}o.length>0&&this.store.getState().setDataBatch(t,o)}i(r,a)},e):(i([],new Error("Adapter not initialized")),()=>{})}catch(r){return i([],h(r)),()=>{}}}}const A=u(()=>new w);export{A as getCrudService};
1
+ import{toast as f}from"@donotdev/components";import{createSingleton as p,handleError as u,getQueryClient as g}from"@donotdev/core";import{FirestoreAdapter as y}from"./adapters/FirestoreAdapter";import{FunctionsAdapter as w}from"./adapters/FunctionsAdapter";const d=1/0,z=1e3*60*30;class S{adapter=null;backend=null;store=null;setStore(t){this.store=t}async initialize(t){if(!(this.backend===t&&this.adapter)){if(this.backend=t,t==="functions")this.adapter=new w;else if(t==="firestore")this.adapter=new y;else throw new Error(`Unknown backend: ${t}`);this.store&&(this.store.getState().setBackend(t),this.store.getState().setCrudService(this))}}getQueryClient(){return g()}getListQueryOptions(t,e,s,a,r="list"){const i=this.adapter,h=()=>this.initialize("firestore");return{queryKey:["crud",t,"query",r,JSON.stringify(e)],queryFn:async()=>{if(i||await h(),!this.adapter)throw new Error("Adapter not initialized");return this.adapter.query(t,e,s)},staleTime:a?.staleTime??d}}getDocQueryOptions(t,e,s,a){const r=this.adapter,i=()=>this.initialize("firestore");return{queryKey:["crud",t,"get",e],queryFn:async()=>{if(r||await i(),!this.adapter)throw new Error("Adapter not initialized");return this.adapter.get(t,e,s)},staleTime:a?.staleTime??d}}_updateGetCache(t,e,s,a){const r=this.getQueryClient(),i=["crud",t,"get",e];a==="delete"?r.removeQueries({queryKey:i}):(a==="update"||a==="add")&&s&&r.setQueryData(i,h=>h?{...h,...s}:s)}_updateListCaches(t,e,s,a){const r=this.getQueryClient();this._updateGetCache(t,e,s,a),r.setQueriesData({queryKey:["crud",t]},i=>Array.isArray(i)?a==="delete"?i.filter(h=>h.id!==e):a==="add"&&s?[...i,{...s,id:e}]:a==="update"&&s&&i.some(o=>o.id===e)?i.map(o=>o.id===e?{...o,...s}:o):i:i)}async invalidateCollection(t){await this.getQueryClient().invalidateQueries({queryKey:["crud",t]})}async get(t,e,s,a){if(this.adapter||await this.initialize("firestore"),a?.noCache)return this._getFromAdapter(t,e,s);this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{return await this.getQueryClient().fetchQuery({queryKey:["crud",t,"get",e],queryFn:()=>this._getFromAdapter(t,e,s,!1),staleTime:a?.staleTime??d})}catch(r){const i=u(r,{userMessage:`Failed to fetch ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,i),i}finally{this.store&&this.store.getState().setLoading(t,!1)}}async _getFromAdapter(t,e,s,a=!0){this.store&&a&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");const r=await this.adapter.get(t,e,s);return this.store&&r&&this.store.getState().setData(t,e,r),r}catch(r){const i=u(r,{userMessage:`Failed to fetch ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,i),i}finally{this.store&&a&&this.store.getState().setLoading(t,!1)}}async query(t,e,s,a,r="list"){if(this.adapter||await this.initialize("firestore"),a?.noCache)return this._queryFromAdapter(t,e,s);this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{return await this.getQueryClient().fetchQuery({queryKey:["crud",t,"query",r,JSON.stringify(e)],queryFn:()=>this._queryFromAdapter(t,e,s,!1),staleTime:a?.staleTime??d})}catch(i){const h=u(i,{userMessage:`Failed to query ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,h),h}finally{this.store&&this.store.getState().setLoading(t,!1)}}async _queryFromAdapter(t,e,s,a=!0){this.store&&a&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));try{if(!this.adapter)throw new Error("Adapter not initialized");const r=await this.adapter.query(t,e,s);if(this.store){const i=[];for(const h of r){const o=h;o.id&&i.push({id:o.id,data:h})}i.length>0&&this.store.getState().setDataBatch(t,i)}return r}catch(r){const i=u(r,{userMessage:`Failed to query ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,i),i}finally{this.store&&a&&this.store.getState().setLoading(t,!1)}}async set(t,e,s,a){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const r=this.store?.getState().getData(t,e);this.store&&this.store.getState().updateOptimistic(t,e,s,r);try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.set(t,e,s,a),this.store&&(this.store.getState().confirmUpdate(t,e),this.store.getState().setData(t,e,s)),this._updateListCaches(t,e,s,"update"),f("success",`${t} saved successfully`)}catch(i){this.store&&this.store.getState().rejectUpdate(t,e);const h=u(i,{userMessage:`Failed to save ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,h),h}finally{this.store&&this.store.getState().setLoading(t,!1)}}async update(t,e,s){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));let a=null;this.store&&(a=this.store.getState().getData(t,e));const r=a?{...a,...s}:{...s,id:e};this.store&&a&&this.store.getState().updateOptimistic(t,e,r,a);try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.update(t,e,s),this.store&&(this.store.getState().confirmUpdate(t,e),this.store.getState().setData(t,e,r)),this._updateListCaches(t,e,r,"update"),f("success",`${t} updated successfully`)}catch(i){this.store&&this.store.getState().rejectUpdate(t,e);const h=u(i,{userMessage:`Failed to update ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,h),h}finally{this.store&&this.store.getState().setLoading(t,!1)}}async delete(t,e){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const s=this.store?.getState().getData(t,e);this.store&&s&&this.store.getState().deleteOptimistic(t,e,s);try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.delete(t,e),this.store&&this.store.getState().confirmDelete(t,e),this._updateListCaches(t,e,null,"delete"),f("success",`${t} deleted successfully`)}catch(a){this.store&&this.store.getState().rejectDelete(t,e);const r=u(a,{userMessage:`Failed to delete ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,r),r}finally{this.store&&this.store.getState().setLoading(t,!1)}}async add(t,e,s){this.adapter||await this.initialize("firestore"),this.store&&(this.store.getState().setLoading(t,!0),this.store.getState().setError(t,null));const a=`temp_${crypto.randomUUID()}`;this.store&&this.store.getState().addOptimistic(t,a,{...e,id:a});try{if(!this.adapter)throw new Error("Adapter not initialized");const r=await this.adapter.add(t,e,s);return this.store&&this.store.getState().confirmOptimistic(t,a,r,{...e,id:r}),this._updateListCaches(t,r,{...e,id:r},"add"),f("success",`${t} created successfully`),r}catch(r){this.store&&this.store.getState().rejectOptimistic(t,a);const i=u(r,{userMessage:`Failed to create ${t}`,showNotification:!0});throw this.store&&this.store.getState().setError(t,i),i}finally{this.store&&this.store.getState().setLoading(t,!1)}}subscribe(t,e,s,a){this.adapter||this.initialize("firestore").catch(()=>{});try{return this.adapter?this.adapter.subscribe(t,e,(r,i)=>{r&&this.store&&this.store.getState().setData(t,e,r),r&&this.getQueryClient().setQueryData(["crud",t,"get",e],r),s(r,i)},a):(s(null,new Error("Adapter not initialized")),()=>{})}catch(r){return s(null,u(r)),()=>{}}}subscribeToCollection(t,e,s,a){this.adapter||this.initialize("firestore").catch(()=>{});try{return this.adapter?this.adapter.subscribeToCollection(t,e,(r,i)=>{if(r&&this.store){const h=[];for(const o of r){const n=o;n.id&&h.push({id:n.id,data:o})}h.length>0&&this.store.getState().setDataBatch(t,h)}r&&this.getQueryClient().setQueryData(["crud",t,"query",JSON.stringify(e)],r),s(r,i)},a):(s([],new Error("Adapter not initialized")),()=>{})}catch(r){return s([],u(r)),()=>{}}}async addOptimistic(t,e,s){this.adapter||await this.initialize("firestore");const a=`temp_${crypto.randomUUID()}`,r={...e,id:a,_optimistic:!0};this.store&&this.store.getState().addOptimistic(t,a,r);try{if(!this.adapter)throw new Error("Adapter not initialized");const i=await this.adapter.add(t,e,s),h={...e,id:i};return this.store&&this.store.getState().confirmOptimistic(t,a,i,h),this._updateListCaches(t,i,h,"add"),f("success",`${t} created successfully`),h}catch(i){throw this.store&&this.store.getState().rejectOptimistic(t,a),u(i,{userMessage:`Failed to create ${t}`,showNotification:!0})}}async updateOptimistic(t,e,s,a){this.adapter||await this.initialize("firestore");let r=null;this.store&&(r=this.store.getState().getData(t,e));const i=r?{...r,...s,_optimistic:!0}:{...s,id:e,_optimistic:!0};this.store&&r&&this.store.getState().updateOptimistic(t,e,i,r);try{if(!this.adapter)throw new Error("Adapter not initialized");return await this.adapter.update(t,e,s),this.store&&(this.store.getState().confirmUpdate(t,e),this.store.getState().setData(t,e,{...i,_optimistic:void 0})),this._updateListCaches(t,e,i,"update"),f("success",`${t} updated successfully`),i}catch(h){throw this.store&&this.store.getState().rejectUpdate(t,e),u(h,{userMessage:`Failed to update ${t}`,showNotification:!0})}}async deleteOptimistic(t,e){this.adapter||await this.initialize("firestore");let s=null;this.store&&(s=this.store.getState().getData(t,e)),this.store&&s&&this.store.getState().deleteOptimistic(t,e,s);try{if(!this.adapter)throw new Error("Adapter not initialized");await this.adapter.delete(t,e),this.store&&this.store.getState().confirmDelete(t,e),this._updateListCaches(t,e,null,"delete"),f("success",`${t} deleted successfully`)}catch(a){throw this.store&&this.store.getState().rejectDelete(t,e),u(a,{userMessage:`Failed to delete ${t}`,showNotification:!0})}}}const A=p(()=>new S);export{A as getCrudService};
@@ -7,10 +7,23 @@ import type { CrudServiceInterface } from './CrudService';
7
7
  * @author AMBROISE PARK Consulting
8
8
  */
9
9
  export type BackendType = 'functions' | 'firestore';
10
+ /**
11
+ * Optimistic operation status
12
+ */
13
+ export type OptimisticStatus = 'pending' | 'confirmed' | 'failed';
14
+ /**
15
+ * Optimistic operation metadata
16
+ */
17
+ export interface OptimisticMeta {
18
+ tempId: string;
19
+ originalData: unknown | null;
20
+ status: OptimisticStatus;
21
+ operation: 'add' | 'update' | 'delete';
22
+ }
10
23
  /**
11
24
  * CRUD store state interface
12
25
  *
13
- * @version 0.0.1
26
+ * @version 0.0.2
14
27
  * @since 0.0.1
15
28
  * @author AMBROISE PARK Consulting
16
29
  */
@@ -22,12 +35,14 @@ export interface CrudState {
22
35
  error: Error | null;
23
36
  data: Record<string, unknown>;
24
37
  lastUpdated: number;
38
+ /** Optimistic operation metadata keyed by document id */
39
+ optimistic: Record<string, OptimisticMeta>;
25
40
  }>;
26
41
  }
27
42
  /**
28
43
  * CRUD store actions interface
29
44
  *
30
- * @version 0.0.1
45
+ * @version 0.0.2
31
46
  * @since 0.0.1
32
47
  * @author AMBROISE PARK Consulting
33
48
  */
@@ -45,9 +60,37 @@ export interface CrudActions {
45
60
  removeData: (collection: string, id: string) => void;
46
61
  clearCollection: (collection: string) => void;
47
62
  clearError: (collection: string) => void;
63
+ /** Add item optimistically (before server confirms) */
64
+ addOptimistic: (collection: string, tempId: string, data: unknown) => void;
65
+ /** Confirm optimistic add - replace temp item with real item */
66
+ confirmOptimistic: (collection: string, tempId: string, realId: string, realData: unknown) => void;
67
+ /** Reject optimistic add - remove temp item */
68
+ rejectOptimistic: (collection: string, tempId: string) => void;
69
+ /** Update item optimistically */
70
+ updateOptimistic: (collection: string, id: string, data: unknown, originalData: unknown) => void;
71
+ /** Confirm optimistic update */
72
+ confirmUpdate: (collection: string, id: string) => void;
73
+ /** Reject optimistic update - restore original data */
74
+ rejectUpdate: (collection: string, id: string) => void;
75
+ /** Delete item optimistically (hide but keep for rollback) */
76
+ deleteOptimistic: (collection: string, id: string, originalData: unknown) => void;
77
+ /** Confirm optimistic delete - remove completely */
78
+ confirmDelete: (collection: string, id: string) => void;
79
+ /** Reject optimistic delete - restore item */
80
+ rejectDelete: (collection: string, id: string) => void;
48
81
  getLoading: (collection: string) => boolean;
49
82
  getError: (collection: string) => Error | null;
50
83
  getData: (collection: string, id: string) => unknown | null;
84
+ /** Check if item is optimistic (not yet confirmed by server) */
85
+ isOptimistic: (collection: string, id: string) => boolean;
86
+ /** Get optimistic status for an item */
87
+ getOptimisticStatus: (collection: string, id: string) => OptimisticStatus | null;
88
+ /** Get all items in collection (including optimistic, excluding deleted) */
89
+ getCollectionData: (collection: string) => Array<{
90
+ id: string;
91
+ data: unknown;
92
+ isOptimistic: boolean;
93
+ }>;
51
94
  }
52
95
  /**
53
96
  * CRUD store hook for accessing CRUD state and actions
@@ -1 +1 @@
1
- {"version":3,"file":"CrudStore.d.ts","sourceRoot":"","sources":["../src/CrudStore.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IAExB,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAGzC,WAAW,EAAE,MAAM,CACjB,MAAM,EACN;QACE,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,WAAW,EAAE,MAAM,CAAC;KACrB,CACF,CAAC;CACH;AAQD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAE1B,cAAc,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACxD,UAAU,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAG3C,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5D,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,6EAA6E;IAC7E,YAAY,EAAE,CACZ,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,KACxC,IAAI,CAAC;IACV,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAGzC,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,KAAK,GAAG,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAC;CAC7D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,iIA6LvB,CAAC"}
1
+ {"version":3,"file":"CrudStore.d.ts","sourceRoot":"","sources":["../src/CrudStore.ts"],"names":[],"mappings":"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"}
package/dist/CrudStore.js CHANGED
@@ -1 +1 @@
1
- import{createDoNotDevStore as d}from"@donotdev/core";const s={backend:null,crudService:null,collections:{}},S=d({name:"crud-store",createStore:(r,a)=>({...s,setCrudService:o=>{r({crudService:o})},setBackend:o=>{r({backend:o})},setLoading:(o,l)=>{r(t=>{const e=t.collections[o]||{loading:!1,error:null,data:{},lastUpdated:0};return{collections:{...t.collections,[o]:{...e,loading:l}}}})},setError:(o,l)=>{r(t=>{const e=t.collections[o]||{loading:!1,error:null,data:{},lastUpdated:0};return{collections:{...t.collections,[o]:{...e,error:l,loading:!1}}}})},setData:(o,l,t)=>{r(e=>{const n=e.collections[o]||{loading:!1,error:null,data:{},lastUpdated:0};return{collections:{...e.collections,[o]:{...n,data:{...n.data,[l]:t},lastUpdated:Date.now(),error:null}}}})},setDataBatch:(o,l)=>{l.length!==0&&r(t=>{const e=t.collections[o]||{loading:!1,error:null,data:{},lastUpdated:0},n={...e.data};for(const{id:c,data:i}of l)n[c]=i;return{collections:{...t.collections,[o]:{...e,data:n,lastUpdated:Date.now(),error:null}}}})},removeData:(o,l)=>{r(t=>{const e=t.collections[o];if(!e)return t;const{[l]:n,...c}=e.data;return{collections:{...t.collections,[o]:{...e,data:c,lastUpdated:Date.now()}}}})},clearCollection:o=>{r(l=>{const{[o]:t,...e}=l.collections;return{collections:e}})},clearError:o=>{r(l=>{const t=l.collections[o];return t?{collections:{...l.collections,[o]:{...t,error:null}}}:l})},getLoading:o=>a().collections[o]?.loading||!1,getError:o=>a().collections[o]?.error||null,getData:(o,l)=>a().collections[o]?.data[l]||null})});export{S as useCrudStore};
1
+ import{createDoNotDevStore as d}from"@donotdev/core";const m={backend:null,crudService:null,collections:{}},D=d({name:"crud-store",createStore:(l,r)=>({...m,setCrudService:t=>{l({crudService:t})},setBackend:t=>{l({backend:t})},setLoading:(t,i)=>{l(c=>{const o=c.collections[t]||{loading:!1,error:null,data:{},lastUpdated:0,optimistic:{}};return{collections:{...c.collections,[t]:{...o,loading:i}}}})},setError:(t,i)=>{l(c=>{const o=c.collections[t]||{loading:!1,error:null,data:{},lastUpdated:0,optimistic:{}};return{collections:{...c.collections,[t]:{...o,error:i,loading:!1}}}})},setData:(t,i,c)=>{l(o=>{const n=o.collections[t]||{loading:!1,error:null,data:{},lastUpdated:0,optimistic:{}};return{collections:{...o.collections,[t]:{...n,data:{...n.data,[i]:c},lastUpdated:Date.now(),error:null}}}})},setDataBatch:(t,i)=>{i.length!==0&&l(c=>{const o=c.collections[t]||{loading:!1,error:null,data:{},lastUpdated:0,optimistic:{}},n={...o.data};for(const{id:e,data:a}of i)n[e]=a;return{collections:{...c.collections,[t]:{...o,data:n,lastUpdated:Date.now(),error:null}}}})},removeData:(t,i)=>{l(c=>{const o=c.collections[t];if(!o)return c;const{[i]:n,...e}=o.data;return{collections:{...c.collections,[t]:{...o,data:e,lastUpdated:Date.now()}}}})},clearCollection:t=>{l(i=>{const{[t]:c,...o}=i.collections;return{collections:o}})},clearError:t=>{l(i=>{const c=i.collections[t];return c?{collections:{...i.collections,[t]:{...c,error:null}}}:i})},addOptimistic:(t,i,c)=>{l(o=>{const n=o.collections[t]||{loading:!1,error:null,data:{},lastUpdated:0,optimistic:{}};return{collections:{...o.collections,[t]:{...n,data:{...n.data,[i]:c},optimistic:{...n.optimistic,[i]:{tempId:i,originalData:null,status:"pending",operation:"add"}},lastUpdated:Date.now()}}}})},confirmOptimistic:(t,i,c,o)=>{l(n=>{const e=n.collections[t];if(!e)return n;const{[i]:a,...s}=e.data,{[i]:u,...p}=e.optimistic;return{collections:{...n.collections,[t]:{...e,data:{...s,[c]:o},optimistic:p,lastUpdated:Date.now()}}}})},rejectOptimistic:(t,i)=>{l(c=>{const o=c.collections[t];if(!o)return c;const{[i]:n,...e}=o.data,{[i]:a,...s}=o.optimistic;return{collections:{...c.collections,[t]:{...o,data:e,optimistic:s,lastUpdated:Date.now()}}}})},updateOptimistic:(t,i,c,o)=>{l(n=>{const e=n.collections[t]||{loading:!1,error:null,data:{},lastUpdated:0,optimistic:{}};return{collections:{...n.collections,[t]:{...e,data:{...e.data,[i]:c},optimistic:{...e.optimistic,[i]:{tempId:i,originalData:o,status:"pending",operation:"update"}},lastUpdated:Date.now()}}}})},confirmUpdate:(t,i)=>{l(c=>{const o=c.collections[t];if(!o)return c;const{[i]:n,...e}=o.optimistic;return{collections:{...c.collections,[t]:{...o,optimistic:e}}}})},rejectUpdate:(t,i)=>{l(c=>{const o=c.collections[t];if(!o)return c;const n=o.optimistic[i];if(!n||n.operation!=="update")return c;const{[i]:e,...a}=o.optimistic;return{collections:{...c.collections,[t]:{...o,data:{...o.data,[i]:n.originalData},optimistic:a,lastUpdated:Date.now()}}}})},deleteOptimistic:(t,i,c)=>{l(o=>{const n=o.collections[t];if(!n)return o;const{[i]:e,...a}=n.data;return{collections:{...o.collections,[t]:{...n,data:a,optimistic:{...n.optimistic,[i]:{tempId:i,originalData:c,status:"pending",operation:"delete"}},lastUpdated:Date.now()}}}})},confirmDelete:(t,i)=>{l(c=>{const o=c.collections[t];if(!o)return c;const{[i]:n,...e}=o.optimistic;return{collections:{...c.collections,[t]:{...o,optimistic:e}}}})},rejectDelete:(t,i)=>{l(c=>{const o=c.collections[t];if(!o)return c;const n=o.optimistic[i];if(!n||n.operation!=="delete")return c;const{[i]:e,...a}=o.optimistic;return{collections:{...c.collections,[t]:{...o,data:{...o.data,[i]:n.originalData},optimistic:a,lastUpdated:Date.now()}}}})},getLoading:t=>r().collections[t]?.loading||!1,getError:t=>r().collections[t]?.error||null,getData:(t,i)=>r().collections[t]?.data[i]||null,isOptimistic:(t,i)=>r().collections[t]?.optimistic[i]?.status==="pending",getOptimisticStatus:(t,i)=>r().collections[t]?.optimistic[i]?.status??null,getCollectionData:t=>{const i=r().collections[t];return i?Object.entries(i.data).map(([c,o])=>({id:c,data:o,isOptimistic:i.optimistic[c]?.status==="pending"})):[]}})});export{D as useCrudStore};
@@ -6,17 +6,20 @@
6
6
  * @since 0.0.1
7
7
  * @author AMBROISE PARK Consulting
8
8
  */
9
+ import type { EntityField, FieldType, ValueTypeForField } from '@donotdev/core';
9
10
  import type { ComponentType } from 'react';
10
11
  import type { Control, ControllerRenderProps, FieldErrors, FieldValues, Path } from 'react-hook-form';
11
- import type { BaseSchema, BaseIssue } from 'valibot';
12
- import type { FieldConfig, FieldType, EntityField, ValueTypeForField } from '@donotdev/core';
13
12
  /**
14
13
  * Props for controlled field components (react-hook-form)
14
+ *
15
+ * Use framework's `useController` hook (from @donotdev/crud) instead of react-hook-form's useController
16
+ * to ensure type compatibility.
15
17
  */
16
18
  export interface ControlledFieldProps<T extends FieldValues = FieldValues, FT extends FieldType = FieldType> {
19
+ /** Control object from react-hook-form - use with framework's useController hook */
17
20
  control: Control<T>;
18
21
  errors: FieldErrors<T>;
19
- fieldConfig: FieldConfig<FT>;
22
+ fieldConfig: EntityField<FT>;
20
23
  t: (key: string, options?: Record<string, unknown>) => string;
21
24
  onChange?: (value: ValueTypeForField<FT>) => void;
22
25
  placeholder?: string;
@@ -31,6 +34,8 @@ export interface ControlledFieldProps<T extends FieldValues = FieldValues, FT ex
31
34
  isTouched: boolean;
32
35
  invalid: boolean;
33
36
  };
37
+ /** Form ID for upload tracking - used by file upload fields */
38
+ formId?: string;
34
39
  }
35
40
  /**
36
41
  * Props for uncontrolled field components
@@ -43,20 +48,16 @@ export interface UncontrolledFieldProps<FT extends FieldType = FieldType> {
43
48
  error?: string;
44
49
  helperText?: string;
45
50
  t: (key: string) => string;
46
- config: FieldConfig<FT>;
51
+ config: EntityField<FT>;
47
52
  }
48
53
  /**
49
- * Schema generator function type
50
- */
51
- export type SchemaGenerator = (field: EntityField<FieldType>) => BaseSchema<unknown, unknown, BaseIssue<unknown>>;
52
- /**
53
- * Full registration for custom field types
54
+ * Registration for custom field types (UI components only)
55
+ * Schemas must be defined in entity.validation.schema
54
56
  */
55
57
  export interface FieldTypeRegistration<FT extends string = string> {
56
58
  type: FT;
57
59
  controlledComponent: ComponentType<ControlledFieldProps<any, any>>;
58
60
  uncontrolledComponent?: ComponentType<UncontrolledFieldProps>;
59
- schemaGenerator: SchemaGenerator;
60
61
  }
61
62
  /**
62
63
  * Field Registry - UI components only
@@ -70,8 +71,8 @@ declare class FieldRegistry {
70
71
  */
71
72
  registerComponent(type: string, controlled: ComponentType<ControlledFieldProps<any, any>>, uncontrolled?: ComponentType<UncontrolledFieldProps>): void;
72
73
  /**
73
- * Register a custom field type with UI components AND schema
74
- * Use this for custom types not in @donotdev/core
74
+ * Register a custom field type (UI components only)
75
+ * Schemas must be defined in entity.validation.schema
75
76
  */
76
77
  register<FT extends string>(registration: FieldTypeRegistration<FT>): void;
77
78
  /**
@@ -97,23 +98,58 @@ declare class FieldRegistry {
97
98
  }
98
99
  /**
99
100
  * Get the field registry singleton
101
+ *
102
+ * Note: Built-in field types are auto-registered via side-effect import in FormFieldRenderer
103
+ * This ensures they're registered when the registry is first used, without tree-shaking issues
100
104
  */
101
105
  export declare function getFieldRegistry(): FieldRegistry;
102
106
  /**
103
- * Register a custom field type
107
+ * Register a custom field type (UI component only)
108
+ * Schema must be defined in entity.validation.schema
104
109
  *
105
110
  * @example
106
111
  * ```ts
112
+ * import { useController, registerFieldType } from '@donotdev/crud';
113
+ * import type { ControlledFieldProps } from '@donotdev/crud';
107
114
  * import * as v from 'valibot';
108
- * import { registerFieldType } from '@donotdev/crud';
109
115
  *
116
+ * // Custom controlled component MUST use framework's useController (not react-hook-form)
117
+ * function ControlledRepairOperationsField({
118
+ * fieldConfig,
119
+ * control,
120
+ * errors,
121
+ * t,
122
+ * }: ControlledFieldProps) {
123
+ * // REQUIRED: Use framework's useController - ensures type compatibility
124
+ * const { field, fieldState } = useController({
125
+ * name: fieldConfig.name,
126
+ * control: control,
127
+ * });
128
+ *
129
+ * // Use field.value and field.onChange
130
+ * return (
131
+ * <div>
132
+ * Your custom UI here
133
+ * </div>
134
+ * );
135
+ * }
136
+ *
137
+ * // Register UI component
110
138
  * registerFieldType({
111
- * type: 'ratp',
112
- * controlledComponent: ControlledRatpField,
113
- * schemaGenerator: (field) => {
114
- * const schema = v.object({ line: v.string(), station: v.string() });
115
- * return field.validation?.required ? schema : v.optional(schema);
116
- * },
139
+ * type: 'repairOperations',
140
+ * controlledComponent: ControlledRepairOperationsField,
141
+ * });
142
+ *
143
+ * // Then define schema in entity
144
+ * const carEntity = defineEntity({
145
+ * fields: {
146
+ * repairs: {
147
+ * type: 'repairOperations',
148
+ * validation: {
149
+ * schema: v.array(v.object({ operation: v.string(), cost: v.number() }))
150
+ * }
151
+ * }
152
+ * }
117
153
  * });
118
154
  * ```
119
155
  */
@@ -1 +1 @@
1
- {"version":3,"file":"FieldRegistry.d.ts","sourceRoot":"","sources":["../src/FieldRegistry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FieldRegistry.d.ts","sourceRoot":"","sources":["../src/FieldRegistry.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- "use client";import{registerSchemaGenerator as l,hasCustomSchemaGenerator as p}from"@donotdev/core";class m{components=new Map;registerComponent(e,t,o){this.components.set(e,{controlled:t,uncontrolled:o})}register(e){const{type:t,controlledComponent:o,uncontrolledComponent:i,schemaGenerator:c}=e;this.components.set(t,{controlled:o,uncontrolled:i}),p(t)||l(t,c)}getControlledComponent(e){return this.components.get(e)?.controlled}getUncontrolledComponent(e){return this.components.get(e)?.uncontrolled}has(e){return this.components.has(e)}getRegisteredTypes(){return Array.from(this.components.keys())}clear(){this.components.clear()}}let r=null;function s(){return r||(r=new m),r}function g(n){s().register(n)}function u(n){return s().has(n)}export{s as getFieldRegistry,u as isFieldTypeRegistered,g as registerFieldType};
1
+ "use client";class i{components=new Map;registerComponent(e,n,o){this.components.set(e,{controlled:n,uncontrolled:o})}register(e){const{type:n,controlledComponent:o,uncontrolledComponent:l}=e;this.components.set(n,{controlled:o,uncontrolled:l})}getControlledComponent(e){return this.components.get(e)?.controlled}getUncontrolledComponent(e){return this.components.get(e)?.uncontrolled}has(e){return this.components.has(e)}getRegisteredTypes(){return Array.from(this.components.keys())}clear(){this.components.clear()}}let r=null;function s(){return r||(r=new i),r}function c(t){s().register(t)}function p(t){return s().has(t)}export{s as getFieldRegistry,p as isFieldTypeRegistered,c as registerFieldType};
@@ -51,13 +51,13 @@ export declare class FirestoreAdapter {
51
51
  private firestore;
52
52
  private ensureFirestore;
53
53
  private getCollectionRef;
54
- get<T>(collectionName: string, id: string, schema: dndevSchema<T>): Promise<T | null>;
54
+ get<T>(collectionName: string, id: string, schema: dndevSchema<unknown>): Promise<T | null>;
55
55
  set<T>(collectionName: string, id: string, data: T, schema: dndevSchema<T>): Promise<void>;
56
56
  update<T>(collectionName: string, id: string, data: Partial<T>): Promise<void>;
57
57
  delete(collectionName: string, id: string): Promise<void>;
58
58
  add<T>(collectionName: string, data: T, schema: dndevSchema<T>): Promise<string>;
59
- query<T>(collectionName: string, options: QueryOptions, schema: dndevSchema<T>): Promise<T[]>;
60
- subscribe<T>(collectionName: string, id: string, callback: SubscriptionCallback<T>, schema: dndevSchema<T>): Unsubscribe;
61
- subscribeToCollection<T>(collectionName: string, options: QueryOptions, callback: CollectionSubscriptionCallback<T>, schema: dndevSchema<T>): Unsubscribe;
59
+ query<T>(collectionName: string, options: QueryOptions, schema: dndevSchema<unknown>): Promise<T[]>;
60
+ subscribe<T>(collectionName: string, id: string, callback: SubscriptionCallback<T>, schema: dndevSchema<unknown>): Unsubscribe;
61
+ subscribeToCollection<T>(collectionName: string, options: QueryOptions, callback: CollectionSubscriptionCallback<T>, schema: dndevSchema<unknown>): Unsubscribe;
62
62
  }
63
63
  //# sourceMappingURL=FirestoreAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FirestoreAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/FirestoreAdapter.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAoBL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAQ5B;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,IAAI,GACJ,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,gBAAgB,GAChB,IAAI,GACJ,QAAQ,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9E,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,CACpC,IAAI,EAAE,CAAC,GAAG,IAAI,EACd,KAAK,CAAC,EAAE,cAAc,KACnB,IAAI,CAAC;AACV;;;;;;GAMG;AACH,MAAM,MAAM,8BAA8B,CAAC,CAAC,IAAI,CAC9C,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,CAAC,EAAE,cAAc,KACnB,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,gBAAgB;IAKlB,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IA2Bd,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,IAAI,CAAC;IAYV,MAAM,CAAC,CAAC,EACZ,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GACf,OAAO,CAAC,IAAI,CAAC;IAWV,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzD,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,MAAM,CAAC;IAcZ,KAAK,CAAC,CAAC,EACX,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,EAAE,CAAC;IAoEf,SAAS,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,EACjC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,WAAW;IA2Bd,qBAAqB,CAAC,CAAC,EACrB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,8BAA8B,CAAC,CAAC,CAAC,EAC3C,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,WAAW;CAgDf"}
1
+ {"version":3,"file":"FirestoreAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/FirestoreAdapter.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAqBL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAQ5B;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,IAAI,GACJ,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,gBAAgB,GAChB,IAAI,GACJ,QAAQ,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9E,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,CACpC,IAAI,EAAE,CAAC,GAAG,IAAI,EACd,KAAK,CAAC,EAAE,cAAc,KACnB,IAAI,CAAC;AACV;;;;;;GAMG;AACH,MAAM,MAAM,8BAA8B,CAAC,CAAC,IAAI,CAC9C,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,CAAC,EAAE,cAAc,KACnB,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,gBAAgB;IAKlB,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAC3B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IA2Bd,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,IAAI,CAAC;IAYV,MAAM,CAAC,CAAC,EACZ,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GACf,OAAO,CAAC,IAAI,CAAC;IAWV,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzD,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,MAAM,CAAC;IA+CZ,KAAK,CAAC,CAAC,EACX,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAC3B,OAAO,CAAC,CAAC,EAAE,CAAC;IAoEf,SAAS,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,EACjC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAC3B,WAAW;IA2Bd,qBAAqB,CAAC,CAAC,EACrB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,8BAA8B,CAAC,CAAC,CAAC,EAC3C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAC3B,WAAW;CAgDf"}
@@ -1 +1 @@
1
- import*as u from"valibot";import{handleError as p}from"@donotdev/core";import{getFirestore as A,doc as l,getDoc as q,getDocs as x,setDoc as v,updateDoc as B,deleteDoc as C,addDoc as z,collection as E,query as F,where as w,orderBy as g,limit as R,onSnapshot as m}from"@donotdev/firebase";import{transformFirestoreData as d,prepareForFirestore as y}from"@donotdev/firebase";class G{firestore;ensureFirestore(){if(this.firestore)return!0;try{return this.firestore=A(),!0}catch{return!1}}getCollectionRef(s){return!this.ensureFirestore()||!this.firestore?null:E(this.firestore,s)}async get(s,r,e){if(!this.ensureFirestore()||!this.firestore)return null;try{const o=l(this.firestore,s,r),t=await q(o);if(!t.exists())return null;let i=t.data();return i=d(i),{...u.parse(e,i),id:r}}catch(o){return p(o,{context:{operation:"FirestoreAdapter.get",collection:s,docId:r},severity:"warning"}),null}}async set(s,r,e,o){if(!(!this.ensureFirestore()||!this.firestore))try{u.parse(o,e);const t=l(this.firestore,s,r),i=y(e);await v(t,i)}catch(t){throw t}}async update(s,r,e){if(!(!this.ensureFirestore()||!this.firestore))try{const o=l(this.firestore,s,r),t=y(e);await B(o,t)}catch(o){throw o}}async delete(s,r){if(!(!this.ensureFirestore()||!this.firestore))try{const e=l(this.firestore,s,r);await C(e)}catch(e){throw e}}async add(s,r,e){if(!this.ensureFirestore())return"";try{u.parse(e,r);const o=this.getCollectionRef(s);if(!o)return"";const t=y(r);return(await z(o,t)).id}catch(o){throw o}}async query(s,r,e){if(!this.ensureFirestore())return[];const o=this.getCollectionRef(s);if(!o)return[];try{const t=[];if(r.where)for(const a of r.where)t.push(w(a.field,a.operator,a.value));if(r.orderBy)for(const a of r.orderBy)t.push(g(a.field,a.direction||"asc"));r.limit&&t.push(R(r.limit));const i=F(o,...t),c=await x(i),n=[];return c.forEach(a=>{try{let f=a.data();if(!f)return;f=d(f);const h=u.parse(e,f);n.push({...h,id:a.id})}catch(f){p(f,{context:{operation:"FirestoreAdapter.query.parse",docId:a.id,collection:s},showNotification:!1})}}),n}catch(t){throw p(t,{context:{operation:"FirestoreAdapter.query",collection:s,options:r}}),t}}subscribe(s,r,e,o){if(!this.ensureFirestore()||!this.firestore)return()=>{};const t=l(this.firestore,s,r);return m(t,i=>{try{if(!i.exists()){e(null);return}let c=i.data();c=d(c);const n=u.parse(o,c);e({...n,id:r})}catch(c){e(null,c)}},i=>{e(null,i)})}subscribeToCollection(s,r,e,o){if(!this.ensureFirestore())return()=>{};const t=this.getCollectionRef(s);if(!t)return()=>{};try{const i=[];if(r.where)for(const n of r.where)i.push(w(n.field,n.operator,n.value));if(r.orderBy)for(const n of r.orderBy)i.push(g(n.field,n.direction||"asc"));r.limit&&i.push(R(r.limit));const c=F(t,...i);return m(c,n=>{try{const a=[];n.forEach(f=>{let h=f.data();h=d(h);const D=u.parse(o,h);a.push({...D,id:f.id})}),e(a)}catch(a){e([],a)}},n=>{e([],n)})}catch(i){return e([],i),()=>{}}}}export{G as FirestoreAdapter};
1
+ import*as f from"valibot";import{handleError as p}from"@donotdev/core";import{getFirestore as R,getFirebaseSDK as I,doc as l,getDoc as B,getDocs as q,setDoc as x,updateDoc as C,deleteDoc as E,addDoc as v,collection as S,query as F,where as g,orderBy as w,limit as m,onSnapshot as A}from"@donotdev/firebase";import{transformFirestoreData as h,prepareForFirestore as y}from"@donotdev/firebase";class L{firestore;ensureFirestore(){if(this.firestore)return!0;try{return this.firestore=R(),!0}catch{return!1}}getCollectionRef(s){return!this.ensureFirestore()||!this.firestore?null:S(this.firestore,s)}async get(s,e,r){if(!this.ensureFirestore()||!this.firestore)return null;try{const i=l(this.firestore,s,e),t=await B(i);if(!t.exists())return null;let o=t.data();return o=h(o),{...f.parse(r,o),id:e}}catch(i){return p(i,{context:{operation:"FirestoreAdapter.get",collection:s,docId:e},severity:"warning"}),null}}async set(s,e,r,i){if(!(!this.ensureFirestore()||!this.firestore))try{f.parse(i,r);const t=l(this.firestore,s,e),o=y(r);await x(t,o)}catch(t){throw t}}async update(s,e,r){if(!(!this.ensureFirestore()||!this.firestore))try{const i=l(this.firestore,s,e),t=y(r);await C(i,t)}catch(i){throw i}}async delete(s,e){if(!(!this.ensureFirestore()||!this.firestore))try{const r=l(this.firestore,s,e);await E(r)}catch(r){throw r}}async add(s,e,r){if(!this.ensureFirestore())return"";try{f.parse(r,e);const i=this.getCollectionRef(s);if(!i)return"";const t=new Date().toISOString(),o=I().getCurrentUser()?.uid||"anonymous",c={...e,createdAt:t,updatedAt:t,createdById:o,updatedById:o},a=y(c);return(await v(i,a)).id}catch(i){throw i}}async query(s,e,r){if(!this.ensureFirestore())return[];const i=this.getCollectionRef(s);if(!i)return[];try{const t=[];if(e.where)for(const n of e.where)t.push(g(n.field,n.operator,n.value));if(e.orderBy)for(const n of e.orderBy)t.push(w(n.field,n.direction||"asc"));e.limit&&t.push(m(e.limit));const o=F(i,...t),c=await q(o),a=[];return c.forEach(n=>{try{let d=n.data();if(!d)return;d=h(d);const u=f.parse(r,d);a.push({...u,id:n.id})}catch(d){p(d,{context:{operation:"FirestoreAdapter.query.parse",docId:n.id,collection:s},showNotification:!1})}}),a}catch(t){throw p(t,{context:{operation:"FirestoreAdapter.query",collection:s,options:e}}),t}}subscribe(s,e,r,i){if(!this.ensureFirestore()||!this.firestore)return()=>{};const t=l(this.firestore,s,e);return A(t,o=>{try{if(!o.exists()){r(null);return}let c=o.data();c=h(c);const a=f.parse(i,c);r({...a,id:e})}catch(c){r(null,c)}},o=>{r(null,o)})}subscribeToCollection(s,e,r,i){if(!this.ensureFirestore())return()=>{};const t=this.getCollectionRef(s);if(!t)return()=>{};try{const o=[];if(e.where)for(const a of e.where)o.push(g(a.field,a.operator,a.value));if(e.orderBy)for(const a of e.orderBy)o.push(w(a.field,a.direction||"asc"));e.limit&&o.push(m(e.limit));const c=F(t,...o);return A(c,a=>{try{const n=[];a.forEach(d=>{let u=d.data();u=h(u);const D=f.parse(i,u);n.push({...D,id:d.id})}),r(n)}catch(n){r([],n)}},a=>{r([],a)})}catch(o){return r([],o),()=>{}}}}export{L as FirestoreAdapter};
@@ -32,12 +32,13 @@ export declare class FunctionsAdapter {
32
32
  private region;
33
33
  constructor();
34
34
  private ensureFunctions;
35
- get<T>(collectionName: string, id: string, schema: dndevSchema<T>): Promise<T | null>;
35
+ get<T>(collectionName: string, id: string, schema: dndevSchema<unknown>): Promise<T | null>;
36
36
  set<T>(collectionName: string, id: string, data: T, schema: dndevSchema<T>): Promise<void>;
37
37
  update<T>(collectionName: string, id: string, data: Partial<T>): Promise<void>;
38
38
  delete(collectionName: string, id: string): Promise<void>;
39
39
  add<T>(collectionName: string, data: T, schema: dndevSchema<T>): Promise<string>;
40
- query<T>(collectionName: string, options: FunctionsQueryOptions, schema: dndevSchema<T>): Promise<T[]>;
40
+ query<T>(collectionName: string, options: FunctionsQueryOptions, schema: dndevSchema<unknown>): Promise<T[]>;
41
+ listCard<T>(collectionName: string, options: FunctionsQueryOptions, schema: dndevSchema<T>): Promise<T[]>;
41
42
  subscribe<T>(): () => void;
42
43
  subscribeToCollection<T>(): () => void;
43
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FunctionsAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/FunctionsAdapter.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAS;;YAOT,eAAe;IAUvB,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAed,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,IAAI,CAAC;IAeV,MAAM,CAAC,CAAC,EACZ,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GACf,OAAO,CAAC,IAAI,CAAC;IAcV,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczD,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,MAAM,CAAC;IAgBZ,KAAK,CAAC,CAAC,EACX,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,EAAE,CAAC;IAgBf,SAAS,CAAC,CAAC,KAAK,MAAM,IAAI;IAM1B,qBAAqB,CAAC,CAAC,KAAK,MAAM,IAAI;CAKvC"}
1
+ {"version":3,"file":"FunctionsAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/FunctionsAdapter.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAS;;YAOT,eAAe;IAUvB,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAC3B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAed,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,IAAI,CAAC;IAeV,MAAM,CAAC,CAAC,EACZ,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GACf,OAAO,CAAC,IAAI,CAAC;IAcV,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczD,GAAG,CAAC,CAAC,EACT,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,MAAM,CAAC;IAgBZ,KAAK,CAAC,CAAC,EACX,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAC3B,OAAO,CAAC,CAAC,EAAE,CAAC;IA+CT,QAAQ,CAAC,CAAC,EACd,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,EAAE,CAAC;IAgDf,SAAS,CAAC,CAAC,KAAK,MAAM,IAAI;IAM1B,qBAAqB,CAAC,CAAC,KAAK,MAAM,IAAI;CAKvC"}
@@ -1 +1 @@
1
- import{httpsCallable as o}from"firebase/functions";import*as i from"valibot";import{getPlatformEnvVar as c}from"@donotdev/core";import{getFirebaseFunctions as u}from"@donotdev/firebase";class p{functions;region;constructor(){this.region=c("FIREBASE_FUNCTIONS_REGION")||"europe-west1"}async ensureFunctions(){if(this.functions)return!0;try{return this.functions=await u(this.region),!0}catch{return!1}}async get(e,r,n){if(!await this.ensureFunctions())return null;try{const t=`get_${e}`;return(await o(this.functions,t)({id:r})).data}catch(t){throw t}}async set(e,r,n,t){if(await this.ensureFunctions())try{i.parse(t,n);const s=`update_${e}`;await o(this.functions,s)({id:r,payload:n})}catch(s){throw s}}async update(e,r,n){if(await this.ensureFunctions())try{const t=`update_${e}`;await o(this.functions,t)({id:r,payload:n})}catch(t){throw t}}async delete(e,r){if(await this.ensureFunctions())try{const n=`delete_${e}`;await o(this.functions,n)({id:r})}catch(n){throw n}}async add(e,r,n){if(!await this.ensureFunctions())return"";try{i.parse(n,r);const t=`create_${e}`;return(await o(this.functions,t)({payload:r})).data.id}catch(t){throw t}}async query(e,r,n){if(!await this.ensureFunctions())return[];try{const t=`list_${e}`;return(await o(this.functions,t)({filters:r})).data}catch(t){throw t}}subscribe(){throw new Error("Subscriptions are not supported with Functions backend. Use Firestore backend for real-time features.")}subscribeToCollection(){throw new Error("Subscriptions are not supported with Functions backend. Use Firestore backend for real-time features.")}}export{p as FunctionsAdapter};
1
+ import{httpsCallable as a}from"firebase/functions";import*as o from"valibot";import{getPlatformEnvVar as h}from"@donotdev/core";import{getFirebaseFunctions as l}from"@donotdev/firebase";class F{functions;region;constructor(){this.region=h("FIREBASE_FUNCTIONS_REGION")||"europe-west1"}async ensureFunctions(){if(this.functions)return!0;try{return this.functions=await l(this.region),!0}catch{return!1}}async get(n,t,s){if(!await this.ensureFunctions())return null;try{const r=`get_${n}`;return(await a(this.functions,r)({id:t})).data}catch(r){throw r}}async set(n,t,s,r){if(await this.ensureFunctions())try{o.parse(r,s);const e=`update_${n}`;await a(this.functions,e)({id:t,payload:s})}catch(e){throw e}}async update(n,t,s){if(await this.ensureFunctions())try{const r=`update_${n}`;await a(this.functions,r)({id:t,payload:s})}catch(r){throw r}}async delete(n,t){if(await this.ensureFunctions())try{const s=`delete_${n}`;await a(this.functions,s)({id:t})}catch(s){throw s}}async add(n,t,s){if(!await this.ensureFunctions())return"";try{o.parse(s,t);const r=`create_${n}`;return(await a(this.functions,r)({payload:t})).data.id}catch(r){throw r}}async query(n,t,s){if(!await this.ensureFunctions())return[];try{const r=`list_${n}`,e={};return t.where&&(e.where=t.where.map(i=>[i.field,i.operator,i.value])),t.orderBy&&(e.orderBy=t.orderBy.map(i=>[i.field,i.direction||"asc"])),t.limit&&(e.limit=t.limit),(await a(this.functions,r)(e)).data.items}catch(r){throw r}}async listCard(n,t,s){if(!await this.ensureFunctions())return[];try{const r=`listCard_${n}`,e={};return t.where&&(e.where=t.where.map(i=>[i.field,i.operator,i.value])),t.orderBy&&(e.orderBy=t.orderBy.map(i=>[i.field,i.direction||"asc"])),t.limit&&(e.limit=t.limit),(await a(this.functions,r)(e)).data.items}catch(r){throw r}}subscribe(){throw new Error("Subscriptions are not supported with Functions backend. Use Firestore backend for real-time features.")}subscribeToCollection(){throw new Error("Subscriptions are not supported with Functions backend. Use Firestore backend for real-time features.")}}export{F as FunctionsAdapter};