@nextsparkjs/core 0.1.0-beta.195 → 0.1.0-beta.196

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 (168) hide show
  1. package/dist/components/billing/InvoicesPagination.js +2 -2
  2. package/dist/components/dashboard/navigation/DynamicNavigation.js +2 -2
  3. package/dist/components/settings/layouts/SettingsSidebar.d.ts.map +1 -1
  4. package/dist/components/settings/layouts/SettingsSidebar.js +0 -1
  5. package/dist/components/teams/CreateTeamButton.js +2 -2
  6. package/dist/components/teams/CreateTeamDialog.js +1 -1
  7. package/dist/components/teams/InviteMemberButton.js +3 -3
  8. package/dist/components/teams/InviteMemberDialog.js +1 -1
  9. package/dist/components/teams/TeamPendingInvitations.js +2 -2
  10. package/dist/lib/api/api-error.d.ts +2 -0
  11. package/dist/lib/api/api-error.d.ts.map +1 -1
  12. package/dist/lib/api/api-error.js +3 -1
  13. package/dist/lib/api/auth/dual-auth.d.ts +2 -1
  14. package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
  15. package/dist/lib/api/auth/dual-auth.js +22 -4
  16. package/dist/lib/api/auth/scope-policy.d.ts +6 -3
  17. package/dist/lib/api/auth/scope-policy.d.ts.map +1 -1
  18. package/dist/lib/api/cors-response.d.ts +3 -2
  19. package/dist/lib/api/cors-response.d.ts.map +1 -1
  20. package/dist/lib/api/cors-response.js +8 -6
  21. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  22. package/dist/lib/api/entity/generic-handler.js +0 -3
  23. package/dist/lib/api/helpers.d.ts.map +1 -1
  24. package/dist/lib/api/helpers.js +5 -22
  25. package/dist/lib/api/permission-middleware.d.ts.map +1 -1
  26. package/dist/lib/api/permission-middleware.js +0 -2
  27. package/dist/lib/api/rate-limit.d.ts +8 -0
  28. package/dist/lib/api/rate-limit.d.ts.map +1 -1
  29. package/dist/lib/api/rate-limit.js +34 -3
  30. package/dist/lib/api/request-origin.d.ts.map +1 -1
  31. package/dist/lib/api/request-origin.js +1 -1
  32. package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
  33. package/dist/lib/auth/runtime-readiness.js +2 -0
  34. package/dist/lib/auth/sample-accounts.d.ts +17 -0
  35. package/dist/lib/auth/sample-accounts.d.ts.map +1 -0
  36. package/dist/lib/auth/sample-accounts.js +22 -0
  37. package/dist/lib/auth.d.ts.map +1 -1
  38. package/dist/lib/auth.js +6 -3
  39. package/dist/lib/cache/public-entity-cache.d.ts +21 -0
  40. package/dist/lib/cache/public-entity-cache.d.ts.map +1 -0
  41. package/dist/lib/cache/public-entity-cache.js +25 -0
  42. package/dist/lib/entities/entity-hooks.d.ts.map +1 -1
  43. package/dist/lib/entities/entity-hooks.js +4 -0
  44. package/dist/lib/mcp/errors.d.ts +2 -0
  45. package/dist/lib/mcp/errors.d.ts.map +1 -1
  46. package/dist/lib/mcp/errors.js +3 -1
  47. package/dist/lib/mcp/index.d.ts +1 -1
  48. package/dist/lib/mcp/index.d.ts.map +1 -1
  49. package/dist/lib/mcp/index.js +2 -1
  50. package/dist/lib/services/generic-entity.service.d.ts.map +1 -1
  51. package/dist/lib/services/generic-entity.service.js +2 -0
  52. package/dist/lib/teams/actions.d.ts.map +1 -1
  53. package/dist/lib/teams/actions.js +0 -1
  54. package/dist/messages/de/billing.json +12 -1
  55. package/dist/messages/de/common.json +2 -0
  56. package/dist/messages/de/docs.json +1 -0
  57. package/dist/messages/de/features.json +16 -4
  58. package/dist/messages/de/home.json +5 -0
  59. package/dist/messages/de/index.d.ts +68 -25
  60. package/dist/messages/de/index.d.ts.map +1 -1
  61. package/dist/messages/de/index.js +2 -0
  62. package/dist/messages/de/index.ts +2 -0
  63. package/dist/messages/de/settings.json +1 -0
  64. package/dist/messages/de/teams.json +3 -18
  65. package/dist/messages/en/billing.json +1 -1
  66. package/dist/messages/en/common.json +2 -0
  67. package/dist/messages/en/docs.json +1 -0
  68. package/dist/messages/en/features.json +16 -4
  69. package/dist/messages/en/home.json +5 -0
  70. package/dist/messages/en/index.d.ts +58 -25
  71. package/dist/messages/en/index.d.ts.map +1 -1
  72. package/dist/messages/en/index.js +2 -0
  73. package/dist/messages/en/index.ts +2 -0
  74. package/dist/messages/en/settings.json +1 -0
  75. package/dist/messages/en/teams.json +3 -18
  76. package/dist/messages/es/billing.json +1 -1
  77. package/dist/messages/es/common.json +2 -0
  78. package/dist/messages/es/docs.json +1 -0
  79. package/dist/messages/es/features.json +16 -4
  80. package/dist/messages/es/home.json +5 -0
  81. package/dist/messages/es/index.d.ts +41 -8
  82. package/dist/messages/es/index.d.ts.map +1 -1
  83. package/dist/messages/es/index.js +2 -0
  84. package/dist/messages/es/index.ts +2 -0
  85. package/dist/messages/es/settings.json +1 -0
  86. package/dist/messages/es/teams.json +3 -0
  87. package/dist/messages/fr/billing.json +12 -1
  88. package/dist/messages/fr/common.json +2 -0
  89. package/dist/messages/fr/docs.json +1 -0
  90. package/dist/messages/fr/features.json +16 -4
  91. package/dist/messages/fr/home.json +5 -0
  92. package/dist/messages/fr/index.d.ts +68 -25
  93. package/dist/messages/fr/index.d.ts.map +1 -1
  94. package/dist/messages/fr/index.js +2 -0
  95. package/dist/messages/fr/index.ts +2 -0
  96. package/dist/messages/fr/settings.json +1 -0
  97. package/dist/messages/fr/teams.json +3 -18
  98. package/dist/messages/it/billing.json +12 -1
  99. package/dist/messages/it/common.json +2 -0
  100. package/dist/messages/it/docs.json +1 -0
  101. package/dist/messages/it/features.json +16 -4
  102. package/dist/messages/it/home.json +5 -0
  103. package/dist/messages/it/index.d.ts +68 -25
  104. package/dist/messages/it/index.d.ts.map +1 -1
  105. package/dist/messages/it/index.js +2 -0
  106. package/dist/messages/it/index.ts +2 -0
  107. package/dist/messages/it/settings.json +1 -0
  108. package/dist/messages/it/teams.json +3 -18
  109. package/dist/messages/pt/billing.json +12 -1
  110. package/dist/messages/pt/common.json +2 -0
  111. package/dist/messages/pt/docs.json +1 -0
  112. package/dist/messages/pt/features.json +16 -4
  113. package/dist/messages/pt/home.json +5 -0
  114. package/dist/messages/pt/index.d.ts +68 -25
  115. package/dist/messages/pt/index.d.ts.map +1 -1
  116. package/dist/messages/pt/index.js +2 -0
  117. package/dist/messages/pt/index.ts +2 -0
  118. package/dist/messages/pt/settings.json +1 -0
  119. package/dist/messages/pt/teams.json +3 -18
  120. package/dist/migrations/029_sample_accounts_outside_development.sql +55 -0
  121. package/dist/migrations/090_sample_data.sql +10 -0
  122. package/dist/routes/_internal/entity-permission-layout.d.ts.map +1 -1
  123. package/dist/routes/_internal/entity-permission-layout.js +0 -7
  124. package/dist/routes/api/mcp/route.d.ts.map +1 -1
  125. package/dist/routes/api/mcp/route.js +7 -1
  126. package/dist/routes/api/v1/media/upload/route.d.ts +2 -1
  127. package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
  128. package/dist/routes/api/v1/media/upload/route.js +10 -2
  129. package/dist/routes/api/v1/teams/[teamId]/members/route.d.ts.map +1 -1
  130. package/dist/routes/api/v1/teams/[teamId]/members/route.js +12 -10
  131. package/dist/routes/api/v1/teams/switch/route.d.ts.map +1 -1
  132. package/dist/routes/api/v1/teams/switch/route.js +4 -1
  133. package/dist/routes/dashboard/settings/password/page.d.ts.map +1 -1
  134. package/dist/routes/dashboard/settings/password/page.js +10 -12
  135. package/dist/routes/devtools/config/page.js +1 -1
  136. package/dist/routes/devtools/page.js +1 -1
  137. package/dist/routes/devtools/scheduled-actions/page.js +1 -1
  138. package/dist/routes/devtools/tests/[[...path]]/page.js +1 -1
  139. package/dist/templates/ci-workflows/github/cypress-regression.yml +1 -1
  140. package/dist/templates/ci-workflows/github/cypress-smoke.yml +2 -1
  141. package/dist/templates/projects/starter/README.md +2 -0
  142. package/dist/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
  143. package/dist/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
  144. package/dist/templates/proxy.ts +15 -8
  145. package/dist/templates/public/uploads/README.md +5 -94
  146. package/migrations/029_sample_accounts_outside_development.sql +55 -0
  147. package/migrations/090_sample_data.sql +10 -0
  148. package/package.json +2 -2
  149. package/scripts/build/registry/host/__tests__/host-proxy-areas.test.mjs +72 -1
  150. package/scripts/build/registry/host/proxy-areas.mjs +65 -2
  151. package/scripts/db/run-migrations.mjs +30 -10
  152. package/scripts/db/sample-data.mjs +44 -0
  153. package/scripts/db/verify-theme-migrations.mjs +6 -0
  154. package/templates/ci-workflows/github/cypress-regression.yml +1 -1
  155. package/templates/ci-workflows/github/cypress-smoke.yml +2 -1
  156. package/templates/projects/starter/README.md +2 -0
  157. package/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
  158. package/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
  159. package/templates/proxy.ts +15 -8
  160. package/templates/public/uploads/README.md +5 -94
  161. package/tests/jest/__mocks__/@nextsparkjs/registries/api-presets-registry.ts +2 -0
  162. package/tests/jest/__mocks__/@nextsparkjs/registries/mcp-registry.ts +2 -0
  163. package/dist/templates/projects/starter/public/brand/.gitkeep +0 -0
  164. package/dist/templates/public/uploads/.gitignore +0 -6
  165. package/dist/templates/public/uploads/temp/.gitkeep +0 -1
  166. package/templates/projects/starter/public/brand/.gitkeep +0 -0
  167. package/templates/public/uploads/.gitignore +0 -6
  168. package/templates/public/uploads/temp/.gitkeep +0 -1
@@ -8,6 +8,7 @@ import devtools from "./devtools.json";
8
8
  import docs from "./docs.json";
9
9
  import email from "./email.json";
10
10
  import entities from "./entities.json";
11
+ import features from "./features.json";
11
12
  import footer from "./footer.json";
12
13
  import home from "./home.json";
13
14
  import navigation from "./navigation.json";
@@ -29,6 +30,7 @@ var it_default = {
29
30
  docs,
30
31
  email,
31
32
  entities,
33
+ features,
32
34
  footer,
33
35
  home,
34
36
  navigation,
@@ -8,6 +8,7 @@ import devtools from './devtools.json'
8
8
  import docs from './docs.json'
9
9
  import email from './email.json'
10
10
  import entities from './entities.json'
11
+ import features from './features.json'
11
12
  import footer from './footer.json'
12
13
  import home from './home.json'
13
14
  import navigation from './navigation.json'
@@ -30,6 +31,7 @@ export default {
30
31
  docs,
31
32
  email,
32
33
  entities,
34
+ features,
33
35
  footer,
34
36
  home,
35
37
  navigation,
@@ -368,6 +368,7 @@
368
368
  "refunded": "Rimborsata"
369
369
  },
370
370
  "pagination": {
371
+ "page": "Pagina {current} di {total}",
371
372
  "showing": "Mostrando da {start} a {end} di {total} fatture",
372
373
  "previous": "Precedente",
373
374
  "next": "Successivo"
@@ -2,20 +2,6 @@
2
2
  "title": "Team",
3
3
  "description": "Gestisci i tuoi team e collaborazioni",
4
4
 
5
- "entity": {
6
- "description": "Gestisci i tuoi team, membri e inviti",
7
- "plural": "Team"
8
- },
9
-
10
- "fields": {
11
- "name": "Nome",
12
- "slug": "URL",
13
- "description": "Descrizione",
14
- "email": "Email",
15
- "role": "Ruolo",
16
- "joinedAt": "Data iscrizione"
17
- },
18
-
19
5
  "types": {
20
6
  "personal": "Personale",
21
7
  "work": "Team di Lavoro"
@@ -120,6 +106,7 @@
120
106
  },
121
107
 
122
108
  "invitations": {
109
+ "expired": "Scaduto",
123
110
  "title": "Inviti in Sospeso",
124
111
  "description": "Inviti in attesa di risposta",
125
112
  "pending": "In sospeso",
@@ -138,6 +125,7 @@
138
125
  },
139
126
 
140
127
  "invite": {
128
+ "limitReached": "Limite di membri del team raggiunto ({limit})",
141
129
  "title": "Invita Membro",
142
130
  "description": "Invita qualcuno a unirsi a questo team",
143
131
  "emailLabel": "Email",
@@ -168,10 +156,6 @@
168
156
  "danger": "Zona Pericolosa"
169
157
  },
170
158
 
171
- "messages": {
172
- "loading": "Caricamento..."
173
- },
174
-
175
159
  "errors": {
176
160
  "notFound": "Team non trovato",
177
161
  "notMember": "Non sei membro di questo team",
@@ -197,6 +181,7 @@
197
181
  },
198
182
 
199
183
  "messages": {
184
+ "cancelling": "Annullamento...",
200
185
  "created": "Team creato con successo",
201
186
  "loading": "Caricamento team...",
202
187
  "memberInvited": "Membro invitato con successo"
@@ -7,7 +7,6 @@
7
7
  "contactUs": "Fale Conosco",
8
8
  "unlimited": "Ilimitado",
9
9
  "upgrade": "Fazer Upgrade",
10
- "downgrade": "Fazer Downgrade",
11
10
  "cancelSubscription": "Cancelar Assinatura",
12
11
  "upgradeDescription": "Escolha o plano que melhor se adapta as suas necessidades",
13
12
  "monthly": "Mensal",
@@ -159,6 +158,18 @@
159
158
  "failed": "Falhou"
160
159
  },
161
160
 
161
+ "changePlan": {
162
+ "title": "Alterar plano",
163
+ "from": "Plano atual",
164
+ "to": "Novo plano",
165
+ "upgradeDescription": "A cobrança será ajustada proporcionalmente ao período atual",
166
+ "downgradeDescription": "Os recursos existentes continuarão acessíveis, mas a criação de novos pode ser limitada",
167
+ "downgradeToFreeDescription": "Sua assinatura será cancelada e você passará para o plano gratuito",
168
+ "confirm": "Confirmar alteração",
169
+ "cancel": "Cancelar",
170
+ "confirming": "Alterando o plano..."
171
+ },
172
+
162
173
  "quota": {
163
174
  "limitReached": "Voce atingiu seu limite de {entity}",
164
175
  "limitReachedDetail": "Seu plano atual nao permite mais {entity}. Faca upgrade para continuar crescendo.",
@@ -1,4 +1,6 @@
1
1
  {
2
+ "soon": "Em breve",
3
+ "comingSoon": "Em breve",
2
4
  "navigation": {
3
5
  "dashboard": "Painel",
4
6
  "settings": "Configuracoes",
@@ -18,6 +18,7 @@
18
18
  "home": "Inicio"
19
19
  },
20
20
  "sidebar": {
21
+ "close": "Fechar menu lateral",
21
22
  "open": "Abrir menu lateral",
22
23
  "label": "Navegacao da documentacao"
23
24
  },
@@ -1,8 +1,20 @@
1
1
  {
2
2
  "analytics": {
3
- "title": "",
4
- "benefit1": "",
5
- "benefit2": "",
6
- "benefit3": ""
3
+ "title": "Analytics Avançado",
4
+ "benefit1": "Métricas em tempo real",
5
+ "benefit2": "Construtor de relatórios personalizados",
6
+ "benefit3": "Exportar para PDF/CSV"
7
+ },
8
+ "webhooks": {
9
+ "title": "Webhooks",
10
+ "benefit1": "Callbacks HTTP para eventos",
11
+ "benefit2": "Templates de payload personalizados",
12
+ "benefit3": "Lógica de retry e logging"
13
+ },
14
+ "automation": {
15
+ "title": "Automação de Tarefas",
16
+ "benefit1": "Criação automática de tarefas",
17
+ "benefit2": "Ações agendadas",
18
+ "benefit3": "Gatilhos de workflow"
7
19
  }
8
20
  }
@@ -9,5 +9,10 @@
9
9
  "features": {
10
10
  "title": "Recursos",
11
11
  "subtitle": "Tudo o que voce precisa"
12
+ },
13
+ "auth": {
14
+ "signIn": "Entrar",
15
+ "createAccount": "Criar conta",
16
+ "goToDashboard": "Ir para o painel"
12
17
  }
13
18
  }
@@ -422,14 +422,6 @@ declare const _default: {
422
422
  contactUs: string;
423
423
  unlimited: string;
424
424
  upgrade: string;
425
- downgrade: {
426
- title: string;
427
- description: string;
428
- resource_over: string;
429
- policy: string;
430
- confirm: string;
431
- cancel: string;
432
- };
433
425
  cancelSubscription: string;
434
426
  upgradeDescription: string;
435
427
  monthly: string;
@@ -536,6 +528,14 @@ declare const _default: {
536
528
  featureNotAvailable: string;
537
529
  upgradeRequired: string;
538
530
  };
531
+ downgrade: {
532
+ title: string;
533
+ description: string;
534
+ resource_over: string;
535
+ policy: string;
536
+ confirm: string;
537
+ cancel: string;
538
+ };
539
539
  portal: {
540
540
  manage: string;
541
541
  loading: string;
@@ -563,6 +563,17 @@ declare const _default: {
563
563
  pending: string;
564
564
  failed: string;
565
565
  };
566
+ changePlan: {
567
+ title: string;
568
+ from: string;
569
+ to: string;
570
+ upgradeDescription: string;
571
+ downgradeDescription: string;
572
+ downgradeToFreeDescription: string;
573
+ confirm: string;
574
+ cancel: string;
575
+ confirming: string;
576
+ };
566
577
  quota: {
567
578
  limitReached: string;
568
579
  limitReachedDetail: string;
@@ -598,6 +609,8 @@ declare const _default: {
598
609
  signingOut: string;
599
610
  };
600
611
  readonly common: {
612
+ soon: string;
613
+ comingSoon: string;
601
614
  navigation: {
602
615
  dashboard: string;
603
616
  settings: string;
@@ -1238,6 +1251,7 @@ declare const _default: {
1238
1251
  home: string;
1239
1252
  };
1240
1253
  sidebar: {
1254
+ close: string;
1241
1255
  open: string;
1242
1256
  label: string;
1243
1257
  };
@@ -1356,6 +1370,26 @@ declare const _default: {
1356
1370
  idCopied: string;
1357
1371
  };
1358
1372
  };
1373
+ readonly features: {
1374
+ analytics: {
1375
+ title: string;
1376
+ benefit1: string;
1377
+ benefit2: string;
1378
+ benefit3: string;
1379
+ };
1380
+ webhooks: {
1381
+ title: string;
1382
+ benefit1: string;
1383
+ benefit2: string;
1384
+ benefit3: string;
1385
+ };
1386
+ automation: {
1387
+ title: string;
1388
+ benefit1: string;
1389
+ benefit2: string;
1390
+ benefit3: string;
1391
+ };
1392
+ };
1359
1393
  readonly footer: {
1360
1394
  product: string;
1361
1395
  features: string;
@@ -1390,6 +1424,11 @@ declare const _default: {
1390
1424
  title: string;
1391
1425
  subtitle: string;
1392
1426
  };
1427
+ auth: {
1428
+ signIn: string;
1429
+ createAccount: string;
1430
+ goToDashboard: string;
1431
+ };
1393
1432
  };
1394
1433
  readonly navigation: {
1395
1434
  home: string;
@@ -1893,6 +1932,7 @@ declare const _default: {
1893
1932
  refunded: string;
1894
1933
  };
1895
1934
  pagination: {
1935
+ page: string;
1896
1936
  showing: string;
1897
1937
  previous: string;
1898
1938
  next: string;
@@ -2129,18 +2169,6 @@ declare const _default: {
2129
2169
  readonly teams: {
2130
2170
  title: string;
2131
2171
  description: string;
2132
- entity: {
2133
- description: string;
2134
- plural: string;
2135
- };
2136
- fields: {
2137
- name: string;
2138
- slug: string;
2139
- description: string;
2140
- email: string;
2141
- role: string;
2142
- joinedAt: string;
2143
- };
2144
2172
  types: {
2145
2173
  personal: string;
2146
2174
  work: string;
@@ -2157,6 +2185,10 @@ declare const _default: {
2157
2185
  member: string;
2158
2186
  viewer: string;
2159
2187
  };
2188
+ entity: {
2189
+ description: string;
2190
+ plural: string;
2191
+ };
2160
2192
  actions: {
2161
2193
  create: string;
2162
2194
  creating: string;
@@ -2230,6 +2262,7 @@ declare const _default: {
2230
2262
  joined: string;
2231
2263
  };
2232
2264
  invitations: {
2265
+ expired: string;
2233
2266
  title: string;
2234
2267
  description: string;
2235
2268
  pending: string;
@@ -2247,6 +2280,7 @@ declare const _default: {
2247
2280
  cancelError: string;
2248
2281
  };
2249
2282
  invite: {
2283
+ limitReached: string;
2250
2284
  title: string;
2251
2285
  description: string;
2252
2286
  emailLabel: string;
@@ -2274,11 +2308,6 @@ declare const _default: {
2274
2308
  billing: string;
2275
2309
  danger: string;
2276
2310
  };
2277
- messages: {
2278
- created: string;
2279
- loading: string;
2280
- memberInvited: string;
2281
- };
2282
2311
  errors: {
2283
2312
  notFound: string;
2284
2313
  notMember: string;
@@ -2292,6 +2321,20 @@ declare const _default: {
2292
2321
  title: string;
2293
2322
  description: string;
2294
2323
  };
2324
+ fields: {
2325
+ name: string;
2326
+ slug: string;
2327
+ description: string;
2328
+ email: string;
2329
+ role: string;
2330
+ joinedAt: string;
2331
+ };
2332
+ messages: {
2333
+ cancelling: string;
2334
+ created: string;
2335
+ loading: string;
2336
+ memberInvited: string;
2337
+ };
2295
2338
  };
2296
2339
  readonly validation: {
2297
2340
  email: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/messages/pt/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,wBAqBU"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/messages/pt/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,wBAsBU"}
@@ -8,6 +8,7 @@ import devtools from "./devtools.json";
8
8
  import docs from "./docs.json";
9
9
  import email from "./email.json";
10
10
  import entities from "./entities.json";
11
+ import features from "./features.json";
11
12
  import footer from "./footer.json";
12
13
  import home from "./home.json";
13
14
  import navigation from "./navigation.json";
@@ -29,6 +30,7 @@ var pt_default = {
29
30
  docs,
30
31
  email,
31
32
  entities,
33
+ features,
32
34
  footer,
33
35
  home,
34
36
  navigation,
@@ -8,6 +8,7 @@ import devtools from './devtools.json'
8
8
  import docs from './docs.json'
9
9
  import email from './email.json'
10
10
  import entities from './entities.json'
11
+ import features from './features.json'
11
12
  import footer from './footer.json'
12
13
  import home from './home.json'
13
14
  import navigation from './navigation.json'
@@ -30,6 +31,7 @@ export default {
30
31
  docs,
31
32
  email,
32
33
  entities,
34
+ features,
33
35
  footer,
34
36
  home,
35
37
  navigation,
@@ -368,6 +368,7 @@
368
368
  "refunded": "Reembolsada"
369
369
  },
370
370
  "pagination": {
371
+ "page": "Página {current} de {total}",
371
372
  "showing": "Mostrando {start} a {end} de {total} faturas",
372
373
  "previous": "Anterior",
373
374
  "next": "Proximo"
@@ -2,20 +2,6 @@
2
2
  "title": "Equipes",
3
3
  "description": "Gerencie suas equipes e colaboracoes",
4
4
 
5
- "entity": {
6
- "description": "Gerencie suas equipes, membros e convites",
7
- "plural": "Equipes"
8
- },
9
-
10
- "fields": {
11
- "name": "Nome",
12
- "slug": "URL",
13
- "description": "Descricao",
14
- "email": "Email",
15
- "role": "Funcao",
16
- "joinedAt": "Data de entrada"
17
- },
18
-
19
5
  "types": {
20
6
  "personal": "Pessoal",
21
7
  "work": "Equipe de Trabalho"
@@ -120,6 +106,7 @@
120
106
  },
121
107
 
122
108
  "invitations": {
109
+ "expired": "Expirado",
123
110
  "title": "Convites Pendentes",
124
111
  "description": "Convites aguardando resposta",
125
112
  "pending": "Pendente",
@@ -138,6 +125,7 @@
138
125
  },
139
126
 
140
127
  "invite": {
128
+ "limitReached": "Limite de membros da equipe atingido ({limit})",
141
129
  "title": "Convidar Membro",
142
130
  "description": "Convide alguem para participar desta equipe",
143
131
  "emailLabel": "Email",
@@ -168,10 +156,6 @@
168
156
  "danger": "Zona de Perigo"
169
157
  },
170
158
 
171
- "messages": {
172
- "loading": "Carregando..."
173
- },
174
-
175
159
  "errors": {
176
160
  "notFound": "Equipe nao encontrada",
177
161
  "notMember": "Voce nao e membro desta equipe",
@@ -197,6 +181,7 @@
197
181
  },
198
182
 
199
183
  "messages": {
184
+ "cancelling": "Cancelando...",
200
185
  "created": "Equipe criada com sucesso",
201
186
  "loading": "Carregando equipes...",
202
187
  "memberInvited": "Membro convidado com sucesso"
@@ -0,0 +1,55 @@
1
+ -- Migration: 029_sample_accounts_outside_development.sql
2
+ -- Description: sample accounts keep no usable credentials outside development
3
+ --
4
+ -- Sample data (090_sample_data.sql and the projects' *sample_data* files) is
5
+ -- only applied by an explicit development opt-in (`nextspark db:seed`,
6
+ -- `--sample-data` or NEXTSPARK_SEED_SAMPLE_DATA=1). Databases migrated before
7
+ -- that may still hold the sample accounts. This migration finds them by the
8
+ -- sample password, never by name, so a renamed account is found and an account
9
+ -- whose password was changed is left alone; for each one it:
10
+ -- - removes the sample password (its "credential" account row),
11
+ -- - removes its sessions,
12
+ -- - deactivates its API keys (status 'inactive'; deleting them would delete
13
+ -- their api_audit_log rows),
14
+ -- - sets its global role to 'member' (027's trigger then removes it from the
15
+ -- System Admin Team, as for any user who loses that role).
16
+ -- It also removes the sample sessions and deactivates the sample API key by
17
+ -- their fixed values, whoever owns them now. Nothing else is changed.
18
+ --
19
+ -- It runs once, everywhere, except in a development run that opted into sample
20
+ -- data (the runner sets nextspark.seed_sample_data to 'on' then), where those
21
+ -- accounts are wanted. To keep using one of them deliberately, give it a new
22
+ -- password before upgrading; to restore one afterwards, set its role back and
23
+ -- reset its password.
24
+
25
+ DO $$
26
+ DECLARE
27
+ sample_passwords CONSTANT TEXT[] := ARRAY[
28
+ '22de14d5472248ed0bece911df908b2a:d29576424798ba6845d348a3767c0b0f38a00f2aca461b3b1d34b99a93cab06c86774c6edb183e6d6ec47457649b032a49a7b60a48f6f4f7fbbc4ea40258f19f',
29
+ '3db9e98e2b4d3caca97fdf2783791cbc:34b293de615caf277a237773208858e960ea8aa10f1f5c5c309b632f192cac34d52ceafbd338385616f4929e4b1b6c055b67429c6722ffdb80b01d9bf4764866'
30
+ ];
31
+ sample_session_tokens CONSTANT TEXT[] := ARRAY['tmt_superadmin_session_token_001', 'tmt_developer_session_token_001'];
32
+ sample_key_hashes CONSTANT TEXT[] := ARRAY[
33
+ '205f13ae4d2e18df417e61123bb84030c124fcb5013699046379ae1b5ec04324',
34
+ 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
35
+ ];
36
+ sample_users TEXT[];
37
+ BEGIN
38
+ IF current_setting('nextspark.seed_sample_data', true) = 'on' THEN
39
+ RAISE NOTICE 'Sample accounts: kept (development run with sample data).';
40
+ RETURN;
41
+ END IF;
42
+
43
+ SELECT COALESCE(array_agg(DISTINCT "userId"), '{}') INTO sample_users
44
+ FROM "account"
45
+ WHERE "providerId" = 'credential' AND "password" = ANY (sample_passwords);
46
+
47
+ DELETE FROM "account" WHERE "providerId" = 'credential' AND "password" = ANY (sample_passwords);
48
+ DELETE FROM "session" WHERE "userId" = ANY (sample_users) OR token = ANY (sample_session_tokens);
49
+ UPDATE "api_key" SET status = 'inactive', "updatedAt" = now()
50
+ WHERE status IS DISTINCT FROM 'inactive' AND ("userId" = ANY (sample_users) OR "keyHash" = ANY (sample_key_hashes));
51
+ UPDATE "users" SET role = 'member', "updatedAt" = now()
52
+ WHERE id = ANY (sample_users) AND role <> 'member';
53
+
54
+ RAISE NOTICE 'Sample accounts: % disabled (no password, sessions or active API keys; role member).', cardinality(sample_users);
55
+ END $$;
@@ -7,6 +7,16 @@
7
7
  -- Theme-specific demo data (TMT.dev users, companies, invoices) is in:
8
8
  -- migrations/090_demo_users_teams.sql
9
9
 
10
+ -- Only a development run that asked for sample data applies this file (see
11
+ -- scripts/db/sample-data.mjs); anything else that runs it, such as a tool that
12
+ -- applies every core .sql file in order, fails here instead of creating these accounts.
13
+ DO $$
14
+ BEGIN
15
+ IF current_setting('nextspark.seed_sample_data', true) IS DISTINCT FROM 'on' THEN
16
+ RAISE EXCEPTION 'Sample data is applied only by `pnpm db:seed` (or NEXTSPARK_SEED_SAMPLE_DATA=1) outside production. If you ran that, the session setting it relies on was lost: a transaction-mode pooler (PgBouncer, Supavisor on port 6543) drops it, so point MIGRATE_DATABASE_URL at a direct connection.';
17
+ END IF;
18
+ END $$;
19
+
10
20
  -- ============================================
11
21
  -- STEP 1: CREATE CORE TEST USERS
12
22
  -- ============================================
@@ -1 +1 @@
1
- {"version":3,"file":"entity-permission-layout.d.ts","sourceRoot":"","sources":["../../../src/routes/_internal/entity-permission-layout.tsx"],"names":[],"mappings":"AAqDA,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,MAAM,EACN,QAAQ,GACT,EAAE,2BAA2B,oDAiD7B"}
1
+ {"version":3,"file":"entity-permission-layout.d.ts","sourceRoot":"","sources":["../../../src/routes/_internal/entity-permission-layout.tsx"],"names":[],"mappings":"AAqDA,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,MAAM,EACN,QAAQ,GACT,EAAE,2BAA2B,oDAyC7B"}
@@ -34,13 +34,6 @@ export async function EntityPermissionLayout({
34
34
  }
35
35
  const action = detectActionFromPathname(pathname, entity);
36
36
  const permission = `${entity}.${action}`;
37
- console.log("[EntityPermissionLayout] Checking permission:", {
38
- entity,
39
- action,
40
- permission,
41
- userId,
42
- teamId
43
- });
44
37
  const hasPermission = await checkPermission(userId, teamId, permission);
45
38
  if (!hasPermission) {
46
39
  console.log("[EntityPermissionLayout] Permission denied, redirecting");
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/routes/api/mcp/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAOvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAoIvE,eAAO,MAAM,IAAI,iDAA0C,CAAA;AAE3D,wBAAsB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,CAKjD;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC,CAKpD;AAED,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/routes/api/mcp/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAOvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AA2IvE,eAAO,MAAM,IAAI,iDAA0C,CAAA;AAE3D,wBAAsB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,CAKjD;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC,CAKpD;AAED,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
@@ -7,7 +7,7 @@ import { validateApiKey } from "@nextsparkjs/core/lib/api/auth";
7
7
  import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
8
8
  import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
9
9
  import { setEntityRegistry } from "@nextsparkjs/core/lib/entities/queries";
10
- import { createMcpEngine } from "@nextsparkjs/core/lib/mcp";
10
+ import { createMcpEngine, RATE_LIMIT_MESSAGE } from "@nextsparkjs/core/lib/mcp";
11
11
  import { ENTITY_REGISTRY, ENTITY_METADATA } from "@nextsparkjs/registries/entity-registry";
12
12
  import { MCP_OVERRIDES } from "@nextsparkjs/registries/mcp-registry";
13
13
  import { API_PRESETS_REGISTRY } from "@nextsparkjs/registries/api-presets-registry";
@@ -56,6 +56,12 @@ async function handleMcpPost(request) {
56
56
  return jsonRpcError(403, -32e3, "Origin not allowed");
57
57
  }
58
58
  const authResult = await authenticateRequest(request, { allowAnyScope: true });
59
+ if (authResult.rateLimitResponse) {
60
+ const limited = jsonRpcError(429, -32e3, RATE_LIMIT_MESSAGE);
61
+ const retryAfter = authResult.rateLimitResponse.headers.get("Retry-After");
62
+ if (retryAfter) limited.headers.set("Retry-After", retryAfter);
63
+ return limited;
64
+ }
59
65
  if (!authResult.success || authResult.type !== "api-key" || !authResult.user) {
60
66
  return jsonRpcError(401, -32001, API_KEY_HELP);
61
67
  }
@@ -7,7 +7,8 @@ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response';
7
7
  * Enhanced version that creates database records for uploaded files.
8
8
  *
9
9
  * Features:
10
- * - Uploads files to Vercel Blob (production) or local storage (development)
10
+ * - Uploads files to Vercel Blob; development without a token falls back to local storage,
11
+ * production without one answers 503 STORAGE_NOT_CONFIGURED
11
12
  * - Creates media records in database for tracking
12
13
  * - Extracts image dimensions automatically
13
14
  * - Returns both legacy URLs array and new media records array
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/media/upload/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAOzC,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAkCvE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,IAAI,uEA0KN,CAAC;AAEZ;;;;GAIG;AACH,eAAO,MAAM,GAAG,uEA0CN,CAAC;AAEX,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/media/upload/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAOzC,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AA8CvE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,IAAI,uEA6KN,CAAC;AAEZ;;;;GAIG;AACH,eAAO,MAAM,GAAG,uEA0CN,CAAC;AAEX,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
@@ -15,6 +15,13 @@ const isVercelBlobConfigured = () => {
15
15
  const token = process.env.BLOB_READ_WRITE_TOKEN;
16
16
  return !!token && token.startsWith("vercel_blob_");
17
17
  };
18
+ const localFallbackAllowed = () => process.env.NODE_ENV !== "production";
19
+ const storageNotConfigured = () => createApiError(
20
+ 'Media storage is not configured: set BLOB_READ_WRITE_TOKEN (a Vercel Blob read/write token, starts with "vercel_blob_") to upload files in production.',
21
+ 503,
22
+ { missing: "BLOB_READ_WRITE_TOKEN" },
23
+ API_ERROR_CODES.STORAGE_NOT_CONFIGURED
24
+ );
18
25
  async function uploadToLocalStorageBuffer(buffer, fileName) {
19
26
  const uploadDir = join(process.cwd(), "public", "uploads", "temp");
20
27
  if (!existsSync(uploadDir)) {
@@ -37,6 +44,7 @@ export const POST = withRateLimitTier(async (request) => {
37
44
  if (!await checkPermission(authResult.user.id, teamId, "media.upload")) {
38
45
  return createApiError("Permission denied", 403, void 0, API_ERROR_CODES.PERMISSION_DENIED);
39
46
  }
47
+ if (!isVercelBlobConfigured() && !localFallbackAllowed()) return storageNotConfigured();
40
48
  const formData = await request.formData();
41
49
  const files = Array.from(formData.getAll("files")).filter((value) => value instanceof File);
42
50
  if (files.length === 0) {
@@ -46,7 +54,6 @@ export const POST = withRateLimitTier(async (request) => {
46
54
  const uploadedMedia = [];
47
55
  const useVercelBlob = isVercelBlobConfigured();
48
56
  console.log(`\u{1F4E4} [Media Upload] Storage mode: ${useVercelBlob ? "Vercel Blob" : "Local Storage"}`);
49
- console.log(`\u{1F4E4} [Media Upload] Team context: ${teamId}`);
50
57
  for (const file of files) {
51
58
  if (!file.size) {
52
59
  continue;
@@ -101,6 +108,7 @@ export const POST = withRateLimitTier(async (request) => {
101
108
  uploadedUrl = blob.url;
102
109
  console.log(`\u2705 [Media Upload] Uploaded to Vercel Blob: ${uploadedUrl}`);
103
110
  } catch (blobError) {
111
+ if (!localFallbackAllowed()) throw blobError;
104
112
  console.warn(`\u26A0\uFE0F [Media Upload] Vercel Blob failed, falling back to local storage:`, blobError);
105
113
  uploadedUrl = await uploadToLocalStorageBuffer(fileBuffer, fileName);
106
114
  console.log(`\u2705 [Media Upload] Uploaded to local storage (fallback): ${uploadedUrl}`);
@@ -179,7 +187,7 @@ export const GET = withRateLimitTier(async (request) => {
179
187
  const maxSizeMB = ((_a = MEDIA_CONFIG) == null ? void 0 : _a.maxSizeMB) ?? 10;
180
188
  return createApiResponse({
181
189
  message: "Media upload endpoint is active",
182
- storage: useVercelBlob ? "Vercel Blob" : "Local Storage",
190
+ storage: useVercelBlob ? "Vercel Blob" : localFallbackAllowed() ? "Local Storage" : "Not configured (set BLOB_READ_WRITE_TOKEN)",
183
191
  uploadPath: "uploads/temp/",
184
192
  supportedTypes: ((_b = MEDIA_CONFIG) == null ? void 0 : _b.allowedMimeTypes) ?? ["image/jpeg", "image/png", "image/gif", "image/webp", "video/mp4", "video/webm"],
185
193
  maxFileSize: `${maxSizeMB}MB`,