@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,258 @@
1
+ import type { ResourceSchema } from '../models/schema.model';
2
+
3
+ /**
4
+ * Colección con pestañas — base.md §11, api.md §3.2–§3.5.
5
+ * Imágenes, specs y FAQ viven en hojas hijas; la API los ensambla.
6
+ */
7
+ export const productsSchema: ResourceSchema = {
8
+ id: 'products',
9
+ label: 'Producto',
10
+ labelPlural: 'Productos',
11
+ kind: 'collection',
12
+ uiViews: {
13
+ list: { type: 'list' },
14
+ create: { type: 'form', path: 'new' },
15
+ edit: { type: 'form', path: ':key/edit' },
16
+ },
17
+ endpoint: {
18
+ list: '/admin/products',
19
+ get: '/admin/products/{key}',
20
+ create: '/admin/products',
21
+ update: '/admin/products/{key}',
22
+ remove: '/admin/products/{key}',
23
+ },
24
+ keyField: 'slug',
25
+ titleField: 'name',
26
+ search: ['name', 'sku'],
27
+ filters: [
28
+ {
29
+ key: 'availability',
30
+ label: 'Disponibilidad',
31
+ type: 'select',
32
+ options: [
33
+ { value: 'InStock', label: 'En stock' },
34
+ { value: 'PreOrder', label: 'Preventa' },
35
+ { value: 'OutOfStock', label: 'Agotado' },
36
+ ],
37
+ },
38
+ { key: 'active', label: 'Activo', type: 'boolean' },
39
+ ],
40
+ listColumns: [
41
+ { key: 'images', label: 'Imagen', format: 'thumbnail' },
42
+ { key: 'name', label: 'Nombre' },
43
+ { key: 'category_slug', label: 'Categoría' },
44
+ { key: 'price', label: 'Precio', format: 'currency' },
45
+ { key: 'availability', label: 'Disponibilidad' },
46
+ { key: 'registro_sanitario', label: 'Sanitario', format: 'badge' },
47
+ { key: 'active', label: 'Activo', format: 'boolean' },
48
+ ],
49
+ layout: {
50
+ mode: 'tabs',
51
+ sections: [
52
+ { id: 'general', label: 'General' },
53
+ { id: 'contenido', label: 'Contenido' },
54
+ { id: 'imagenes', label: 'Imágenes' },
55
+ { id: 'sanitario', label: 'Sanitario' },
56
+ { id: 'ficha', label: 'Ficha técnica' },
57
+ { id: 'faq', label: 'FAQ' },
58
+ ],
59
+ },
60
+ fields: [
61
+ // ── General ──
62
+ {
63
+ type: 'text',
64
+ key: 'name',
65
+ label: 'Nombre',
66
+ required: true,
67
+ section: 'general',
68
+ width: 6,
69
+ },
70
+ {
71
+ type: 'slug',
72
+ key: 'slug',
73
+ label: 'Slug',
74
+ from: 'name',
75
+ lockAfterCreate: true,
76
+ required: true,
77
+ validators: { unique: true },
78
+ help: 'Inmutable tras publicar.',
79
+ section: 'general',
80
+ width: 6,
81
+ },
82
+ {
83
+ type: 'relation',
84
+ key: 'category_slug',
85
+ label: 'Categoría',
86
+ required: true,
87
+ // F8 · R6.5 (D62): UN objeto `source` para todas las fuentes.
88
+ source: { resource: 'categories', valueField: 'slug', labelField: 'name' },
89
+ onlyActive: true,
90
+ section: 'general',
91
+ width: 6,
92
+ },
93
+ {
94
+ type: 'text',
95
+ key: 'sku',
96
+ label: 'SKU',
97
+ required: true,
98
+ validators: { unique: true },
99
+ section: 'general',
100
+ width: 6,
101
+ },
102
+ {
103
+ type: 'text',
104
+ key: 'brand',
105
+ label: 'Marca',
106
+ section: 'general',
107
+ width: 6,
108
+ },
109
+ {
110
+ type: 'currency',
111
+ key: 'price',
112
+ label: 'Precio',
113
+ required: true,
114
+ section: 'general',
115
+ width: 6,
116
+ },
117
+ {
118
+ type: 'select',
119
+ key: 'availability',
120
+ label: 'Disponibilidad',
121
+ required: true,
122
+ options: [
123
+ { value: 'InStock', label: 'En stock' },
124
+ { value: 'PreOrder', label: 'Preventa' },
125
+ { value: 'OutOfStock', label: 'Agotado' },
126
+ ],
127
+ section: 'general',
128
+ width: 6,
129
+ },
130
+ {
131
+ type: 'boolean',
132
+ key: 'featured',
133
+ label: 'Destacado',
134
+ required: true,
135
+ default: false,
136
+ trueLabel: 'Sí',
137
+ falseLabel: 'No',
138
+ section: 'general',
139
+ width: 6,
140
+ },
141
+ {
142
+ type: 'boolean',
143
+ key: 'active',
144
+ label: 'Activo',
145
+ required: true,
146
+ default: true,
147
+ trueLabel: 'Activo',
148
+ falseLabel: 'Inactivo',
149
+ section: 'general',
150
+ width: 6,
151
+ },
152
+ // ── Contenido ──
153
+ {
154
+ type: 'textarea',
155
+ key: 'description',
156
+ label: 'Descripción',
157
+ required: true,
158
+ rows: 8,
159
+ help: 'Entre 100 y 2000 caracteres.',
160
+ validators: { minLength: 100, maxLength: 2000 },
161
+ section: 'contenido',
162
+ width: 12,
163
+ },
164
+ {
165
+ type: 'text',
166
+ key: 'seo_title',
167
+ label: 'Título SEO',
168
+ section: 'contenido',
169
+ width: 12,
170
+ },
171
+ {
172
+ type: 'textarea',
173
+ key: 'seo_description',
174
+ label: 'Descripción SEO',
175
+ required: true,
176
+ rows: 3,
177
+ section: 'contenido',
178
+ width: 12,
179
+ },
180
+ // ── Imágenes (mín 1; la primera es la principal) ──
181
+ {
182
+ type: 'list',
183
+ key: 'images',
184
+ label: 'Imágenes',
185
+ required: true,
186
+ min: 1,
187
+ primaryFirst: true,
188
+ positionField: 'position',
189
+ addLabel: 'Agregar imagen',
190
+ emptyText: 'Sin imágenes. La primera será la imagen principal.',
191
+ itemDisplay: 'card',
192
+ itemTitle: 'image_alt',
193
+ itemFields: [
194
+ { type: 'image', key: 'image_url', label: 'Imagen', required: true },
195
+ { type: 'text', key: 'image_alt', label: 'Texto alternativo', required: true },
196
+ ],
197
+ section: 'imagenes',
198
+ width: 12,
199
+ },
200
+ // ── Sanitario ──
201
+ {
202
+ type: 'text',
203
+ key: 'registro_sanitario',
204
+ label: 'Registro sanitario',
205
+ help: 'Sin esto el producto no se publica.',
206
+ section: 'sanitario',
207
+ width: 4,
208
+ },
209
+ {
210
+ type: 'select',
211
+ key: 'clase_riesgo',
212
+ label: 'Clase de riesgo',
213
+ options: [
214
+ { value: 'I', label: 'I' },
215
+ { value: 'IIa', label: 'IIa' },
216
+ { value: 'IIb', label: 'IIb' },
217
+ { value: 'III', label: 'III' },
218
+ ],
219
+ section: 'sanitario',
220
+ width: 4,
221
+ },
222
+ {
223
+ type: 'text',
224
+ key: 'titular_registro',
225
+ label: 'Titular del registro',
226
+ section: 'sanitario',
227
+ width: 4,
228
+ },
229
+ // ── Ficha técnica ──
230
+ {
231
+ type: 'key-value',
232
+ key: 'specs',
233
+ label: 'Especificaciones',
234
+ positionField: 'position',
235
+ addLabel: 'Agregar especificación',
236
+ emptyText: 'Sin especificaciones.',
237
+ section: 'ficha',
238
+ width: 12,
239
+ },
240
+ // ── FAQ ──
241
+ {
242
+ type: 'list',
243
+ key: 'faq',
244
+ label: 'Preguntas frecuentes',
245
+ positionField: 'position',
246
+ addLabel: 'Agregar pregunta',
247
+ emptyText: 'Sin preguntas frecuentes.',
248
+ itemDisplay: 'card',
249
+ itemTitle: 'question',
250
+ itemFields: [
251
+ { type: 'text', key: 'question', label: 'Pregunta', required: true },
252
+ { type: 'textarea', key: 'answer', label: 'Respuesta', required: true, rows: 4 },
253
+ ],
254
+ section: 'faq',
255
+ width: 12,
256
+ },
257
+ ],
258
+ };
@@ -0,0 +1,195 @@
1
+ import type { ResourceSchema } from '../models/schema.model';
2
+
3
+ /**
4
+ * Singleton de configuración del sitio — base.md §11, api.md §3.6–§3.8.
5
+ * La API aplana `address_street` etc. a objetos anidados al responder.
6
+ */
7
+ export const siteSchema: ResourceSchema = {
8
+ id: 'site',
9
+ label: 'Sitio',
10
+ labelPlural: 'Sitio',
11
+ kind: 'singleton',
12
+ uiViews: {
13
+ settings: { type: 'form' },
14
+ },
15
+ endpoint: {
16
+ get: '/admin/site',
17
+ update: '/admin/site',
18
+ },
19
+ // Los singleton no tienen clave de registro; `get`/`update` no la usan.
20
+ keyField: 'key',
21
+ titleField: 'name',
22
+ // Sin listado: `listColumns` queda vacío por tipo.
23
+ listColumns: [],
24
+ layout: {
25
+ mode: 'sections',
26
+ sections: [
27
+ { id: 'negocio', label: 'Negocio' },
28
+ { id: 'contacto', label: 'Contacto' },
29
+ { id: 'direccion', label: 'Dirección' },
30
+ { id: 'horarios', label: 'Horarios' },
31
+ { id: 'redes', label: 'Redes' },
32
+ ],
33
+ },
34
+ fields: [
35
+ // ── Negocio ──
36
+ {
37
+ type: 'text',
38
+ key: 'name',
39
+ label: 'Nombre del negocio',
40
+ required: true,
41
+ section: 'negocio',
42
+ width: 6,
43
+ },
44
+ {
45
+ type: 'url',
46
+ key: 'url',
47
+ label: 'Sitio web',
48
+ required: true,
49
+ section: 'negocio',
50
+ width: 6,
51
+ },
52
+ {
53
+ type: 'textarea',
54
+ key: 'description',
55
+ label: 'Descripción',
56
+ required: true,
57
+ rows: 4,
58
+ section: 'negocio',
59
+ width: 12,
60
+ },
61
+ {
62
+ type: 'text',
63
+ key: 'currency',
64
+ label: 'Moneda',
65
+ required: true,
66
+ default: 'PEN',
67
+ help: 'Código ISO 4217 (ej. PEN).',
68
+ validators: { pattern: '^[A-Z]{3}$' },
69
+ section: 'negocio',
70
+ width: 6,
71
+ },
72
+ // ── Contacto ──
73
+ {
74
+ type: 'phone',
75
+ key: 'phone',
76
+ label: 'Teléfono',
77
+ required: true,
78
+ format: 'e164',
79
+ section: 'contacto',
80
+ width: 6,
81
+ },
82
+ {
83
+ type: 'phone',
84
+ key: 'whatsapp',
85
+ label: 'WhatsApp',
86
+ required: true,
87
+ format: 'digits',
88
+ help: 'Solo dígitos, sin +.',
89
+ section: 'contacto',
90
+ width: 6,
91
+ },
92
+ {
93
+ type: 'email',
94
+ key: 'email',
95
+ label: 'Correo',
96
+ required: true,
97
+ section: 'contacto',
98
+ width: 6,
99
+ },
100
+ // ── Dirección (grupos address y geo) ──
101
+ {
102
+ type: 'group',
103
+ key: 'address',
104
+ label: 'Dirección',
105
+ required: true,
106
+ display: 'card',
107
+ section: 'direccion',
108
+ width: 12,
109
+ fields: [
110
+ { type: 'text', key: 'street', label: 'Calle', required: true },
111
+ { type: 'text', key: 'city', label: 'Ciudad', required: true },
112
+ { type: 'text', key: 'region', label: 'Región', required: true },
113
+ { type: 'text', key: 'postal_code', label: 'Código postal', required: true },
114
+ {
115
+ type: 'text',
116
+ key: 'country',
117
+ label: 'País',
118
+ required: true,
119
+ help: 'ISO alpha-2 (ej. PE).',
120
+ validators: { pattern: '^[A-Z]{2}$' },
121
+ },
122
+ ],
123
+ },
124
+ {
125
+ type: 'group',
126
+ key: 'geo',
127
+ label: 'Coordenadas',
128
+ required: true,
129
+ display: 'card',
130
+ section: 'direccion',
131
+ width: 12,
132
+ fields: [
133
+ {
134
+ type: 'number',
135
+ key: 'lat',
136
+ label: 'Latitud',
137
+ required: true,
138
+ min: -90,
139
+ max: 90,
140
+ decimals: 6,
141
+ },
142
+ {
143
+ type: 'number',
144
+ key: 'lng',
145
+ label: 'Longitud',
146
+ required: true,
147
+ min: -180,
148
+ max: 180,
149
+ decimals: 6,
150
+ },
151
+ ],
152
+ },
153
+ // ── Horarios ──
154
+ {
155
+ type: 'list',
156
+ key: 'hours',
157
+ label: 'Horarios',
158
+ positionField: 'position',
159
+ addLabel: 'Agregar tramo',
160
+ emptyText: 'Sin horarios definidos.',
161
+ itemFields: [
162
+ {
163
+ type: 'multiselect',
164
+ key: 'days',
165
+ label: 'Días',
166
+ required: true,
167
+ options: [
168
+ { value: 'mon', label: 'Lunes' },
169
+ { value: 'tue', label: 'Martes' },
170
+ { value: 'wed', label: 'Miércoles' },
171
+ { value: 'thu', label: 'Jueves' },
172
+ { value: 'fri', label: 'Viernes' },
173
+ { value: 'sat', label: 'Sábado' },
174
+ { value: 'sun', label: 'Domingo' },
175
+ ],
176
+ },
177
+ { type: 'time', key: 'opens', label: 'Abre', required: true },
178
+ { type: 'time', key: 'closes', label: 'Cierra', required: true },
179
+ ],
180
+ section: 'horarios',
181
+ width: 12,
182
+ },
183
+ // ── Redes ──
184
+ {
185
+ type: 'string-list',
186
+ key: 'social',
187
+ label: 'Redes sociales',
188
+ itemType: 'url',
189
+ addLabel: 'Agregar red',
190
+ emptyText: 'Sin redes sociales.',
191
+ section: 'redes',
192
+ width: 12,
193
+ },
194
+ ],
195
+ };
@@ -0,0 +1,21 @@
1
+ import type { ResourceSchema } from '../models/schema.model';
2
+
3
+ import { categoriesSchema } from './categories.schema';
4
+ import { ordersSchema } from './orders.schema';
5
+ import { productsSchema } from './products.schema';
6
+ import { siteSchema } from './site.schema';
7
+
8
+ /**
9
+ * Catálogo de pruebas de la librería: copia CONGELADA de los schemas
10
+ * reales de `admin-schema` (orders, categories, products), del mismo modo
11
+ * que el motor backend congela fixtures de endpoints en sus tests. Los
12
+ * specs del motor prueban comportamiento (navegación, params, caché,
13
+ * composición) contra declaraciones con esa forma; los specs contra los
14
+ * schemas VIVOS del consumidor viven en el repo del consumidor.
15
+ */
16
+ export const testCatalog: readonly ResourceSchema[] = [
17
+ ordersSchema,
18
+ categoriesSchema,
19
+ productsSchema,
20
+ siteSchema,
21
+ ];
@@ -0,0 +1,112 @@
1
+ import { InjectionToken } from '@angular/core';
2
+
3
+ import type { ResponseUnwrap } from './models/schema.model';
4
+
5
+ /**
6
+ * URL base de la API (baseapi §2.3): es la URL directa del Web App de Apps
7
+ * Script; ahí se hace el `POST` del envelope `{ token, method, path, payload }`.
8
+ * OBLIGATORIO proporcionarlo en `app.config.ts`:
9
+ * `{ provide: API_URL, useValue: 'https://…' }` (Fase 3). Vacío = mismo origen.
10
+ */
11
+ export const API_URL = new InjectionToken<string>('API_URL');
12
+
13
+ /**
14
+ * Superficie mínima que `gas-admin-ui` usa de Firebase Auth.
15
+ * Implementada por la aplicación consumidora; inyectada vía `FIREBASE_AUTH_ADAPTER`.
16
+ * Mantener la interfaz fina evita acoplar la librería a una versión específica de Firebase.
17
+ */
18
+ export interface FirebaseAuthAdapter {
19
+ /**
20
+ * Abre un popup de Google sign-in y resuelve al ID token de Firebase.
21
+ * Rechaza si el usuario cancela o hay error.
22
+ */
23
+ signInWithGoogle(): Promise<string>;
24
+
25
+ /**
26
+ * Inicia sesión con email y contraseña vía Firebase y resuelve al ID token.
27
+ * Se usa cuando provider === 'password' Y firebase está configurado (Firebase email auth).
28
+ */
29
+ signInWithEmailAndPassword(email: string, password: string): Promise<string>;
30
+
31
+ /**
32
+ * Cierra sesión en Firebase (llamado junto al clear de la sesión de la app).
33
+ */
34
+ signOut(): Promise<void>;
35
+
36
+ /**
37
+ * Obtiene un ID token de Firebase FRESCO para usarlo en la cabecera
38
+ * `Authorization: Bearer <token>` de las peticiones REST.
39
+ *
40
+ * OPCIONAL: si el adaptador no lo implementa, `gas-admin-ui` envía el token
41
+ * de sesión almacenado tal cual (comportamiento actual). Implementarlo
42
+ * permite refrescar el ID token antes de cada petición REST, evitando
43
+ * errores "ID token inválido" tras la expiración de Firebase (1 hora).
44
+ *
45
+ * El adaptador decide cuándo refrescar (p. ej. `getIdToken(true)` de Firebase
46
+ * SDK fuerza la renovación; sin argumento devuelve el cacheado si aún es válido).
47
+ */
48
+ getIdToken?(): Promise<string>;
49
+ }
50
+
51
+ /**
52
+ * Token DI opcional para el adaptador de Firebase Auth.
53
+ * Proporcionado por la aplicación consumidora cuando usa proveedores federados o Firebase Auth.
54
+ */
55
+ export const FIREBASE_AUTH_ADAPTER = new InjectionToken<FirebaseAuthAdapter>(
56
+ 'gas.admin.firebaseAuthAdapter',
57
+ );
58
+
59
+ /**
60
+ * Driver de transporte HTTP del motor.
61
+ *
62
+ * Vive acá (capa de infraestructura) y NO en `ResourceSchema` (capa de dominio)
63
+ * porque es una decisión de red, no de modelo de datos. Cambiar el driver
64
+ * no debería requerir tocar ningún schema de recursos.
65
+ *
66
+ * - `'gas'` (default): tunnel `POST text/plain` con envelope
67
+ * `{ token, method, path, payload }` — contrato de Google Apps Script.
68
+ * - `'rest'`: verbos HTTP reales (`GET`, `POST`, `PUT`, `DELETE`) con
69
+ * `Authorization: Bearer <token>` en cabeceras y params en la URL (GET/DELETE)
70
+ * o en el body JSON (POST/PUT/PATCH).
71
+ *
72
+ * Se fija en `provideGasAdmin({ driver })`. Sin declaración explícita el
73
+ * motor usa `'gas'` — cero impacto para consumidores existentes.
74
+ */
75
+ export const API_DRIVER = new InjectionToken<'gas' | 'rest'>('gas.admin.driver');
76
+
77
+ /**
78
+ * Registro de FUENTES DE CONTEXTO para marcadores en paths de endpoints.
79
+ *
80
+ * Cada clave es el nombre de una fuente — `{ <fuente> }` o
81
+ * `{ <fuente>.<ruta.anidada> }` dentro de un path declarado en
82
+ * `ResourceEndpoints` — y cada valor es un getter sin argumentos que devuelve
83
+ * el dato ACTUAL en el momento de la petición (no al registrar).
84
+ *
85
+ * El motor ya aporta dos fuentes construidas y éstas NO se declaran acá:
86
+ *
87
+ * - `auth` → la sesión que dueña `AuthService` (usuario y token).
88
+ * - `config` → el mapa global que puebla `ConfigService` desde los singletons.
89
+ *
90
+ * Este registro es sólo para fuentes que aporta el consumidor, para que el
91
+ * motor no conozca nombres de dominio: qué campo se lee lo decide el schema,
92
+ * no el engine.
93
+ *
94
+ * Un marcador que apunte a una fuente no registrada, o a un valor ausente,
95
+ * revienta con un error que nombra el path y el marcador — jamás se manda un
96
+ * segmento vacío al backend.
97
+ */
98
+ export type ValueSources = Readonly<Record<string, () => unknown>>;
99
+
100
+ export const VALUE_SOURCES = new InjectionToken<ValueSources>('gas.admin.valueSources');
101
+
102
+ /**
103
+ * Unwrap de respuesta global por defecto (`GasAdminConfig.defaultResponseUnwrap`).
104
+ *
105
+ * Se fusiona con la declaración `endpoint.responseUnwrap` de cada recurso:
106
+ * la del recurso tiene prioridad en las claves que declara. Sin token, sólo
107
+ * aplica lo declarado por recurso — cero impacto en schemas existentes.
108
+ */
109
+ export const DEFAULT_RESPONSE_UNWRAP = new InjectionToken<ResponseUnwrap>(
110
+ 'gas.admin.defaultResponseUnwrap',
111
+ );
112
+
@@ -0,0 +1,55 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { buildShareMessage } from './clipboard';
4
+
5
+ const URL = 'https://ejemplo.test/p/abc123';
6
+
7
+ /**
8
+ * `buildShareMessage` es el único sitio que decide QUÉ se copia. Aquí vive el
9
+ * bug que motivó la función: `copy()` y la acción del listado escribían sólo
10
+ * `url`, dejando afuera el `shareTextTemplate` formateado (saludo, ref, PIN y
11
+ * el propio enlace) que sí viajaban por WhatsApp.
12
+ */
13
+ describe('buildShareMessage', () => {
14
+ it('sin shareText devuelve sólo la URL', () => {
15
+ expect(buildShareMessage(URL)).toBe(URL);
16
+ expect(buildShareMessage(URL, '')).toBe(URL);
17
+ expect(buildShareMessage(URL, ' ')).toBe(URL);
18
+ });
19
+
20
+ it('con shareText que YA trae la URL no duplica el enlace', () => {
21
+ // Este es el caso de `orders.shareTextTemplate`: el mensaje ya incluye
22
+ // el link escrito dentro. Un `join` a ciegas lo pegaba DOS veces.
23
+ const template = `Hola Ana, puede retirar su pedido A-100 aquí: ${URL}`;
24
+ expect(buildShareMessage(URL, template)).toBe(template);
25
+ });
26
+
27
+ it('con shareText SIN la URL completa el enlace al final', () => {
28
+ const text = 'Hola Ana, su pedido A-100 está listo';
29
+ expect(buildShareMessage(URL, text)).toBe(`${text} ${URL}`);
30
+ });
31
+
32
+ it('un mensaje que sólo menciona la base del sitio NO recibe el enlace', () => {
33
+ // Caso real reportado: la plantilla interpola `{public_base_url}` (la
34
+ // base, sin `/p/{ref}`) y el motor le pegaba la URL con código al final
35
+ // aunque el mensaje YA apuntaba al sitio. El criterio es el origin,
36
+ // no la URL exacta.
37
+ const text = '🔗 Consulta tu pedido en https://ejemplo.test';
38
+ expect(buildShareMessage(URL, text)).toBe(text);
39
+ });
40
+
41
+ it('un mensaje que apunta a OTRO sitio sí recibe el enlace', () => {
42
+ const text = 'Sigue el pedido en https://otro-sitio.test/pedidos';
43
+ expect(buildShareMessage(URL, text)).toBe(`${text} ${URL}`);
44
+ });
45
+
46
+ it('con URL relativa sólo casa la coincidencia exacta', () => {
47
+ expect(buildShareMessage('/p/abc123', 'Ver en /p/abc123')).toBe('Ver en /p/abc123');
48
+ expect(buildShareMessage('/p/abc123', 'Ver tu pedido')).toBe('Ver tu pedido /p/abc123');
49
+ });
50
+
51
+ it('recorta el shareText pero nunca la URL', () => {
52
+ expect(buildShareMessage(URL, ' Hola Ana ')).toBe(`Hola Ana ${URL}`);
53
+ expect(buildShareMessage('', 'Hola Ana')).toBe('Hola Ana');
54
+ });
55
+ });