@sdcorejs/angular 20.1.6 → 20.2.1

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 (213) hide show
  1. package/README.md +10 -0
  2. package/assets/scss/core/menu.scss +18 -0
  3. package/assets/scss/core/utilities/_misc.scss +15 -0
  4. package/assets/scss/sd-core.scss +1 -0
  5. package/components/anchor/index.d.ts +3 -1
  6. package/components/api-contract-builder/index.d.ts +694 -0
  7. package/components/badge/index.d.ts +2 -0
  8. package/components/ckeditor-styles/index.d.ts +1 -1
  9. package/components/form-generic/index.d.ts +44 -33
  10. package/components/import-excel/index.d.ts +1 -0
  11. package/components/index.d.ts +7 -1
  12. package/components/mini-editor/index.d.ts +1 -1
  13. package/components/modal/index.d.ts +3 -2
  14. package/components/modal-resizable/index.d.ts +92 -0
  15. package/components/org-chart/index.d.ts +6 -0
  16. package/components/preview/index.d.ts +1 -0
  17. package/components/query-bar/index.d.ts +55 -17
  18. package/components/query-builder/index.d.ts +150 -98
  19. package/components/section/index.d.ts +5 -0
  20. package/components/tab-router/index.d.ts +19 -19
  21. package/components/table/index.d.ts +251 -109
  22. package/components/tree/index.d.ts +48 -30
  23. package/components/upload-file/index.d.ts +6 -3
  24. package/configurations/index.d.ts +1 -2
  25. package/fesm2022/sdcorejs-angular-components-anchor.mjs +37 -13
  26. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  27. package/fesm2022/sdcorejs-angular-components-api-contract-builder.mjs +3417 -0
  28. package/fesm2022/sdcorejs-angular-components-api-contract-builder.mjs.map +1 -0
  29. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +2 -2
  30. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
  31. package/fesm2022/sdcorejs-angular-components-badge.mjs +27 -2
  32. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  33. package/fesm2022/sdcorejs-angular-components-button.mjs +2 -2
  34. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  35. package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +1 -1
  36. package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs.map +1 -1
  37. package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
  38. package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
  39. package/fesm2022/sdcorejs-angular-components-data-state.mjs +3 -3
  40. package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -1
  41. package/fesm2022/sdcorejs-angular-components-editor.mjs +2 -2
  42. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  43. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +324 -192
  44. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  45. package/fesm2022/sdcorejs-angular-components-history.mjs +4 -4
  46. package/fesm2022/sdcorejs-angular-components-history.mjs.map +1 -1
  47. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +13 -5
  48. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  49. package/fesm2022/sdcorejs-angular-components-inform.mjs +3 -3
  50. package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
  51. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +164 -8
  52. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
  53. package/fesm2022/sdcorejs-angular-components-modal.mjs +30 -18
  54. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  55. package/fesm2022/sdcorejs-angular-components-operator.mjs +2 -2
  56. package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
  57. package/fesm2022/sdcorejs-angular-components-org-chart.mjs +60 -13
  58. package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -1
  59. package/fesm2022/sdcorejs-angular-components-preview.mjs +27 -17
  60. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  61. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +192 -30
  62. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  63. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +187 -127
  64. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  65. package/fesm2022/sdcorejs-angular-components-section.mjs +33 -2
  66. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  67. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +83 -24
  68. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  69. package/fesm2022/sdcorejs-angular-components-splitter.mjs +57 -21
  70. package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
  71. package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -2
  72. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  73. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +68 -20
  74. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  75. package/fesm2022/sdcorejs-angular-components-tab.mjs +3 -2
  76. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  77. package/fesm2022/sdcorejs-angular-components-table.mjs +556 -268
  78. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  79. package/fesm2022/sdcorejs-angular-components-tree.mjs +80 -17
  80. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  81. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +48 -13
  82. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  83. package/fesm2022/sdcorejs-angular-components.mjs +7 -1
  84. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  85. package/fesm2022/sdcorejs-angular-configurations.mjs.map +1 -1
  86. package/fesm2022/sdcorejs-angular-directives.mjs +45 -8
  87. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  88. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +40 -29
  89. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  90. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +5 -5
  91. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  92. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +67 -50
  93. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  94. package/fesm2022/sdcorejs-angular-forms-chip.mjs +57 -43
  95. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  96. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +232 -61
  97. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  98. package/fesm2022/sdcorejs-angular-forms-date.mjs +96 -24
  99. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  100. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +131 -27
  101. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  102. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +40 -16
  103. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -1
  104. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +16 -5
  105. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  106. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +24 -9
  107. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  108. package/fesm2022/sdcorejs-angular-forms-input.mjs +58 -10
  109. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  110. package/fesm2022/sdcorejs-angular-forms-models.mjs +227 -6
  111. package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
  112. package/fesm2022/sdcorejs-angular-forms-radio.mjs +4 -4
  113. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  114. package/fesm2022/sdcorejs-angular-forms-select.mjs +136 -38
  115. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  116. package/fesm2022/sdcorejs-angular-forms-switch.mjs +18 -3
  117. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  118. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +51 -62
  119. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  120. package/fesm2022/sdcorejs-angular-forms-time-range.mjs +57 -12
  121. package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -1
  122. package/fesm2022/sdcorejs-angular-forms-time.mjs +16 -5
  123. package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -1
  124. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +100 -9
  125. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -1
  126. package/fesm2022/sdcorejs-angular-forms.mjs +91 -46
  127. package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
  128. package/fesm2022/sdcorejs-angular-handlers.mjs +18 -3
  129. package/fesm2022/sdcorejs-angular-handlers.mjs.map +1 -1
  130. package/fesm2022/sdcorejs-angular-i18n.mjs +895 -68
  131. package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
  132. package/fesm2022/sdcorejs-angular-interceptors.mjs +87 -29
  133. package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
  134. package/fesm2022/sdcorejs-angular-modules-auth.mjs +25 -15
  135. package/fesm2022/sdcorejs-angular-modules-auth.mjs.map +1 -1
  136. package/fesm2022/sdcorejs-angular-modules-icon.mjs +2 -2
  137. package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
  138. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +32 -3
  139. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs.map +1 -1
  140. package/fesm2022/sdcorejs-angular-modules-layout.mjs +342 -111
  141. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  142. package/fesm2022/sdcorejs-angular-modules-permission.mjs +177 -40
  143. package/fesm2022/sdcorejs-angular-modules-permission.mjs.map +1 -1
  144. package/fesm2022/sdcorejs-angular-pipes.mjs +62 -28
  145. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  146. package/fesm2022/sdcorejs-angular-services-api.mjs +123 -13
  147. package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
  148. package/fesm2022/sdcorejs-angular-services-cache.mjs +53 -3
  149. package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
  150. package/fesm2022/sdcorejs-angular-services-confirm.mjs +25 -73
  151. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  152. package/fesm2022/sdcorejs-angular-services-excel.mjs +12 -10
  153. package/fesm2022/sdcorejs-angular-services-excel.mjs.map +1 -1
  154. package/fesm2022/sdcorejs-angular-services-loading.mjs +75 -84
  155. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  156. package/fesm2022/sdcorejs-angular-services-notify.mjs +46 -5
  157. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  158. package/fesm2022/sdcorejs-angular-services-storage.mjs +4 -0
  159. package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
  160. package/fesm2022/sdcorejs-angular-services.mjs +0 -1
  161. package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
  162. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs +225 -80
  163. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs.map +1 -1
  164. package/fesm2022/sdcorejs-angular-utilities-models.mjs +1 -63
  165. package/fesm2022/sdcorejs-angular-utilities-models.mjs.map +1 -1
  166. package/fesm2022/sdcorejs-angular.mjs +17 -10
  167. package/fesm2022/sdcorejs-angular.mjs.map +1 -1
  168. package/forms/autocomplete/index.d.ts +5 -2
  169. package/forms/chip-calendar/index.d.ts +10 -0
  170. package/forms/date/index.d.ts +13 -2
  171. package/forms/date-range/index.d.ts +14 -2
  172. package/forms/datetime/index.d.ts +13 -2
  173. package/forms/entity-picker/index.d.ts +9 -3
  174. package/forms/index.d.ts +22 -13
  175. package/forms/input/index.d.ts +3 -0
  176. package/forms/input-color/index.d.ts +4 -0
  177. package/forms/input-number/index.d.ts +3 -0
  178. package/forms/models/index.d.ts +119 -4
  179. package/forms/select/index.d.ts +27 -4
  180. package/forms/switch/index.d.ts +7 -1
  181. package/forms/textarea/index.d.ts +5 -3
  182. package/forms/time-range/index.d.ts +22 -1
  183. package/forms/tree-select/index.d.ts +36 -5
  184. package/i18n/index.d.ts +175 -16
  185. package/index.d.ts +11 -2
  186. package/interceptors/index.d.ts +13 -3
  187. package/modules/auth/index.d.ts +1 -1
  188. package/modules/keycloak/index.d.ts +1 -0
  189. package/modules/layout/index.d.ts +94 -28
  190. package/modules/permission/index.d.ts +66 -4
  191. package/package.json +36 -25
  192. package/pipes/index.d.ts +27 -5
  193. package/services/api/index.d.ts +21 -1
  194. package/services/cache/index.d.ts +11 -1
  195. package/services/index.d.ts +0 -1
  196. package/services/notify/index.d.ts +1 -1
  197. package/utilities/extensions/index.d.ts +83 -61
  198. package/utilities/models/index.d.ts +2 -76
  199. package/components/base/index.d.ts +0 -11
  200. package/components/document-builder/index.d.ts +0 -252
  201. package/fesm2022/sdcorejs-angular-components-base.mjs +0 -23
  202. package/fesm2022/sdcorejs-angular-components-base.mjs.map +0 -1
  203. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +0 -5038
  204. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +0 -1
  205. package/fesm2022/sdcorejs-angular-models.mjs +0 -6
  206. package/fesm2022/sdcorejs-angular-models.mjs.map +0 -1
  207. package/fesm2022/sdcorejs-angular-services-docx.mjs +0 -291
  208. package/fesm2022/sdcorejs-angular-services-docx.mjs.map +0 -1
  209. package/fesm2022/sdcorejs-angular-services-license.mjs +0 -97
  210. package/fesm2022/sdcorejs-angular-services-license.mjs.map +0 -1
  211. package/models/index.d.ts +0 -2
  212. package/services/docx/index.d.ts +0 -27
  213. package/services/license/index.d.ts +0 -12
@@ -49,6 +49,17 @@ interface ISdPermissionConfiguration {
49
49
  * Hỗ trợ trả về đồng bộ, Promise hoặc Observable.
50
50
  */
51
51
  getToken?: () => MaybeAsync<string | undefined | null>;
52
+ /**
53
+ * Cho phép mirror danh sách mã quyền của key này xuống `sessionStorage` để sống qua reload.
54
+ *
55
+ * ⚠️ Mặc định `false` — danh sách quyền CHỈ nằm trong bộ nhớ.
56
+ *
57
+ * Bật cờ này nghĩa là chấp nhận: mọi script chạy trên cùng origin đều ĐỌC và GHI được danh sách đó.
58
+ * Cache KHÔNG phải một ranh giới phân quyền — nó chỉ tiết kiệm một lần gọi API khi reload; backend
59
+ * vẫn phải kiểm tra quyền cho từng request. Khi bật, nhớ gọi `SdPermissionService.reset()` lúc
60
+ * signout để xoá cả bản mirror.
61
+ */
62
+ persistCache?: boolean;
52
63
  }
53
64
  /**
54
65
  * InjectionToken cho cấu hình permission.
@@ -65,13 +76,64 @@ interface ISdPermissionConfiguration {
65
76
  */
66
77
  declare const SD_PERMISSION_CONFIGURATION: InjectionToken<ISdPermissionConfiguration | ISdPermissionConfiguration[]>;
67
78
 
79
+ /**
80
+ * Opt-out TƯỜNG MINH: "chỗ này cố ý không yêu cầu quyền nào".
81
+ *
82
+ * Dùng cho `route.data.permission`, `[sdPermission]` hoặc `hasPermission(...)` khi một route/phần tử
83
+ * thật sự công khai. Mọi giá trị rỗng khác (`undefined`, `null`, `''`, `[]`) đều bị coi là CẤU HÌNH
84
+ * THIẾU và bị từ chối — xem `SdPermissionService.hasPermission`.
85
+ */
86
+ declare const SD_PERMISSION_PUBLIC = "__SD_PERMISSION_PUBLIC__";
87
+ /** Kiểu đầu vào cho `hasPermission` / `[sdPermission]`. */
88
+ type SdPermissionInput = string | string[] | null | undefined;
68
89
  declare class SdPermissionService {
69
90
  #private;
70
91
  constructor();
71
92
  loadPermissions: (key?: string) => Promise<string[]>;
72
93
  loadAllPermissions: () => Promise<void>;
73
- hasPermission: (permission: string | string[], key?: string) => boolean;
94
+ /**
95
+ * Xoá TOÀN BỘ quyền đã nạp (mọi key) — cả map trong bộ nhớ, cờ "đã nạp" lẫn bản mirror
96
+ * `sessionStorage` của các key bật `persistCache`.
97
+ *
98
+ * ⚠️ BẮT BUỘC gọi khi signout. Service là singleton `providedIn: 'root'`, nên trong một SPA
99
+ * signout → signin (không reload trang) mà không reset thì `loadPermissions()` sẽ short-circuit
100
+ * theo key đã cache và user MỚI thừa hưởng nguyên bộ quyền của user CŨ.
101
+ *
102
+ * ```ts
103
+ * auth.signout$?.subscribe(() => permissionService.reset());
104
+ * ```
105
+ */
106
+ reset: () => void;
107
+ /**
108
+ * Xoá quyền đã nạp của MỘT key (mặc định là key portal `undefined`), buộc lần
109
+ * `loadPermissions(key)` kế tiếp gọi lại loader. Dùng khi chỉ một profile/tenant đổi quyền;
110
+ * signout thì dùng {@link reset}.
111
+ */
112
+ invalidate: (key?: string) => void;
113
+ /**
114
+ * Kiểm tra quyền (OR cho mảng).
115
+ *
116
+ * ⚠️ BREAKING: đầu vào rỗng (`undefined` / `null` / `''` / `[]`) giờ trả `false`.
117
+ * Muốn "không yêu cầu quyền" thì phải nói ra bằng {@link SD_PERMISSION_PUBLIC}.
118
+ */
119
+ hasPermission: (permission: SdPermissionInput, key?: string) => boolean;
74
120
  getToken: (key?: string) => Promise<string | null | undefined>;
121
+ /**
122
+ * Giải mã phần payload của JWT hiện tại và trả về claim **CHƯA ĐƯỢC XÁC THỰC**.
123
+ *
124
+ * ⚠️ KHÔNG kiểm chữ ký, KHÔNG kiểm `exp`/`nbf`/`aud`/`iss`. Đây thuần tuý là base64url-decode: bất
125
+ * kỳ ai cũng tự tạo được một token có claim tuỳ ý và hàm này sẽ vui vẻ trả về. Vì vậy kết quả CHỈ
126
+ * dùng cho mục đích hiển thị (tên, avatar, tenant đang chọn…) và TUYỆT ĐỐI không được dùng để ra
127
+ * quyết định phân quyền — quyền phải do backend xác thực chữ ký rồi trả về.
128
+ *
129
+ * Trả `null` khi không có token hoặc payload hỏng.
130
+ */
131
+ readUnverifiedTokenClaims: <T>(key?: string) => Promise<T | null>;
132
+ /**
133
+ * @deprecated Tên `decodeToken` gợi ý một thao tác đã được kiểm chứng, trong khi thực tế payload
134
+ * hoàn toàn KHÔNG được xác thực. Dùng {@link readUnverifiedTokenClaims} — alias này chỉ còn để
135
+ * consumer cũ không vỡ và sẽ bị gỡ ở release sau.
136
+ */
75
137
  decodeToken: <T>(key?: string) => Promise<T | null>;
76
138
  static ɵfac: i0.ɵɵFactoryDeclaration<SdPermissionService, never>;
77
139
  static ɵprov: i0.ɵɵInjectableDeclaration<SdPermissionService>;
@@ -79,7 +141,7 @@ declare class SdPermissionService {
79
141
 
80
142
  declare class SdPermissionDirective {
81
143
  #private;
82
- readonly sdPermission: i0.InputSignal<string | string[] | null | undefined>;
144
+ readonly sdPermission: i0.InputSignal<SdPermissionInput>;
83
145
  readonly sdPermissionKey: i0.InputSignal<string | undefined>;
84
146
  constructor();
85
147
  static ɵfac: i0.ɵɵFactoryDeclaration<SdPermissionDirective, never>;
@@ -96,5 +158,5 @@ declare class SdPermissionGuard implements CanActivate, CanActivateChild {
96
158
  static ɵprov: i0.ɵɵInjectableDeclaration<SdPermissionGuard>;
97
159
  }
98
160
 
99
- export { SD_PERMISSION_CONFIGURATION, SdPermissionDirective, SdPermissionGuard, SdPermissionService };
100
- export type { ISdPermissionConfiguration };
161
+ export { SD_PERMISSION_CONFIGURATION, SD_PERMISSION_PUBLIC, SdPermissionDirective, SdPermissionGuard, SdPermissionService };
162
+ export type { ISdPermissionConfiguration, SdPermissionInput };
package/package.json CHANGED
@@ -1,7 +1,24 @@
1
1
  {
2
2
  "name": "@sdcorejs/angular",
3
- "version": "20.1.6",
3
+ "version": "20.2.1",
4
+ "description": "Angular component library: data table, query bar/builder, 20+ signal-based form controls, layout, auth and workflow services. Standalone, OnPush, signals-first. Published in parallel lines for Angular 19, 20 and 21.",
5
+ "keywords": [
6
+ "angular",
7
+ "angular-components",
8
+ "component-library",
9
+ "ui-components",
10
+ "angular-material",
11
+ "signals",
12
+ "standalone-components",
13
+ "data-table",
14
+ "forms",
15
+ "query-builder"
16
+ ],
17
+ "author": "SDCoreJS",
4
18
  "license": "MIT",
19
+ "engines": {
20
+ "node": ">=20.11.0"
21
+ },
5
22
  "repository": {
6
23
  "type": "git",
7
24
  "url": "git+https://github.com/sdcorejs/sdcorejs-angular.git"
@@ -11,18 +28,22 @@
11
28
  "url": "https://github.com/sdcorejs/sdcorejs-angular/issues"
12
29
  },
13
30
  "peerDependencies": {
31
+ "@angular/animations": "^19.0.0 || ^20.0.0 || ^21.0.0",
32
+ "@angular/cdk": "^19.0.0 || ^20.0.0 || ^21.0.0",
14
33
  "@angular/common": "^19.0.0 || ^20.0.0 || ^21.0.0",
15
34
  "@angular/core": "^19.0.0 || ^20.0.0 || ^21.0.0",
35
+ "@angular/forms": "^19.0.0 || ^20.0.0 || ^21.0.0",
16
36
  "@angular/material": "^19.0.0 || ^20.0.0 || ^21.0.0",
17
- "@angular/material-date-fns-adapter": "^19.0.0 || ^20.0.0 || ^21.0.0"
37
+ "@angular/material-date-fns-adapter": "^19.0.0 || ^20.0.0 || ^21.0.0",
38
+ "@angular/platform-browser": "^19.0.0 || ^20.0.0 || ^21.0.0",
39
+ "@angular/router": "^19.0.0 || ^20.0.0 || ^21.0.0",
40
+ "rxjs": "^7.8.0"
18
41
  },
19
42
  "dependencies": {
20
43
  "@sdcorejs/angular-material-datetime": "1.0.3",
21
44
  "@sdcorejs/utils": "1.1.4",
22
45
  "@lucide/angular": "^1.22.0",
23
46
  "@ckeditor/ckeditor5-angular": "11.1.2",
24
- "@omer-go/docx-parser-converter-ts": "^1.0.0",
25
- "@bjorn3/browser_wasi_shim": "^0.4.2",
26
47
  "ckeditor5": "48.0.0",
27
48
  "chart.js": "^4.5.1",
28
49
  "date-fns": "^3.6.0",
@@ -32,7 +53,13 @@
32
53
  "prismjs": "^1.30.0",
33
54
  "tslib": "^2.8.0"
34
55
  },
35
- "sideEffects": false,
56
+ "sideEffects": [
57
+ "**/*.css",
58
+ "**/*.scss",
59
+ "./fesm2022/sdcorejs-angular-components-chart.mjs",
60
+ "./fesm2022/sdcorejs-angular-components-code-editor.mjs",
61
+ "./fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs"
62
+ ],
36
63
  "module": "fesm2022/sdcorejs-angular.mjs",
37
64
  "typings": "index.d.ts",
38
65
  "exports": {
@@ -51,6 +78,10 @@
51
78
  "types": "./components/anchor/index.d.ts",
52
79
  "default": "./fesm2022/sdcorejs-angular-components-anchor.mjs"
53
80
  },
81
+ "./components/api-contract-builder": {
82
+ "types": "./components/api-contract-builder/index.d.ts",
83
+ "default": "./fesm2022/sdcorejs-angular-components-api-contract-builder.mjs"
84
+ },
54
85
  "./components/audit-diff": {
55
86
  "types": "./components/audit-diff/index.d.ts",
56
87
  "default": "./fesm2022/sdcorejs-angular-components-audit-diff.mjs"
@@ -67,10 +98,6 @@
67
98
  "types": "./components/badge/index.d.ts",
68
99
  "default": "./fesm2022/sdcorejs-angular-components-badge.mjs"
69
100
  },
70
- "./components/base": {
71
- "types": "./components/base/index.d.ts",
72
- "default": "./fesm2022/sdcorejs-angular-components-base.mjs"
73
- },
74
101
  "./components/breadcrumb": {
75
102
  "types": "./components/breadcrumb/index.d.ts",
76
103
  "default": "./fesm2022/sdcorejs-angular-components-breadcrumb.mjs"
@@ -95,10 +122,6 @@
95
122
  "types": "./components/data-state/index.d.ts",
96
123
  "default": "./fesm2022/sdcorejs-angular-components-data-state.mjs"
97
124
  },
98
- "./components/document-builder": {
99
- "types": "./components/document-builder/index.d.ts",
100
- "default": "./fesm2022/sdcorejs-angular-components-document-builder.mjs"
101
- },
102
125
  "./components/editor": {
103
126
  "types": "./components/editor/index.d.ts",
104
127
  "default": "./fesm2022/sdcorejs-angular-components-editor.mjs"
@@ -311,10 +334,6 @@
311
334
  "types": "./interceptors/index.d.ts",
312
335
  "default": "./fesm2022/sdcorejs-angular-interceptors.mjs"
313
336
  },
314
- "./models": {
315
- "types": "./models/index.d.ts",
316
- "default": "./fesm2022/sdcorejs-angular-models.mjs"
317
- },
318
337
  "./modules": {
319
338
  "types": "./modules/index.d.ts",
320
339
  "default": "./fesm2022/sdcorejs-angular-modules.mjs"
@@ -359,18 +378,10 @@
359
378
  "types": "./services/confirm/index.d.ts",
360
379
  "default": "./fesm2022/sdcorejs-angular-services-confirm.mjs"
361
380
  },
362
- "./services/docx": {
363
- "types": "./services/docx/index.d.ts",
364
- "default": "./fesm2022/sdcorejs-angular-services-docx.mjs"
365
- },
366
381
  "./services/excel": {
367
382
  "types": "./services/excel/index.d.ts",
368
383
  "default": "./fesm2022/sdcorejs-angular-services-excel.mjs"
369
384
  },
370
- "./services/license": {
371
- "types": "./services/license/index.d.ts",
372
- "default": "./fesm2022/sdcorejs-angular-services-license.mjs"
373
- },
374
385
  "./services/loading": {
375
386
  "types": "./services/loading/index.d.ts",
376
387
  "default": "./fesm2022/sdcorejs-angular-services-loading.mjs"
package/pipes/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { PipeTransform } from '@angular/core';
3
- import * as _angular_platform_browser from '@angular/platform-browser';
3
+ import { SafeHtml } from '@angular/platform-browser';
4
4
  import { Observable } from 'rxjs';
5
5
 
6
6
  declare class SdFormatDatePipe implements PipeTransform {
@@ -25,17 +25,39 @@ declare class SdFormatNumberPipe implements PipeTransform {
25
25
  static ɵprov: i0.ɵɵInjectableDeclaration<SdFormatNumberPipe>;
26
26
  }
27
27
 
28
+ /**
29
+ * Render an HTML string through `[innerHTML]`.
30
+ *
31
+ * why: this pipe used to call `bypassSecurityTrustHtml()` unconditionally, on every value, with no
32
+ * sanitize step. That turned every call site into a stored-XSS sink — and the library itself pipes
33
+ * server-supplied table cell data through it
34
+ * (`components/table/src/components/desktop-cell/view/view.component.html`), while
35
+ * `components/table/sd-table.md` already described the value as "sanitized via sdSafeHtml".
36
+ *
37
+ * Now it **sanitizes by default** and the bypass is an explicit, per-call-site opt-in:
38
+ *
39
+ * ```html
40
+ * <!-- untrusted / server-supplied: script, on* handlers and javascript: urls are stripped -->
41
+ * <div [innerHTML]="row.note | sdSafeHtml"></div>
42
+ *
43
+ * <!-- app-authored markup you control, e.g. an inline SVG sprite -->
44
+ * <span [innerHTML]="iconSvg | sdSafeHtml: true"></span>
45
+ * ```
46
+ *
47
+ * This mirrors the decision already taken for the toast in `services/notify`: text-safe by default,
48
+ * opt-in HTML. Auto-detecting "this looks like HTML" is deliberately NOT done — it would escalate
49
+ * untrusted text that merely contains `<` straight back into the unsanitized sink.
50
+ */
28
51
  declare class SdSafeHtmlPipe implements PipeTransform {
29
- private sanitizer;
30
- /** Inserted by Angular inject() migration for backwards compatibility */
31
- constructor(...args: unknown[]);
32
- transform(html: string | number | undefined | null): _angular_platform_browser.SafeHtml | undefined;
52
+ #private;
53
+ transform(html: string | number | undefined | null, trusted?: boolean): SafeHtml | string | number | undefined;
33
54
  static ɵfac: i0.ɵɵFactoryDeclaration<SdSafeHtmlPipe, never>;
34
55
  static ɵpipe: i0.ɵɵPipeDeclaration<SdSafeHtmlPipe, "sdSafeHtml", true>;
35
56
  static ɵprov: i0.ɵɵInjectableDeclaration<SdSafeHtmlPipe>;
36
57
  }
37
58
 
38
59
  declare class SdTimeDifferentPipe implements PipeTransform {
60
+ #private;
39
61
  private maxSecond;
40
62
  private maxMinute;
41
63
  private maxHour;
@@ -75,6 +75,20 @@ interface ISdApiConfiguration {
75
75
  declare const SD_API_CONFIG: InjectionToken<ISdApiConfiguration>;
76
76
  /** @deprecated Use `SD_API_CONFIG`. This is the same injection token. */
77
77
  declare const SD_API_CONFIGURATION: InjectionToken<ISdApiConfiguration>;
78
+ /**
79
+ * Lỗi nghiệp vụ: HTTP 200 nhưng body envelope báo thất bại (`{ ok: false, ... }`).
80
+ *
81
+ * why: trước đây `SdApiService` `throw body` — một plain object. Hệ quả: `error instanceof Error`
82
+ * là `false`, `error.message` là `undefined`, nên mọi `catch` của consumer và predicate
83
+ * `retry.retryWhen` đều bỏ sót nhánh này. Bọc vào một Error thật để envelope lỗi đi chung
84
+ * đường với lỗi HTTP; body gốc vẫn giữ nguyên ở `.body`.
85
+ */
86
+ declare class SdApiError<TBody = unknown> extends Error {
87
+ readonly name = "SdApiError";
88
+ /** Body nguyên bản của response (đúng object server trả về). */
89
+ readonly body: TBody;
90
+ constructor(body: TBody, message?: string);
91
+ }
78
92
 
79
93
  /**
80
94
  * Response generics intentionally default to `unknown` for type safety.
@@ -105,11 +119,17 @@ declare class SdHttpInterceptor implements HttpInterceptor {
105
119
  static ɵprov: i0.ɵɵInjectableDeclaration<SdHttpInterceptor>;
106
120
  }
107
121
 
122
+ /**
123
+ * Thông điệp của assertion dev-mode ở constructor. Export ra để spec khẳng định đúng nội dung,
124
+ * và để consumer grep được khi thấy nó trong console.
125
+ */
126
+ declare const SD_API_MISSING_HTTP_CLIENT_MESSAGE: string;
108
127
  declare class SdApiModule {
128
+ constructor();
109
129
  static ɵfac: i0.ɵɵFactoryDeclaration<SdApiModule, never>;
110
130
  static ɵmod: i0.ɵɵNgModuleDeclaration<SdApiModule, never, never, never>;
111
131
  static ɵinj: i0.ɵɵInjectorDeclaration<SdApiModule>;
112
132
  }
113
133
 
114
- export { SD_API_CONFIG, SD_API_CONFIGURATION, SdApiModule, SdApiService, SdHttpInterceptor };
134
+ export { SD_API_CONFIG, SD_API_CONFIGURATION, SD_API_MISSING_HTTP_CLIENT_MESSAGE, SdApiError, SdApiModule, SdApiService, SdHttpInterceptor };
115
135
  export type { ISdApiConfiguration, SdApiHandler, SdApiHttpOption, SdApiOption, SdApiRequestUpdate, SdApiResponseType, SdApiRetryOption, SdDeleteOption, SdGetOption, SdPatchOption, SdPostOption, SdPutOption };
@@ -43,12 +43,22 @@ interface SdCacheStoredValue<T = unknown> {
43
43
  type SdCacheSetCallback = (key: string, value: SdCacheStoredValue<unknown>, option?: SdCacheOption<unknown>) => Promise<void> | void;
44
44
  type SdCacheGetCallback = (key: string, option?: SdCacheOption<unknown>) => Promise<SdCacheStoredValue<unknown> | undefined>;
45
45
  type SdCacheRemoveCallback = (key: string, option?: SdCacheOption<unknown>) => Promise<void> | void;
46
+ /**
47
+ * Số entry `type: 'memory'` tối đa được giữ trước khi LRU đẩy entry cũ nhất ra.
48
+ * Ghi đè bằng `maxMemoryEntries` trên `SD_CACHE_CONFIG`.
49
+ */
50
+ declare const SD_CACHE_DEFAULT_MAX_MEMORY_ENTRIES = 500;
46
51
  interface ISdCacheConfiguration {
47
52
  convertKey?: (key: string) => string;
48
53
  namespace?: string;
49
54
  version?: string | number;
50
55
  serializer?: SdPersistenceSerializer;
51
56
  identityCanonicalizer?: SdPersistenceIdentityCanonicalizer;
57
+ /**
58
+ * Trần LRU cho cache `type: 'memory'`. Mặc định `SD_CACHE_DEFAULT_MAX_MEMORY_ENTRIES` (500).
59
+ * Giá trị không hợp lệ (không hữu hạn, < 1) sẽ rơi về mặc định.
60
+ */
61
+ maxMemoryEntries?: number;
52
62
  set?: SdCacheSetCallback;
53
63
  get?: SdCacheGetCallback;
54
64
  remove?: SdCacheRemoveCallback;
@@ -75,5 +85,5 @@ declare class SdCacheService {
75
85
  static ɵprov: i0.ɵɵInjectableDeclaration<SdCacheService>;
76
86
  }
77
87
 
78
- export { SD_CACHE_CONFIG, SdCacheService, adaptLegacySdCacheCallbacks };
88
+ export { SD_CACHE_CONFIG, SD_CACHE_DEFAULT_MAX_MEMORY_ENTRIES, SdCacheService, adaptLegacySdCacheCallbacks };
79
89
  export type { ISdCacheConfiguration, SdCache, SdCacheGetCallback, SdCacheOption, SdCacheRemoveCallback, SdCacheSetCallback, SdCacheSnapshot, SdCacheStoredValue, SdCacheWithDefault, SdLegacyCacheCallbacks };
@@ -6,7 +6,6 @@ export * from '@sdcorejs/angular/services/confirm';
6
6
  export * from '@sdcorejs/angular/services/api';
7
7
  export * from '@sdcorejs/angular/services/loading';
8
8
  export * from '@sdcorejs/angular/services/excel';
9
- export * from '@sdcorejs/angular/services/docx';
10
9
  export * from '@sdcorejs/angular/services/viewport';
11
10
  export * from '@sdcorejs/angular/services/unsaved-changes';
12
11
  export * from '@sdcorejs/angular/services/task';
@@ -53,4 +53,4 @@ declare class SdNotifyService {
53
53
  }
54
54
 
55
55
  export { SdNotifyService };
56
- export type { NotifyOption as SdNotifyOption };
56
+ export type { NotifyOption as SdNotifyOption, ToastData as SdToastData, ToastType as SdToastType };
@@ -1,58 +1,12 @@
1
- export { ArrayUtilities, BrowserUtilities, ColorUtilities, DateUtilities, NumberUtilities, Utilities, ValidationUtilities } from '@sdcorejs/utils/fns';
2
-
3
- declare const StringUtilities: {
4
- /** @deprecated Use REGEX_VN_PHONE instead */
5
- REGEX_PHONE_VN: string;
6
- /** @deprecated Use REGEX_VN_ID instead */
7
- REGEX_IDVN: string;
8
- /** @deprecated Use REGEX_VN_ID_OR_PASSPORT instead */
9
- REGEX_IDVN_OR_PASSPORT: string;
10
- /** @deprecated Use {@link ValidationUtilities.isEmail} instead */
11
- isValidEmail: (value: any) => boolean;
12
- /** @deprecated Use {@link ValidationUtilities.isPhone} instead */
13
- isValidPhone: (value: any) => boolean;
14
- /** @deprecated Use {@link ValidationUtilities.isCode} instead */
15
- isValidCode: (value: any) => boolean;
16
- REGEX_EMAIL: string;
17
- REGEX_PHONE: string;
18
- REGEX_VN_PHONE: string;
19
- REGEX_VN_ID: string;
20
- REGEX_PASSPORT: string;
21
- REGEX_VN_ID_OR_PASSPORT: string;
22
- REGEX_TIME: string;
23
- REGEX_URL: string;
24
- REGEX_DOMAIN: string;
25
- REGEX_IPV4: string;
26
- REGEX_IPV6: string;
27
- REGEX_IMAGE_URL: string;
28
- REGEX_SLUG: string;
29
- REGEX_NUMBER: string;
30
- REGEX_INTEGER: string;
31
- REGEX_DECIMAL: string;
32
- REGEX_POSITIVE_NUMBER: string;
33
- REGEX_UUID: string;
34
- REGEX_CODE_16: string;
35
- REGEX_CODE_32: string;
36
- REGEX_HEX_COLOR: string;
37
- REGEX_BASE64: string;
38
- changeAliasLowerCase: (alias: any) => string;
39
- aliasIncludes: (alias: any, searchText: any) => boolean;
40
- format: (template: string, ...arr: any[]) => string;
41
- templateToDisplay: (template: string, entity: Record<string, any>) => string;
42
- parseExpression: (template: string, entity: Record<string, any>) => any;
43
- encrypt: (obj: any) => string;
44
- decrypt: (encripted: string) => any;
45
- isNullOrEmpty: (value: any) => boolean;
46
- isNullOrWhiteSpace: (value: any) => boolean;
47
- convertToSnakeCaseCode: (name: string) => string;
48
- generateUniqueCode: (name: string, existingCodes: string[]) => string;
49
- sha256: (input: string) => Promise<string>;
50
- };
51
-
52
1
  /**
53
- * @deprecated Use {@link Utilities} and {@link BrowserUtilities} from `@sdcorejs/utils/fns` instead.
54
- * - upload/download/clipboard/isMobile → BrowserUtilities
55
- * - allWithPaging (→ fetchAllByPaging) / randomId / hash / parseQueryParams / generateUuid / getNestedValue Utilities
2
+ * Facade tiện ích chung của `@sdcorejs/angular` (upload/download, clipboard, paging, hash, uuid…).
3
+ *
4
+ * why: khối này TỪNG bị đánh dấu `@deprecated` như thể chỉ alias mỏng của `Utilities` /
5
+ * `BrowserUtilities` bên `@sdcorejs/utils/fns` — điều đó SAI. Cả 14 member dưới đây là cài đặt
6
+ * cục bộ trong chính file này (xem phần trên), có hành vi riêng cho môi trường Angular (interceptor,
7
+ * i18n, DOM). Xoá nó theo diện "dead alias" sẽ mất code thật, nên marker `@deprecated` đã được gỡ
8
+ * trong đợt breaking rename thay vì gỡ implementation. Các alias thật sự chết ở `utilities/**`
9
+ * (`SdColor`, `SD_EMPTY_STR`, `SdFilter*`, `SdPatternCommons`, `hslToHex`/`rgbToHex`…) đã bị xoá hẳn.
56
10
  */
57
11
  declare const SdUtilities: {
58
12
  upload: (option?: {
@@ -74,16 +28,11 @@ declare const SdUtilities: {
74
28
  randomId: (prefix?: string | null) => string;
75
29
  hash: (obj: any) => string;
76
30
  parseQueryParams: (queryString?: string) => Record<string, string>;
77
- getClientPublicIp: () => Promise<string | null>;
31
+ getClientPublicIp: (endpoint: string) => Promise<string | null>;
78
32
  generateUuid: () => string;
79
33
  getNestedValue: (obj: any, path: string) => any;
80
34
  };
81
35
 
82
- /** @deprecated Use {@link ColorUtilities.hslToHex} from `@sdcorejs/utils/fns` instead */
83
- declare const hslToHex: (h: number, s: number, l: number) => string;
84
- /** @deprecated Use {@link ColorUtilities.rgbToHex} from `@sdcorejs/utils/fns` instead */
85
- declare const rgbToHex: (r: number, g: number, b: number) => string;
86
-
87
36
  type PlainObject = Record<PropertyKey, unknown>;
88
37
  declare const ObjectUtilities: {
89
38
  isPlainObject: (value: unknown) => value is PlainObject;
@@ -92,4 +41,77 @@ declare const ObjectUtilities: {
92
41
  deepMerge: <T extends PlainObject>(...sources: T[]) => T;
93
42
  };
94
43
 
95
- export { ObjectUtilities, SdUtilities, StringUtilities, hslToHex, rgbToHex };
44
+ /**
45
+ * URL safety helpers.
46
+ *
47
+ * why: this library used to decide "is this an external link?" and "should this request carry the
48
+ * bearer token?" with plain substring tests — `path.includes('http')` and `url.includes(route)`.
49
+ * Both are unsound:
50
+ *
51
+ * - `'javascript:fetch(...)//http'.includes('http')` is `true`, so a menu entry could be opened
52
+ * with `window.open()` and execute script in the app origin.
53
+ * - With `secureRoutes: ['/api/v1']`, `'https://evil.example.com/api/v1/collect'.includes('/api/v1')`
54
+ * is `true`, so a third-party host received the `Authorization: Bearer <token>` header.
55
+ *
56
+ * Everything here parses the URL instead of pattern-matching the string, and fails closed.
57
+ */
58
+ /**
59
+ * Stand-in origin used when there is no `window.location` (SSR, prerender, unit tests).
60
+ *
61
+ * why: without a base, a relative route entry like `'/api/v1'` cannot be parsed, so every
62
+ * origin-aware check would silently answer `false` on the server — e.g. the keycloak interceptor
63
+ * would stop attaching the bearer token to every server-rendered request. Resolving BOTH the route
64
+ * entry and the request URL against one fixed synthetic origin keeps relative-vs-relative matching
65
+ * consistent across environments, while an ABSOLUTE route entry still has to match a real origin,
66
+ * so nothing is loosened.
67
+ */
68
+ declare const SD_NON_BROWSER_ORIGIN = "http://sdcorejs.invalid";
69
+ /** Resolve the origin that relative URLs should be interpreted against. */
70
+ declare function sdResolveBaseOrigin(explicit?: string): string;
71
+ /**
72
+ * Parse `value` into a URL. Relative values are resolved against `base` when one is supplied.
73
+ * Returns `undefined` instead of throwing so callers can fail closed with a simple null check.
74
+ */
75
+ declare function sdParseUrl(value: string | null | undefined, base?: string): URL | undefined;
76
+ /**
77
+ * True only when `value` is an ABSOLUTE `http:`/`https:` URL.
78
+ *
79
+ * Replaces `url.startsWith('http')` / `path.includes('http')`. Note that `startsWith('http')` also
80
+ * accepts nonsense like `'httpfoo'`, and `includes('http')` accepts any string that merely mentions
81
+ * it — including `javascript:` payloads.
82
+ */
83
+ declare function sdIsExternalHttpUrl(value: string | null | undefined): boolean;
84
+ /**
85
+ * Open an external link in a new browsing context.
86
+ *
87
+ * Refuses anything that is not absolute `http:`/`https:` (returns `null` without opening), and
88
+ * always passes `noopener,noreferrer` so the opened page cannot reach back through `window.opener`
89
+ * (reverse tabnabbing).
90
+ */
91
+ declare function sdOpenExternal(value: string | null | undefined, target?: string): Window | null;
92
+ /**
93
+ * True when `url` is same-origin, or its origin is in `allowedOrigins`.
94
+ *
95
+ * Relative URLs (`/api/v1/users`) always count as same-origin. Outside a browser they resolve
96
+ * against {@link SD_NON_BROWSER_ORIGIN} unless `baseOrigin` is supplied.
97
+ */
98
+ declare function sdIsAllowedOrigin(url: string | null | undefined, allowedOrigins: readonly string[], baseOrigin?: string): boolean;
99
+ /**
100
+ * Decide whether an outgoing request matches one of the configured secure routes, i.e. whether it
101
+ * is allowed to carry credentials.
102
+ *
103
+ * A route entry is either:
104
+ * - a path prefix (`'/api/v1'`) — matches ONLY same-origin requests under that path, or
105
+ * - an absolute URL (`'https://api.example.com/v1'`) — matches that exact origin, under that path.
106
+ *
107
+ * Path matching is segment-aware: `'/api/v1'` matches `/api/v1` and `/api/v1/users`, but NOT
108
+ * `/api/v1beta`. Anything that fails to parse returns `false`.
109
+ */
110
+ declare function sdMatchesSecureRoute(url: string | null | undefined, routes: readonly string[] | undefined, baseOrigin?: string): boolean;
111
+ /**
112
+ * Segment-aware path prefix test: `/api/v1` covers `/api/v1` and `/api/v1/users`, but not
113
+ * `/api/v1beta`. A bare `/` prefix covers everything on that origin.
114
+ */
115
+ declare function sdIsPathPrefix(prefix: string, pathname: string): boolean;
116
+
117
+ export { ObjectUtilities, SD_NON_BROWSER_ORIGIN, SdUtilities, sdIsAllowedOrigin, sdIsExternalHttpUrl, sdIsPathPrefix, sdMatchesSecureRoute, sdOpenExternal, sdParseUrl, sdResolveBaseOrigin };
@@ -1,89 +1,15 @@
1
- import { Color, Size, MaybeAsync, NestedKeyOf, Operator, OperatorHasData, OperatorNoData, Filter, FilterAndOr, FilterBetween, FilterHasData, FilterNoData, Order, PagingReq, PagingRes, QueryReq } from '@sdcorejs/utils/models';
2
- export { Color, Filter, FilterAndOr, FilterBetween, FilterHasData, FilterNoData, MaybeAsync, NestedKeyOf, Operator, OperatorHasData, OperatorNoData, Order, PagingReq, PagingRes, QueryReq, Size, ValidationPattern, ValidationPatternType, normalizeAsync, resolveMaybeAsync } from '@sdcorejs/utils/models';
3
- import * as rxjs from 'rxjs';
4
1
  import { InputSignalWithTransform, InputSignal, ModelSignal } from '@angular/core';
5
- export { EMPTY_STR, VALIDATION_PATTERNS } from '@sdcorejs/utils/constants';
6
-
7
- /** @deprecated Use {@link Color} from `@sdcorejs/utils/models` instead */
8
- type SdColor = Color;
9
-
10
- /** @deprecated Use {@link Size} from `@sdcorejs/utils/models` instead */
11
- type SdSize = Size;
12
2
 
13
3
  type SdIconSet = 'material-icons' | 'material-icons-outlined' | 'material-icons-round' | 'material-icons-sharp' | 'lucide';
14
4
  type SdMaterialIconSet = Exclude<SdIconSet, 'lucide'>;
15
5
  declare const DefaultSdIconSet: SdIconSet;
16
6
  declare const DefaultSdMaterialIconSet: SdMaterialIconSet;
17
7
 
18
- /**
19
- * @deprecated Use {@link ValidationPatternType} from `@sdcorejs/utils/models` instead.
20
- * Note: member names changed — PHONE_VN → VN_PHONE, IDVN → VN_ID, IDVN_OR_PASSPORT → VN_ID_OR_PASSPORT.
21
- */
22
- type SdPatternType = 'EMAIL' | 'PHONE' | 'PHONE_VN' | 'IDVN' | 'PASSPORT' | 'IDVN_OR_PASSPORT' | 'TIME';
23
- /**
24
- * @deprecated Use {@link ValidationPattern} from `@sdcorejs/utils/models` instead.
25
- * Note: `regex` field renamed to `pattern` to align with Angular `Validators.pattern()`.
26
- */
27
- interface SdPatternCommon {
28
- type: SdPatternType;
29
- name: string;
30
- regex: string;
31
- errorMessage: string;
32
- }
33
- /** @deprecated Use `VALIDATION_PATTERNS` from `@sdcorejs/utils/constants` instead. */
34
- declare const SdPatternCommons: SdPatternCommon[];
35
-
36
- /** @deprecated Use {@link EMPTY_STR} from `@sdcorejs/utils/constants` instead */
37
- declare const SD_EMPTY_STR = "--";
38
-
39
- /** @deprecated Use {@link MaybeAsync} from `@sdcorejs/utils/models` instead */
40
- type SdMaybeAsync<T> = MaybeAsync<T>;
41
- /** @deprecated Use {@link resolveMaybeAsync} from `@sdcorejs/utils/models` instead */
42
- declare const SdResolveMaybeAsync: <T>(value: MaybeAsync<T>) => Promise<T>;
43
- /** @deprecated Use {@link normalizeAsync} from `@sdcorejs/utils/models` instead */
44
- declare const SdNormalizeAsync: <T>(value: MaybeAsync<T>) => rxjs.Observable<T>;
45
-
46
- /** @deprecated Use {@link NestedKeyOf} from `@sdcorejs/utils/models` instead */
47
- type SdNestedKeyOf<T> = NestedKeyOf<T>;
48
-
49
8
  /**
50
9
  * Utility Type: Bóc tách kiểu dữ liệu gốc từ Angular Signal Inputs & Models
51
10
  */
52
11
  type SdUnwrapSignal<T> = T extends InputSignalWithTransform<any, infer WriteT> ? WriteT : T extends InputSignal<infer ReadT> ? ReadT : T extends ModelSignal<infer ModelT> ? ModelT : T;
53
12
  type SdUnwrapSafe<T> = SdUnwrapSignal<NonNullable<T>>;
54
13
 
55
- /** @deprecated Use {@link Operator} from `@sdcorejs/utils/models` instead */
56
- type SdOperator = Operator;
57
- /** @deprecated Use {@link OperatorHasData} from `@sdcorejs/utils/models` instead */
58
- type SdOperatorHasData = OperatorHasData;
59
- /** @deprecated Use {@link OperatorNoData} from `@sdcorejs/utils/models` instead */
60
- type SdOperatorNoData = OperatorNoData;
61
- declare const SdOperators: {
62
- value: Operator;
63
- symbol?: string;
64
- display: string;
65
- }[];
66
-
67
- /** @deprecated Use {@link Filter} from `@sdcorejs/utils/models` instead */
68
- type SdFilter<T = any> = Filter<T>;
69
- /** @deprecated Use {@link FilterHasData} from `@sdcorejs/utils/models` instead */
70
- type SdFilterHasData<T = any> = FilterHasData<T>;
71
- /** @deprecated Use {@link FilterBetween} from `@sdcorejs/utils/models` instead */
72
- type SdFilterBetween<T = any> = FilterBetween<T>;
73
- /** @deprecated Use {@link FilterNoData} from `@sdcorejs/utils/models` instead */
74
- type SdFilterNoData<T = any> = FilterNoData<T>;
75
- /** @deprecated Use {@link FilterAndOr} from `@sdcorejs/utils/models` instead */
76
- type SdFilterAndOr<T = any> = FilterAndOr<T>;
77
-
78
- /** @deprecated Use {@link Order} from `@sdcorejs/utils/models` instead */
79
- type SdOrder<T = any> = Order<T>;
80
-
81
- /** @deprecated Use {@link QueryReq} from `@sdcorejs/utils/models` instead */
82
- type SdQueryReq<T = any> = QueryReq<T>;
83
- /** @deprecated Use {@link PagingReq} from `@sdcorejs/utils/models` instead */
84
- type SdPagingReq<T = any> = PagingReq<T>;
85
- /** @deprecated Use {@link PagingRes} from `@sdcorejs/utils/models` instead */
86
- type SdPagingRes<T = any> = PagingRes<T>;
87
-
88
- export { DefaultSdIconSet, DefaultSdMaterialIconSet, SD_EMPTY_STR, SdNormalizeAsync, SdOperators, SdPatternCommons, SdResolveMaybeAsync };
89
- export type { SdColor, SdFilter, SdFilterAndOr, SdFilterBetween, SdFilterHasData, SdFilterNoData, SdIconSet, SdMaterialIconSet, SdMaybeAsync, SdNestedKeyOf, SdOperator, SdOperatorHasData, SdOperatorNoData, SdOrder, SdPagingReq, SdPagingRes, SdPatternCommon, SdPatternType, SdQueryReq, SdSize, SdUnwrapSafe, SdUnwrapSignal };
14
+ export { DefaultSdIconSet, DefaultSdMaterialIconSet };
15
+ export type { SdIconSet, SdMaterialIconSet, SdUnwrapSafe, SdUnwrapSignal };
@@ -1,11 +0,0 @@
1
- import { SdLicenseService } from '@sdcorejs/angular/services/license';
2
- import * as i0 from '@angular/core';
3
-
4
- declare abstract class SdBaseSecureComponent {
5
- protected licenseService: SdLicenseService;
6
- constructor();
7
- static ɵfac: i0.ɵɵFactoryDeclaration<SdBaseSecureComponent, never>;
8
- static ɵdir: i0.ɵɵDirectiveDeclaration<SdBaseSecureComponent, never, never, {}, {}, never, never, true, never>;
9
- }
10
-
11
- export { SdBaseSecureComponent };