@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.
- package/dist/components/billing/InvoicesPagination.js +2 -2
- package/dist/components/dashboard/navigation/DynamicNavigation.js +2 -2
- package/dist/components/settings/layouts/SettingsSidebar.d.ts.map +1 -1
- package/dist/components/settings/layouts/SettingsSidebar.js +0 -1
- package/dist/components/teams/CreateTeamButton.js +2 -2
- package/dist/components/teams/CreateTeamDialog.js +1 -1
- package/dist/components/teams/InviteMemberButton.js +3 -3
- package/dist/components/teams/InviteMemberDialog.js +1 -1
- package/dist/components/teams/TeamPendingInvitations.js +2 -2
- package/dist/lib/api/api-error.d.ts +2 -0
- package/dist/lib/api/api-error.d.ts.map +1 -1
- package/dist/lib/api/api-error.js +3 -1
- package/dist/lib/api/auth/dual-auth.d.ts +2 -1
- package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
- package/dist/lib/api/auth/dual-auth.js +22 -4
- package/dist/lib/api/auth/scope-policy.d.ts +6 -3
- package/dist/lib/api/auth/scope-policy.d.ts.map +1 -1
- package/dist/lib/api/cors-response.d.ts +3 -2
- package/dist/lib/api/cors-response.d.ts.map +1 -1
- package/dist/lib/api/cors-response.js +8 -6
- package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
- package/dist/lib/api/entity/generic-handler.js +0 -3
- package/dist/lib/api/helpers.d.ts.map +1 -1
- package/dist/lib/api/helpers.js +5 -22
- package/dist/lib/api/permission-middleware.d.ts.map +1 -1
- package/dist/lib/api/permission-middleware.js +0 -2
- package/dist/lib/api/rate-limit.d.ts +8 -0
- package/dist/lib/api/rate-limit.d.ts.map +1 -1
- package/dist/lib/api/rate-limit.js +34 -3
- package/dist/lib/api/request-origin.d.ts.map +1 -1
- package/dist/lib/api/request-origin.js +1 -1
- package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
- package/dist/lib/auth/runtime-readiness.js +2 -0
- package/dist/lib/auth/sample-accounts.d.ts +17 -0
- package/dist/lib/auth/sample-accounts.d.ts.map +1 -0
- package/dist/lib/auth/sample-accounts.js +22 -0
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +6 -3
- package/dist/lib/cache/public-entity-cache.d.ts +21 -0
- package/dist/lib/cache/public-entity-cache.d.ts.map +1 -0
- package/dist/lib/cache/public-entity-cache.js +25 -0
- package/dist/lib/entities/entity-hooks.d.ts.map +1 -1
- package/dist/lib/entities/entity-hooks.js +4 -0
- package/dist/lib/mcp/errors.d.ts +2 -0
- package/dist/lib/mcp/errors.d.ts.map +1 -1
- package/dist/lib/mcp/errors.js +3 -1
- package/dist/lib/mcp/index.d.ts +1 -1
- package/dist/lib/mcp/index.d.ts.map +1 -1
- package/dist/lib/mcp/index.js +2 -1
- package/dist/lib/services/generic-entity.service.d.ts.map +1 -1
- package/dist/lib/services/generic-entity.service.js +2 -0
- package/dist/lib/teams/actions.d.ts.map +1 -1
- package/dist/lib/teams/actions.js +0 -1
- package/dist/messages/de/billing.json +12 -1
- package/dist/messages/de/common.json +2 -0
- package/dist/messages/de/docs.json +1 -0
- package/dist/messages/de/features.json +16 -4
- package/dist/messages/de/home.json +5 -0
- package/dist/messages/de/index.d.ts +68 -25
- package/dist/messages/de/index.d.ts.map +1 -1
- package/dist/messages/de/index.js +2 -0
- package/dist/messages/de/index.ts +2 -0
- package/dist/messages/de/settings.json +1 -0
- package/dist/messages/de/teams.json +3 -18
- package/dist/messages/en/billing.json +1 -1
- package/dist/messages/en/common.json +2 -0
- package/dist/messages/en/docs.json +1 -0
- package/dist/messages/en/features.json +16 -4
- package/dist/messages/en/home.json +5 -0
- package/dist/messages/en/index.d.ts +58 -25
- package/dist/messages/en/index.d.ts.map +1 -1
- package/dist/messages/en/index.js +2 -0
- package/dist/messages/en/index.ts +2 -0
- package/dist/messages/en/settings.json +1 -0
- package/dist/messages/en/teams.json +3 -18
- package/dist/messages/es/billing.json +1 -1
- package/dist/messages/es/common.json +2 -0
- package/dist/messages/es/docs.json +1 -0
- package/dist/messages/es/features.json +16 -4
- package/dist/messages/es/home.json +5 -0
- package/dist/messages/es/index.d.ts +41 -8
- package/dist/messages/es/index.d.ts.map +1 -1
- package/dist/messages/es/index.js +2 -0
- package/dist/messages/es/index.ts +2 -0
- package/dist/messages/es/settings.json +1 -0
- package/dist/messages/es/teams.json +3 -0
- package/dist/messages/fr/billing.json +12 -1
- package/dist/messages/fr/common.json +2 -0
- package/dist/messages/fr/docs.json +1 -0
- package/dist/messages/fr/features.json +16 -4
- package/dist/messages/fr/home.json +5 -0
- package/dist/messages/fr/index.d.ts +68 -25
- package/dist/messages/fr/index.d.ts.map +1 -1
- package/dist/messages/fr/index.js +2 -0
- package/dist/messages/fr/index.ts +2 -0
- package/dist/messages/fr/settings.json +1 -0
- package/dist/messages/fr/teams.json +3 -18
- package/dist/messages/it/billing.json +12 -1
- package/dist/messages/it/common.json +2 -0
- package/dist/messages/it/docs.json +1 -0
- package/dist/messages/it/features.json +16 -4
- package/dist/messages/it/home.json +5 -0
- package/dist/messages/it/index.d.ts +68 -25
- package/dist/messages/it/index.d.ts.map +1 -1
- package/dist/messages/it/index.js +2 -0
- package/dist/messages/it/index.ts +2 -0
- package/dist/messages/it/settings.json +1 -0
- package/dist/messages/it/teams.json +3 -18
- package/dist/messages/pt/billing.json +12 -1
- package/dist/messages/pt/common.json +2 -0
- package/dist/messages/pt/docs.json +1 -0
- package/dist/messages/pt/features.json +16 -4
- package/dist/messages/pt/home.json +5 -0
- package/dist/messages/pt/index.d.ts +68 -25
- package/dist/messages/pt/index.d.ts.map +1 -1
- package/dist/messages/pt/index.js +2 -0
- package/dist/messages/pt/index.ts +2 -0
- package/dist/messages/pt/settings.json +1 -0
- package/dist/messages/pt/teams.json +3 -18
- package/dist/migrations/029_sample_accounts_outside_development.sql +55 -0
- package/dist/migrations/090_sample_data.sql +10 -0
- package/dist/routes/_internal/entity-permission-layout.d.ts.map +1 -1
- package/dist/routes/_internal/entity-permission-layout.js +0 -7
- package/dist/routes/api/mcp/route.d.ts.map +1 -1
- package/dist/routes/api/mcp/route.js +7 -1
- package/dist/routes/api/v1/media/upload/route.d.ts +2 -1
- package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media/upload/route.js +10 -2
- package/dist/routes/api/v1/teams/[teamId]/members/route.d.ts.map +1 -1
- package/dist/routes/api/v1/teams/[teamId]/members/route.js +12 -10
- package/dist/routes/api/v1/teams/switch/route.d.ts.map +1 -1
- package/dist/routes/api/v1/teams/switch/route.js +4 -1
- package/dist/routes/dashboard/settings/password/page.d.ts.map +1 -1
- package/dist/routes/dashboard/settings/password/page.js +10 -12
- package/dist/routes/devtools/config/page.js +1 -1
- package/dist/routes/devtools/page.js +1 -1
- package/dist/routes/devtools/scheduled-actions/page.js +1 -1
- package/dist/routes/devtools/tests/[[...path]]/page.js +1 -1
- package/dist/templates/ci-workflows/github/cypress-regression.yml +1 -1
- package/dist/templates/ci-workflows/github/cypress-smoke.yml +2 -1
- package/dist/templates/projects/starter/README.md +2 -0
- package/dist/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
- package/dist/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
- package/dist/templates/proxy.ts +15 -8
- package/dist/templates/public/uploads/README.md +5 -94
- package/migrations/029_sample_accounts_outside_development.sql +55 -0
- package/migrations/090_sample_data.sql +10 -0
- package/package.json +2 -2
- package/scripts/build/registry/host/__tests__/host-proxy-areas.test.mjs +72 -1
- package/scripts/build/registry/host/proxy-areas.mjs +65 -2
- package/scripts/db/run-migrations.mjs +30 -10
- package/scripts/db/sample-data.mjs +44 -0
- package/scripts/db/verify-theme-migrations.mjs +6 -0
- package/templates/ci-workflows/github/cypress-regression.yml +1 -1
- package/templates/ci-workflows/github/cypress-smoke.yml +2 -1
- package/templates/projects/starter/README.md +2 -0
- package/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
- package/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
- package/templates/proxy.ts +15 -8
- package/templates/public/uploads/README.md +5 -94
- package/tests/jest/__mocks__/@nextsparkjs/registries/api-presets-registry.ts +2 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/mcp-registry.ts +2 -0
- package/dist/templates/projects/starter/public/brand/.gitkeep +0 -0
- package/dist/templates/public/uploads/.gitignore +0 -6
- package/dist/templates/public/uploads/temp/.gitkeep +0 -1
- package/templates/projects/starter/public/brand/.gitkeep +0 -0
- package/templates/public/uploads/.gitignore +0 -6
- 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,
|
|
@@ -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,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
|
}
|
|
@@ -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":"
|
|
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,
|
|
@@ -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,
|
|
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;
|
|
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
|
|
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;
|
|
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`,
|