@tinya-code/gas-admin-ui 0.2.0-alpha.12 → 0.2.0-alpha.15

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 (369) hide show
  1. package/README.md +222 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +3 -15
  4. package/src/lib/actions/action-registry.spec.ts +52 -0
  5. package/src/lib/actions/action-registry.ts +126 -0
  6. package/src/lib/actions/action-service.spec.ts +215 -0
  7. package/src/lib/actions/action-service.ts +87 -0
  8. package/src/lib/actions/descriptors.spec.ts +155 -0
  9. package/src/lib/actions/descriptors.ts +154 -0
  10. package/src/lib/columns/column-cell.ts +33 -0
  11. package/src/lib/columns/column-defaults.spec.ts +99 -0
  12. package/src/lib/columns/column-defaults.ts +84 -0
  13. package/src/lib/columns/column-format.spec.ts +274 -0
  14. package/src/lib/columns/descriptors.ts +113 -0
  15. package/src/lib/columns/format-badge.ts +51 -0
  16. package/src/lib/columns/format-boolean.ts +58 -0
  17. package/src/lib/columns/format-currency.ts +30 -0
  18. package/src/lib/columns/format-date.ts +35 -0
  19. package/src/lib/columns/format-number.ts +32 -0
  20. package/src/lib/columns/format-text.ts +23 -0
  21. package/src/lib/columns/format-thumbnail.ts +63 -0
  22. package/src/lib/core/adapters/firebase-auth.adapter.ts +6 -0
  23. package/src/lib/core/guards/auth.guard.spec.ts +88 -0
  24. package/src/lib/core/guards/auth.guard.ts +48 -0
  25. package/src/lib/core/guards/unsaved-changes.guard.ts +16 -0
  26. package/src/lib/core/interceptors/api-error.interceptor.spec.ts +182 -0
  27. package/src/lib/core/interceptors/api-error.interceptor.ts +87 -0
  28. package/src/lib/core/models/api.model.ts +104 -0
  29. package/src/lib/core/models/schema-descriptions.ts +118 -0
  30. package/src/lib/core/models/schema.model.ts +1097 -0
  31. package/src/lib/core/registry/composition-validator.spec.ts +358 -0
  32. package/src/lib/core/registry/composition-validator.ts +270 -0
  33. package/src/lib/core/registry/field-validators.spec.ts +199 -0
  34. package/src/lib/core/registry/field-validators.ts +440 -0
  35. package/src/lib/core/registry/render-host.spec.ts +208 -0
  36. package/src/lib/core/registry/render-host.ts +646 -0
  37. package/src/lib/core/registry/render-registry.spec.ts +96 -0
  38. package/src/lib/core/registry/render-registry.ts +312 -0
  39. package/src/lib/core/registry/schema-catalog.ts +156 -0
  40. package/src/lib/core/services/api.service.spec.ts +1142 -0
  41. package/src/lib/core/services/api.service.ts +371 -0
  42. package/src/lib/core/services/auth.service.spec.ts +653 -0
  43. package/src/lib/core/services/auth.service.ts +503 -0
  44. package/src/lib/core/services/config.service.spec.ts +121 -0
  45. package/src/lib/core/services/config.service.ts +119 -0
  46. package/src/lib/core/services/data-source.service.spec.ts +179 -0
  47. package/src/lib/core/services/data-source.service.ts +142 -0
  48. package/src/lib/core/services/error-mapper.service.spec.ts +50 -0
  49. package/src/lib/core/services/error-mapper.service.ts +49 -0
  50. package/src/lib/core/services/notification.service.ts +73 -0
  51. package/src/lib/core/services/relation-drawer.service.ts +41 -0
  52. package/src/lib/core/services/theme.service.spec.ts +106 -0
  53. package/src/lib/core/services/theme.service.ts +86 -0
  54. package/src/lib/core/services/transport.spec.ts +198 -0
  55. package/src/lib/core/services/transport.ts +164 -0
  56. package/src/lib/core/services/upload.service.ts +81 -0
  57. package/src/lib/core/testing/categories.schema.ts +125 -0
  58. package/src/lib/core/testing/orders.schema.ts +372 -0
  59. package/src/lib/core/testing/products.schema.ts +258 -0
  60. package/src/lib/core/testing/site.schema.ts +195 -0
  61. package/src/lib/core/testing/test-catalog.ts +21 -0
  62. package/src/lib/core/tokens.ts +112 -0
  63. package/src/lib/core/utils/clipboard.spec.ts +55 -0
  64. package/src/lib/core/utils/clipboard.ts +90 -0
  65. package/src/lib/core/utils/context-resolver.spec.ts +95 -0
  66. package/src/lib/core/utils/context-resolver.ts +101 -0
  67. package/src/lib/core/utils/response-unwrapper.spec.ts +70 -0
  68. package/src/lib/core/utils/response-unwrapper.ts +103 -0
  69. package/src/lib/core/utils/source-options.spec.ts +96 -0
  70. package/src/lib/core/utils/source-options.ts +54 -0
  71. package/src/lib/core/utils/template-interpolator.spec.ts +59 -0
  72. package/src/lib/core/utils/template-interpolator.ts +56 -0
  73. package/src/lib/core/view-navigation/view-navigation.service.spec.ts +207 -0
  74. package/src/lib/core/view-navigation/view-navigation.service.ts +132 -0
  75. package/src/lib/fields/boolean/boolean.descriptor.ts +11 -0
  76. package/src/lib/fields/boolean/boolean.ts +40 -0
  77. package/src/lib/fields/color/color.descriptor.ts +12 -0
  78. package/src/lib/fields/color/color.ts +34 -0
  79. package/src/lib/fields/currency/currency.descriptor.ts +12 -0
  80. package/src/lib/fields/currency/currency.ts +67 -0
  81. package/src/lib/fields/date/date.descriptor.ts +12 -0
  82. package/src/lib/fields/date/date.ts +36 -0
  83. package/src/lib/fields/descriptors.ts +122 -0
  84. package/src/lib/fields/display/display-badge.ts +65 -0
  85. package/src/lib/fields/display/display-date.ts +39 -0
  86. package/src/lib/fields/display/display-defaults.ts +84 -0
  87. package/src/lib/fields/display/display-file.ts +41 -0
  88. package/src/lib/fields/display/display-image.ts +54 -0
  89. package/src/lib/fields/display/display-list.ts +107 -0
  90. package/src/lib/fields/display/display-number.ts +41 -0
  91. package/src/lib/fields/display/display-text.ts +42 -0
  92. package/src/lib/fields/display/display.spec.ts +242 -0
  93. package/src/lib/fields/dropdown/dropdown.descriptor.ts +12 -0
  94. package/src/lib/fields/dropdown/dropdown.ts +45 -0
  95. package/src/lib/fields/email/email.descriptor.ts +12 -0
  96. package/src/lib/fields/email/email.ts +28 -0
  97. package/src/lib/fields/field-aria.ts +60 -0
  98. package/src/lib/fields/field-host/field-host.spec.ts +118 -0
  99. package/src/lib/fields/field-host/field-host.ts +47 -0
  100. package/src/lib/fields/field-node.ts +88 -0
  101. package/src/lib/fields/file/file.descriptor.ts +14 -0
  102. package/src/lib/fields/file/file.spec.ts +134 -0
  103. package/src/lib/fields/file/file.ts +281 -0
  104. package/src/lib/fields/group/group.descriptor.ts +21 -0
  105. package/src/lib/fields/group/group.ts +110 -0
  106. package/src/lib/fields/image/image.descriptor.ts +12 -0
  107. package/src/lib/fields/image/image.spec.ts +117 -0
  108. package/src/lib/fields/image/image.ts +281 -0
  109. package/src/lib/fields/key-value/key-value.descriptor.ts +11 -0
  110. package/src/lib/fields/key-value/key-value.ts +283 -0
  111. package/src/lib/fields/list/list.descriptor.ts +21 -0
  112. package/src/lib/fields/list/list.ts +376 -0
  113. package/src/lib/fields/multiselect/multiselect.descriptor.ts +11 -0
  114. package/src/lib/fields/multiselect/multiselect.spec.ts +142 -0
  115. package/src/lib/fields/multiselect/multiselect.ts +152 -0
  116. package/src/lib/fields/number/number.descriptor.ts +12 -0
  117. package/src/lib/fields/number/number.ts +40 -0
  118. package/src/lib/fields/phone/phone.descriptor.ts +12 -0
  119. package/src/lib/fields/phone/phone.ts +46 -0
  120. package/src/lib/fields/readonly-text/readonly-text.descriptor.ts +12 -0
  121. package/src/lib/fields/readonly-text/readonly-text.ts +58 -0
  122. package/src/lib/fields/relation/relation.descriptor.ts +12 -0
  123. package/src/lib/fields/relation/relation.spec.ts +193 -0
  124. package/src/lib/fields/relation/relation.ts +224 -0
  125. package/src/lib/fields/rich-select/rich-select.descriptor.ts +12 -0
  126. package/src/lib/fields/rich-select/rich-select.ts +175 -0
  127. package/src/lib/fields/select/radio-mode.ts +25 -0
  128. package/src/lib/fields/select/select.descriptor.ts +12 -0
  129. package/src/lib/fields/select/select.spec.ts +162 -0
  130. package/src/lib/fields/select/select.ts +210 -0
  131. package/src/lib/fields/slug/slug.descriptor.ts +19 -0
  132. package/src/lib/fields/slug/slug.ts +67 -0
  133. package/src/lib/fields/string-list/string-list.descriptor.ts +11 -0
  134. package/src/lib/fields/string-list/string-list.ts +222 -0
  135. package/src/lib/fields/text/text.descriptor.ts +12 -0
  136. package/src/lib/fields/text/text.ts +35 -0
  137. package/src/lib/fields/textarea/textarea.descriptor.ts +12 -0
  138. package/src/lib/fields/textarea/textarea.spec.ts +117 -0
  139. package/src/lib/fields/textarea/textarea.ts +126 -0
  140. package/src/lib/fields/time/time.descriptor.ts +12 -0
  141. package/src/lib/fields/time/time.ts +28 -0
  142. package/src/lib/fields/unknown-render/unknown-render.ts +49 -0
  143. package/src/lib/fields/url/url.descriptor.ts +12 -0
  144. package/src/lib/fields/url/url.ts +53 -0
  145. package/src/lib/gas-admin-ui.spec.ts +21 -0
  146. package/src/lib/gas-admin-ui.ts +9 -0
  147. package/src/lib/layouts/descriptors.ts +9 -0
  148. package/src/lib/pages/dashboard/dashboard.ts +167 -0
  149. package/src/lib/pages/detail-view/detail-view.spec.ts +333 -0
  150. package/src/lib/pages/detail-view/detail-view.ts +570 -0
  151. package/src/lib/pages/drawer-form/drawer-form.ts +228 -0
  152. package/src/lib/pages/form-view/form-model.ts +88 -0
  153. package/src/lib/pages/form-view/form-schema.ts +255 -0
  154. package/src/lib/pages/form-view/form-view.ts +1622 -0
  155. package/src/lib/pages/list-view/list-view.formats.spec.ts +214 -0
  156. package/src/lib/pages/list-view/list-view.ts +882 -0
  157. package/src/lib/pages/login/login.spec.ts +109 -0
  158. package/src/lib/pages/login/login.ts +227 -0
  159. package/src/lib/pages/resource-page/resource-page.ts +234 -0
  160. package/src/lib/shared/components/badge/badge.ts +35 -0
  161. package/src/lib/shared/components/button/button.ts +65 -0
  162. package/src/lib/shared/components/confirm-dialog/confirm-dialog.ts +48 -0
  163. package/src/lib/shared/components/copy-button/copy-button.ts +56 -0
  164. package/src/lib/shared/components/copy-share/copy-share.spec.ts +122 -0
  165. package/src/lib/shared/components/copy-share/copy-share.ts +107 -0
  166. package/src/lib/shared/components/drawer/drawer.spec.ts +127 -0
  167. package/src/lib/shared/components/drawer/drawer.ts +172 -0
  168. package/src/lib/shared/components/empty-state/empty-state.ts +30 -0
  169. package/src/lib/shared/components/modal/modal.spec.ts +149 -0
  170. package/src/lib/shared/components/modal/modal.ts +145 -0
  171. package/src/lib/shared/components/post-create-modal/post-create-modal.spec.ts +165 -0
  172. package/src/lib/shared/components/post-create-modal/post-create-modal.ts +159 -0
  173. package/src/lib/shared/components/skeleton/skeleton.ts +31 -0
  174. package/src/lib/shared/components/toast/toast.ts +58 -0
  175. package/src/lib/shared/utils/col-span.ts +25 -0
  176. package/src/lib/shared/utils/condition-evaluator.ts +53 -0
  177. package/src/lib/shared/utils/depends-on.ts +48 -0
  178. package/src/lib/shared/utils/dialog-focus.ts +28 -0
  179. package/src/lib/shared/utils/field-path.ts +49 -0
  180. package/src/lib/shared/utils/gap-sorting.ts +144 -0
  181. package/src/lib/shared/utils/seed.spec.ts +64 -0
  182. package/src/lib/shared/utils/seed.ts +149 -0
  183. package/src/lib/shared/utils/slugify.ts +13 -0
  184. package/src/lib/shared/utils/validators.ts +41 -0
  185. package/src/lib/shell/layout/layout.ts +63 -0
  186. package/src/lib/shell/shell.routes.spec.ts +59 -0
  187. package/src/lib/shell/shell.routes.ts +122 -0
  188. package/src/lib/shell/sidebar/sidebar.ts +139 -0
  189. package/src/lib/shell/theme-toggle/theme-toggle.ts +74 -0
  190. package/src/lib/views/calendar-view/calendar-model.ts +426 -0
  191. package/src/lib/views/calendar-view/calendar-view.spec.ts +557 -0
  192. package/src/lib/views/calendar-view/calendar-view.ts +568 -0
  193. package/src/lib/views/composer/composer-host.spec.ts +301 -0
  194. package/src/lib/views/composer/composer-host.ts +248 -0
  195. package/src/lib/views/composer/composer-imports.spec.ts +54 -0
  196. package/src/lib/views/composer/view-context.spec.ts +117 -0
  197. package/src/lib/views/composer/view-context.ts +109 -0
  198. package/src/lib/views/composer/view-slot.spec.ts +130 -0
  199. package/src/lib/views/composer/view-slot.ts +178 -0
  200. package/src/lib/views/descriptors.ts +46 -0
  201. package/src/lib/views/kanban-view/kanban-model.ts +173 -0
  202. package/src/lib/views/kanban-view/kanban-view.spec.ts +540 -0
  203. package/src/lib/views/kanban-view/kanban-view.ts +327 -0
  204. package/src/lib/widgets/bar-chart/bar-chart.descriptor.ts +17 -0
  205. package/src/lib/widgets/bar-chart/bar-chart.spec.ts +66 -0
  206. package/src/lib/widgets/bar-chart/bar-chart.ts +76 -0
  207. package/src/lib/widgets/chart-line/chart-line.descriptor.ts +17 -0
  208. package/src/lib/widgets/chart-line/chart-line.spec.ts +113 -0
  209. package/src/lib/widgets/chart-line/chart-line.ts +219 -0
  210. package/src/lib/widgets/descriptors.ts +29 -0
  211. package/src/lib/widgets/metric-card/metric-card.descriptor.ts +41 -0
  212. package/src/lib/widgets/metric-card/metric-card.spec.ts +52 -0
  213. package/src/lib/widgets/metric-card/metric-card.ts +48 -0
  214. package/src/lib/widgets/quick-actions/quick-actions.descriptor.ts +13 -0
  215. package/src/lib/widgets/quick-actions/quick-actions.spec.ts +61 -0
  216. package/src/lib/widgets/quick-actions/quick-actions.ts +100 -0
  217. package/src/lib/widgets/record-list/record-list.descriptor.ts +16 -0
  218. package/src/lib/widgets/record-list/record-list.spec.ts +79 -0
  219. package/src/lib/widgets/record-list/record-list.ts +115 -0
  220. package/src/lib/widgets/series.spec.ts +42 -0
  221. package/src/lib/widgets/series.ts +56 -0
  222. package/src/lib/widgets/status-progress/status-progress.descriptor.ts +19 -0
  223. package/src/lib/widgets/status-progress/status-progress.spec.ts +63 -0
  224. package/src/lib/widgets/status-progress/status-progress.ts +104 -0
  225. package/src/lib/widgets/widget-host/widget-host.spec.ts +179 -0
  226. package/src/lib/widgets/widget-host/widget-host.ts +99 -0
  227. package/src/public-api.ts +104 -0
  228. package/tinya-code-gas-admin-ui-0.2.0-alpha.15.tgz +0 -0
  229. package/tsconfig.lib.json +13 -0
  230. package/tsconfig.lib.prod.json +11 -0
  231. package/tsconfig.spec.json +10 -0
  232. package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs +0 -84
  233. package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs.map +0 -1
  234. package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs +0 -140
  235. package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs.map +0 -1
  236. package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs +0 -113
  237. package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs.map +0 -1
  238. package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs +0 -163
  239. package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs.map +0 -1
  240. package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs +0 -1027
  241. package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs.map +0 -1
  242. package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs +0 -278
  243. package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs.map +0 -1
  244. package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs +0 -107
  245. package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs.map +0 -1
  246. package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs +0 -101
  247. package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs.map +0 -1
  248. package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs +0 -141
  249. package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs.map +0 -1
  250. package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs +0 -88
  251. package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs.map +0 -1
  252. package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs +0 -107
  253. package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs.map +0 -1
  254. package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs +0 -140
  255. package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs.map +0 -1
  256. package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs +0 -119
  257. package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs.map +0 -1
  258. package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs +0 -125
  259. package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs.map +0 -1
  260. package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs +0 -152
  261. package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs.map +0 -1
  262. package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs +0 -211
  263. package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs.map +0 -1
  264. package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs +0 -116
  265. package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs.map +0 -1
  266. package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs +0 -111
  267. package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs.map +0 -1
  268. package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs +0 -122
  269. package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs.map +0 -1
  270. package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs +0 -107
  271. package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs.map +0 -1
  272. package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs +0 -109
  273. package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs.map +0 -1
  274. package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs +0 -45
  275. package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs.map +0 -1
  276. package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs +0 -50
  277. package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs.map +0 -1
  278. package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs +0 -24
  279. package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs.map +0 -1
  280. package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs +0 -27
  281. package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs.map +0 -1
  282. package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs +0 -408
  283. package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs.map +0 -1
  284. package/fesm2022/tinya-code-gas-admin-ui-form-view-C709rc57.mjs +0 -4516
  285. package/fesm2022/tinya-code-gas-admin-ui-form-view-C709rc57.mjs.map +0 -1
  286. package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs +0 -82
  287. package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs.map +0 -1
  288. package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs +0 -105
  289. package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs.map +0 -1
  290. package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs +0 -65
  291. package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs.map +0 -1
  292. package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs +0 -65
  293. package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs.map +0 -1
  294. package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs +0 -65
  295. package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs.map +0 -1
  296. package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs +0 -59
  297. package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs.map +0 -1
  298. package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs +0 -94
  299. package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs.map +0 -1
  300. package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs +0 -72
  301. package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs.map +0 -1
  302. package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs +0 -238
  303. package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs.map +0 -1
  304. package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs +0 -416
  305. package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs.map +0 -1
  306. package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs +0 -439
  307. package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs.map +0 -1
  308. package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs +0 -513
  309. package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs.map +0 -1
  310. package/fesm2022/tinya-code-gas-admin-ui-list-C8ijJHAx.mjs +0 -637
  311. package/fesm2022/tinya-code-gas-admin-ui-list-C8ijJHAx.mjs.map +0 -1
  312. package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs +0 -127
  313. package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs.map +0 -1
  314. package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs +0 -251
  315. package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs.map +0 -1
  316. package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs +0 -66
  317. package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs.map +0 -1
  318. package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs +0 -114
  319. package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs.map +0 -1
  320. package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs +0 -116
  321. package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs.map +0 -1
  322. package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs +0 -235
  323. package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs.map +0 -1
  324. package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs +0 -8
  325. package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs.map +0 -1
  326. package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs +0 -124
  327. package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs.map +0 -1
  328. package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs +0 -249
  329. package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs.map +0 -1
  330. package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs +0 -39
  331. package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs.map +0 -1
  332. package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs +0 -309
  333. package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs.map +0 -1
  334. package/fesm2022/tinya-code-gas-admin-ui-render-registry-CULkxrSt.mjs +0 -576
  335. package/fesm2022/tinya-code-gas-admin-ui-render-registry-CULkxrSt.mjs.map +0 -1
  336. package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs +0 -161
  337. package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs.map +0 -1
  338. package/fesm2022/tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs +0 -11
  339. package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs +0 -685
  340. package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs.map +0 -1
  341. package/fesm2022/tinya-code-gas-admin-ui-seed-CcCA3FdQ.mjs +0 -80
  342. package/fesm2022/tinya-code-gas-admin-ui-seed-CcCA3FdQ.mjs.map +0 -1
  343. package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs +0 -296
  344. package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs.map +0 -1
  345. package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs +0 -119
  346. package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs.map +0 -1
  347. package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs +0 -158
  348. package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs.map +0 -1
  349. package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs +0 -26
  350. package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs.map +0 -1
  351. package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs +0 -205
  352. package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs.map +0 -1
  353. package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs +0 -432
  354. package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs.map +0 -1
  355. package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs +0 -36
  356. package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs.map +0 -1
  357. package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs +0 -107
  358. package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs.map +0 -1
  359. package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs +0 -223
  360. package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs.map +0 -1
  361. package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs +0 -107
  362. package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs.map +0 -1
  363. package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs +0 -60
  364. package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs.map +0 -1
  365. package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs +0 -141
  366. package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs.map +0 -1
  367. package/fesm2022/tinya-code-gas-admin-ui.mjs +0 -4599
  368. package/fesm2022/tinya-code-gas-admin-ui.mjs.map +0 -1
  369. package/types/tinya-code-gas-admin-ui.d.ts +0 -3632
@@ -0,0 +1,371 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { inject, Injector, Service } from '@angular/core';
3
+ import { map, Observable, tap, throwError } from 'rxjs';
4
+
5
+ import { renewedTokenOf } from '../models/api.model';
6
+ import type { PageResult } from '../models/api.model';
7
+ import type { CustomEndpointDefinition, ResourceEndpoints, ResourceSchema, ResponseUnwrap } from '../models/schema.model';
8
+ import { extractPagination, unwrapResponse } from '../utils/response-unwrapper';
9
+ import { DEFAULT_RESPONSE_UNWRAP, API_DRIVER, API_URL, FIREBASE_AUTH_ADAPTER, VALUE_SOURCES } from '../tokens';
10
+ import type { ValueSources } from '../tokens';
11
+ import { resolveEndpointPath } from '../utils/context-resolver';
12
+ import { sendGas, sendRest, type EnvelopeMethod, type TransportDeps } from './transport';
13
+ import { ConfigService } from './config.service';
14
+ import { AuthService } from './auth.service';
15
+
16
+ export type { EnvelopeMethod } from './transport';
17
+
18
+ /**
19
+ * CRUD genérico sobre el contrato v2 (baseapi §2.3) con soporte dual-driver:
20
+ *
21
+ * - **`gas` (default)**: TODA llamada a la API es un `POST` a `API_URL` con cuerpo
22
+ * `text/plain` y el JSON `{ token, method, path, payload }`.
23
+ * - **`rest`**: Verbos HTTP reales (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`) hacia
24
+ * `${API_URL}${path}` con `Authorization: Bearer ${token}`. `payload` va como query
25
+ * params en GET/DELETE (aplanando objetos anidados como `params`) o como body JSON
26
+ * en POST/PUT/PATCH.
27
+ */
28
+ @Service()
29
+ export class ApiService {
30
+ private readonly http = inject(HttpClient);
31
+ private readonly apiUrl = inject(API_URL);
32
+ private readonly auth = inject(AuthService);
33
+ private readonly driver = inject(API_DRIVER, { optional: true }) ?? 'gas';
34
+ /** Fuentes que aporta el consumidor (`provideGasAdmin({ valueSources })`). */
35
+ private readonly valueSources: ValueSources = inject(VALUE_SOURCES, { optional: true }) ?? {};
36
+ /** Adaptador opcional de Firebase Auth para refrescar el ID token antes de peticiones REST. */
37
+ private readonly firebaseAuthAdapter = inject(FIREBASE_AUTH_ADAPTER, { optional: true });
38
+ /**
39
+ * Acceso PEREZOSO a `ConfigService` (R2 · plan doc/context-sources-plan.md).
40
+ *
41
+ * `config` es fuente construida del motor, pero inyectarla en el constructor
42
+ * formaría un ciclo: `ConfigService` inyecta `ApiService` (opcional) para
43
+ * cargar los singletons ⇒ NG0200 en el arranque. Se pide en el momento de la
44
+ * petición, cuando ambos servicios ya están vivos. Si no existe (TestBed
45
+ * parcial), devuelve `null` y el resolver falla ruidoso con «sin valor».
46
+ */
47
+ private readonly injector = inject(Injector);
48
+ /** Unwrap global por defecto (`GasAdminConfig.defaultResponseUnwrap`); opcional. */
49
+ private readonly defaultUnwrap: ResponseUnwrap | undefined = inject(
50
+ DEFAULT_RESPONSE_UNWRAP,
51
+ { optional: true },
52
+ ) ?? undefined;
53
+
54
+ /**
55
+ * Declaración de unwrap EFECTIVA para un endpoint: fusión del default
56
+ * global con la declaración por recurso (recurso gana en las claves que
57
+ * declara). Sin ninguna de las dos ⇒ `undefined` (comportamiento actual).
58
+ */
59
+ private effectiveUnwrap(endpoint: ResourceEndpoints): ResponseUnwrap | undefined {
60
+ const global = this.defaultUnwrap;
61
+ const local = endpoint.responseUnwrap;
62
+ if (!global) return local;
63
+ if (!local) return global;
64
+ return { ...global, ...local };
65
+ }
66
+
67
+ /**
68
+ * Listado. El backend envuelve la respuesta cuando la operación declara
69
+ * `shape.envelope: 'list'` (F5) ⇒ `{ items, nextCursor, total }` (R6.4);
70
+ * la UI consume `T[]` en todos lados (F7-3) y este es el ÚNICO punto que
71
+ * habla de listas, así que el desenvolvimiento vive acá. `nextCursor` es
72
+ * el token de la página siguiente y `null` en la última — éste servicio
73
+ * lo descarta hoy porque la lista no pagina todavía (backlog-ui-ux).
74
+ * Un listado sin envelope (arreglo plano, el contrato histórico) pasa
75
+ * tal cual.
76
+ *
77
+ * `payload` sólo lo usa una fuente declarada (F8 · R6.5): `{ view, params }`
78
+ * pide el listado filtrado por una vista y sus parámetros. Sin él, la
79
+ * llamada es la de siempre — la lectura llana del recurso.
80
+ */
81
+ list<T>(endpoint: ResourceEndpoints, payload?: Record<string, unknown>): Observable<T[]> {
82
+ const unwrap = this.effectiveUnwrap(endpoint);
83
+ return this.send<unknown>(endpoint.list, 'GET', payload).pipe(
84
+ map((raw) => {
85
+ if (unwrap && (unwrap.apply === 'list' || unwrap.apply === 'all' || !unwrap.apply)) {
86
+ return unwrapResponse(raw, unwrap, 'list') as T[];
87
+ }
88
+ return unwrapList<T>(raw);
89
+ }),
90
+ );
91
+ }
92
+
93
+ /**
94
+ * Listado paginado OPT-IN (plan doc/engine-refactor-plan.md · Fase 3).
95
+ *
96
+ * Misma petición que `list()` pero devuelve `PageResult<T>` con la metadata
97
+ * de paginación que el backend envía en el sobre (`{ items, nextCursor,
98
+ * total }` o dentro de `meta` con unwrap declarado). Las claves se leen
99
+ * según `responseUnwrap.pagination` (cursorKey/totalKey/hasMoreKey) o se
100
+ * auto-detectan (`nextCursor`, `total`, `hasMore`).
101
+ *
102
+ * `payload` acepta normalmente `{ cursor, limit }` para pedir la página
103
+ * siguiente; viaja como cualquier otro payload (query params en GET REST,
104
+ * campo `payload` del envelope en GAS). `list()` no cambia: sigue
105
+ * devolviendo `T[]` (R11).
106
+ */
107
+ listPage<T>(
108
+ endpoint: ResourceEndpoints,
109
+ payload?: Record<string, unknown>,
110
+ ): Observable<PageResult<T>> {
111
+ const unwrap = this.effectiveUnwrap(endpoint);
112
+ const applies = !unwrap || unwrap.apply === 'list' || unwrap.apply === 'all' || !unwrap.apply;
113
+ return this.send<unknown>(endpoint.list, 'GET', payload).pipe(
114
+ map((raw) => {
115
+ const items =
116
+ unwrap && applies
117
+ ? (unwrapResponse(raw, unwrap, 'list') as T[])
118
+ : unwrapList<T>(raw);
119
+ return { items, ...extractPagination(raw, unwrap) };
120
+ }),
121
+ );
122
+ }
123
+
124
+ /** `key` solo aplica a colecciones (`{key}` en la plantilla); los singleton no la llevan. */
125
+ get<T>(endpoint: ResourceEndpoints, key?: string): Observable<T> { const unwrap = this.effectiveUnwrap(endpoint);
126
+ return this.send<unknown>(this.withKey(endpoint.get, key), 'GET').pipe(
127
+ map((raw) => {
128
+ if (unwrap && (unwrap.apply === 'get' || unwrap.apply === 'all' || !unwrap.apply)) {
129
+ return unwrapResponse(raw, unwrap, 'get') as T;
130
+ }
131
+ return raw as T;
132
+ }),
133
+ );
134
+ }
135
+
136
+ create<T>(endpoint: ResourceEndpoints, payload: Record<string, unknown>): Observable<T> {
137
+ const unwrap = this.effectiveUnwrap(endpoint);
138
+ return this.send<unknown>(endpoint.create, 'POST', payload).pipe(
139
+ map((raw) => {
140
+ if (unwrap && (unwrap.apply === 'create' || unwrap.apply === 'all' || !unwrap.apply)) {
141
+ return unwrapResponse(raw, unwrap, 'create') as T;
142
+ }
143
+ return raw as T;
144
+ }),
145
+ );
146
+ }
147
+
148
+ update<T>(
149
+ endpoint: ResourceEndpoints,
150
+ key: string | undefined,
151
+ payload: Record<string, unknown>,
152
+ ): Observable<T> {
153
+ const unwrap = this.effectiveUnwrap(endpoint);
154
+ return this.send<unknown>(this.withKey(endpoint.update, key), 'PUT', payload).pipe(
155
+ map((raw) => {
156
+ if (unwrap && (unwrap.apply === 'update' || unwrap.apply === 'all' || !unwrap.apply)) {
157
+ return unwrapResponse(raw, unwrap, 'update') as T;
158
+ }
159
+ return raw as T;
160
+ }),
161
+ );
162
+ }
163
+
164
+ remove(endpoint: ResourceEndpoints, key?: string): Observable<void> {
165
+ const unwrap = endpoint.responseUnwrap;
166
+ return this.send<unknown>(this.withKey(endpoint.remove, key), 'DELETE').pipe(
167
+ map(() => void 0),
168
+ );
169
+ }
170
+
171
+ /**
172
+ * Operación genérica sobre una ruta ya resuelta: reorder de colección
173
+ * (`PUT /admin/x` con `{ reorder: … }`), `/admin/schema`,
174
+ * `/admin/upload-signature`, etc.
175
+ */
176
+ request<T>(
177
+ method: EnvelopeMethod,
178
+ path: string | undefined,
179
+ payload?: Record<string, unknown>,
180
+ ): Observable<T> {
181
+ const dataKey = this.defaultUnwrap?.dataKey ?? 'data';
182
+ return this.send<T>(path, method, payload).pipe(
183
+ map((raw: unknown) => {
184
+ // Desenvolvimiento passthrough (como el interceptor viejo): sólo si la
185
+ // respuesta trae la clave `data`, se desenvuelve; si no, pasa tal cual.
186
+ // Evita romper endpoints que no envuelven (ej. upload-signature).
187
+ if (raw !== null && typeof raw === 'object' && !Array.isArray(raw)) {
188
+ const rec = raw as Record<string, unknown>;
189
+ if (Object.prototype.hasOwnProperty.call(rec, dataKey)) {
190
+ return rec[dataKey] as T;
191
+ }
192
+ }
193
+ return raw as T;
194
+ }),
195
+ );
196
+ }
197
+
198
+ /**
199
+ * Invoca un endpoint personalizado declarado por el consumidor.
200
+ *
201
+ * Acepta bien la definición directa (`CustomEndpointDefinition`) o un schema
202
+ * + nombre (resuelve en `schema.customEndpoints`). El despacho respeta el
203
+ * método, la ruta, el modo de payload (json/multipart) y el unwrap propios
204
+ * de la declaración.
205
+ */
206
+ invokeCustomEndpoint<T>(
207
+ definitionOrSchema: CustomEndpointDefinition | ResourceSchema,
208
+ nameOrPayload?: string | Record<string, unknown> | FormData,
209
+ payload?: Record<string, unknown> | FormData,
210
+ key?: string,
211
+ ): Observable<T> {
212
+ let definition: CustomEndpointDefinition | undefined;
213
+ let actualPayload: Record<string, unknown> | FormData | undefined;
214
+ let actualKey: string | undefined = key;
215
+
216
+ if (isResourceSchema(definitionOrSchema)) {
217
+ const name = typeof nameOrPayload === 'string' ? nameOrPayload : undefined;
218
+ if (!name) {
219
+ throw new Error('invokeCustomEndpoint requires an endpoint name when given a schema');
220
+ }
221
+ definition = definitionOrSchema.customEndpoints?.[name];
222
+ if (!definition) {
223
+ throw new Error(`Custom endpoint '${name}' is not declared for resource '${definitionOrSchema.id}'`);
224
+ }
225
+ actualPayload = (typeof nameOrPayload === 'string' ? payload : (nameOrPayload as Record<string, unknown> | FormData | undefined)) ?? payload;
226
+ } else {
227
+ definition = definitionOrSchema;
228
+ actualPayload =
229
+ (nameOrPayload as Record<string, unknown> | FormData | undefined) ?? payload;
230
+ }
231
+
232
+ if (!definition) {
233
+ return throwError(() => new Error('Custom endpoint definition is required'));
234
+ }
235
+
236
+ const multipart = definition.payloadMode === 'multipart' || actualPayload instanceof FormData;
237
+ const path = this.withKey(definition.path, actualKey);
238
+ const method = definition.method;
239
+
240
+ const unwrap = definition.responseUnwrap;
241
+ return this.send<unknown>(path, method, actualPayload, multipart).pipe(
242
+ map((raw) => {
243
+ if (unwrap) {
244
+ return unwrapResponse(raw, unwrap, 'get') as T;
245
+ }
246
+ return raw as T;
247
+ }),
248
+ );
249
+ }
250
+
251
+ /** Alias corto de `invokeCustomEndpoint`. */
252
+ invokeCustom<T>(
253
+ schemaOrDefinition: ResourceSchema | CustomEndpointDefinition,
254
+ nameOrPayload?: string | Record<string, unknown> | FormData,
255
+ payload?: Record<string, unknown> | FormData,
256
+ key?: string,
257
+ ): Observable<T> {
258
+ return this.invokeCustomEndpoint<T>(schemaOrDefinition, nameOrPayload, payload, key);
259
+ }
260
+
261
+ /** Alias adicional por compatibilidad. */
262
+ custom<T>(
263
+ schemaOrDefinition: ResourceSchema | CustomEndpointDefinition,
264
+ nameOrPayload?: string | Record<string, unknown> | FormData,
265
+ payload?: Record<string, unknown> | FormData,
266
+ key?: string,
267
+ ): Observable<T> {
268
+ return this.invokeCustomEndpoint<T>(schemaOrDefinition, nameOrPayload, payload, key);
269
+ }
270
+
271
+ private send<T>(
272
+ path: string | undefined,
273
+ method: EnvelopeMethod,
274
+ payload?: Record<string, unknown> | FormData,
275
+ multipart = false,
276
+ ): Observable<T> {
277
+ if (!path) {
278
+ return throwError(() => new Error('Operación no disponible para este recurso'));
279
+ }
280
+
281
+ // Resolución de marcadores de contexto ANTES del despacho (plan Fase 3):
282
+ // un solo punto para todas las operaciones y para ambos drivers. Sin
283
+ // marcadores el path vuelve intacto y ninguna fuente se evalúa.
284
+ let resolvedPath: string;
285
+ try {
286
+ resolvedPath = resolveEndpointPath(path, this.buildSources());
287
+ } catch (error) {
288
+ // Fail loud por el CANAL de errores (no como throw síncrono): el
289
+ // consumidor lo trata como cualquier otro fallo de petición y JAMÁS
290
+ // sale un request con un segmento vacío o el marcador literal.
291
+ return throwError(() => error);
292
+ }
293
+
294
+ const deps = this.transportDeps();
295
+ const request$ =
296
+ this.driver === 'rest'
297
+ ? sendRest<T>(deps, resolvedPath, method, payload, multipart)
298
+ : sendGas<T>(deps, resolvedPath, method, payload, multipart);
299
+
300
+ return request$.pipe(
301
+ // Renovación deslizante (§3.2): si el back adjuntó `meta.renewedToken`
302
+ // se adopta YA, con lo que la siguiente petición ya va firmada nueva.
303
+ tap((res) => {
304
+ const renewed = renewedTokenOf(res);
305
+ if (renewed !== null) this.auth.applyRenewedToken(renewed);
306
+ }),
307
+ );
308
+ }
309
+
310
+ /**
311
+ * Dependencias del transporte (Fase 4): la fachada sólo arma este objeto y
312
+ * delega en `transport.ts`. El token de sesión y el ID token fresco se
313
+ * resuelven vía getters en el momento de la petición (R2.8 / refresh).
314
+ */
315
+ private transportDeps(): TransportDeps {
316
+ const adapter = this.firebaseAuthAdapter;
317
+ return {
318
+ http: this.http,
319
+ apiUrl: this.apiUrl,
320
+ sessionToken: () => this.auth.token(),
321
+ getIdToken: adapter?.getIdToken ? () => adapter.getIdToken!() : undefined,
322
+ };
323
+ }
324
+
325
+ /**
326
+ * Fuentes de contexto de ESTA petición: getters, no valores — se evalúan
327
+ * sólo si el path trae marcadores.
328
+ *
329
+ * Las construidas del motor (`auth`, `config`) van ÚLTIMAS: el motor es
330
+ * dueño de sus fuentes y el registro del consumidor no las pisa.
331
+ */
332
+ private buildSources(): Readonly<Record<string, () => unknown>> {
333
+ return {
334
+ ...this.valueSources,
335
+ auth: () => ({ user: this.auth.user(), token: this.auth.token() }),
336
+ config: () => this.injector.get(ConfigService, null)?.globalConfig() ?? null,
337
+ };
338
+ }
339
+
340
+ private withKey(path: string | undefined, key?: string): string | undefined {
341
+ if (!path) {
342
+ return undefined;
343
+ }
344
+ return path.includes('{key}') ? path.replace('{key}', encodeURIComponent(key ?? '')) : path;
345
+ }
346
+ }
347
+
348
+ /** Guard de forma: ¿es un `ResourceSchema` completo (endpoint + fields)? */
349
+ function isResourceSchema(value: unknown): value is ResourceSchema {
350
+ return typeof value === 'object' && value !== null && 'endpoint' in value && 'fields' in value;
351
+ }
352
+
353
+ /** `{ items, nextCursor, total }` (F5/R6.4) → `T[]`; arreglo plano → tal cual. */
354
+ function unwrapList<T>(raw: unknown): T[] {
355
+ if (Array.isArray(raw)) {
356
+ return raw as T[];
357
+ }
358
+ if (raw !== null && typeof raw === 'object') {
359
+ const items = (raw as { items?: unknown }).items;
360
+ if (Array.isArray(items)) {
361
+ return items as T[];
362
+ }
363
+ // Objeto sin clave reconocida: compat con el baseline (R9) ⇒ [].
364
+ return [];
365
+ }
366
+ // Cuerpo ni array ni objeto (null, string, número): el contrato de listado
367
+ // está roto — fallar ruidoso en vez de devolver [] silenciosamente.
368
+ throw new Error(
369
+ `List response must be an array or an object with an 'items' array; received ${raw === null ? 'null' : typeof raw}`,
370
+ );
371
+ }