@donotdev/ui 0.0.2 → 0.0.4

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 (119) hide show
  1. package/dist/components/auth/AuthMenu.d.ts.map +1 -1
  2. package/dist/components/auth/AuthMenu.js +19 -32
  3. package/dist/components/common/FeatureCard.d.ts +7 -19
  4. package/dist/components/common/FeatureCard.d.ts.map +1 -1
  5. package/dist/components/common/FeatureCard.js +5 -29
  6. package/dist/components/common/TechBento.d.ts +15 -3
  7. package/dist/components/common/TechBento.d.ts.map +1 -1
  8. package/dist/components/common/TechBento.js +20 -2
  9. package/dist/components/cookie-consent/CookieConsent.d.ts.map +1 -1
  10. package/dist/components/cookie-consent/CookieConsent.js +2 -41
  11. package/dist/components/cookie-consent/index.d.ts +0 -1
  12. package/dist/components/cookie-consent/index.d.ts.map +1 -1
  13. package/dist/components/cookie-consent/index.js +1 -1
  14. package/dist/components/layout/components/DropdownNavigation.d.ts.map +1 -1
  15. package/dist/components/layout/components/header/ThemeToggle.d.ts +1 -1
  16. package/dist/components/layout/components/header/ThemeToggle.d.ts.map +1 -1
  17. package/dist/components/layout/components/header/ThemeToggle.js +5 -4
  18. package/dist/dndev.css +373 -249
  19. package/dist/index.js +4 -4
  20. package/dist/internal/devtools/DebugTools.d.ts.map +1 -1
  21. package/dist/internal/devtools/DebugTools.js +8 -4
  22. package/dist/internal/devtools/components/ConfigTab.d.ts.map +1 -1
  23. package/dist/internal/devtools/components/ConfigTab.js +33 -133
  24. package/dist/internal/devtools/components/DebugDialog.d.ts.map +1 -1
  25. package/dist/internal/devtools/components/DebugDialog.js +11 -520
  26. package/dist/internal/devtools/components/DesignTab.d.ts +2 -0
  27. package/dist/internal/devtools/components/DesignTab.d.ts.map +1 -0
  28. package/dist/internal/devtools/components/DesignTab.js +431 -0
  29. package/dist/internal/devtools/components/StoresTab.d.ts.map +1 -1
  30. package/dist/internal/devtools/components/StoresTab.js +54 -102
  31. package/dist/internal/devtools/components/index.d.ts +1 -6
  32. package/dist/internal/devtools/components/index.d.ts.map +1 -1
  33. package/dist/internal/devtools/components/index.js +1 -6
  34. package/dist/internal/devtools/utils/index.d.ts +0 -1
  35. package/dist/internal/devtools/utils/index.d.ts.map +1 -1
  36. package/dist/internal/devtools/utils/index.js +0 -1
  37. package/dist/internal/initializers/BaseStoresInitializer.d.ts.map +1 -1
  38. package/dist/internal/initializers/BaseStoresInitializer.js +36 -59
  39. package/dist/internal/layout/DnDevLayout.js +3 -3
  40. package/dist/internal/layout/components/AutoMetaTags.d.ts.map +1 -1
  41. package/dist/internal/layout/components/AutoMetaTags.js +6 -1
  42. package/dist/internal/layout/components/footer/FooterBranding.d.ts.map +1 -1
  43. package/dist/internal/layout/components/footer/FooterBranding.js +3 -1
  44. package/dist/internal/layout/zones/DnDevFooter.js +2 -2
  45. package/dist/routing/AuthGuard.d.ts +14 -10
  46. package/dist/routing/AuthGuard.d.ts.map +1 -1
  47. package/dist/routing/AuthGuard.js +25 -22
  48. package/dist/routing/Link.d.ts +2 -2
  49. package/dist/routing/Link.js +2 -2
  50. package/dist/routing/hooks/hooks.next.js +1 -1
  51. package/dist/routing/hooks/hooks.vite.js +1 -1
  52. package/dist/routing/hooks/useRedirectGuard.next.d.ts +2 -36
  53. package/dist/routing/hooks/useRedirectGuard.next.d.ts.map +1 -1
  54. package/dist/routing/hooks/useRedirectGuard.next.js +14 -55
  55. package/dist/routing/hooks/useRedirectGuard.vite.d.ts +2 -36
  56. package/dist/routing/hooks/useRedirectGuard.vite.d.ts.map +1 -1
  57. package/dist/routing/hooks/useRedirectGuard.vite.js +14 -55
  58. package/dist/routing/index.d.ts +0 -1
  59. package/dist/routing/index.d.ts.map +1 -1
  60. package/dist/routing/index.js +1 -1
  61. package/dist/styles/index.css +373 -249
  62. package/dist/utils/assetResolver.d.ts +5 -5
  63. package/dist/utils/assetResolver.d.ts.map +1 -1
  64. package/dist/utils/assetResolver.js +26 -15
  65. package/dist/utils/index.d.ts +1 -0
  66. package/dist/utils/index.d.ts.map +1 -1
  67. package/dist/utils/index.js +1 -0
  68. package/dist/utils/tList.d.ts +30 -0
  69. package/dist/utils/tList.d.ts.map +1 -0
  70. package/dist/utils/tList.js +51 -0
  71. package/dist/utils/useAuthSafe.d.ts +25 -12
  72. package/dist/utils/useAuthSafe.d.ts.map +1 -1
  73. package/dist/utils/useAuthSafe.js +3 -1
  74. package/dist/utils/useAuthVisibility.d.ts +3 -3
  75. package/dist/utils/useAuthVisibility.d.ts.map +1 -1
  76. package/dist/utils/useAuthVisibility.js +25 -21
  77. package/dist/utils/useBillingVisibility.d.ts +2 -2
  78. package/dist/utils/useBillingVisibility.d.ts.map +1 -1
  79. package/dist/utils/useBillingVisibility.js +12 -13
  80. package/dist/utils/useCrudSafe.d.ts +1 -1
  81. package/dist/utils/useCrudSafe.d.ts.map +1 -1
  82. package/dist/utils/useCrudSafe.js +26 -13
  83. package/dist/utils/useOAuthSafe.d.ts +25 -12
  84. package/dist/utils/useOAuthSafe.d.ts.map +1 -1
  85. package/dist/utils/useStripeBillingSafe.d.ts +30 -18
  86. package/dist/utils/useStripeBillingSafe.d.ts.map +1 -1
  87. package/dist/utils/useStripeBillingSafe.js +5 -6
  88. package/dist/vite-routing/AppRoutes.d.ts.map +1 -1
  89. package/dist/vite-routing/AppRoutes.js +5 -5
  90. package/dist/vite-routing/RootLayout.d.ts.map +1 -1
  91. package/dist/vite-routing/RootLayout.js +34 -7
  92. package/package.json +9 -9
  93. package/dist/internal/devtools/components/AuthTab.d.ts +0 -2
  94. package/dist/internal/devtools/components/AuthTab.d.ts.map +0 -1
  95. package/dist/internal/devtools/components/AuthTab.js +0 -98
  96. package/dist/internal/devtools/components/ColorRatioTab.d.ts +0 -2
  97. package/dist/internal/devtools/components/ColorRatioTab.d.ts.map +0 -1
  98. package/dist/internal/devtools/components/ColorRatioTab.js +0 -322
  99. package/dist/internal/devtools/components/DebugToggle.d.ts +0 -2
  100. package/dist/internal/devtools/components/DebugToggle.d.ts.map +0 -1
  101. package/dist/internal/devtools/components/DebugToggle.js +0 -57
  102. package/dist/internal/devtools/components/EnvironmentTab.d.ts +0 -2
  103. package/dist/internal/devtools/components/EnvironmentTab.d.ts.map +0 -1
  104. package/dist/internal/devtools/components/EnvironmentTab.js +0 -26
  105. package/dist/internal/devtools/components/I18nTab.d.ts +0 -2
  106. package/dist/internal/devtools/components/I18nTab.d.ts.map +0 -1
  107. package/dist/internal/devtools/components/I18nTab.js +0 -76
  108. package/dist/internal/devtools/components/OAuthGuideButton.d.ts +0 -10
  109. package/dist/internal/devtools/components/OAuthGuideButton.d.ts.map +0 -1
  110. package/dist/internal/devtools/components/OAuthGuideButton.js +0 -71
  111. package/dist/internal/devtools/components/StripeDebugTab.d.ts +0 -2
  112. package/dist/internal/devtools/components/StripeDebugTab.d.ts.map +0 -1
  113. package/dist/internal/devtools/components/StripeDebugTab.js +0 -175
  114. package/dist/internal/devtools/components/ThemesTab.d.ts +0 -2
  115. package/dist/internal/devtools/components/ThemesTab.d.ts.map +0 -1
  116. package/dist/internal/devtools/components/ThemesTab.js +0 -77
  117. package/dist/internal/devtools/utils/spacingAnalyzer.d.ts +0 -15
  118. package/dist/internal/devtools/utils/spacingAnalyzer.d.ts.map +0 -1
  119. package/dist/internal/devtools/utils/spacingAnalyzer.js +0 -88
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Asset formats interface
3
3
  *
4
- * @version 0.0.1
4
+ * @version 0.0.3
5
5
  * @since 0.0.1
6
6
  * @author AMBROISE PARK Consulting
7
7
  */
@@ -14,7 +14,7 @@ export interface AssetFormats {
14
14
  /**
15
15
  * Favicon set interface
16
16
  *
17
- * @version 0.0.1
17
+ * @version 0.0.3
18
18
  * @since 0.0.1
19
19
  * @author AMBROISE PARK Consulting
20
20
  */
@@ -58,7 +58,7 @@ interface AssetManifest {
58
58
  * Modern asset resolution with format preference and browser capability detection
59
59
  * Follows Next.js Image optimization patterns
60
60
  *
61
- * @version 0.0.1
61
+ * @version 0.0.3
62
62
  * @since 0.0.1
63
63
  * @author AMBROISE PARK Consulting
64
64
  */
@@ -126,7 +126,7 @@ export declare class AssetResolver {
126
126
  /**
127
127
  * Utility function for logo resolution
128
128
  *
129
- * @version 0.0.1
129
+ * @version 0.0.3
130
130
  * @since 0.0.1
131
131
  * @author AMBROISE PARK Consulting
132
132
  */
@@ -134,7 +134,7 @@ export declare function resolveLogo(customPath?: string): string;
134
134
  /**
135
135
  * Utility function for favicon resolution
136
136
  *
137
- * @version 0.0.1
137
+ * @version 0.0.3
138
138
  * @since 0.0.1
139
139
  * @author AMBROISE PARK Consulting
140
140
  */
@@ -1 +1 @@
1
- {"version":3,"file":"assetResolver.d.ts","sourceRoot":"","sources":["../../src/utils/assetResolver.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,cAAc;IACtB,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,GAAG,CAAC,EAAE,UAAU,CAAC;KAClB,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE;QACd,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACrB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAKD;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAA0B;IAE9C;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,cAAc;IAyC1C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAmBlC;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAYzC;;OAEG;IACH,MAAM,CAAC,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAM/C;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAKzC;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;IAe/C;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAgB/B;;;OAGG;IACH,MAAM,CAAC,iBAAiB,IAAI,UAAU;IAkDtC;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,MAAM;IAuB/B;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;IASzB;;OAEG;IACH,MAAM,CAAC,YAAY;;;;;;;;CAQpB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CAE9C;AAgBD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"assetResolver.d.ts","sourceRoot":"","sources":["../../src/utils/assetResolver.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,cAAc;IACtB,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,GAAG,CAAC,EAAE,UAAU,CAAC;KAClB,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE;QACd,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACrB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAKD;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAA0B;IAE9C;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,cAAc;IAyC1C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAmBlC;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAYzC;;OAEG;IACH,MAAM,CAAC,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAM/C;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAKzC;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;IAe/C;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAgB/B;;;OAGG;IACH,MAAM,CAAC,iBAAiB,IAAI,UAAU;IA6DtC;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,MAAM;IAuB/B;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;IASzB;;OAEG;IACH,MAAM,CAAC,YAAY;;;;;;;;CAQpB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CAE9C;AAgBD,eAAe,aAAa,CAAC"}
@@ -3,7 +3,7 @@
3
3
  * @fileoverview Modern asset resolution system for DoNotDev
4
4
  * @description Handles logo and favicon resolution with format preferences and fallbacks
5
5
  *
6
- * @version 0.0.1
6
+ * @version 0.0.3
7
7
  * @since 0.0.1
8
8
  * @author AMBROISE PARK Consulting
9
9
  */
@@ -14,7 +14,7 @@ import { getDndevConfig, isClient, isDev } from '@donotdev/core';
14
14
  * Modern asset resolution with format preference and browser capability detection
15
15
  * Follows Next.js Image optimization patterns
16
16
  *
17
- * @version 0.0.1
17
+ * @version 0.0.3
18
18
  * @since 0.0.1
19
19
  * @author AMBROISE PARK Consulting
20
20
  */
@@ -164,38 +164,49 @@ export class AssetResolver {
164
164
  const manifest = this.getAssetManifest();
165
165
  if (manifest?.favicon?.set) {
166
166
  const set = manifest.favicon.set;
167
+ // Use icon-512x512.png as fallback (generated from logo.svg)
168
+ const fallbackIcon = this.assetExists('/icon-512x512.png')
169
+ ? '/icon-512x512.png'
170
+ : this.assetExists('/icon-192x192.png')
171
+ ? '/icon-192x192.png'
172
+ : '/logo.svg';
167
173
  // Filter out null values and provide framework fallbacks
168
174
  const resolvedSet = {
169
175
  svg: set.svg || '/favicon.svg',
170
176
  ico: set.ico || '/favicon.ico',
171
- png16: set.png16 || '/logo.png',
172
- png32: set.png32 || '/logo.png',
173
- apple180: set.apple180 || '/logo.png',
174
- android192: set.android192 || '/logo.png',
175
- android512: set.android512 || '/logo.png',
177
+ png16: set.png16 || fallbackIcon,
178
+ png32: set.png32 || fallbackIcon,
179
+ apple180: set.apple180 || fallbackIcon,
180
+ android192: set.android192 || fallbackIcon,
181
+ android512: set.android512 || fallbackIcon,
176
182
  };
177
183
  this.cache.set(cacheKey, resolvedSet);
178
184
  return resolvedSet;
179
185
  }
180
- // Manual detection fallback
186
+ // Manual detection fallback - use generated icons instead of logo.png
187
+ const fallbackIcon = this.assetExists('/icon-512x512.png')
188
+ ? '/icon-512x512.png'
189
+ : this.assetExists('/icon-192x192.png')
190
+ ? '/icon-192x192.png'
191
+ : '/logo.svg';
181
192
  const faviconSet = {
182
193
  svg: this.assetExists('/favicon.svg') ? '/favicon.svg' : '/logo.svg',
183
194
  ico: this.assetExists('/favicon.ico') ? '/favicon.ico' : '/favicon.svg',
184
195
  png16: this.assetExists('/favicon-16x16.png')
185
196
  ? '/favicon-16x16.png'
186
- : '/logo.png',
197
+ : fallbackIcon,
187
198
  png32: this.assetExists('/favicon-32x32.png')
188
199
  ? '/favicon-32x32.png'
189
- : '/logo.png',
200
+ : fallbackIcon,
190
201
  apple180: this.assetExists('/apple-touch-icon.png')
191
202
  ? '/apple-touch-icon.png'
192
- : '/logo.png',
203
+ : fallbackIcon,
193
204
  android192: this.assetExists('/icon-192x192.png')
194
205
  ? '/icon-192x192.png'
195
- : '/logo.png',
206
+ : fallbackIcon,
196
207
  android512: this.assetExists('/icon-512x512.png')
197
208
  ? '/icon-512x512.png'
198
- : '/logo.png',
209
+ : fallbackIcon,
199
210
  };
200
211
  this.cache.set(cacheKey, faviconSet);
201
212
  return faviconSet;
@@ -248,7 +259,7 @@ export class AssetResolver {
248
259
  /**
249
260
  * Utility function for logo resolution
250
261
  *
251
- * @version 0.0.1
262
+ * @version 0.0.3
252
263
  * @since 0.0.1
253
264
  * @author AMBROISE PARK Consulting
254
265
  */
@@ -258,7 +269,7 @@ export function resolveLogo(customPath) {
258
269
  /**
259
270
  * Utility function for favicon resolution
260
271
  *
261
- * @version 0.0.1
272
+ * @version 0.0.3
262
273
  * @since 0.0.1
263
274
  * @author AMBROISE PARK Consulting
264
275
  */
@@ -13,4 +13,5 @@ export * from './useStripeBillingSafe';
13
13
  export * from './useBillingVisibility';
14
14
  export * from './useCrudSafe';
15
15
  export * from './useOAuthSafe';
16
+ export * from './tList';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC"}
@@ -14,3 +14,4 @@ export * from './useStripeBillingSafe';
14
14
  export * from './useBillingVisibility';
15
15
  export * from './useCrudSafe';
16
16
  export * from './useOAuthSafe';
17
+ export * from './tList';
@@ -0,0 +1,30 @@
1
+ import type { LucideIcon } from 'lucide-react';
2
+ import type { TFunction } from 'i18next';
3
+ import type { ReactNode } from 'react';
4
+ /**
5
+ * Renders a translated array as a List with optional icon
6
+ *
7
+ * Opinionated helper that reduces boilerplate for the common pattern:
8
+ * `<List icon={<CheckCircle size={16} />} items={translateArray(t, key, count)} />`
9
+ *
10
+ * @param t - Translation function from useTranslation
11
+ * @param key - Translation key prefix for the array
12
+ * @param count - Maximum number of items to fetch
13
+ * @param icon - Lucide icon, null for no icon, or undefined for default (CheckCircle)
14
+ * @param size - Optional icon size (default: 16)
15
+ * @returns ReactNode containing the List component
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * // With default icon (CheckCircle)
20
+ * <Card content={tList(t, 'features.items', 4)} />
21
+ *
22
+ * // With custom icon
23
+ * <Card content={tList(t, 'features.items', 4, Star)} />
24
+ *
25
+ * // Without icon (for emoji-prefixed labels like "🚀 Kick-off")
26
+ * <Card content={tList(t, 'features.items', 4, null)} />
27
+ * ```
28
+ */
29
+ export declare function tList(t: TFunction, key: string, count: number, icon?: LucideIcon | null, size?: number): ReactNode;
30
+ //# sourceMappingURL=tList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tList.d.ts","sourceRoot":"","sources":["../../src/utils/tList.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAevC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,KAAK,CACnB,CAAC,EAAE,SAAS,EACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,UAAU,GAAG,IAAmB,EACtC,IAAI,GAAE,MAAqB,GAC1B,SAAS,CAUX"}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // packages/ui/src/utils/tList.tsx
3
+ /**
4
+ * @fileoverview Translated List helper
5
+ * @description Opinionated helper for rendering translated content as List
6
+ *
7
+ * @version 0.0.1
8
+ * @since 0.0.4
9
+ * @author AMBROISE PARK Consulting
10
+ */
11
+ import { CheckCircle } from 'lucide-react';
12
+ import { List } from '@donotdev/components';
13
+ import { translateArray } from '@donotdev/core';
14
+ /**
15
+ * Framework default icon for list items
16
+ */
17
+ const DEFAULT_ICON = CheckCircle;
18
+ /**
19
+ * Framework default icon size (matches --icon-sm)
20
+ */
21
+ const DEFAULT_SIZE = 16;
22
+ /**
23
+ * Renders a translated array as a List with optional icon
24
+ *
25
+ * Opinionated helper that reduces boilerplate for the common pattern:
26
+ * `<List icon={<CheckCircle size={16} />} items={translateArray(t, key, count)} />`
27
+ *
28
+ * @param t - Translation function from useTranslation
29
+ * @param key - Translation key prefix for the array
30
+ * @param count - Maximum number of items to fetch
31
+ * @param icon - Lucide icon, null for no icon, or undefined for default (CheckCircle)
32
+ * @param size - Optional icon size (default: 16)
33
+ * @returns ReactNode containing the List component
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * // With default icon (CheckCircle)
38
+ * <Card content={tList(t, 'features.items', 4)} />
39
+ *
40
+ * // With custom icon
41
+ * <Card content={tList(t, 'features.items', 4, Star)} />
42
+ *
43
+ * // Without icon (for emoji-prefixed labels like "🚀 Kick-off")
44
+ * <Card content={tList(t, 'features.items', 4, null)} />
45
+ * ```
46
+ */
47
+ export function tList(t, key, count, icon = DEFAULT_ICON, size = DEFAULT_SIZE) {
48
+ const Icon = icon;
49
+ const iconElement = Icon ? _jsx(Icon, { size: size }) : undefined;
50
+ return (_jsx(List, { icon: iconElement, items: translateArray(t, key, count), style: { listStyle: 'none', paddingInlineStart: 0 } }));
51
+ }
@@ -3,18 +3,31 @@
3
3
  * @description Provides auth functionality when @donotdev/auth is installed,
4
4
  * gracefully degrades to no-op when not installed.
5
5
  *
6
- * **How it works:**
7
- * 1. Import @donotdev/auth (Vite aliases to empty module if not installed)
8
- * 2. Check if useAuth export exists
9
- * 3. If exists use real hook | If not → use stub
10
- *
11
- * **Why this pattern:**
12
- * - Vite aliases missing packages to empty modules at build time
13
- * - Decision is made ONCE at import time, never changes
14
- * - No conditional hook calls = no Rules of Hooks violations
15
- * - Real hook handles all runtime state (Firebase, consent) internally
16
- *
17
- * @version 0.0.1
6
+ * ## CRITICAL: DO NOT USE DYNAMIC IMPORTS
7
+ *
8
+ * This file MUST use sync `import * as authModule from '@donotdev/auth'`
9
+ * at module level. DO NOT refactor to use async `import('@donotdev/auth').then(...)`.
10
+ *
11
+ * ### Why sync import is required:
12
+ *
13
+ * 1. **Bundler aliasing**: Vite/webpack alias missing packages to empty modules
14
+ * at BUILD TIME. The import completes immediately (no async).
15
+ *
16
+ * 2. **Rules of Hooks**: If we use async dynamic import:
17
+ * - First render: `realUseAuth = null` → uses stub (0 hooks)
18
+ * - Async completes: `realUseAuth = useAuth` → now has hooks
19
+ * - Next render: React sees different hook count → CRASH
20
+ *
21
+ * 3. **Monorepo gotcha**: Dynamic imports resolve workspace packages even when
22
+ * the consuming app doesn't have them as dependencies. This causes the
23
+ * real hook to activate unexpectedly → Rules of Hooks violation.
24
+ *
25
+ * 4. **Decision is immutable**: With sync import, `authModule?.useAuth` is
26
+ * evaluated ONCE at module load. It's either the real hook or undefined.
27
+ * This never changes during the app lifecycle.
28
+ *
29
+ * @see docs/development/GRACEFUL_DEGRADATION.md
30
+ * @version 0.0.4
18
31
  * @since 0.0.1
19
32
  * @author AMBROISE PARK Consulting
20
33
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useAuthSafe.d.ts","sourceRoot":"","sources":["../../src/utils/useAuthSafe.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAkB9C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAKvE;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,SAAoC,CAAC"}
1
+ {"version":3,"file":"useAuthSafe.d.ts","sourceRoot":"","sources":["../../src/utils/useAuthSafe.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAoB9C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAKvE;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,SAAoC,CAAC"}
@@ -1,7 +1,9 @@
1
1
  // packages/ui/src/utils/useAuthSafe.ts
2
2
  import { DEGRADED_AUTH_API } from '@donotdev/core';
3
+ // Sync import - bundler aliases to empty module if not installed
4
+ // Decision made ONCE at module load time, never changes
3
5
  import * as authModule from '@donotdev/auth';
4
- // Check if real hook exists (will be undefined if Vite aliased to empty module)
6
+ // Extract useAuth if available (undefined if package not installed/aliased)
5
7
  const realUseAuth = authModule?.useAuth;
6
8
  /**
7
9
  * Stub that returns degraded auth values.
@@ -20,9 +20,9 @@ export interface AuthVisibilityState {
20
20
  * Hook to determine auth UI visibility and loading states
21
21
  *
22
22
  * **Visibility Rules:**
23
- * - Hide if `!initialized || !isAvailable` (not ready or not installed)
24
- * - Show with loading if `loading` during operations (user action in progress)
25
- * - Show normal UI when `initialized && isAvailable && !loading`
23
+ * - Hide if `status !== 'ready' || !isAvailable` (not ready or not installed)
24
+ * - Show with loading if `status === 'initializing'` during operations
25
+ * - Show normal UI when `status === 'ready' && isAvailable`
26
26
  *
27
27
  * @returns AuthVisibilityState with visibility flags
28
28
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useAuthVisibility.d.ts","sourceRoot":"","sources":["../../src/utils/useAuthVisibility.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CAkBvD"}
1
+ {"version":3,"file":"useAuthVisibility.d.ts","sourceRoot":"","sources":["../../src/utils/useAuthVisibility.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CAqBvD"}
@@ -1,25 +1,26 @@
1
1
  // packages/ui/src/utils/useAuthVisibility.ts
2
2
  /**
3
3
  * @fileoverview useAuthVisibility Hook
4
- * @description Determines when to show/hide auth UI based on initialization and loading states
4
+ * @description Determines when to show/hide auth UI based on feature status
5
5
  *
6
6
  * This hook encapsulates the common pattern for auth UI visibility:
7
- * - Hide if not initialized or not available (not ready yet)
8
- * - Show with loading state during operations (user action in progress)
9
- * - Show normal UI when ready
7
+ * - Hide if status !== 'ready' or not available (not ready yet)
8
+ * - Show with loading state during initialization
9
+ * - Show normal UI when status === 'ready'
10
10
  *
11
- * @version 0.0.1
11
+ * @version 0.0.3
12
12
  * @since 0.0.1
13
13
  * @author AMBROISE PARK Consulting
14
14
  */
15
+ import { useMemo } from 'react';
15
16
  import { useAuthSafe } from './useAuthSafe';
16
17
  /**
17
18
  * Hook to determine auth UI visibility and loading states
18
19
  *
19
20
  * **Visibility Rules:**
20
- * - Hide if `!initialized || !isAvailable` (not ready or not installed)
21
- * - Show with loading if `loading` during operations (user action in progress)
22
- * - Show normal UI when `initialized && isAvailable && !loading`
21
+ * - Hide if `status !== 'ready' || !isAvailable` (not ready or not installed)
22
+ * - Show with loading if `status === 'initializing'` during operations
23
+ * - Show normal UI when `status === 'ready' && isAvailable`
23
24
  *
24
25
  * @returns AuthVisibilityState with visibility flags
25
26
  *
@@ -41,19 +42,22 @@ import { useAuthSafe } from './useAuthSafe';
41
42
  * ```
42
43
  */
43
44
  export function useAuthVisibility() {
44
- const initialized = useAuthSafe('initialized');
45
- const authStateChecked = useAuthSafe('authStateChecked');
46
- const loading = useAuthSafe('loading');
45
+ // Read all values first - each triggers subscription
46
+ const status = useAuthSafe('status');
47
47
  const isAvailable = useAuthSafe('isAvailable');
48
48
  const user = useAuthSafe('user');
49
- const shouldHide = !initialized || !isAvailable;
50
- const isLoading = Boolean(loading);
51
- const isReady = initialized && isAvailable && authStateChecked;
52
- const isAuthenticated = Boolean(user);
53
- return {
54
- shouldHide,
55
- isLoading,
56
- isReady,
57
- isAuthenticated,
58
- };
49
+ // Derive all visibility state atomically from current values
50
+ // useMemo ensures consistent state within a single render
51
+ return useMemo(() => {
52
+ const shouldHide = status !== 'ready' || !isAvailable;
53
+ const isLoading = status === 'initializing';
54
+ const isReady = status === 'ready' && isAvailable;
55
+ const isAuthenticated = Boolean(user);
56
+ return {
57
+ shouldHide,
58
+ isLoading,
59
+ isReady,
60
+ isAuthenticated,
61
+ };
62
+ }, [status, isAvailable, user]);
59
63
  }
@@ -17,8 +17,8 @@ export interface BillingVisibilityState {
17
17
  *
18
18
  * **Visibility Rules:**
19
19
  * - Hide if `!isAvailable` (not installed/configured)
20
- * - Show with loading if `loading` during operations (user action in progress)
21
- * - Show normal UI when `isAvailable && !loading`
20
+ * - Show with loading if `status === 'initializing'` during operations
21
+ * - Show normal UI when `isAvailable && status === 'ready'`
22
22
  *
23
23
  * @returns BillingVisibilityState with visibility flags
24
24
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useBillingVisibility.d.ts","sourceRoot":"","sources":["../../src/utils/useBillingVisibility.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CA2B7D"}
1
+ {"version":3,"file":"useBillingVisibility.d.ts","sourceRoot":"","sources":["../../src/utils/useBillingVisibility.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CA0B7D"}
@@ -1,14 +1,14 @@
1
1
  // packages/ui/src/utils/useBillingVisibility.ts
2
2
  /**
3
3
  * @fileoverview useBillingVisibility Hook
4
- * @description Determines when to show/hide billing UI based on availability and loading states
4
+ * @description Determines when to show/hide billing UI based on feature status
5
5
  *
6
6
  * This hook encapsulates the common pattern for billing UI visibility:
7
7
  * - Hide if not available (not installed/configured)
8
- * - Show with loading state during operations
9
- * - Show normal UI when ready
8
+ * - Show with loading state during initialization
9
+ * - Show normal UI when status === 'ready'
10
10
  *
11
- * @version 0.0.1
11
+ * @version 0.0.3
12
12
  * @since 0.0.1
13
13
  * @author AMBROISE PARK Consulting
14
14
  */
@@ -19,8 +19,8 @@ import { useStripeBillingSafe } from './useStripeBillingSafe';
19
19
  *
20
20
  * **Visibility Rules:**
21
21
  * - Hide if `!isAvailable` (not installed/configured)
22
- * - Show with loading if `loading` during operations (user action in progress)
23
- * - Show normal UI when `isAvailable && !loading`
22
+ * - Show with loading if `status === 'initializing'` during operations
23
+ * - Show normal UI when `isAvailable && status === 'ready'`
24
24
  *
25
25
  * @returns BillingVisibilityState with visibility flags
26
26
  *
@@ -42,16 +42,15 @@ import { useStripeBillingSafe } from './useStripeBillingSafe';
42
42
  export function useBillingVisibility() {
43
43
  // Get auth state for billing (required for isAvailable to work)
44
44
  const user = useAuthSafe('user');
45
- const initialized = useAuthSafe('initialized');
46
- const authStateChecked = useAuthSafe('authStateChecked');
47
- const authState = { user, initialized, authStateChecked };
48
- const loading = useStripeBillingSafe('loading', authState);
45
+ const status = useAuthSafe('status');
46
+ const authState = { user, status };
47
+ const billingStatus = useStripeBillingSafe('status', authState);
49
48
  const isAvailable = useStripeBillingSafe('isAvailable', authState);
50
49
  const shouldHide = !isAvailable;
51
- const isLoading = Boolean(loading);
52
- const isReady = isAvailable;
50
+ const isLoading = billingStatus === 'initializing';
51
+ const isReady = isAvailable && billingStatus === 'ready';
53
52
  console.log('[useBillingVisibility]', {
54
- loading,
53
+ billingStatus,
55
54
  isAvailable,
56
55
  shouldHide,
57
56
  isLoading,
@@ -17,7 +17,7 @@ interface UseCrudOptions<T> {
17
17
  * @example
18
18
  * ```typescript
19
19
  * const crud = useCrudSafe('users', { backend: 'firestore', schema: UserSchema });
20
- * const { data, loading, error, get, set } = crud;
20
+ * const { data, status, error, get, set } = crud;
21
21
  * ```
22
22
  */
23
23
  export declare function useCrudSafe<T = unknown>(collection: string, options?: UseCrudOptions<T>): CrudAPI<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"useCrudSafe.d.ts","sourceRoot":"","sources":["../../src/utils/useCrudSafe.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAK3D,KAAK,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE7C,UAAU,cAAc,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CACzB;AAeD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,OAAO,EACrC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,cAAc,CAAC,CAAC,CAAM,GAC9B,OAAO,CAAC,CAAC,CAAC,CAKZ;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,SAAoC,CAAC"}
1
+ {"version":3,"file":"useCrudSafe.d.ts","sourceRoot":"","sources":["../../src/utils/useCrudSafe.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAK3D,KAAK,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE7C,UAAU,cAAc,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CACzB;AAeD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,OAAO,EACrC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,cAAc,CAAC,CAAC,CAAM,GAC9B,OAAO,CAAC,CAAC,CAAC,CAKZ;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,SAAoC,CAAC"}
@@ -4,18 +4,31 @@
4
4
  * @description Provides CRUD functionality when @donotdev/crud is installed,
5
5
  * gracefully degrades to no-op when not installed.
6
6
  *
7
- * **How it works:**
8
- * 1. Import @donotdev/crud (Vite aliases to empty module if not installed)
9
- * 2. Check if useCrud export exists
10
- * 3. If exists use real hook | If not → use stub
11
- *
12
- * **Why this pattern:**
13
- * - Vite aliases missing packages to empty modules at build time
14
- * - Decision is made ONCE at import time, never changes
15
- * - No conditional hook calls = no Rules of Hooks violations
16
- * - Real hook handles all runtime state (Firebase, consent) internally
17
- *
18
- * @version 0.0.1
7
+ * ## CRITICAL: DO NOT USE DYNAMIC IMPORTS
8
+ *
9
+ * This file MUST use sync `import * as crudModule from '@donotdev/crud'`
10
+ * at module level. DO NOT refactor to use async `import('@donotdev/crud').then(...)`.
11
+ *
12
+ * ### Why sync import is required:
13
+ *
14
+ * 1. **Bundler aliasing**: Vite/webpack alias missing packages to empty modules
15
+ * at BUILD TIME. The import completes immediately (no async).
16
+ *
17
+ * 2. **Rules of Hooks**: If we use async dynamic import:
18
+ * - First render: `realUseCrud = null` → uses stub (0 hooks)
19
+ * - Async completes: `realUseCrud = useCrud` → now has hooks
20
+ * - Next render: React sees different hook count → CRASH
21
+ *
22
+ * 3. **Monorepo gotcha**: Dynamic imports resolve workspace packages even when
23
+ * the consuming app doesn't have them as dependencies. This causes the
24
+ * real hook to activate unexpectedly → Rules of Hooks violation.
25
+ *
26
+ * 4. **Decision is immutable**: With sync import, `crudModule?.useCrud`
27
+ * is evaluated ONCE at module load. It's either the real hook or undefined.
28
+ * This never changes during the app lifecycle.
29
+ *
30
+ * @see docs/development/GRACEFUL_DEGRADATION.md
31
+ * @version 0.0.4
19
32
  * @since 0.0.1
20
33
  * @author AMBROISE PARK Consulting
21
34
  */
@@ -43,7 +56,7 @@ function useCrudStub() {
43
56
  * @example
44
57
  * ```typescript
45
58
  * const crud = useCrudSafe('users', { backend: 'firestore', schema: UserSchema });
46
- * const { data, loading, error, get, set } = crud;
59
+ * const { data, status, error, get, set } = crud;
47
60
  * ```
48
61
  */
49
62
  export function useCrudSafe(collection, options = {}) {
@@ -3,18 +3,31 @@
3
3
  * @description Provides OAuth functionality when @donotdev/oauth is installed,
4
4
  * gracefully degrades to no-op when not installed.
5
5
  *
6
- * **How it works:**
7
- * 1. Import @donotdev/oauth (Vite aliases to empty module if not installed)
8
- * 2. Check if useOAuth export exists
9
- * 3. If exists use real hook | If not → use stub
10
- *
11
- * **Why this pattern:**
12
- * - Vite aliases missing packages to empty modules at build time
13
- * - Decision is made ONCE at import time, never changes
14
- * - No conditional hook calls = no Rules of Hooks violations
15
- * - Real hook handles all runtime state (credentials, consent) internally
16
- *
17
- * @version 0.0.1
6
+ * ## CRITICAL: DO NOT USE DYNAMIC IMPORTS
7
+ *
8
+ * This file MUST use sync `import * as oauthModule from '@donotdev/oauth'`
9
+ * at module level. DO NOT refactor to use async `import('@donotdev/oauth').then(...)`.
10
+ *
11
+ * ### Why sync import is required:
12
+ *
13
+ * 1. **Bundler aliasing**: Vite/webpack alias missing packages to empty modules
14
+ * at BUILD TIME. The import completes immediately (no async).
15
+ *
16
+ * 2. **Rules of Hooks**: If we use async dynamic import:
17
+ * - First render: `realUseOAuth = null` → uses stub (0 hooks)
18
+ * - Async completes: `realUseOAuth = useOAuth` → now has hooks
19
+ * - Next render: React sees different hook count → CRASH
20
+ *
21
+ * 3. **Monorepo gotcha**: Dynamic imports resolve workspace packages even when
22
+ * the consuming app doesn't have them as dependencies. This causes the
23
+ * real hook to activate unexpectedly → Rules of Hooks violation.
24
+ *
25
+ * 4. **Decision is immutable**: With sync import, `oauthModule?.useOAuth`
26
+ * is evaluated ONCE at module load. It's either the real hook or undefined.
27
+ * This never changes during the app lifecycle.
28
+ *
29
+ * @see docs/development/GRACEFUL_DEGRADATION.md
30
+ * @version 0.0.2
18
31
  * @since 0.0.1
19
32
  * @author AMBROISE PARK Consulting
20
33
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useOAuthSafe.d.ts","sourceRoot":"","sources":["../../src/utils/useOAuthSafe.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAkB/C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAK1E;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,SAAqC,CAAC"}
1
+ {"version":3,"file":"useOAuthSafe.d.ts","sourceRoot":"","sources":["../../src/utils/useOAuthSafe.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAkB/C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAK1E;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,SAAqC,CAAC"}