@tinya-code/gas-admin-ui 0.2.0-alpha.13 → 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 (368) hide show
  1. package/ng-package.json +7 -0
  2. package/package.json +3 -15
  3. package/src/lib/actions/action-registry.spec.ts +52 -0
  4. package/src/lib/actions/action-registry.ts +126 -0
  5. package/src/lib/actions/action-service.spec.ts +215 -0
  6. package/src/lib/actions/action-service.ts +87 -0
  7. package/src/lib/actions/descriptors.spec.ts +155 -0
  8. package/src/lib/actions/descriptors.ts +154 -0
  9. package/src/lib/columns/column-cell.ts +33 -0
  10. package/src/lib/columns/column-defaults.spec.ts +99 -0
  11. package/src/lib/columns/column-defaults.ts +84 -0
  12. package/src/lib/columns/column-format.spec.ts +274 -0
  13. package/src/lib/columns/descriptors.ts +113 -0
  14. package/src/lib/columns/format-badge.ts +51 -0
  15. package/src/lib/columns/format-boolean.ts +58 -0
  16. package/src/lib/columns/format-currency.ts +30 -0
  17. package/src/lib/columns/format-date.ts +35 -0
  18. package/src/lib/columns/format-number.ts +32 -0
  19. package/src/lib/columns/format-text.ts +23 -0
  20. package/src/lib/columns/format-thumbnail.ts +63 -0
  21. package/src/lib/core/adapters/firebase-auth.adapter.ts +6 -0
  22. package/src/lib/core/guards/auth.guard.spec.ts +88 -0
  23. package/src/lib/core/guards/auth.guard.ts +48 -0
  24. package/src/lib/core/guards/unsaved-changes.guard.ts +16 -0
  25. package/src/lib/core/interceptors/api-error.interceptor.spec.ts +182 -0
  26. package/src/lib/core/interceptors/api-error.interceptor.ts +87 -0
  27. package/src/lib/core/models/api.model.ts +104 -0
  28. package/src/lib/core/models/schema-descriptions.ts +118 -0
  29. package/src/lib/core/models/schema.model.ts +1097 -0
  30. package/src/lib/core/registry/composition-validator.spec.ts +358 -0
  31. package/src/lib/core/registry/composition-validator.ts +270 -0
  32. package/src/lib/core/registry/field-validators.spec.ts +199 -0
  33. package/src/lib/core/registry/field-validators.ts +440 -0
  34. package/src/lib/core/registry/render-host.spec.ts +208 -0
  35. package/src/lib/core/registry/render-host.ts +646 -0
  36. package/src/lib/core/registry/render-registry.spec.ts +96 -0
  37. package/src/lib/core/registry/render-registry.ts +312 -0
  38. package/src/lib/core/registry/schema-catalog.ts +156 -0
  39. package/src/lib/core/services/api.service.spec.ts +1142 -0
  40. package/src/lib/core/services/api.service.ts +371 -0
  41. package/src/lib/core/services/auth.service.spec.ts +653 -0
  42. package/src/lib/core/services/auth.service.ts +503 -0
  43. package/src/lib/core/services/config.service.spec.ts +121 -0
  44. package/src/lib/core/services/config.service.ts +119 -0
  45. package/src/lib/core/services/data-source.service.spec.ts +179 -0
  46. package/src/lib/core/services/data-source.service.ts +142 -0
  47. package/src/lib/core/services/error-mapper.service.spec.ts +50 -0
  48. package/src/lib/core/services/error-mapper.service.ts +49 -0
  49. package/src/lib/core/services/notification.service.ts +73 -0
  50. package/src/lib/core/services/relation-drawer.service.ts +41 -0
  51. package/src/lib/core/services/theme.service.spec.ts +106 -0
  52. package/src/lib/core/services/theme.service.ts +86 -0
  53. package/src/lib/core/services/transport.spec.ts +198 -0
  54. package/src/lib/core/services/transport.ts +164 -0
  55. package/src/lib/core/services/upload.service.ts +81 -0
  56. package/src/lib/core/testing/categories.schema.ts +125 -0
  57. package/src/lib/core/testing/orders.schema.ts +372 -0
  58. package/src/lib/core/testing/products.schema.ts +258 -0
  59. package/src/lib/core/testing/site.schema.ts +195 -0
  60. package/src/lib/core/testing/test-catalog.ts +21 -0
  61. package/src/lib/core/tokens.ts +112 -0
  62. package/src/lib/core/utils/clipboard.spec.ts +55 -0
  63. package/src/lib/core/utils/clipboard.ts +90 -0
  64. package/src/lib/core/utils/context-resolver.spec.ts +95 -0
  65. package/src/lib/core/utils/context-resolver.ts +101 -0
  66. package/src/lib/core/utils/response-unwrapper.spec.ts +70 -0
  67. package/src/lib/core/utils/response-unwrapper.ts +103 -0
  68. package/src/lib/core/utils/source-options.spec.ts +96 -0
  69. package/src/lib/core/utils/source-options.ts +54 -0
  70. package/src/lib/core/utils/template-interpolator.spec.ts +59 -0
  71. package/src/lib/core/utils/template-interpolator.ts +56 -0
  72. package/src/lib/core/view-navigation/view-navigation.service.spec.ts +207 -0
  73. package/src/lib/core/view-navigation/view-navigation.service.ts +132 -0
  74. package/src/lib/fields/boolean/boolean.descriptor.ts +11 -0
  75. package/src/lib/fields/boolean/boolean.ts +40 -0
  76. package/src/lib/fields/color/color.descriptor.ts +12 -0
  77. package/src/lib/fields/color/color.ts +34 -0
  78. package/src/lib/fields/currency/currency.descriptor.ts +12 -0
  79. package/src/lib/fields/currency/currency.ts +67 -0
  80. package/src/lib/fields/date/date.descriptor.ts +12 -0
  81. package/src/lib/fields/date/date.ts +36 -0
  82. package/src/lib/fields/descriptors.ts +122 -0
  83. package/src/lib/fields/display/display-badge.ts +65 -0
  84. package/src/lib/fields/display/display-date.ts +39 -0
  85. package/src/lib/fields/display/display-defaults.ts +84 -0
  86. package/src/lib/fields/display/display-file.ts +41 -0
  87. package/src/lib/fields/display/display-image.ts +54 -0
  88. package/src/lib/fields/display/display-list.ts +107 -0
  89. package/src/lib/fields/display/display-number.ts +41 -0
  90. package/src/lib/fields/display/display-text.ts +42 -0
  91. package/src/lib/fields/display/display.spec.ts +242 -0
  92. package/src/lib/fields/dropdown/dropdown.descriptor.ts +12 -0
  93. package/src/lib/fields/dropdown/dropdown.ts +45 -0
  94. package/src/lib/fields/email/email.descriptor.ts +12 -0
  95. package/src/lib/fields/email/email.ts +28 -0
  96. package/src/lib/fields/field-aria.ts +60 -0
  97. package/src/lib/fields/field-host/field-host.spec.ts +118 -0
  98. package/src/lib/fields/field-host/field-host.ts +47 -0
  99. package/src/lib/fields/field-node.ts +88 -0
  100. package/src/lib/fields/file/file.descriptor.ts +14 -0
  101. package/src/lib/fields/file/file.spec.ts +134 -0
  102. package/src/lib/fields/file/file.ts +281 -0
  103. package/src/lib/fields/group/group.descriptor.ts +21 -0
  104. package/src/lib/fields/group/group.ts +110 -0
  105. package/src/lib/fields/image/image.descriptor.ts +12 -0
  106. package/src/lib/fields/image/image.spec.ts +117 -0
  107. package/src/lib/fields/image/image.ts +281 -0
  108. package/src/lib/fields/key-value/key-value.descriptor.ts +11 -0
  109. package/src/lib/fields/key-value/key-value.ts +283 -0
  110. package/src/lib/fields/list/list.descriptor.ts +21 -0
  111. package/src/lib/fields/list/list.ts +376 -0
  112. package/src/lib/fields/multiselect/multiselect.descriptor.ts +11 -0
  113. package/src/lib/fields/multiselect/multiselect.spec.ts +142 -0
  114. package/src/lib/fields/multiselect/multiselect.ts +152 -0
  115. package/src/lib/fields/number/number.descriptor.ts +12 -0
  116. package/src/lib/fields/number/number.ts +40 -0
  117. package/src/lib/fields/phone/phone.descriptor.ts +12 -0
  118. package/src/lib/fields/phone/phone.ts +46 -0
  119. package/src/lib/fields/readonly-text/readonly-text.descriptor.ts +12 -0
  120. package/src/lib/fields/readonly-text/readonly-text.ts +58 -0
  121. package/src/lib/fields/relation/relation.descriptor.ts +12 -0
  122. package/src/lib/fields/relation/relation.spec.ts +193 -0
  123. package/src/lib/fields/relation/relation.ts +224 -0
  124. package/src/lib/fields/rich-select/rich-select.descriptor.ts +12 -0
  125. package/src/lib/fields/rich-select/rich-select.ts +175 -0
  126. package/src/lib/fields/select/radio-mode.ts +25 -0
  127. package/src/lib/fields/select/select.descriptor.ts +12 -0
  128. package/src/lib/fields/select/select.spec.ts +162 -0
  129. package/src/lib/fields/select/select.ts +210 -0
  130. package/src/lib/fields/slug/slug.descriptor.ts +19 -0
  131. package/src/lib/fields/slug/slug.ts +67 -0
  132. package/src/lib/fields/string-list/string-list.descriptor.ts +11 -0
  133. package/src/lib/fields/string-list/string-list.ts +222 -0
  134. package/src/lib/fields/text/text.descriptor.ts +12 -0
  135. package/src/lib/fields/text/text.ts +35 -0
  136. package/src/lib/fields/textarea/textarea.descriptor.ts +12 -0
  137. package/src/lib/fields/textarea/textarea.spec.ts +117 -0
  138. package/src/lib/fields/textarea/textarea.ts +126 -0
  139. package/src/lib/fields/time/time.descriptor.ts +12 -0
  140. package/src/lib/fields/time/time.ts +28 -0
  141. package/src/lib/fields/unknown-render/unknown-render.ts +49 -0
  142. package/src/lib/fields/url/url.descriptor.ts +12 -0
  143. package/src/lib/fields/url/url.ts +53 -0
  144. package/src/lib/gas-admin-ui.spec.ts +21 -0
  145. package/src/lib/gas-admin-ui.ts +9 -0
  146. package/src/lib/layouts/descriptors.ts +9 -0
  147. package/src/lib/pages/dashboard/dashboard.ts +167 -0
  148. package/src/lib/pages/detail-view/detail-view.spec.ts +333 -0
  149. package/src/lib/pages/detail-view/detail-view.ts +570 -0
  150. package/src/lib/pages/drawer-form/drawer-form.ts +228 -0
  151. package/src/lib/pages/form-view/form-model.ts +88 -0
  152. package/src/lib/pages/form-view/form-schema.ts +255 -0
  153. package/src/lib/pages/form-view/form-view.ts +1622 -0
  154. package/src/lib/pages/list-view/list-view.formats.spec.ts +214 -0
  155. package/src/lib/pages/list-view/list-view.ts +882 -0
  156. package/src/lib/pages/login/login.spec.ts +109 -0
  157. package/src/lib/pages/login/login.ts +227 -0
  158. package/src/lib/pages/resource-page/resource-page.ts +234 -0
  159. package/src/lib/shared/components/badge/badge.ts +35 -0
  160. package/src/lib/shared/components/button/button.ts +65 -0
  161. package/src/lib/shared/components/confirm-dialog/confirm-dialog.ts +48 -0
  162. package/src/lib/shared/components/copy-button/copy-button.ts +56 -0
  163. package/src/lib/shared/components/copy-share/copy-share.spec.ts +122 -0
  164. package/src/lib/shared/components/copy-share/copy-share.ts +107 -0
  165. package/src/lib/shared/components/drawer/drawer.spec.ts +127 -0
  166. package/src/lib/shared/components/drawer/drawer.ts +172 -0
  167. package/src/lib/shared/components/empty-state/empty-state.ts +30 -0
  168. package/src/lib/shared/components/modal/modal.spec.ts +149 -0
  169. package/src/lib/shared/components/modal/modal.ts +145 -0
  170. package/src/lib/shared/components/post-create-modal/post-create-modal.spec.ts +165 -0
  171. package/src/lib/shared/components/post-create-modal/post-create-modal.ts +159 -0
  172. package/src/lib/shared/components/skeleton/skeleton.ts +31 -0
  173. package/src/lib/shared/components/toast/toast.ts +58 -0
  174. package/src/lib/shared/utils/col-span.ts +25 -0
  175. package/src/lib/shared/utils/condition-evaluator.ts +53 -0
  176. package/src/lib/shared/utils/depends-on.ts +48 -0
  177. package/src/lib/shared/utils/dialog-focus.ts +28 -0
  178. package/src/lib/shared/utils/field-path.ts +49 -0
  179. package/src/lib/shared/utils/gap-sorting.ts +144 -0
  180. package/src/lib/shared/utils/seed.spec.ts +64 -0
  181. package/src/lib/shared/utils/seed.ts +149 -0
  182. package/src/lib/shared/utils/slugify.ts +13 -0
  183. package/src/lib/shared/utils/validators.ts +41 -0
  184. package/src/lib/shell/layout/layout.ts +63 -0
  185. package/src/lib/shell/shell.routes.spec.ts +59 -0
  186. package/src/lib/shell/shell.routes.ts +122 -0
  187. package/src/lib/shell/sidebar/sidebar.ts +139 -0
  188. package/src/lib/shell/theme-toggle/theme-toggle.ts +74 -0
  189. package/src/lib/views/calendar-view/calendar-model.ts +426 -0
  190. package/src/lib/views/calendar-view/calendar-view.spec.ts +557 -0
  191. package/src/lib/views/calendar-view/calendar-view.ts +568 -0
  192. package/src/lib/views/composer/composer-host.spec.ts +301 -0
  193. package/src/lib/views/composer/composer-host.ts +248 -0
  194. package/src/lib/views/composer/composer-imports.spec.ts +54 -0
  195. package/src/lib/views/composer/view-context.spec.ts +117 -0
  196. package/src/lib/views/composer/view-context.ts +109 -0
  197. package/src/lib/views/composer/view-slot.spec.ts +130 -0
  198. package/src/lib/views/composer/view-slot.ts +178 -0
  199. package/src/lib/views/descriptors.ts +46 -0
  200. package/src/lib/views/kanban-view/kanban-model.ts +173 -0
  201. package/src/lib/views/kanban-view/kanban-view.spec.ts +540 -0
  202. package/src/lib/views/kanban-view/kanban-view.ts +327 -0
  203. package/src/lib/widgets/bar-chart/bar-chart.descriptor.ts +17 -0
  204. package/src/lib/widgets/bar-chart/bar-chart.spec.ts +66 -0
  205. package/src/lib/widgets/bar-chart/bar-chart.ts +76 -0
  206. package/src/lib/widgets/chart-line/chart-line.descriptor.ts +17 -0
  207. package/src/lib/widgets/chart-line/chart-line.spec.ts +113 -0
  208. package/src/lib/widgets/chart-line/chart-line.ts +219 -0
  209. package/src/lib/widgets/descriptors.ts +29 -0
  210. package/src/lib/widgets/metric-card/metric-card.descriptor.ts +41 -0
  211. package/src/lib/widgets/metric-card/metric-card.spec.ts +52 -0
  212. package/src/lib/widgets/metric-card/metric-card.ts +48 -0
  213. package/src/lib/widgets/quick-actions/quick-actions.descriptor.ts +13 -0
  214. package/src/lib/widgets/quick-actions/quick-actions.spec.ts +61 -0
  215. package/src/lib/widgets/quick-actions/quick-actions.ts +100 -0
  216. package/src/lib/widgets/record-list/record-list.descriptor.ts +16 -0
  217. package/src/lib/widgets/record-list/record-list.spec.ts +79 -0
  218. package/src/lib/widgets/record-list/record-list.ts +115 -0
  219. package/src/lib/widgets/series.spec.ts +42 -0
  220. package/src/lib/widgets/series.ts +56 -0
  221. package/src/lib/widgets/status-progress/status-progress.descriptor.ts +19 -0
  222. package/src/lib/widgets/status-progress/status-progress.spec.ts +63 -0
  223. package/src/lib/widgets/status-progress/status-progress.ts +104 -0
  224. package/src/lib/widgets/widget-host/widget-host.spec.ts +179 -0
  225. package/src/lib/widgets/widget-host/widget-host.ts +99 -0
  226. package/src/public-api.ts +104 -0
  227. package/tinya-code-gas-admin-ui-0.2.0-alpha.15.tgz +0 -0
  228. package/tsconfig.lib.json +13 -0
  229. package/tsconfig.lib.prod.json +11 -0
  230. package/tsconfig.spec.json +10 -0
  231. package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs +0 -84
  232. package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs.map +0 -1
  233. package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs +0 -140
  234. package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs.map +0 -1
  235. package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs +0 -113
  236. package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs.map +0 -1
  237. package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs +0 -163
  238. package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs.map +0 -1
  239. package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs +0 -1027
  240. package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs.map +0 -1
  241. package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs +0 -278
  242. package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs.map +0 -1
  243. package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs +0 -107
  244. package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs.map +0 -1
  245. package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs +0 -101
  246. package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs.map +0 -1
  247. package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs +0 -141
  248. package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs.map +0 -1
  249. package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs +0 -88
  250. package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs.map +0 -1
  251. package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs +0 -107
  252. package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs.map +0 -1
  253. package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs +0 -140
  254. package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs.map +0 -1
  255. package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs +0 -119
  256. package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs.map +0 -1
  257. package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs +0 -125
  258. package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs.map +0 -1
  259. package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs +0 -152
  260. package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs.map +0 -1
  261. package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs +0 -211
  262. package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs.map +0 -1
  263. package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs +0 -116
  264. package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs.map +0 -1
  265. package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs +0 -111
  266. package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs.map +0 -1
  267. package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs +0 -122
  268. package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs.map +0 -1
  269. package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs +0 -107
  270. package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs.map +0 -1
  271. package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs +0 -109
  272. package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs.map +0 -1
  273. package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs +0 -45
  274. package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs.map +0 -1
  275. package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs +0 -50
  276. package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs.map +0 -1
  277. package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs +0 -24
  278. package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs.map +0 -1
  279. package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs +0 -27
  280. package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs.map +0 -1
  281. package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs +0 -408
  282. package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs.map +0 -1
  283. package/fesm2022/tinya-code-gas-admin-ui-form-view-C709rc57.mjs +0 -4516
  284. package/fesm2022/tinya-code-gas-admin-ui-form-view-C709rc57.mjs.map +0 -1
  285. package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs +0 -82
  286. package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs.map +0 -1
  287. package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs +0 -105
  288. package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs.map +0 -1
  289. package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs +0 -65
  290. package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs.map +0 -1
  291. package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs +0 -65
  292. package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs.map +0 -1
  293. package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs +0 -65
  294. package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs.map +0 -1
  295. package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs +0 -59
  296. package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs.map +0 -1
  297. package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs +0 -94
  298. package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs.map +0 -1
  299. package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs +0 -72
  300. package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs.map +0 -1
  301. package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs +0 -238
  302. package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs.map +0 -1
  303. package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs +0 -416
  304. package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs.map +0 -1
  305. package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs +0 -439
  306. package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs.map +0 -1
  307. package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs +0 -513
  308. package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs.map +0 -1
  309. package/fesm2022/tinya-code-gas-admin-ui-list-C8ijJHAx.mjs +0 -637
  310. package/fesm2022/tinya-code-gas-admin-ui-list-C8ijJHAx.mjs.map +0 -1
  311. package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs +0 -127
  312. package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs.map +0 -1
  313. package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs +0 -251
  314. package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs.map +0 -1
  315. package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs +0 -66
  316. package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs.map +0 -1
  317. package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs +0 -114
  318. package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs.map +0 -1
  319. package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs +0 -116
  320. package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs.map +0 -1
  321. package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs +0 -235
  322. package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs.map +0 -1
  323. package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs +0 -8
  324. package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs.map +0 -1
  325. package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs +0 -124
  326. package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs.map +0 -1
  327. package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs +0 -249
  328. package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs.map +0 -1
  329. package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs +0 -39
  330. package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs.map +0 -1
  331. package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs +0 -309
  332. package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs.map +0 -1
  333. package/fesm2022/tinya-code-gas-admin-ui-render-registry-CULkxrSt.mjs +0 -576
  334. package/fesm2022/tinya-code-gas-admin-ui-render-registry-CULkxrSt.mjs.map +0 -1
  335. package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs +0 -161
  336. package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs.map +0 -1
  337. package/fesm2022/tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs +0 -11
  338. package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs +0 -685
  339. package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs.map +0 -1
  340. package/fesm2022/tinya-code-gas-admin-ui-seed-CcCA3FdQ.mjs +0 -80
  341. package/fesm2022/tinya-code-gas-admin-ui-seed-CcCA3FdQ.mjs.map +0 -1
  342. package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs +0 -296
  343. package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs.map +0 -1
  344. package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs +0 -119
  345. package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs.map +0 -1
  346. package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs +0 -158
  347. package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs.map +0 -1
  348. package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs +0 -26
  349. package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs.map +0 -1
  350. package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs +0 -205
  351. package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs.map +0 -1
  352. package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs +0 -432
  353. package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs.map +0 -1
  354. package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs +0 -36
  355. package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs.map +0 -1
  356. package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs +0 -107
  357. package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs.map +0 -1
  358. package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs +0 -223
  359. package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs.map +0 -1
  360. package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs +0 -107
  361. package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs.map +0 -1
  362. package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs +0 -60
  363. package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs.map +0 -1
  364. package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs +0 -141
  365. package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs.map +0 -1
  366. package/fesm2022/tinya-code-gas-admin-ui.mjs +0 -4599
  367. package/fesm2022/tinya-code-gas-admin-ui.mjs.map +0 -1
  368. 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
+ }