@nextsparkjs/core 0.1.0-beta.67 → 0.1.0-beta.69

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 (201) hide show
  1. package/dist/components/dashboard/block-editor/block-picker.d.ts +7 -2
  2. package/dist/components/dashboard/block-editor/block-picker.d.ts.map +1 -1
  3. package/dist/components/dashboard/block-editor/block-picker.js +27 -20
  4. package/dist/components/dashboard/block-editor/block-preview-canvas.d.ts.map +1 -1
  5. package/dist/components/dashboard/block-editor/block-preview-canvas.js +37 -37
  6. package/dist/components/dashboard/block-editor/block-settings-panel.js +3 -3
  7. package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
  8. package/dist/components/dashboard/block-editor/builder-editor-view.js +124 -82
  9. package/dist/components/dashboard/block-editor/config-panel.d.ts +18 -0
  10. package/dist/components/dashboard/block-editor/config-panel.d.ts.map +1 -0
  11. package/dist/components/dashboard/block-editor/config-panel.js +413 -0
  12. package/dist/components/dashboard/block-editor/floating-block-toolbar.js +1 -1
  13. package/dist/components/dashboard/block-editor/pattern-card.js +1 -1
  14. package/dist/components/dashboard/block-editor/pattern-reference-preview.js +1 -1
  15. package/dist/components/dashboard/block-editor/sortable-block.js +1 -1
  16. package/dist/components/dashboard/block-editor/tree-view-node.d.ts +11 -0
  17. package/dist/components/dashboard/block-editor/tree-view-node.d.ts.map +1 -0
  18. package/dist/components/dashboard/block-editor/tree-view-node.js +91 -0
  19. package/dist/components/dashboard/block-editor/tree-view.d.ts +17 -0
  20. package/dist/components/dashboard/block-editor/tree-view.d.ts.map +1 -0
  21. package/dist/components/dashboard/block-editor/tree-view.js +125 -0
  22. package/dist/components/dashboard/block-editor/viewport-toggle.d.ts +10 -0
  23. package/dist/components/dashboard/block-editor/viewport-toggle.d.ts.map +1 -0
  24. package/dist/components/dashboard/block-editor/viewport-toggle.js +55 -0
  25. package/dist/components/public/pageBuilder/PageRenderer.d.ts.map +1 -1
  26. package/dist/components/public/pageBuilder/PageRenderer.js +10 -1
  27. package/dist/components/settings/layouts/SettingsSidebar.d.ts.map +1 -1
  28. package/dist/components/settings/layouts/SettingsSidebar.js +14 -0
  29. package/dist/components/ui/dynamic-icon.d.ts +12 -0
  30. package/dist/components/ui/dynamic-icon.d.ts.map +1 -0
  31. package/dist/components/ui/dynamic-icon.js +11 -0
  32. package/dist/components/ui/index.d.ts +7 -0
  33. package/dist/components/ui/index.d.ts.map +1 -1
  34. package/dist/components/ui/index.js +7 -0
  35. package/dist/components/ui/skeleton-dashboard.d.ts +32 -0
  36. package/dist/components/ui/skeleton-dashboard.d.ts.map +1 -0
  37. package/dist/components/ui/skeleton-dashboard.js +69 -0
  38. package/dist/components/ui/skeleton-detail.d.ts.map +1 -1
  39. package/dist/components/ui/skeleton-detail.js +0 -1
  40. package/dist/components/ui/skeleton-features.d.ts +27 -0
  41. package/dist/components/ui/skeleton-features.d.ts.map +1 -0
  42. package/dist/components/ui/skeleton-features.js +90 -0
  43. package/dist/components/ui/skeleton-form.d.ts.map +1 -1
  44. package/dist/components/ui/skeleton-form.js +0 -1
  45. package/dist/components/ui/skeleton-list.d.ts.map +1 -1
  46. package/dist/components/ui/skeleton-list.js +0 -1
  47. package/dist/components/ui/skeleton-public.d.ts +26 -0
  48. package/dist/components/ui/skeleton-public.d.ts.map +1 -0
  49. package/dist/components/ui/skeleton-public.js +61 -0
  50. package/dist/components/ui/skeleton-settings.d.ts +54 -0
  51. package/dist/components/ui/skeleton-settings.d.ts.map +1 -0
  52. package/dist/components/ui/skeleton-settings.js +332 -0
  53. package/dist/components/ui/skeleton.d.ts +23 -1
  54. package/dist/components/ui/skeleton.d.ts.map +1 -1
  55. package/dist/components/ui/skeleton.js +46 -2
  56. package/dist/contexts/TeamContext.d.ts +2 -0
  57. package/dist/contexts/TeamContext.d.ts.map +1 -1
  58. package/dist/contexts/TeamContext.js +78 -68
  59. package/dist/hooks/usePrefetch.d.ts +43 -0
  60. package/dist/hooks/usePrefetch.d.ts.map +1 -0
  61. package/dist/hooks/usePrefetch.js +56 -0
  62. package/dist/lib/actions/index.d.ts +27 -14
  63. package/dist/lib/actions/index.d.ts.map +1 -1
  64. package/dist/lib/actions/index.js +19 -1
  65. package/dist/lib/actions/team.actions.d.ts +107 -0
  66. package/dist/lib/actions/team.actions.d.ts.map +1 -0
  67. package/dist/lib/actions/team.actions.js +220 -0
  68. package/dist/lib/actions/user.actions.d.ts +99 -0
  69. package/dist/lib/actions/user.actions.d.ts.map +1 -0
  70. package/dist/lib/actions/user.actions.js +149 -0
  71. package/dist/lib/selectors/core-selectors.d.ts +98 -44
  72. package/dist/lib/selectors/core-selectors.d.ts.map +1 -1
  73. package/dist/lib/selectors/domains/block-editor.selectors.d.ts +136 -71
  74. package/dist/lib/selectors/domains/block-editor.selectors.d.ts.map +1 -1
  75. package/dist/lib/selectors/domains/block-editor.selectors.js +130 -60
  76. package/dist/lib/selectors/selectors.d.ts +196 -88
  77. package/dist/lib/selectors/selectors.d.ts.map +1 -1
  78. package/dist/messages/de/devtools.json +4 -0
  79. package/dist/messages/de/index.d.ts +4 -0
  80. package/dist/messages/de/index.d.ts.map +1 -1
  81. package/dist/messages/en/admin.json +15 -1
  82. package/dist/messages/en/devtools.json +16 -0
  83. package/dist/messages/en/index.d.ts +30 -0
  84. package/dist/messages/en/index.d.ts.map +1 -1
  85. package/dist/messages/es/admin.json +16 -1
  86. package/dist/messages/es/devtools.json +4 -0
  87. package/dist/messages/es/index.d.ts +19 -0
  88. package/dist/messages/es/index.d.ts.map +1 -1
  89. package/dist/messages/fr/devtools.json +4 -0
  90. package/dist/messages/fr/index.d.ts +4 -0
  91. package/dist/messages/fr/index.d.ts.map +1 -1
  92. package/dist/messages/it/devtools.json +4 -0
  93. package/dist/messages/it/index.d.ts +4 -0
  94. package/dist/messages/it/index.d.ts.map +1 -1
  95. package/dist/messages/pt/devtools.json +4 -0
  96. package/dist/messages/pt/index.d.ts +4 -0
  97. package/dist/messages/pt/index.d.ts.map +1 -1
  98. package/dist/nextspark-entities.d.ts +59 -0
  99. package/dist/presets/blocks/cta-section/component.tsx +4 -4
  100. package/dist/presets/blocks/features-grid/component.tsx +5 -5
  101. package/dist/presets/blocks/hero/component.tsx +2 -2
  102. package/dist/presets/blocks/testimonials/component.tsx +4 -4
  103. package/dist/presets/blocks/text-content/component.tsx +2 -2
  104. package/dist/presets/theme/blocks/hero/component.tsx +2 -2
  105. package/dist/presets/theme/tests/cypress/src/core/BlockEditorBasePOM.ts +123 -24
  106. package/dist/styles/classes.json +22 -2
  107. package/dist/styles/ui.css +1 -1
  108. package/dist/templates/app/(public)/[...slug]/page.tsx +2 -1
  109. package/dist/templates/app/(public)/docs/[section]/[page]/page.tsx +1 -1
  110. package/dist/templates/app/api/devtools/config/entities/route.ts +2 -1
  111. package/dist/templates/app/api/user/plan-flags/route.ts +1 -1
  112. package/dist/templates/app/api/v1/[entity]/[id]/child/[childType]/[childId]/route.ts +4 -2
  113. package/dist/templates/app/dashboard/(main)/layout.tsx +2 -1
  114. package/dist/templates/app/dashboard/(main)/loading.tsx +5 -0
  115. package/dist/templates/app/dashboard/features/loading.tsx +5 -0
  116. package/dist/templates/app/dashboard/settings/api-keys/loading.tsx +5 -0
  117. package/dist/templates/app/dashboard/settings/billing/loading.tsx +5 -0
  118. package/dist/templates/app/dashboard/settings/invoices/loading.tsx +5 -0
  119. package/dist/templates/app/dashboard/settings/loading.tsx +5 -0
  120. package/dist/templates/app/dashboard/settings/notifications/loading.tsx +5 -0
  121. package/dist/templates/app/dashboard/settings/password/loading.tsx +5 -0
  122. package/dist/templates/app/dashboard/settings/plans/loading.tsx +5 -0
  123. package/dist/templates/app/dashboard/settings/profile/loading.tsx +5 -0
  124. package/dist/templates/app/dashboard/settings/security/loading.tsx +5 -0
  125. package/dist/templates/app/dashboard/settings/teams/loading.tsx +5 -0
  126. package/dist/templates/app/devtools/config/page.tsx +1 -1
  127. package/dist/templates/app/devtools/page.tsx +1 -1
  128. package/dist/templates/app/devtools/tests/[[...path]]/page.tsx +1 -1
  129. package/dist/templates/contents/themes/starter/messages/de/common.json +4 -1
  130. package/dist/templates/contents/themes/starter/messages/de/index.ts +15 -0
  131. package/dist/templates/contents/themes/starter/messages/en/common.json +4 -1
  132. package/dist/templates/contents/themes/starter/messages/en/index.ts +15 -0
  133. package/dist/templates/contents/themes/starter/messages/es/common.json +4 -1
  134. package/dist/templates/contents/themes/starter/messages/es/index.ts +15 -0
  135. package/dist/templates/contents/themes/starter/messages/fr/common.json +4 -1
  136. package/dist/templates/contents/themes/starter/messages/fr/index.ts +15 -0
  137. package/dist/templates/contents/themes/starter/messages/it/common.json +4 -1
  138. package/dist/templates/contents/themes/starter/messages/it/index.ts +13 -0
  139. package/dist/templates/contents/themes/starter/messages/pt/common.json +4 -1
  140. package/dist/templates/contents/themes/starter/messages/pt/index.ts +13 -0
  141. package/dist/templates/contents/themes/starter/styles/globals.css +3 -1
  142. package/dist/templates/contents/themes/starter/templates/(dashboard)/analytics/loading.tsx +5 -0
  143. package/dist/templates/contents/themes/starter/templates/(public)/loading.tsx +5 -0
  144. package/dist/templates/features/blog/blocks/post-content/component.tsx +2 -2
  145. package/dist/templates/features/pages/blocks/hero/component.tsx +2 -2
  146. package/dist/templates/next.config.mjs +10 -3
  147. package/dist/templates/{middleware.ts → proxy.ts} +5 -6
  148. package/globals.css +54 -0
  149. package/nextspark-entities.d.ts +59 -0
  150. package/package.json +18 -16
  151. package/scripts/build/registry/discovery/api-presets.mjs +20 -12
  152. package/scripts/build/registry/generators/api-presets-registry.mjs +18 -5
  153. package/scripts/build/registry/generators/block-registry.mjs +14 -3
  154. package/scripts/build/registry/generators/docs-registry.mjs +21 -3
  155. package/scripts/build/registry/generators/translation-registry.mjs +16 -7
  156. package/scripts/build/theme.mjs +2 -1
  157. package/templates/app/(public)/[...slug]/page.tsx +2 -1
  158. package/templates/app/(public)/docs/[section]/[page]/page.tsx +1 -1
  159. package/templates/app/api/auth/[...all]/route.ts +13 -5
  160. package/templates/app/api/devtools/config/entities/route.ts +2 -1
  161. package/templates/app/api/user/plan-flags/route.ts +1 -1
  162. package/templates/app/api/v1/[entity]/[id]/child/[childType]/[childId]/route.ts +4 -2
  163. package/templates/app/dashboard/(main)/layout.tsx +2 -1
  164. package/templates/app/dashboard/(main)/loading.tsx +5 -0
  165. package/templates/app/dashboard/features/loading.tsx +5 -0
  166. package/templates/app/dashboard/settings/api-keys/loading.tsx +5 -0
  167. package/templates/app/dashboard/settings/billing/loading.tsx +5 -0
  168. package/templates/app/dashboard/settings/invoices/loading.tsx +5 -0
  169. package/templates/app/dashboard/settings/loading.tsx +5 -0
  170. package/templates/app/dashboard/settings/notifications/loading.tsx +5 -0
  171. package/templates/app/dashboard/settings/password/loading.tsx +5 -0
  172. package/templates/app/dashboard/settings/plans/loading.tsx +5 -0
  173. package/templates/app/dashboard/settings/profile/loading.tsx +5 -0
  174. package/templates/app/dashboard/settings/security/loading.tsx +5 -0
  175. package/templates/app/dashboard/settings/teams/loading.tsx +5 -0
  176. package/templates/app/devtools/config/page.tsx +1 -1
  177. package/templates/app/devtools/page.tsx +1 -1
  178. package/templates/app/devtools/tests/[[...path]]/page.tsx +1 -1
  179. package/templates/contents/themes/starter/config/app.config.ts +8 -7
  180. package/templates/contents/themes/starter/messages/de/common.json +4 -1
  181. package/templates/contents/themes/starter/messages/de/index.ts +15 -0
  182. package/templates/contents/themes/starter/messages/en/common.json +4 -1
  183. package/templates/contents/themes/starter/messages/en/index.ts +15 -0
  184. package/templates/contents/themes/starter/messages/es/common.json +4 -1
  185. package/templates/contents/themes/starter/messages/es/index.ts +15 -0
  186. package/templates/contents/themes/starter/messages/fr/common.json +4 -1
  187. package/templates/contents/themes/starter/messages/fr/index.ts +15 -0
  188. package/templates/contents/themes/starter/messages/it/common.json +4 -1
  189. package/templates/contents/themes/starter/messages/it/index.ts +13 -0
  190. package/templates/contents/themes/starter/messages/pt/common.json +4 -1
  191. package/templates/contents/themes/starter/messages/pt/index.ts +13 -0
  192. package/templates/contents/themes/starter/styles/globals.css +3 -1
  193. package/templates/contents/themes/starter/templates/(dashboard)/analytics/loading.tsx +5 -0
  194. package/templates/contents/themes/starter/templates/(public)/loading.tsx +5 -0
  195. package/templates/features/blog/blocks/post-content/component.tsx +2 -2
  196. package/templates/features/pages/blocks/hero/component.tsx +2 -2
  197. package/templates/next.config.mjs +10 -3
  198. package/templates/pnpm-workspace.yaml +5 -0
  199. package/templates/{middleware.ts → proxy.ts} +5 -6
  200. package/tests/jest/setup.ts +5 -0
  201. package/dist/presets/plugin/.env.example.template +0 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/core",
3
- "version": "0.1.0-beta.67",
3
+ "version": "0.1.0-beta.69",
4
4
  "description": "NextSpark - The complete SaaS framework for Next.js",
5
5
  "license": "MIT",
6
6
  "author": "NextSpark <hello@nextspark.dev>",
@@ -288,9 +288,21 @@
288
288
  "tests/jest/__mocks__",
289
289
  "globals.css",
290
290
  "theme-styles.css",
291
+ "nextspark-entities.d.ts",
291
292
  "README.md",
292
293
  "scripts"
293
294
  ],
295
+ "scripts": {
296
+ "postinstall": "node scripts/postinstall.mjs || true",
297
+ "build": "tsup && pnpm build:dts && pnpm build:ui-css",
298
+ "build:js": "tsup",
299
+ "build:dts": "tsc -p tsconfig.dts.json || echo '⚠️ DTS generation completed with some type errors (partial coverage)'",
300
+ "build:ui-css": "node scripts/build/build-ui-css.mjs",
301
+ "dev": "tsup --watch",
302
+ "test": "jest",
303
+ "test:watch": "jest --watch",
304
+ "test:coverage": "jest --coverage"
305
+ },
294
306
  "peerDependencies": {
295
307
  "next": ">=14.0.0",
296
308
  "react": ">=18.0.0",
@@ -318,15 +330,13 @@
318
330
  "typescript": "^5"
319
331
  },
320
332
  "dependencies": {
321
- "@nextsparkjs/testing": "0.1.0-beta.53",
322
- "@upstash/ratelimit": "^2.0.3",
323
- "@upstash/redis": "^1.20.6",
324
333
  "@codemirror/lang-json": "^6.0.2",
325
334
  "@dnd-kit/core": "^6.3.1",
326
335
  "@dnd-kit/sortable": "^10.0.0",
327
336
  "@dnd-kit/utilities": "^3.2.2",
328
337
  "@hookform/resolvers": "^5.2.1",
329
338
  "@inquirer/prompts": "^7.2.0",
339
+ "@nextsparkjs/testing": "0.1.0-beta.53",
330
340
  "@radix-ui/react-accordion": "^1.2.12",
331
341
  "@radix-ui/react-alert-dialog": "^1.1.15",
332
342
  "@radix-ui/react-avatar": "^1.1.10",
@@ -351,10 +361,13 @@
351
361
  "@radix-ui/react-toggle": "^1.1.10",
352
362
  "@radix-ui/react-tooltip": "^1.2.8",
353
363
  "@shikijs/rehype": "^3.20.0",
364
+ "@tailwindcss/container-queries": "^0.1.1",
354
365
  "@tanstack/react-query": "^5.85.0",
355
366
  "@tanstack/react-query-devtools": "^5.85.0",
356
367
  "@uiw/codemirror-theme-github": "^4.25.4",
357
368
  "@uiw/react-codemirror": "^4.25.4",
369
+ "@upstash/ratelimit": "^2.0.3",
370
+ "@upstash/redis": "^1.20.6",
358
371
  "@vercel/blob": "^2.0.0",
359
372
  "better-auth": "^1.3.5",
360
373
  "chalk": "^5.4.1",
@@ -385,16 +398,5 @@
385
398
  "tailwind-merge": "^3.3.1",
386
399
  "uuid": "^13.0.0",
387
400
  "zod": "^4.1.5"
388
- },
389
- "scripts": {
390
- "postinstall": "node scripts/postinstall.mjs || true",
391
- "build": "tsup && pnpm build:dts && pnpm build:ui-css",
392
- "build:js": "tsup",
393
- "build:dts": "tsc -p tsconfig.dts.json || echo '⚠️ DTS generation completed with some type errors (partial coverage)'",
394
- "build:ui-css": "node scripts/build/build-ui-css.mjs",
395
- "dev": "tsup --watch",
396
- "test": "jest",
397
- "test:watch": "jest --watch",
398
- "test:coverage": "jest --coverage"
399
401
  }
400
- }
402
+ }
@@ -18,6 +18,15 @@ import { existsSync } from 'fs'
18
18
  import { CONFIG as DEFAULT_CONFIG } from '../config.mjs'
19
19
  import { log, verbose } from '../../../utils/index.mjs'
20
20
 
21
+ /**
22
+ * Normalize path separators to forward slashes (for cross-platform compatibility)
23
+ * @param {string} path - Path to normalize
24
+ * @returns {string} Path with forward slashes
25
+ */
26
+ function normalizePath(path) {
27
+ return path.replace(/\\/g, '/')
28
+ }
29
+
21
30
  /**
22
31
  * Find the matching closing brace for an opening brace
23
32
  * Uses brace counting to handle nested objects correctly
@@ -276,23 +285,22 @@ function deriveEndpointFromRoute(routePath) {
276
285
 
277
286
  /**
278
287
  * Get the storage path for registry (handles monorepo vs npm mode)
288
+ * Always normalizes to forward slashes for cross-platform compatibility
279
289
  * @param {string} absolutePath - Absolute file path
280
290
  * @param {object} config - Configuration object
281
- * @returns {string} Path to store in registry
291
+ * @returns {string} Path to store in registry (with forward slashes)
282
292
  */
283
293
  function getStoragePath(absolutePath, config) {
294
+ let result
284
295
  if (config.isMonorepoMode) {
285
296
  // In monorepo, use path relative to monorepo root
286
- return relative(config.monorepoRoot, absolutePath)
297
+ result = relative(config.monorepoRoot, absolutePath)
287
298
  } else {
288
299
  // In npm mode, use path relative to project root with contents/ prefix
289
- const relativePath = relative(config.projectRoot, absolutePath)
290
- // If path doesn't start with contents/, add it
291
- if (!relativePath.startsWith('contents/')) {
292
- return relativePath
293
- }
294
- return relativePath
300
+ result = relative(config.projectRoot, absolutePath)
295
301
  }
302
+ // Always normalize to forward slashes (Windows uses backslashes)
303
+ return normalizePath(result)
296
304
  }
297
305
 
298
306
  /**
@@ -447,7 +455,7 @@ async function discoverThemeRoutes(config, results, processedEndpoints) {
447
455
  try {
448
456
  const routeDir = dirname(docsPath)
449
457
  const relativeDir = relative(join(config.themesDir, themeName, 'app'), routeDir)
450
- const endpoint = '/' + relativeDir
458
+ const endpoint = '/' + normalizePath(relativeDir)
451
459
 
452
460
  const content = await readFile(docsPath, 'utf-8')
453
461
  const title = extractMarkdownTitle(content)
@@ -476,7 +484,7 @@ async function discoverThemeRoutes(config, results, processedEndpoints) {
476
484
  try {
477
485
  const routeDir = dirname(presetsPath)
478
486
  const relativeDir = relative(join(config.themesDir, themeName, 'app'), routeDir)
479
- const endpoint = '/' + relativeDir
487
+ const endpoint = '/' + normalizePath(relativeDir)
480
488
 
481
489
  const content = await readFile(presetsPath, 'utf-8')
482
490
  const presetConfig = parsePresetFile(content)
@@ -525,7 +533,7 @@ async function discoverCoreRoutes(config, results, processedEndpoints) {
525
533
  try {
526
534
  const routeDir = dirname(docsPath)
527
535
  const relativeDir = relative(join(config.coreDir, 'templates', 'app'), routeDir)
528
- const endpoint = '/' + relativeDir
536
+ const endpoint = '/' + normalizePath(relativeDir)
529
537
 
530
538
  // Skip if already processed by theme or entity
531
539
  if (processedEndpoints.has(endpoint)) {
@@ -557,7 +565,7 @@ async function discoverCoreRoutes(config, results, processedEndpoints) {
557
565
  try {
558
566
  const routeDir = dirname(presetsPath)
559
567
  const relativeDir = relative(join(config.coreDir, 'templates', 'app'), routeDir)
560
- const endpoint = '/' + relativeDir
568
+ const endpoint = '/' + normalizePath(relativeDir)
561
569
 
562
570
  // Skip if already processed by theme or entity
563
571
  if (processedEndpoints.has(endpoint)) {
@@ -11,6 +11,16 @@
11
11
  import { join } from 'path'
12
12
  import { convertCorePath } from '../config.mjs'
13
13
 
14
+ /**
15
+ * Normalize path separators to forward slashes (for cross-platform compatibility)
16
+ * @param {string} path - Path to normalize
17
+ * @returns {string} Path with forward slashes
18
+ */
19
+ function normalizePath(path) {
20
+ if (typeof path !== 'string') return path
21
+ return path.replace(/\\/g, '/')
22
+ }
23
+
14
24
  /**
15
25
  * Escape string for use in TypeScript string literal
16
26
  * @param {string} str - String to escape
@@ -170,10 +180,12 @@ export function hasPresets(endpoint: string): boolean {
170
180
  .join(',\n')
171
181
 
172
182
  const source = endpointConfig.source || 'unknown'
173
- return ` '${endpointConfig.endpoint}': {
174
- endpoint: '${endpointConfig.endpoint}',
183
+ const normalizedEndpoint = normalizePath(endpointConfig.endpoint)
184
+ const normalizedSourcePath = normalizePath(endpointConfig.sourcePath)
185
+ return ` '${normalizedEndpoint}': {
186
+ endpoint: '${normalizedEndpoint}',
175
187
  summary: '${escapeString(endpointConfig.summary || '')}',
176
- sourcePath: '${endpointConfig.sourcePath}',
188
+ sourcePath: '${normalizedSourcePath}',
177
189
  source: '${source}',
178
190
  presets: [
179
191
  ${presetsCode}
@@ -325,10 +337,11 @@ export function getAllDocEndpoints(): string[] {
325
337
 
326
338
  // Build docs code - use endpoint from discovery
327
339
  const docsCode = docs.map(doc => {
328
- const endpoint = doc.endpoint
340
+ const endpoint = normalizePath(doc.endpoint)
341
+ const filePath = normalizePath(doc.filePath)
329
342
  const source = doc.source || 'unknown'
330
343
  return ` '${endpoint}': {
331
- path: '${doc.filePath}',
344
+ path: '${filePath}',
332
345
  title: '${escapeString(doc.title)}',
333
346
  endpoint: '${endpoint}',
334
347
  source: '${source}'
@@ -18,6 +18,8 @@ import { convertCorePath } from '../config.mjs'
18
18
  export function generateBlockRegistry(blocks, config) {
19
19
  const outputFilePath = join(config.outputDir, 'block-registry.ts')
20
20
  if (blocks.length === 0) {
21
+ // When no blocks, use inline type definition to avoid import issues in npm mode
22
+ // (DTS generation is disabled in core package for performance reasons)
21
23
  return `/**
22
24
  * Auto-generated Block Registry
23
25
  *
@@ -28,13 +30,22 @@ export function generateBlockRegistry(blocks, config) {
28
30
  */
29
31
 
30
32
  import React from 'react'
31
- import type { BlockConfig } from '${convertCorePath('@/core/types/blocks', outputFilePath, config)}'
33
+
34
+ // Inline type definition for empty registry (avoids import issues in npm mode)
35
+ type BlockConfig = {
36
+ slug: string
37
+ name: string
38
+ description?: string
39
+ category: string
40
+ icon?: string
41
+ fields?: unknown[]
42
+ }
32
43
 
33
44
  export const BLOCK_REGISTRY: Record<string, BlockConfig> = {}
34
45
 
35
46
  export const BLOCK_CATEGORIES: string[] = []
36
47
 
37
- export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<React.ComponentType<any>>> = {}
48
+ export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<React.ComponentType<unknown>>> = {}
38
49
 
39
50
  export const BLOCK_METADATA = {
40
51
  totalBlocks: 0,
@@ -109,7 +120,7 @@ export const BLOCK_METADATA = {
109
120
  */
110
121
 
111
122
  import React from 'react'
112
- import type { BlockConfig, BlockCategory } from '${convertCorePath('@/core/types/blocks', outputFilePath, config)}'
123
+ import type { BlockConfig, BlockCategory } from '${convertCorePath('@/core/types', outputFilePath, config)}'
113
124
 
114
125
  ${fieldImports}
115
126
 
@@ -168,10 +168,28 @@ export function generateDocsRegistry() {
168
168
  * DO NOT EDIT - This file is auto-generated
169
169
  */
170
170
 
171
- import type { DocPageMeta, DocSectionMeta, DocsRegistryStructure } from '@nextsparkjs/core/types/docs'
171
+ // Inline type definitions for npm mode (avoids import issues since DTS is disabled)
172
+ export interface DocPageMeta {
173
+ slug: string
174
+ title: string
175
+ order: number
176
+ path: string
177
+ source: 'public' | 'superadmin'
178
+ }
179
+
180
+ export interface DocSectionMeta {
181
+ slug: string
182
+ title: string
183
+ order: number
184
+ pages: DocPageMeta[]
185
+ source: 'public' | 'superadmin'
186
+ }
172
187
 
173
- // Re-export types for external use
174
- export type { DocPageMeta, DocSectionMeta, DocsRegistryStructure }
188
+ export interface DocsRegistryStructure {
189
+ public: DocSectionMeta[]
190
+ superadmin: DocSectionMeta[]
191
+ all: DocSectionMeta[]
192
+ }
175
193
 
176
194
  export const DOCS_REGISTRY: DocsRegistryStructure = ${JSON.stringify(registry, null, 2)} as const
177
195
 
@@ -93,11 +93,14 @@ function getEntityLocales(entityDir, supportedLocales) {
93
93
 
94
94
  /**
95
95
  * Detect locale entries from a messages directory
96
- * Supports both directory pattern (en/, es/ with index.ts) and flat file pattern (en.json, es.json)
97
- * Directory pattern takes precedence if both exist
96
+ * Supports three patterns:
97
+ * 1. Directory with index.ts (en/, es/ with index.ts) - imports from directory
98
+ * 2. Directory with JSON files (en/, es/ with *.json files) - imports individual files
99
+ * 3. Flat file pattern (en.json, es.json) - imports single file
100
+ * Directory patterns take precedence if both exist
98
101
  *
99
102
  * @param {string} messagesDir - Path to the messages directory
100
- * @returns {Array<{locale: string, isDirectory: boolean}>} Detected locales with their type
103
+ * @returns {Array<{locale: string, isDirectory: boolean, hasIndexTs: boolean, jsonFiles: string[]}>} Detected locales with their type
101
104
  */
102
105
  function detectLocales(messagesDir) {
103
106
  if (!existsSync(messagesDir)) {
@@ -112,17 +115,23 @@ function detectLocales(messagesDir) {
112
115
  const stat = statSync(entryPath)
113
116
 
114
117
  if (stat.isDirectory()) {
115
- // Directory pattern: check for index.ts
118
+ // Directory pattern: check for index.ts first
116
119
  const indexPath = join(entryPath, 'index.ts')
117
120
  if (existsSync(indexPath)) {
118
- // Directory pattern takes precedence
119
- locales.set(entry, { locale: entry, isDirectory: true })
121
+ // Directory with index.ts takes precedence
122
+ locales.set(entry, { locale: entry, isDirectory: true, hasIndexTs: true, jsonFiles: [] })
123
+ } else {
124
+ // Check for JSON files in directory (new pattern for themes)
125
+ const jsonFiles = readdirSync(entryPath).filter(f => f.endsWith('.json'))
126
+ if (jsonFiles.length > 0) {
127
+ locales.set(entry, { locale: entry, isDirectory: true, hasIndexTs: false, jsonFiles })
128
+ }
120
129
  }
121
130
  } else if (entry.endsWith('.json')) {
122
131
  // Flat file pattern (only if directory doesn't exist)
123
132
  const locale = entry.replace(/\.json$/, '')
124
133
  if (!locales.has(locale)) {
125
- locales.set(locale, { locale, isDirectory: false })
134
+ locales.set(locale, { locale, isDirectory: false, hasIndexTs: false, jsonFiles: [] })
126
135
  }
127
136
  }
128
137
  })
@@ -48,7 +48,8 @@ export function syncAppGlobalsCss(config, activeTheme) {
48
48
  // Calculate the correct relative path from app/ to theme globals.css
49
49
  const appDir = path.join(config.projectRoot, 'app')
50
50
  const themeGlobalsPath = path.join(config.themesDir, activeTheme, 'styles', 'globals.css')
51
- const relativePath = path.relative(appDir, themeGlobalsPath)
51
+ // Normalize to forward slashes for cross-platform CSS compatibility
52
+ const relativePath = path.relative(appDir, themeGlobalsPath).replace(/\\/g, '/')
52
53
 
53
54
  // Expected import statement
54
55
  const expectedImport = `@import "${relativePath}";`
@@ -45,7 +45,8 @@ function getEntityConfigs(): Record<string, EntityConfig> {
45
45
  const registry = getEntityRegistry()
46
46
  const configs: Record<string, EntityConfig> = {}
47
47
  for (const [key, entry] of Object.entries(registry)) {
48
- configs[key] = entry.config as EntityConfig
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
+ configs[key] = (entry as any).config as EntityConfig
49
50
  }
50
51
  return configs
51
52
  }
@@ -16,7 +16,7 @@ interface DocsPageProps {
16
16
  }
17
17
 
18
18
  export async function generateStaticParams() {
19
- const params = []
19
+ const params: Array<{ section: string; page: string }> = []
20
20
 
21
21
  // Generate params for public docs only
22
22
  for (const section of DOCS_REGISTRY.public) {
@@ -4,9 +4,15 @@ import { NextRequest, NextResponse } from "next/server";
4
4
  import { TEAMS_CONFIG } from "@nextsparkjs/core/lib/config";
5
5
  import { isPublicSignupRestricted } from "@nextsparkjs/core/lib/teams/helpers";
6
6
  import { TeamService } from "@nextsparkjs/core/lib/services";
7
+ import { wrapAuthHandlerWithCors, handleCorsPreflightRequest, addCorsHeaders } from "@nextsparkjs/core/lib/api/helpers";
7
8
 
8
9
  const handlers = toNextJsHandler(auth);
9
10
 
11
+ // Handle CORS preflight requests for cross-origin auth (mobile apps, etc.)
12
+ export async function OPTIONS(req: NextRequest) {
13
+ return handleCorsPreflightRequest(req);
14
+ }
15
+
10
16
  // Intercept email verification requests to redirect to UI page
11
17
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
12
18
  export async function GET(req: NextRequest, context: { params: Promise<{ all: string[] }> }) {
@@ -31,8 +37,8 @@ export async function GET(req: NextRequest, context: { params: Promise<{ all: st
31
37
  }
32
38
  }
33
39
 
34
- // For all other requests (including UI verification calls), use the default Better Auth handler
35
- return handlers.GET(req);
40
+ // Wrap with CORS headers for cross-origin requests (mobile apps, etc.)
41
+ return wrapAuthHandlerWithCors(() => handlers.GET(req), req);
36
42
  }
37
43
 
38
44
  // Intercept signup requests to validate single-tenant mode
@@ -53,7 +59,8 @@ export async function POST(req: NextRequest) {
53
59
 
54
60
  if (teamExists) {
55
61
  // Block public signup - users must be invited
56
- return NextResponse.json(
62
+ // Add CORS headers so mobile apps can read the error message
63
+ const errorResponse = NextResponse.json(
57
64
  {
58
65
  error: 'Registration is closed',
59
66
  message: 'This application requires an invitation to register. Please contact an administrator.',
@@ -61,10 +68,11 @@ export async function POST(req: NextRequest) {
61
68
  },
62
69
  { status: 403 }
63
70
  );
71
+ return await addCorsHeaders(errorResponse, req);
64
72
  }
65
73
  }
66
74
  }
67
75
 
68
- // Continue with normal Better Auth handling
69
- return handlers.POST(req);
76
+ // Wrap with CORS headers for cross-origin requests (mobile apps, etc.)
77
+ return wrapAuthHandlerWithCors(() => handlers.POST(req), req);
70
78
  }
@@ -60,7 +60,8 @@ export const GET = withRateLimitTier(async (request: Request) => {
60
60
  const registry = getEntityRegistry();
61
61
 
62
62
  for (const [, entry] of Object.entries(registry)) {
63
- const config = entry.config;
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ const config = (entry as any).config;
64
65
  if (!isEntityConfig(config)) continue;
65
66
 
66
67
  entities.push({
@@ -219,7 +219,7 @@ export const POST = withRateLimitTier(async (request: NextRequest) => {
219
219
  }
220
220
 
221
221
  const { updates } = validation.data
222
- const results = []
222
+ const results: Array<{ success: boolean; userId: string; plan?: boolean; flags?: boolean; error?: string }> = []
223
223
 
224
224
  // Process each update
225
225
  for (const update of updates) {
@@ -94,9 +94,11 @@ export const PUT = withRateLimitTier(async (
94
94
 
95
95
  // Handle relation-multi fields - store as JSONB array of IDs
96
96
  if (field?.type === 'relation-multi') {
97
- let relationIds = []
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ let relationIds: any[] = []
98
99
  if (Array.isArray(value)) {
99
- relationIds = value.map(item =>
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ relationIds = value.map((item: any) =>
100
102
  typeof item === 'object' && item && 'id' in item ? item.id : item
101
103
  ).filter(id => id && String(id).trim() !== '')
102
104
  }
@@ -61,7 +61,8 @@ async function DefaultMainDashboardLayout({
61
61
  children: React.ReactNode
62
62
  }) {
63
63
  // Get entities directly from the imported registry
64
- const allEntities = Object.values(ENTITY_REGISTRY).map(entry => entry.config)
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ const allEntities = Object.values(ENTITY_REGISTRY).map(entry => (entry as any).config)
65
66
  // Filter to only include full EntityConfig (not child entities)
66
67
  const entities = allEntities.filter(isEntityConfig)
67
68
  const serializedEntities: SerializableEntityConfig[] = entities.map(serializeEntityConfig)
@@ -0,0 +1,5 @@
1
+ import { SkeletonDashboardHome } from '@nextsparkjs/core/components/ui/skeleton-dashboard'
2
+
3
+ export default function DashboardLoading() {
4
+ return <SkeletonDashboardHome />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonFeaturePlaceholder } from '@nextsparkjs/core/components/ui/skeleton-features'
2
+
3
+ export default function FeaturesLoading() {
4
+ return <SkeletonFeaturePlaceholder />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonApiKeysPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function ApiKeysLoading() {
4
+ return <SkeletonApiKeysPage />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonBillingPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function BillingLoading() {
4
+ return <SkeletonBillingPage />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonInvoicesPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function InvoicesLoading() {
4
+ return <SkeletonInvoicesPage />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonSettingsOverview } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function SettingsLoading() {
4
+ return <SkeletonSettingsOverview />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonNotificationsPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function NotificationsLoading() {
4
+ return <SkeletonNotificationsPage />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonPasswordPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function PasswordLoading() {
4
+ return <SkeletonPasswordPage />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonPlansPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function PlansLoading() {
4
+ return <SkeletonPlansPage />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonProfileForm } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function ProfileLoading() {
4
+ return <SkeletonProfileForm />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonSecurityPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function SecurityLoading() {
4
+ return <SkeletonSecurityPage />
5
+ }
@@ -0,0 +1,5 @@
1
+ import { SkeletonTeamsPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+
3
+ export default function TeamsLoading() {
4
+ return <SkeletonTeamsPage />
5
+ }
@@ -9,7 +9,7 @@ import { getTranslations } from "next-intl/server";
9
9
  * Provides read-only view with JSON formatting and copy functionality.
10
10
  */
11
11
  export default async function DevConfigPage() {
12
- const t = await getTranslations('dev.config');
12
+ const t = await getTranslations('devtools.config');
13
13
 
14
14
  return (
15
15
  <div className="space-y-6" data-cy="devtools-config-page">
@@ -10,7 +10,7 @@ import { getTranslations } from "next-intl/server";
10
10
  * Shows overview of available sections in the dev area.
11
11
  */
12
12
  export default async function DevHomePage() {
13
- const t = await getTranslations('dev');
13
+ const t = await getTranslations('devtools');
14
14
  const tCommon = await getTranslations('common');
15
15
 
16
16
  const sections = [
@@ -19,7 +19,7 @@ interface DevTestsPageProps {
19
19
  */
20
20
  export default async function DevTestsPage({ params }: DevTestsPageProps) {
21
21
  const { path } = await params;
22
- const t = await getTranslations("dev.tests");
22
+ const t = await getTranslations("devtools.tests");
23
23
 
24
24
  // Convert path array to string (e.g., ['auth', 'login.bdd.md'] -> 'auth/login.bdd.md')
25
25
  const initialPath = path?.join("/") || null;
@@ -80,16 +80,17 @@ export const APP_CONFIG_OVERRIDES = {
80
80
  // =============================================================================
81
81
  api: {
82
82
  cors: {
83
- allowedOrigins: {
83
+ // Theme-specific CORS origins (extends core defaults, does not replace)
84
+ // Core already includes: localhost:3000, localhost:5173, and their 127.0.0.1 variants
85
+ additionalOrigins: {
84
86
  development: [
85
- 'http://localhost:3000',
86
- 'http://localhost:5173',
87
- 'http://127.0.0.1:3000',
88
- 'http://127.0.0.1:5173',
87
+ // Add your development origins here
88
+ // 'http://localhost:4200', // Angular dev server
89
+ // 'http://localhost:8081', // Expo mobile web
89
90
  ],
90
91
  production: [
91
- // Add production domains:
92
- // 'https://your-domain.com',
92
+ // Add your production origins here
93
+ // 'https://mobile.yourapp.com',
93
94
  ],
94
95
  },
95
96
  },
@@ -8,7 +8,10 @@
8
8
  "delete": "Löschen",
9
9
  "edit": "Bearbeiten",
10
10
  "create": "Erstellen",
11
- "search": "Suchen...",
11
+ "search": {
12
+ "placeholder": "Suchen...",
13
+ "label": "Suchen"
14
+ },
12
15
  "noResults": "Keine Ergebnisse gefunden",
13
16
  "confirm": "Bestätigen",
14
17
  "back": "Zurück",
@@ -0,0 +1,15 @@
1
+ import analytics from './analytics.json'
2
+ import common from './common.json'
3
+ import features from './features.json'
4
+ import home from './home.json'
5
+ import navigation from './navigation.json'
6
+ import public_ from './public.json'
7
+
8
+ export default {
9
+ analytics,
10
+ common,
11
+ features,
12
+ home,
13
+ navigation,
14
+ public: public_
15
+ } as const
@@ -8,7 +8,10 @@
8
8
  "delete": "Delete",
9
9
  "edit": "Edit",
10
10
  "create": "Create",
11
- "search": "Search...",
11
+ "search": {
12
+ "placeholder": "Search...",
13
+ "label": "Search"
14
+ },
12
15
  "noResults": "No results found",
13
16
  "confirm": "Confirm",
14
17
  "back": "Back",