feat: update environment variable handling and dependencies
- Added @t3-oss/env-nextjs for improved environment variable management. - Updated zod to version 4.1.12 for enhanced validation capabilities. - Upgraded jiti to version 2.6.1 for better module loading. - Refactored environment variable imports from env.mjs to env.ts. - Removed deprecated env.mjs file and replaced it with a new env.ts file using @t3-oss/env-nextjs. - Adjusted various components and API routes to utilize the new environment variable structure. - Updated next.config.js to support the new environment variable management. - Modified Docker configuration to align with new BASE_URL handling.
This commit is contained in:
parent
60e3f26fd8
commit
699579b432
44 changed files with 279 additions and 282 deletions
|
|
@ -1,5 +1,7 @@
|
|||
.gitignore
|
||||
.git
|
||||
.env
|
||||
.env.marcopedone
|
||||
.env.infoalloggi
|
||||
dev-tester.yml
|
||||
nginx.conf
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#BASE_URL="https://www.infoalloggi.it"
|
||||
NEXT_PUBLIC_BASE_URL = "https://info.marcopedone.it"
|
||||
BASE_URL="https://www.infoalloggi.it"
|
||||
INTERNAL_BASE_URL = "http://web:3000"
|
||||
#Api key for the mail service
|
||||
SENDGRID_API_KEY='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'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#BASE_URL="https://info.marcopedone.it"
|
||||
NEXT_PUBLIC_BASE_URL = "https://info.marcopedone.it"
|
||||
BASE_URL="https://info.marcopedone.it"
|
||||
INTERNAL_BASE_URL = "http://web:3000"
|
||||
#Api key for the mail service
|
||||
SENDGRID_API_KEY='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'
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,4 +1,6 @@
|
|||
.env
|
||||
.env.marcopedone
|
||||
.env.infoalloggi
|
||||
build_logs.txt
|
||||
|
||||
infoalloggi_old/
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ ENV NEXT_TELEMETRY_DISABLED=1
|
|||
ENV SKIP_REDIS="true"
|
||||
|
||||
# Only essential build-time variables
|
||||
ARG NEXT_PUBLIC_BASE_URL
|
||||
ENV NEXT_PUBLIC_BASE_URL=$NEXT_PUBLIC_BASE_URL
|
||||
ARG BASE_URL
|
||||
ENV BASE_URL=$BASE_URL
|
||||
ENV NEXT_PUBLIC_BASE_URL=$BASE_URL
|
||||
|
||||
ARG NEXT_PUBLIC_STRIPE_PUBLIC_KEY
|
||||
ENV NEXT_PUBLIC_STRIPE_PUBLIC_KEY=$NEXT_PUBLIC_STRIPE_PUBLIC_KEY
|
||||
|
|
@ -81,8 +82,9 @@ ENV NEXT_TELEMETRY_DISABLED=1
|
|||
ENV SKIP_REDIS="false"
|
||||
|
||||
# Essential runtime variables
|
||||
ARG NEXT_PUBLIC_BASE_URL
|
||||
ENV NEXT_PUBLIC_BASE_URL=$NEXT_PUBLIC_BASE_URL
|
||||
ARG BASE_URL
|
||||
ENV BASE_URL=$BASE_URL
|
||||
ENV NEXT_PUBLIC_BASE_URL=$BASE_URL
|
||||
ARG INTERNAL_BASE_URL
|
||||
ENV INTERNAL_BASE_URL=$INTERNAL_BASE_URL
|
||||
ARG POSTGRES_USER
|
||||
|
|
|
|||
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
|
||||
* This is especially useful for Docker builds.
|
||||
*/
|
||||
|
||||
import { env } from "node:process";
|
||||
|
||||
/** @type {import("next").NextConfig} */
|
||||
const nextConfig = {
|
||||
compiler: {
|
||||
removeConsole: false,
|
||||
},
|
||||
experimental: {
|
||||
// esmExternals: "loose", // This if react-pdf gives compilation issues
|
||||
},
|
||||
|
||||
env: {
|
||||
NEXT_PUBLIC_BUILD_ID: Math.random().toString(36).slice(2, 8),
|
||||
},
|
||||
|
||||
devIndicators: false,
|
||||
headers: async () => {
|
||||
return [
|
||||
{
|
||||
headers: [
|
||||
{
|
||||
key: "X-Frame-Options",
|
||||
value: "",
|
||||
},
|
||||
],
|
||||
source: "/:path*",
|
||||
},
|
||||
];
|
||||
},
|
||||
i18n: {
|
||||
defaultLocale: "it",
|
||||
locales: ["it", "en"],
|
||||
localeDetection: false,
|
||||
},
|
||||
images: {
|
||||
minimumCacheTTL: 7200,
|
||||
remotePatterns: [
|
||||
{
|
||||
hostname: "*.googleusercontent.com",
|
||||
pathname: "**",
|
||||
port: "",
|
||||
protocol: "https",
|
||||
},
|
||||
{
|
||||
hostname: `${env.BACKENDSERVER_URL}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
output: env.NODE_ENV === "production" ? "standalone" : undefined, // This is for docker builds
|
||||
reactStrictMode: true,
|
||||
rewrites: async () => {
|
||||
return [
|
||||
{
|
||||
destination: env.NODE_ENV === "production" ? "/404" : "/api/panel",
|
||||
source: "/api/panel",
|
||||
},
|
||||
{
|
||||
destination: `${env.BACKENDSERVER_URL}/images/get/:slug*`,
|
||||
source: "/go-api/images/get/:slug*",
|
||||
},
|
||||
{
|
||||
destination: `${env.BACKENDSERVER_URL}/storage/get/:slug*`,
|
||||
has: [
|
||||
{ key: "access_token", type: "cookie" },
|
||||
{
|
||||
key: "token",
|
||||
type: "query",
|
||||
value:
|
||||
"(?<token>^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$)",
|
||||
},
|
||||
],
|
||||
source: "/go-api/storage/get/:slug*",
|
||||
},
|
||||
{
|
||||
destination: `${env.BACKENDSERVER_URL}/storage/upload:slug*`,
|
||||
has: [
|
||||
{ key: "access_token", type: "cookie" },
|
||||
{
|
||||
key: "token",
|
||||
type: "query",
|
||||
value:
|
||||
"(?<token>^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$)",
|
||||
},
|
||||
],
|
||||
source: "/go-api/storage/upload:slug*",
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
109
apps/infoalloggi/next.config.ts
Normal file
109
apps/infoalloggi/next.config.ts
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
|
||||
* This is especially useful for Docker builds.
|
||||
*/
|
||||
|
||||
import { env } from "node:process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
async function createNextConfig(): Promise<NextConfig> {
|
||||
const { createJiti } = await import("jiti");
|
||||
const jiti = createJiti(fileURLToPath(import.meta.url));
|
||||
|
||||
await jiti.import("./src/env.ts");
|
||||
|
||||
return {
|
||||
compiler: {
|
||||
removeConsole: false,
|
||||
},
|
||||
experimental: {
|
||||
// esmExternals: "loose", // This if react-pdf gives compilation issues
|
||||
},
|
||||
|
||||
env: {
|
||||
NEXT_PUBLIC_BUILD_ID: Math.random().toString(36).slice(2, 8),
|
||||
},
|
||||
|
||||
devIndicators: false,
|
||||
headers: async () => {
|
||||
return [
|
||||
{
|
||||
headers: [
|
||||
{
|
||||
key: "X-Frame-Options",
|
||||
value: "",
|
||||
},
|
||||
],
|
||||
source: "/:path*",
|
||||
},
|
||||
];
|
||||
},
|
||||
i18n: {
|
||||
defaultLocale: "it",
|
||||
locales: ["it", "en"],
|
||||
localeDetection: false,
|
||||
},
|
||||
images: {
|
||||
minimumCacheTTL: 7200,
|
||||
remotePatterns: [
|
||||
{
|
||||
hostname: "*.googleusercontent.com",
|
||||
pathname: "**",
|
||||
port: "",
|
||||
protocol: "https",
|
||||
},
|
||||
{
|
||||
hostname: `${env.BACKENDSERVER_URL}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
output: env.NODE_ENV === "production" ? "standalone" : undefined, // This is for docker builds
|
||||
transpilePackages: ["@t3-oss/env-nextjs", "@t3-oss/env-core"],
|
||||
reactStrictMode: true,
|
||||
rewrites: async () => {
|
||||
return [
|
||||
{
|
||||
destination: env.NODE_ENV === "production" ? "/404" : "/api/panel",
|
||||
source: "/api/panel",
|
||||
},
|
||||
{
|
||||
destination: `${env.BACKENDSERVER_URL}/images/get/:slug*`,
|
||||
source: "/go-api/images/get/:slug*",
|
||||
},
|
||||
{
|
||||
destination: `${env.BACKENDSERVER_URL}/storage/get/:slug*`,
|
||||
has: [
|
||||
{ key: "access_token", type: "cookie" },
|
||||
{
|
||||
key: "token",
|
||||
type: "query",
|
||||
value:
|
||||
"(?<token>^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$)",
|
||||
},
|
||||
],
|
||||
source: "/go-api/storage/get/:slug*",
|
||||
},
|
||||
{
|
||||
destination: `${env.BACKENDSERVER_URL}/storage/upload:slug*`,
|
||||
has: [
|
||||
{ key: "access_token", type: "cookie" },
|
||||
{
|
||||
key: "token",
|
||||
type: "query",
|
||||
value:
|
||||
"(?<token>^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$)",
|
||||
},
|
||||
],
|
||||
source: "/go-api/storage/upload:slug*",
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default (async () => await createNextConfig())();
|
||||
72
apps/infoalloggi/package-lock.json
generated
72
apps/infoalloggi/package-lock.json
generated
|
|
@ -18,6 +18,7 @@
|
|||
"@react-email/render": "^1.1.4",
|
||||
"@stripe/react-stripe-js": "^3.9.0",
|
||||
"@stripe/stripe-js": "^7.8.0",
|
||||
"@t3-oss/env-nextjs": "^0.13.8",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
|
|
@ -87,7 +88,7 @@
|
|||
"uuid": "^11.1.0",
|
||||
"vaul": "^1.1.2",
|
||||
"yaml": "^2.8.1",
|
||||
"zod": "^4.0.15"
|
||||
"zod": "^4.1.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.2.2",
|
||||
|
|
@ -105,7 +106,7 @@
|
|||
"@types/react-is": "^19.0.0",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"cross-env": "^10.0.0",
|
||||
"jiti": "^2.5.1",
|
||||
"jiti": "^2.6.1",
|
||||
"kanel": "^3.14.2",
|
||||
"kanel-kysely": "^0.7.1",
|
||||
"knip": "^5.62.0",
|
||||
|
|
@ -8175,6 +8176,61 @@
|
|||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@t3-oss/env-core": {
|
||||
"version": "0.13.8",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.13.8.tgz",
|
||||
"integrity": "sha512-L1inmpzLQyYu4+Q1DyrXsGJYCXbtXjC4cICw1uAKv0ppYPQv656lhZPU91Qd1VS6SO/bou1/q5ufVzBGbNsUpw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"arktype": "^2.1.0",
|
||||
"typescript": ">=5.0.0",
|
||||
"valibot": "^1.0.0-beta.7 || ^1.0.0",
|
||||
"zod": "^3.24.0 || ^4.0.0-beta.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"arktype": {
|
||||
"optional": true
|
||||
},
|
||||
"typescript": {
|
||||
"optional": true
|
||||
},
|
||||
"valibot": {
|
||||
"optional": true
|
||||
},
|
||||
"zod": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@t3-oss/env-nextjs": {
|
||||
"version": "0.13.8",
|
||||
"resolved": "https://registry.npmjs.org/@t3-oss/env-nextjs/-/env-nextjs-0.13.8.tgz",
|
||||
"integrity": "sha512-QmTLnsdQJ8BiQad2W2nvV6oUpH4oMZMqnFEjhVpzU0h3sI9hn8zb8crjWJ1Amq453mGZs6A4v4ihIeBFDOrLeQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@t3-oss/env-core": "0.13.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"arktype": "^2.1.0",
|
||||
"typescript": ">=5.0.0",
|
||||
"valibot": "^1.0.0-beta.7 || ^1.0.0",
|
||||
"zod": "^3.24.0 || ^4.0.0-beta.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"arktype": {
|
||||
"optional": true
|
||||
},
|
||||
"typescript": {
|
||||
"optional": true
|
||||
},
|
||||
"valibot": {
|
||||
"optional": true
|
||||
},
|
||||
"zod": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/forms": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz",
|
||||
|
|
@ -12912,9 +12968,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz",
|
||||
"integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==",
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
|
||||
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "lib/jiti-cli.mjs"
|
||||
|
|
@ -19085,9 +19141,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "4.0.17",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.0.17.tgz",
|
||||
"integrity": "sha512-1PHjlYRevNxxdy2JZ8JcNAw7rX8V9P1AKkP+x/xZfxB0K5FYfuV+Ug6P/6NVSR2jHQ+FzDDoDHS04nYUsOIyLQ==",
|
||||
"version": "4.1.12",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
|
||||
"integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
"@react-email/render": "^1.1.4",
|
||||
"@stripe/react-stripe-js": "^3.9.0",
|
||||
"@stripe/stripe-js": "^7.8.0",
|
||||
"@t3-oss/env-nextjs": "^0.13.8",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
|
|
@ -98,7 +99,7 @@
|
|||
"uuid": "^11.1.0",
|
||||
"vaul": "^1.1.2",
|
||||
"yaml": "^2.8.1",
|
||||
"zod": "^4.0.15"
|
||||
"zod": "^4.1.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.2.2",
|
||||
|
|
@ -116,7 +117,7 @@
|
|||
"@types/react-is": "^19.0.0",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"cross-env": "^10.0.0",
|
||||
"jiti": "^2.5.1",
|
||||
"jiti": "^2.6.1",
|
||||
"kanel": "^3.14.2",
|
||||
"kanel-kysely": "^0.7.1",
|
||||
"knip": "^5.62.0",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { LoadingPage } from "~/components/loading";
|
|||
import { Status500 } from "~/components/status-page";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { formatCurrency } from "~/lib/utils";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import type { PaymentsId } from "~/schemas/public/Payments";
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from "react-hook-form";
|
||||
import { Label } from "src/components/ui/label";
|
||||
import { cn } from "src/lib/utils";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
const Form = FormProvider;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import {
|
|||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "~/components/ui/tooltip";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { AnnunciId } from "~/schemas/public/Annunci";
|
||||
import type { Servizio, ServizioServizioId } from "~/schemas/public/Servizio";
|
||||
import type { UsersId } from "~/schemas/public/Users";
|
||||
|
|
@ -70,7 +70,7 @@ export const TabServizio = ({
|
|||
toast.error(error.message);
|
||||
},
|
||||
onSuccess: async () => {
|
||||
toast.success("Servizio rimosso con successo");
|
||||
toast.success("Email onboarding inviata con successo");
|
||||
await utils.servizio.getUserServizi.invalidate();
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
// @ts-nocheck
|
||||
|
||||
import { z } from "zod/v4";
|
||||
|
||||
/**
|
||||
* Specify your server-side environment variables schema here. This way you can ensure the app isn't
|
||||
* built with invalid env vars.
|
||||
*/
|
||||
const server = z.object({
|
||||
ARUBA_PASS: z.string(),
|
||||
ARUBA_USER: z.string(),
|
||||
BACKENDSERVER_URL: z.string(),
|
||||
EXP_API_PASS: z.string(),
|
||||
EXP_API_USER: z.string(),
|
||||
FIC_ACCESS_TOKEN: z.string(),
|
||||
FIC_CLIENT_ID: z.string(),
|
||||
FIC_COMPANY_ID: z.string(),
|
||||
INTERNAL_BASE_URL: z.url(),
|
||||
JWT_SECRET: z.string(),
|
||||
KEYDB_URL: z.string(),
|
||||
NODE_ENV: z.enum(["development", "test", "production"]),
|
||||
PGHOST: z.string(),
|
||||
PGPORT: z.string(),
|
||||
POSTGRES_DB: z.string(),
|
||||
POSTGRES_PASSWORD: z.string(),
|
||||
POSTGRES_USER: z.string(),
|
||||
SKIP_REDIS: z.string(),
|
||||
STRIPE_SECRET_KEY: z.string(),
|
||||
STRIPE_WEBHOOK_SECRET: z.string(),
|
||||
TILES_URL: z.string(),
|
||||
SKEBBY_USER: z.string(),
|
||||
SKEBBY_PASS: z.string(),
|
||||
REVALIDATION_SECRET: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Specify your client-side environment variables schema here. This way you can ensure the app isn't
|
||||
* built with invalid env vars. To expose them to the client, prefix them with `NEXT_PUBLIC_`.
|
||||
*/
|
||||
const client = z.object({
|
||||
NEXT_PUBLIC_BASE_URL: z.string(),
|
||||
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.
|
||||
* middlewares) or client-side so we need to destruct manually.
|
||||
*
|
||||
* @type {Record<keyof z.infer<typeof server> | keyof z.infer<typeof client>, string | undefined>}
|
||||
*/
|
||||
const processEnv = {
|
||||
ARUBA_PASS: process.env.ARUBA_PASS,
|
||||
ARUBA_USER: process.env.ARUBA_USER,
|
||||
BACKENDSERVER_URL: process.env.BACKENDSERVER_URL,
|
||||
EXP_API_PASS: process.env.EXP_API_PASS,
|
||||
EXP_API_USER: process.env.EXP_API_USER,
|
||||
FIC_ACCESS_TOKEN: process.env.FIC_ACCESS_TOKEN,
|
||||
FIC_CLIENT_ID: process.env.FIC_CLIENT_ID,
|
||||
FIC_COMPANY_ID: process.env.FIC_COMPANY_ID,
|
||||
INTERNAL_BASE_URL: process.env.INTERNAL_BASE_URL,
|
||||
JWT_SECRET: process.env.JWT_SECRET,
|
||||
KEYDB_URL: process.env.KEYDB_URL,
|
||||
NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL,
|
||||
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY,
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
PGHOST: process.env.PGHOST,
|
||||
PGPORT: process.env.PGPORT,
|
||||
POSTGRES_DB: process.env.POSTGRES_DB,
|
||||
POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD,
|
||||
POSTGRES_USER: process.env.POSTGRES_USER,
|
||||
SKIP_REDIS: process.env.SKIP_REDIS,
|
||||
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
|
||||
STRIPE_WEBHOOK_SECRET: process.env.STRIPE_WEBHOOK_SECRET,
|
||||
TILES_URL: process.env.TILES_URL,
|
||||
SKEBBY_USER: process.env.SKEBBY_USER,
|
||||
SKEBBY_PASS: process.env.SKEBBY_PASS,
|
||||
REVALIDATION_SECRET: process.env.REVALIDATION_SECRET,
|
||||
};
|
||||
|
||||
// Don't touch the part below
|
||||
// --------------------------
|
||||
|
||||
const merged = server.merge(client);
|
||||
|
||||
/** @typedef {z.input<typeof merged>} MergedInput */
|
||||
/** @typedef {z.infer<typeof merged>} MergedOutput */
|
||||
/** @typedef {z.SafeParseReturnType<MergedInput, MergedOutput>} MergedSafeParseReturn */
|
||||
|
||||
let env = /** @type {MergedOutput} */ (process.env);
|
||||
|
||||
if (!!process.env.SKIP_ENV_VALIDATION === false) {
|
||||
const isServer = typeof window === "undefined";
|
||||
const parsed = /** @type {MergedSafeParseReturn} */ (
|
||||
isServer
|
||||
? merged.safeParse(processEnv) // on server we can validate all env vars
|
||||
: client.safeParse(processEnv) // on client we can only validate the ones that are exposed
|
||||
);
|
||||
|
||||
if (parsed.success === false) {
|
||||
console.error(
|
||||
"❌ Invalid environment variables:",
|
||||
z.treeifyError(parsed.error).fieldErrors,
|
||||
);
|
||||
throw new Error("Invalid environment variables");
|
||||
}
|
||||
|
||||
env = new Proxy(parsed.data, {
|
||||
get(target, prop) {
|
||||
if (typeof prop !== "string") return undefined;
|
||||
// Throw a descriptive error if a server-side env var is accessed on the client
|
||||
// Otherwise it would just be returning `undefined` and be annoying to debug
|
||||
if (!isServer && !prop.startsWith("NEXT_PUBLIC_"))
|
||||
throw new Error(
|
||||
process.env.NODE_ENV === "production"
|
||||
? "❌ Attempted to access a server-side environment variable on the client"
|
||||
: `❌ Attempted to access server-side environment variable '${prop}' on the client`,
|
||||
);
|
||||
return target[/** @type {keyof typeof target} */ (prop)];
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export { env };
|
||||
44
apps/infoalloggi/src/env.ts
Normal file
44
apps/infoalloggi/src/env.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { createEnv } from "@t3-oss/env-nextjs";
|
||||
import { z } from "zod";
|
||||
|
||||
export const env = createEnv({
|
||||
server: {
|
||||
BASE_URL: z.string(),
|
||||
ARUBA_PASS: z.string(),
|
||||
ARUBA_USER: z.string(),
|
||||
BACKENDSERVER_URL: z.string(),
|
||||
EXP_API_PASS: z.string(),
|
||||
EXP_API_USER: z.string(),
|
||||
FIC_ACCESS_TOKEN: z.string(),
|
||||
FIC_CLIENT_ID: z.string(),
|
||||
FIC_COMPANY_ID: z.string(),
|
||||
INTERNAL_BASE_URL: z.string(),
|
||||
JWT_SECRET: z.string(),
|
||||
KEYDB_URL: z.string(),
|
||||
NODE_ENV: z.enum(["development", "test", "production"]),
|
||||
PGHOST: z.string(),
|
||||
PGPORT: z.string(),
|
||||
POSTGRES_DB: z.string(),
|
||||
POSTGRES_PASSWORD: z.string(),
|
||||
POSTGRES_USER: z.string(),
|
||||
SKIP_REDIS: z.string(),
|
||||
STRIPE_SECRET_KEY: z.string(),
|
||||
STRIPE_WEBHOOK_SECRET: z.string(),
|
||||
TILES_URL: z.string(),
|
||||
SKEBBY_USER: z.string(),
|
||||
SKEBBY_PASS: z.string(),
|
||||
REVALIDATION_SECRET: z.string(),
|
||||
},
|
||||
client: {
|
||||
NEXT_PUBLIC_BASE_URL: z.string(),
|
||||
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: z.string(),
|
||||
},
|
||||
// shared: {
|
||||
// NEXT_PUBLIC_BASE_URL: z.string(),
|
||||
// },
|
||||
// If you're using Next.js < 13.4.4, you'll need to specify the runtimeEnv manually
|
||||
experimental__runtimeEnv: {
|
||||
NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL,
|
||||
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY,
|
||||
},
|
||||
});
|
||||
|
|
@ -15,7 +15,7 @@ import Input from "~/components/custom_ui/input";
|
|||
import { LoadingSpinner } from "~/components/spinner";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Checkbox } from "~/components/ui/checkbox";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import { api } from "~/utils/api";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
export const apisMiddleware = async (req: NextRequest) => {
|
||||
const path = req.nextUrl.pathname;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ import {
|
|||
} from "~/components/ui/dialog";
|
||||
import { Label } from "~/components/ui/label";
|
||||
import { VideoPlayer } from "~/components/videoPlayer";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import {
|
||||
type CaratteristicheFiltered,
|
||||
filteredCaratteristiche,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import Stripe from "stripe";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { PaymentsId } from "~/schemas/public/Payments";
|
||||
import { appRouter } from "~/server/api/root";
|
||||
import { createTRPCContext, t } from "~/server/api/trpc";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import Redis from "ioredis";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
let tiles: Redis | null = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { createNextApiHandler } from "@trpc/server/adapters/next";
|
||||
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { appRouter } from "~/server/api/root";
|
||||
import { createTRPCContext } from "~/server/api/trpc";
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { PricingChoice } from "~/components/prezzi";
|
|||
import { HeroSvg, LogoSvg } from "~/components/svgs";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { LangDict } from "~/i18n/locales";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { useEffect, useState } from "react";
|
|||
import PaymentStatus from "~/components/payment_status";
|
||||
import { ProgressRedirect } from "~/components/progress_redirect";
|
||||
import { Button, buttonVariants } from "~/components/ui/button";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { AcquistoProcessing } from "~/components/acquisto_processing";
|
|||
import { AreaRiservataLayout } from "~/components/Layout";
|
||||
import { LoadingPage } from "~/components/loading";
|
||||
import { Status500 } from "~/components/status-page";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { NextPageWithLayout } from "~/pages/_app";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { GetServerSideProps } from "next";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { generateSSGHelper } from "~/server/utils/ssgHelper";
|
||||
|
||||
async function generateSiteMap() {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import {
|
|||
ClientsApi,
|
||||
Configuration,
|
||||
} from "@fattureincloud/fattureincloud-ts-sdk";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
const apiConfig = new Configuration({
|
||||
accessToken: env.FIC_ACCESS_TOKEN,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { TRPCError } from "@trpc/server";
|
||||
import z from "zod/v4";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
|
||||
import { db } from "~/server/db";
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { TRPCError } from "@trpc/server";
|
||||
import { z } from "zod/v4";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { BannersIdbanner } from "~/schemas/public/Banners";
|
||||
import {
|
||||
adminProcedure,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import type { CreateNextContextOptions } from "@trpc/server/adapters/next";
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import superjson from "superjson";
|
||||
import z, { ZodError } from "zod/v4";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { verifyToken } from "~/server/auth/jwt";
|
||||
import { zUserId } from "~/server/utils/zod_types";
|
||||
import { TOKEN_CONFIG } from "../auth/configs";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { TRPCError } from "@trpc/server";
|
||||
import { jwtVerify, SignJWT } from "jose";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { type Session, sessionSchema } from "~/server/api/trpc";
|
||||
|
||||
const secret = new TextEncoder().encode(env.JWT_SECRET);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { TRPCError } from "@trpc/server";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type {
|
||||
Annunci,
|
||||
AnnunciId,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { sql } from "kysely";
|
|||
import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/postgres";
|
||||
import { z } from "zod/v4";
|
||||
import type { PurchaseData } from "~/components/acquisto_receipt";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { AnnunciId } from "~/schemas/public/Annunci";
|
||||
import OrderTypeEnum from "~/schemas/public/OrderTypeEnum";
|
||||
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
|
||||
|
|
@ -753,7 +753,7 @@ export const updateServizioAnnuncio = async ({
|
|||
mailType: "generic",
|
||||
props: {
|
||||
link: {
|
||||
href: `${env.NEXT_PUBLIC_BASE_URL}/area-riservata/dashboard#${servizioId}-${annuncioId}`,
|
||||
href: `${env.BASE_URL}/area-riservata/dashboard#${servizioId}-${annuncioId}`,
|
||||
label: "Vai al servizio",
|
||||
},
|
||||
noreply: true,
|
||||
|
|
@ -772,7 +772,7 @@ export const updateServizioAnnuncio = async ({
|
|||
mailType: "generic",
|
||||
props: {
|
||||
link: {
|
||||
href: `${env.NEXT_PUBLIC_BASE_URL}/area-riservata/admin/user-view/ricerca/${servizio.user_id}#${servizioId}-${annuncioId}`,
|
||||
href: `${env.BASE_URL}/area-riservata/admin/user-view/ricerca/${servizio.user_id}#${servizioId}-${annuncioId}`,
|
||||
label: "Vai al servizio",
|
||||
},
|
||||
noreply: true,
|
||||
|
|
@ -930,7 +930,7 @@ export const SbloccaContatti = async ({
|
|||
mailType: "generic",
|
||||
props: {
|
||||
link: {
|
||||
href: `${env.NEXT_PUBLIC_BASE_URL}/area-riservata/dashboard#${servizioId}-${annuncioId}`,
|
||||
href: `${env.BASE_URL}/area-riservata/dashboard#${servizioId}-${annuncioId}`,
|
||||
label: "Vai al servizio",
|
||||
},
|
||||
noreply: true,
|
||||
|
|
@ -1052,7 +1052,7 @@ export const interruzioneServizio = async (servizioId: ServizioServizioId) => {
|
|||
mailType: "generic",
|
||||
props: {
|
||||
link: {
|
||||
href: `${env.NEXT_PUBLIC_BASE_URL}/area-riservata/admin/user-view/ricerca/${servizio.user_id}#${servizioId}`,
|
||||
href: `${env.BASE_URL}/area-riservata/admin/user-view/ricerca/${servizio.user_id}#${servizioId}`,
|
||||
label: "Vai al servizio",
|
||||
},
|
||||
noreply: true,
|
||||
|
|
@ -1155,6 +1155,12 @@ export const sendServizioEmail = async ({
|
|||
.where("servizio_annunci.servizio_id", "=", servizioId)
|
||||
.execute();
|
||||
|
||||
console.log("=== EMAIL DEBUG ===");
|
||||
console.log("BASE_URL:", env.BASE_URL);
|
||||
console.log("INTERNAL_BASE_URL:", env.INTERNAL_BASE_URL);
|
||||
console.log("NEXT_PUBLIC_BASE_URL:", env.NEXT_PUBLIC_BASE_URL);
|
||||
console.log("==================");
|
||||
|
||||
const { email, nome } = user;
|
||||
await NewMail({
|
||||
mailType: "onboardingServizio",
|
||||
|
|
@ -1169,7 +1175,7 @@ export const sendServizioEmail = async ({
|
|||
})),
|
||||
nome,
|
||||
token: servizioId,
|
||||
baseUrl: env.NEXT_PUBLIC_BASE_URL,
|
||||
baseUrl: env.BASE_URL,
|
||||
},
|
||||
subject: "Procedi ora su Infoalloggi.it",
|
||||
to: email,
|
||||
|
|
@ -1234,7 +1240,7 @@ export const userConfirmImmobile = async ({
|
|||
mailType: "generic",
|
||||
props: {
|
||||
link: {
|
||||
href: `${env.NEXT_PUBLIC_BASE_URL}/area-riservata/admin/user-view/ricerca/${servizio.user_id}#${servizioId}-${annuncioId}`,
|
||||
href: `${env.BASE_URL}/area-riservata/admin/user-view/ricerca/${servizio.user_id}#${servizioId}-${annuncioId}`,
|
||||
label: "Visualizza Annuncio",
|
||||
},
|
||||
noreply: true,
|
||||
|
|
@ -1448,7 +1454,7 @@ export const SendContactEmail = async ({
|
|||
messaggio,
|
||||
nome,
|
||||
telefono,
|
||||
baseUrl: env.NEXT_PUBLIC_BASE_URL,
|
||||
baseUrl: env.BASE_URL,
|
||||
},
|
||||
subject: "Contatto per annuncio",
|
||||
to: "web@infoalloggi.it",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import { GetFlagValueHandler } from "~/server/controllers/flags.controller";
|
||||
import { db } from "~/server/db";
|
||||
import { NewMail } from "~/server/services/mailer";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { TRPCError } from "@trpc/server";
|
||||
import Stripe from "stripe";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import OrderTypeEnum from "~/schemas/public/OrderTypeEnum";
|
||||
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
|
||||
import type { Payments, PaymentsId } from "~/schemas/public/Payments";
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
type Transaction,
|
||||
} from "kysely";
|
||||
import { Pool } from "pg";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type Database from "~/schemas/Database";
|
||||
import type PublicSchema from "~/schemas/public/PublicSchema";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { randomBytes } from "node:crypto";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { add } from "date-fns";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { UsersId } from "~/schemas/public/Users";
|
||||
import { db } from "~/server/db";
|
||||
import { NewMail } from "~/server/services/mailer";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
export const createSrcset = (url_immagini: string[]) => {
|
||||
const finalSrcset = [];
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import { createTransport } from "nodemailer";
|
|||
import type { Options } from "nodemailer/lib/mailer";
|
||||
import { htmlToText } from "nodemailer-html-to-text";
|
||||
import type { JSX } from "react";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type { UsersId } from "~/schemas/public/Users";
|
||||
import { GetFlagValueHandler } from "~/server/controllers/flags.controller";
|
||||
import { db } from "~/server/db";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { TRPCError } from "@trpc/server";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
import type {
|
||||
StorageindexId,
|
||||
StorageindexUpdate,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
export const revalidate = async (path: string) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
export const getMediaUrl = (path: string) => {
|
||||
const baseURL = !env.NEXT_PUBLIC_BASE_URL.includes("localhost")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import Redis from "ioredis";
|
||||
import { env } from "~/env.mjs";
|
||||
import { env } from "~/env";
|
||||
|
||||
let keydb: Redis | null = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
"include": [
|
||||
"src",
|
||||
"next-env.d.ts",
|
||||
"next.config.mjs",
|
||||
"next.config.ts",
|
||||
"postcss.config.cjs",
|
||||
"reset.d.ts",
|
||||
"TypeHelpers.type.ts",
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ services:
|
|||
BACKENDSERVER_URL: http://backend:1323
|
||||
KEYDB_URL: keydb:6379
|
||||
TILES_URL: tiles:6379
|
||||
#BASE_URL: ${BASE_URL}
|
||||
BASE_URL: ${BASE_URL}
|
||||
SENDGRID_API_KEY: ${SENDGRID_API_KEY}
|
||||
STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY}
|
||||
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: ${NEXT_PUBLIC_STRIPE_PUBLIC_KEY}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue