From 8d4310bc3178a00414e517d3b3796ddd47fff244 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:03:27 +0300 Subject: [PATCH 1/6] Minimal working payload cms setup --- apps/climatemappedafrica/package.json | 20 +- apps/climatemappedafrica/payload.config.ts | 125 +++++++ apps/climatemappedafrica/server.ts | 92 +++++ .../src/payload/access/isAdmin.js | 11 + .../src/payload/access/isAdminOrPublished.js | 14 + .../src/payload/access/isAdminOrSelf.js | 24 ++ .../src/payload/access/roles.js | 7 + .../src/payload/collections/Media.js | 29 ++ .../src/payload/collections/Users.js | 59 +++ .../src/payload/utils/locales.js | 5 + apps/climatemappedafrica/tsconfig.json | 28 ++ apps/climatemappedafrica/tsconfig.server.json | 12 + apps/climatemappedafrica/turbo.json | 2 + apps/codeforafrica/server.ts | 2 +- pnpm-lock.yaml | 345 ++++++++++++++++-- 15 files changed, 737 insertions(+), 38 deletions(-) create mode 100644 apps/climatemappedafrica/payload.config.ts create mode 100644 apps/climatemappedafrica/server.ts create mode 100644 apps/climatemappedafrica/src/payload/access/isAdmin.js create mode 100644 apps/climatemappedafrica/src/payload/access/isAdminOrPublished.js create mode 100644 apps/climatemappedafrica/src/payload/access/isAdminOrSelf.js create mode 100644 apps/climatemappedafrica/src/payload/access/roles.js create mode 100644 apps/climatemappedafrica/src/payload/collections/Media.js create mode 100644 apps/climatemappedafrica/src/payload/collections/Users.js create mode 100644 apps/climatemappedafrica/src/payload/utils/locales.js create mode 100644 apps/climatemappedafrica/tsconfig.json create mode 100644 apps/climatemappedafrica/tsconfig.server.json diff --git a/apps/climatemappedafrica/package.json b/apps/climatemappedafrica/package.json index 86116b9bb..083893ab3 100644 --- a/apps/climatemappedafrica/package.json +++ b/apps/climatemappedafrica/package.json @@ -21,13 +21,15 @@ "url": "https://github.com/codeforafrica/ui/issues" }, "scripts": { - "dev": "NODE_OPTIONS='--inspect' next dev", + "build-server": "tsc --project tsconfig.server.json", + "build-next": "NEXT_BUILD=true pnpm build-server && NEXT_BUILD=true PAYLOAD_CONFIG_PATH=${PAYLOAD_CONFIG_PATH:-dist/payload.config.js} node dist/server.js", + "build-payload": "payload build", + "start": "PAYLOAD_CONFIG_PATH=${PAYLOAD_CONFIG_PATH:-dist/payload.config.js} NODE_ENV=${NODE_ENV:-production} node dist/server.js", + "dev": "NODE_OPTIONS='--inspect' ts-node --project tsconfig.server.json server.ts", "lint-check": "TIMING=1 eslint './'", "lint": "TIMING=1 eslint --fix './'", - "jest": "jest --passWithNoTests", + "jest": "jest", "playwright": "npx playwright test", - "build": "next build", - "start": "next start", "clean": "rm -rf .next .turbo node_modules" }, "dependencies": { @@ -42,17 +44,26 @@ "@mui/material": "catalog:mui-styles", "@mui/styles": "catalog:mui-styles", "@mui/utils": "catalog:mui-styles", + "@payloadcms/bundler-webpack": "catalog:", + "@payloadcms/db-mongodb": "catalog:", + "@payloadcms/plugin-cloud-storage": "catalog:", + "@payloadcms/plugin-nested-docs": "catalog:", + "@payloadcms/plugin-sentry": "catalog:", + "@payloadcms/plugin-seo": "catalog:", + "@payloadcms/richtext-slate": "catalog:", "@reactour/tour": "catalog:", "aws-sdk": "catalog:", "clsx": "catalog:", "d3-format": "catalog:", "deepmerge": "catalog:", + "dotenv": "catalog:", "leaflet": "catalog:", "lodash": "catalog:", "next": "catalog:", "next-images": "catalog:", "next-seo": "catalog:", "papaparse": "catalog:", + "payload": "catalog:", "plaiceholder": "catalog:", "prop-types": "catalog:", "react": "catalog:", @@ -112,6 +123,7 @@ "prettier": "catalog:", "react-test-renderer": "catalog:", "svg-url-loader": "catalog:", + "ts-node": "catalog:", "typescript": "catalog:" }, "engines": { diff --git a/apps/climatemappedafrica/payload.config.ts b/apps/climatemappedafrica/payload.config.ts new file mode 100644 index 000000000..e8d132076 --- /dev/null +++ b/apps/climatemappedafrica/payload.config.ts @@ -0,0 +1,125 @@ +import path from "path"; + +import { buildConfig } from "payload/config"; +import dotenv from "dotenv"; +import { cloudStorage } from "@payloadcms/plugin-cloud-storage"; +import { s3Adapter } from "@payloadcms/plugin-cloud-storage/s3"; +import { slateEditor } from "@payloadcms/richtext-slate"; +import { mongooseAdapter } from "@payloadcms/db-mongodb"; +import { webpackBundler } from "@payloadcms/bundler-webpack"; +import { CollectionConfig, GlobalConfig } from "payload/types"; +import nestedDocs from "@payloadcms/plugin-nested-docs"; +import seo from "@payloadcms/plugin-seo"; +import { sentry } from "@payloadcms/plugin-sentry"; +import { defaultLocale, locales } from "./src/payload/utils/locales"; + +import Media from "./src/payload/collections/Media"; +import Users from "./src/payload/collections/Users"; + + +dotenv.config(); +dotenv.config({ path: path.resolve(__dirname, "./.env.local") }); + +const appURL = process.env.PAYLOAD_PUBLIC_APP_URL; + +const cors = + process?.env?.PAYLOAD_CORS?.split(",") + ?.map((d) => d.trim()) + ?.filter(Boolean) ?? []; + +const csrf = + process?.env?.PAYLOAD_CSRF?.split(",") + ?.map((d) => d.trim()) + ?.filter(Boolean) ?? []; + + const adapter = s3Adapter({ + config: { + region: process?.env?.S3_REGION, + credentials: { + accessKeyId: process?.env?.S3_ACCESS_KEY_ID, + secretAccessKey: process?.env?.S3_SECRET_ACCESS_KEY, + }, + }, + bucket: process?.env?.S3_BUCKET, +} as any); + +export default buildConfig({ + serverURL: appURL, + editor: slateEditor({}), + routes: { + admin: "/admin", + }, + db: mongooseAdapter({ + url: process.env.MONGO_URL, + migrationDir: process.env.MIGRATIONS_DIR, + }), + collections:[ + Media, + Users, + ]as CollectionConfig[], + globals: []as GlobalConfig[], + ...(locales?.length + ? { + localization: { + locales, + defaultLocale, + fallback: true, + }, + } + : undefined), + admin: { + webpack: (config) => ({ + ...config, + resolve: { + ...config.resolve, + fallback: { + ...config?.resolve?.fallback, + fs: false, + os: false, + "process/browser": false, + }, + }, + }), + bundler: webpackBundler(), + }, + cors, + csrf, + i18n: { + fallbackLng: "en", // default + debug: false, // default + resources: { + en: { + "codeforafrica.validation": { + uniquePlatforms: "Please select a unique platform", + }, + }, + }, + }, + plugins: [ + cloudStorage({ + collections: { + media: { + adapter, + prefix: "media", + }, + }, + }), + sentry({ + dsn: process?.env?.NEXT_PUBLIC_SENTRY_DSN, + }), + seo({ + collections: ["pages"], + globals: ["settings"], + uploadsCollection: "media", + generateTitle: ({ doc }: any) => doc?.title?.value as string, + generateURL: ({ doc }: any) => + doc?.slug?.value ? `${appURL}/${doc.slug.value}` : undefined, + }), + nestedDocs({ + collections: ["pages"], + generateLabel: (_, doc) => doc.title as string, + generateURL: (docs) => + docs.reduce((url, doc) => `${url}/${doc.slug}`, ""), + }), + ], +}) diff --git a/apps/climatemappedafrica/server.ts b/apps/climatemappedafrica/server.ts new file mode 100644 index 000000000..fc699e90a --- /dev/null +++ b/apps/climatemappedafrica/server.ts @@ -0,0 +1,92 @@ +import path from "path"; +import { spawn } from "child_process"; +import express from "express"; +import next from "next"; +import nodemailerSendgrid from "nodemailer-sendgrid"; +import payload from "payload"; +import { Payload } from "payload/dist/payload"; +import { loadEnvConfig } from "@next/env"; + +const projectDir = process.cwd(); +loadEnvConfig(projectDir); + +const dev = process.env.NODE_ENV !== "production"; +const hostname = process.env.NEXT_HOSTNAME || "localhost"; +const port = parseInt(process.env.PORT || "3000", 10); +const sendGridAPIKey = process.env.SENDGRID_API_KEY; + +if (!process.env.NEXT_MANUAL_SIG_HANDLE) { + process.on("SIGTERM", () => process.exit(0)); + process.on("SIGINT", () => process.exit(0)); +} + +const app = express(); + +const start = async (): Promise => { + let localPayload: Payload; + try { + localPayload = await payload.init({ + ...(sendGridAPIKey + ? { + email: { + transportOptions: nodemailerSendgrid({ + apiKey: sendGridAPIKey, + }), + fromName: process.env.SENDGRID_FROM_NAME || "ClimateMapped Africa CMS", + fromAddress: + process.env.SENDGRID_FROM_EMAIL || "noreply@dodeforafrica.org", + }, + } + : undefined), + secret: process.env.PAYLOAD_SECRET, + express: app, + onInit: (initPayload) => { + initPayload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`); + }, + }); + } catch (e: any) { + console.error(e); + process.exit(); + } + + if (process.env.NEXT_BUILD) { + app.listen(port, async () => { + localPayload.logger.info("NextJS is now building..."); + const nextBuild = spawn( + "pnpm", + ["next", "build", path.resolve(projectDir)], + { + shell: true, + stdio: "inherit", + }, + ); + nextBuild.on("close", (code) => { + process.exit(code); + }); + nextBuild.on("error", (err) => { + localPayload.logger.error(err); + process.exit(1); + }); + }); + + return; + } + + const nextApp = next({ dev, hostname, port }); + const nextHandler = nextApp.getRequestHandler(); + nextApp.prepare().then(() => { + localPayload.logger.info("NextJS started"); + + app.get("*", (req: any, res: any) => nextHandler(req, res)); + app.post("*", (req: any, res: any) => nextHandler(req, res)); + app.put("*", (req: any, res: any) => nextHandler(req, res)); + + app.listen(port, async () => { + localPayload.logger.info( + `Next.js App URL: ${process.env.NEXT_PUBLIC_APP_URL}`, + ); + }); + }); +}; + +start(); diff --git a/apps/climatemappedafrica/src/payload/access/isAdmin.js b/apps/climatemappedafrica/src/payload/access/isAdmin.js new file mode 100644 index 000000000..08301afd9 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/access/isAdmin.js @@ -0,0 +1,11 @@ +import { ROLE_ADMIN } from "./roles"; + +export const isAdmin = ({ req: { user } }) => { + // Return true or false based on if the user has an admin role + return Boolean(user?.roles?.includes(ROLE_ADMIN)); +}; + +export const isAdminFieldLevel = ({ req: { user } }) => { + // Return true or false based on if the user has an admin role + return Boolean(user?.roles?.includes(ROLE_ADMIN)); +}; diff --git a/apps/climatemappedafrica/src/payload/access/isAdminOrPublished.js b/apps/climatemappedafrica/src/payload/access/isAdminOrPublished.js new file mode 100644 index 000000000..c006014ec --- /dev/null +++ b/apps/climatemappedafrica/src/payload/access/isAdminOrPublished.js @@ -0,0 +1,14 @@ +import { ROLE_ADMIN } from "./roles"; + +export const isAdminOrPublished = ({ req: { user } }) => { + if (user?.roles?.includes(ROLE_ADMIN)) { + return true; + } + return { + _status: { + equals: "published", + }, + }; +}; + +export default undefined; diff --git a/apps/climatemappedafrica/src/payload/access/isAdminOrSelf.js b/apps/climatemappedafrica/src/payload/access/isAdminOrSelf.js new file mode 100644 index 000000000..4dfae4152 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/access/isAdminOrSelf.js @@ -0,0 +1,24 @@ +import { ROLE_ADMIN } from "./roles"; + +export const isAdminOrSelf = ({ req: { user } }) => { + // Need to be logged in + if (user) { + // If user has role of 'admin' + if (user.roles?.includes(ROLE_ADMIN)) { + return true; + } + // If any other type of user, only provide access to themselves + return { + id: { + equals: user.id, + }, + }; + } + + // Reject everyone else + return false; +}; + +export const isAdminOrSelfFieldLevel = ({ id, req: { user } }) => { + return user?.roles?.includes(ROLE_ADMIN) || id === user?.id; +}; diff --git a/apps/climatemappedafrica/src/payload/access/roles.js b/apps/climatemappedafrica/src/payload/access/roles.js new file mode 100644 index 000000000..d060bbf8e --- /dev/null +++ b/apps/climatemappedafrica/src/payload/access/roles.js @@ -0,0 +1,7 @@ +export const ROLE_ADMIN = "admin"; +export const ROLE_EDITOR = "editor"; +export const ROLE_DEFAULT = ROLE_EDITOR; +export const ROLE_OPTIONS = [ + { label: "Admin", value: ROLE_ADMIN }, + { label: "Editor", value: ROLE_EDITOR }, +]; diff --git a/apps/climatemappedafrica/src/payload/collections/Media.js b/apps/climatemappedafrica/src/payload/collections/Media.js new file mode 100644 index 000000000..bbd5b3040 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/collections/Media.js @@ -0,0 +1,29 @@ +const Media = { + slug: "media", + admin: { + defaultColumns: ["alt", "updatedAt"], + enableRichTextLink: false, + group: "Publication", + useAsTitle: "alt", + }, + access: { + read: () => true, // Everyone can read Media + }, + upload: { + staticURL: "/media", + staticDir: "media", + }, + fields: [ + { + name: "alt", + label: "Alt Text", + type: "text", + required: true, + }, + ], + hooks: { + afterRead: [({ doc }) => ({ ...doc, src: doc.url })], + }, +}; + +export default Media; diff --git a/apps/climatemappedafrica/src/payload/collections/Users.js b/apps/climatemappedafrica/src/payload/collections/Users.js new file mode 100644 index 000000000..ac0015006 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/collections/Users.js @@ -0,0 +1,59 @@ +import { isAdmin, isAdminFieldLevel } from "../access/isAdmin"; +import { + isAdminOrSelf, + isAdminOrSelfFieldLevel, +} from "../access/isAdminOrSelf"; +import { ROLE_DEFAULT, ROLE_OPTIONS } from "../access/roles"; + +const User = { + slug: "users", + access: { + create: isAdmin, + read: () => true, + update: isAdminOrSelf, + delete: isAdminOrSelf, + }, + admin: { + defaultColumns: ["firstName", "lastName", "email", "updatedAt"], + enableRichTextLink: false, + group: "Settings", + useAsTitle: "email", + }, + auth: { + verify: true, + }, + fields: [ + { + type: "row", + fields: [ + { + name: "firstName", + type: "text", + required: true, + }, + { + name: "lastName", + type: "text", + required: true, + }, + ], + }, + { + name: "roles", + type: "select", + // Save this field to JWT so we can use from `req.user` + saveToJWT: true, + required: true, + defaultValue: [ROLE_DEFAULT], + hasMany: true, + access: { + read: isAdminOrSelfFieldLevel, + create: isAdminFieldLevel, + update: isAdminFieldLevel, + }, + options: ROLE_OPTIONS, + }, + ], +}; + +export default User; diff --git a/apps/climatemappedafrica/src/payload/utils/locales.js b/apps/climatemappedafrica/src/payload/utils/locales.js new file mode 100644 index 000000000..11cf08c91 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/utils/locales.js @@ -0,0 +1,5 @@ +export const locales = process.env.PAYLOAD_PUBLIC_LOCALES?.split(",") + ?.map((l) => l.trim()) + .filter(Boolean) || ["en"]; +export const defaultLocale = + process.env.PAYLOAD_PUBLIC_DEFAULT_LOCALE?.trim() || locales?.[0]; diff --git a/apps/climatemappedafrica/tsconfig.json b/apps/climatemappedafrica/tsconfig.json new file mode 100644 index 000000000..189d8a6a0 --- /dev/null +++ b/apps/climatemappedafrica/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "baseUrl": ".", + "paths": { + "@/climatemappedafrica/*": ["./src/*"], + "@/commons-ui/core/*": ["../../packages/commons-ui-core/src/*"], + "@/commons-ui/next/*": ["../../packages/commons-ui-next/src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["build", "dist", "node_modules"], + "ts-node": { + "swc": true + } +} diff --git a/apps/climatemappedafrica/tsconfig.server.json b/apps/climatemappedafrica/tsconfig.server.json new file mode 100644 index 000000000..e013c7a98 --- /dev/null +++ b/apps/climatemappedafrica/tsconfig.server.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "ES2015", + "noEmit": false, + "module": "CommonJS", + "jsx": "react", + "outDir": "./dist", + "rootDir": "./" + }, + "include": ["payload.config.ts", "server.ts"] +} diff --git a/apps/climatemappedafrica/turbo.json b/apps/climatemappedafrica/turbo.json index 3dbc40709..697c4610e 100644 --- a/apps/climatemappedafrica/turbo.json +++ b/apps/climatemappedafrica/turbo.json @@ -9,9 +9,11 @@ "env": [ "HURUMAP_API_URL", "NEXT_PUBLIC_APP_URL", + "PAYLOAD_PUBLIC_DEFAULT_LOCALE", "NEXT_PUBLIC_IMAGE_DOMAINS", "NEXT_PUBLIC_IMAGE_UNOPTIMIZED", "NEXT_PUBLIC_IMAGE_SCALE_FACTOR", + "PAYLOAD_PUBLIC_LOCALES", "NEXT_PUBLIC_OPENAFRICA_DOMAINS", "NEXT_PUBLIC_SOURCEAFRICA_DOMAINS", "NEXT_PUBLIC_VERCEL_ENV", diff --git a/apps/codeforafrica/server.ts b/apps/codeforafrica/server.ts index 063368788..ec874fbdb 100644 --- a/apps/codeforafrica/server.ts +++ b/apps/codeforafrica/server.ts @@ -34,7 +34,7 @@ const start = async (): Promise => { }), fromName: process.env.SENDGRID_FROM_NAME || "Code for Africa CMS", fromAddress: - process.env.SENDGRID_FROM_EMAIL || "noreply@dodeforafrica.org", + process.env.SENDGRID_FROM_EMAIL || "noreply@codeforafrica.org", }, } : undefined), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c275fd72b..a50b55cd5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1073,6 +1073,27 @@ importers: '@mui/utils': specifier: catalog:mui-styles version: 5.16.6(@types/react@18.3.10)(react@18.3.1) + '@payloadcms/bundler-webpack': + specifier: 'catalog:' + version: 1.0.7(@swc/core@1.7.26(@swc/helpers@0.5.5))(ajv@8.17.1)(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(sass@1.69.4) + '@payloadcms/db-mongodb': + specifier: 'catalog:' + version: 1.7.2(@aws-sdk/client-sso-oidc@3.658.1(@aws-sdk/client-sts@3.658.1))(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + '@payloadcms/plugin-cloud-storage': + specifier: 'catalog:' + version: 1.1.3(@aws-sdk/client-s3@3.658.1)(@aws-sdk/lib-storage@3.658.1(@aws-sdk/client-s3@3.658.1))(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + '@payloadcms/plugin-nested-docs': + specifier: 'catalog:' + version: 1.0.12(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + '@payloadcms/plugin-sentry': + specifier: 'catalog:' + version: 0.0.6(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(react@18.3.1) + '@payloadcms/plugin-seo': + specifier: 'catalog:' + version: 2.3.2(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(react@18.3.1) + '@payloadcms/richtext-slate': + specifier: 'catalog:' + version: 1.5.2(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reactour/tour': specifier: 'catalog:' version: 3.7.0(react@18.3.1) @@ -1088,6 +1109,9 @@ importers: deepmerge: specifier: 'catalog:' version: 4.3.1 + dotenv: + specifier: 'catalog:' + version: 16.4.5 leaflet: specifier: 'catalog:' version: 1.9.4 @@ -1099,13 +1123,16 @@ importers: version: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4) next-images: specifier: 'catalog:' - version: 1.8.5(webpack@5.95.0) + version: 1.8.5(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) next-seo: specifier: 'catalog:' version: 6.6.0(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) papaparse: specifier: 'catalog:' version: 5.4.1 + payload: + specifier: 'catalog:' + version: 2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) plaiceholder: specifier: 'catalog:' version: 2.5.0(sharp@0.33.5) @@ -1162,7 +1189,7 @@ importers: version: 3.0.1(video.js@8.17.4) webpack: specifier: 'catalog:' - version: 5.95.0 + version: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) xlsx: specifier: 'catalog:' version: 0.18.5 @@ -1202,7 +1229,7 @@ importers: version: 8.3.4(@babel/preset-env@7.25.4(@babel/core@7.25.2)) '@storybook/nextjs': specifier: 'catalog:' - version: 8.3.4(babel-plugin-macros@3.1.0)(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0) + version: 8.3.4(@swc/core@1.7.26(@swc/helpers@0.5.5))(babel-plugin-macros@3.1.0)(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) '@storybook/react': specifier: 'catalog:' version: 8.3.4(@storybook/test@8.3.4(storybook@8.3.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.6.2) @@ -1226,7 +1253,7 @@ importers: version: 29.7.0(@babel/core@7.25.2) babel-loader: specifier: 'catalog:' - version: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0) + version: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) eslint: specifier: 'catalog:' version: 8.57.1 @@ -1277,7 +1304,10 @@ importers: version: 18.3.1(react@18.3.1) svg-url-loader: specifier: 'catalog:' - version: 8.0.0(webpack@5.95.0) + version: 8.0.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + ts-node: + specifier: 'catalog:' + version: 10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@20.16.10)(typescript@5.6.2) typescript: specifier: 'catalog:' version: 5.6.2 @@ -2261,7 +2291,7 @@ importers: version: 8.3.4(@babel/preset-env@7.25.4(@babel/core@7.25.2)) '@storybook/nextjs': specifier: 'catalog:' - version: 8.3.4(babel-plugin-macros@3.1.0)(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0) + version: 8.3.4(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0) '@storybook/react': specifier: 'catalog:' version: 8.3.4(@storybook/test@8.3.4(storybook@8.3.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.6.2) @@ -6296,6 +6326,7 @@ packages: '@swc/register@0.1.10': resolution: {integrity: sha512-6STwH/q4dc3pitXLVkV7sP0Hiy+zBsU2wOF1aXpXR95pnH3RYHKIsDC+gvesfyB7jxNT9OOZgcqOp9RPxVTx9A==} + deprecated: Use @swc-node/register instead hasBin: true peerDependencies: '@swc/core': ^1.0.46 @@ -17935,6 +17966,21 @@ snapshots: dependencies: playwright: 1.47.2 + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@4.26.1)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))': + dependencies: + ansi-html: 0.0.9 + core-js-pure: 3.38.1 + error-stack-parser: 2.1.4 + html-entities: 2.5.2 + loader-utils: 2.0.4 + react-refresh: 0.14.2 + schema-utils: 4.2.0 + source-map: 0.7.4 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + optionalDependencies: + type-fest: 4.26.1 + webpack-hot-middleware: 2.26.1 + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@4.26.1)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1))': dependencies: ansi-html: 0.0.9 @@ -18920,6 +18966,46 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@storybook/builder-webpack5@8.3.4(@swc/core@1.7.26(@swc/helpers@0.5.5))(storybook@8.3.4)(typescript@5.6.2)': + dependencies: + '@storybook/core-webpack': 8.3.4(storybook@8.3.4) + '@types/node': 22.7.4 + '@types/semver': 7.5.8 + browser-assert: 1.2.1 + case-sensitive-paths-webpack-plugin: 2.4.0 + cjs-module-lexer: 1.4.1 + constants-browserify: 1.0.0 + css-loader: 6.11.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + es-module-lexer: 1.5.4 + express: 4.21.0 + fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + fs-extra: 11.2.0 + html-webpack-plugin: 5.6.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + magic-string: 0.30.11 + path-browserify: 1.0.1 + process: 0.11.10 + semver: 7.6.3 + storybook: 8.3.4 + style-loader: 3.3.4(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + ts-dedent: 2.2.0 + url: 0.11.4 + util: 0.12.5 + util-deprecate: 1.0.2 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + webpack-dev-middleware: 6.1.3(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + webpack-hot-middleware: 2.26.1 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - '@rspack/core' + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + '@storybook/builder-webpack5@8.3.4(esbuild@0.23.1)(storybook@8.3.4)(typescript@5.6.2)': dependencies: '@storybook/core-webpack': 8.3.4(storybook@8.3.4) @@ -19109,6 +19195,74 @@ snapshots: dependencies: storybook: 8.3.4 + '@storybook/nextjs@8.3.4(@swc/core@1.7.26(@swc/helpers@0.5.5))(babel-plugin-macros@3.1.0)(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))': + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-import-assertions': 7.25.6(@babel/core@7.25.2) + '@babel/plugin-transform-class-properties': 7.25.4(@babel/core@7.25.2) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-runtime': 7.25.4(@babel/core@7.25.2) + '@babel/preset-env': 7.25.4(@babel/core@7.25.2) + '@babel/preset-react': 7.24.7(@babel/core@7.25.2) + '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/runtime': 7.25.6 + '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.14.2)(type-fest@4.26.1)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + '@storybook/builder-webpack5': 8.3.4(@swc/core@1.7.26(@swc/helpers@0.5.5))(storybook@8.3.4)(typescript@5.6.2) + '@storybook/preset-react-webpack': 8.3.4(@storybook/test@8.3.4(storybook@8.3.4))(@swc/core@1.7.26(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.6.2) + '@storybook/react': 8.3.4(@storybook/test@8.3.4(storybook@8.3.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.6.2) + '@storybook/test': 8.3.4(storybook@8.3.4) + '@types/node': 22.7.4 + '@types/semver': 7.5.8 + babel-loader: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + css-loader: 6.11.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + find-up: 5.0.0 + fs-extra: 11.2.0 + image-size: 1.1.1 + loader-utils: 3.3.1 + next: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4) + node-polyfill-webpack-plugin: 2.0.1(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + pnp-webpack-plugin: 1.7.0(typescript@5.6.2) + postcss: 8.4.47 + postcss-loader: 8.1.1(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-refresh: 0.14.2 + resolve-url-loader: 5.0.0 + sass-loader: 13.3.3(sass@1.69.4)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + semver: 7.6.3 + storybook: 8.3.4 + style-loader: 3.3.4(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + styled-jsx: 5.1.6(@babel/core@7.25.2)(babel-plugin-macros@3.1.0)(react@18.3.1) + ts-dedent: 2.2.0 + tsconfig-paths: 4.2.0 + tsconfig-paths-webpack-plugin: 4.1.0 + optionalDependencies: + sharp: 0.33.5 + typescript: 5.6.2 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + transitivePeerDependencies: + - '@rspack/core' + - '@swc/core' + - '@types/webpack' + - babel-plugin-macros + - esbuild + - fibers + - node-sass + - sass + - sass-embedded + - sockjs-client + - supports-color + - type-fest + - uglify-js + - webpack-cli + - webpack-dev-server + - webpack-hot-middleware + - webpack-plugin-serve + '@storybook/nextjs@8.3.4(babel-plugin-macros@3.1.0)(esbuild@0.23.1)(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1))': dependencies: '@babel/core': 7.25.2 @@ -19177,7 +19331,7 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/nextjs@8.3.4(babel-plugin-macros@3.1.0)(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0)': + '@storybook/nextjs@8.3.4(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)(storybook@8.3.4)(type-fest@4.26.1)(typescript@5.6.2)(webpack-hot-middleware@2.26.1)(webpack@5.95.0)': dependencies: '@babel/core': 7.25.2 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) @@ -19245,6 +19399,34 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve + '@storybook/preset-react-webpack@8.3.4(@storybook/test@8.3.4(storybook@8.3.4))(@swc/core@1.7.26(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.6.2)': + dependencies: + '@storybook/core-webpack': 8.3.4(storybook@8.3.4) + '@storybook/react': 8.3.4(@storybook/test@8.3.4(storybook@8.3.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.6.2) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + '@types/node': 22.7.4 + '@types/semver': 7.5.8 + find-up: 5.0.0 + fs-extra: 11.2.0 + magic-string: 0.30.11 + react: 18.3.1 + react-docgen: 7.0.3 + react-dom: 18.3.1(react@18.3.1) + resolve: 1.22.8 + semver: 7.6.3 + storybook: 8.3.4 + tsconfig-paths: 4.2.0 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - '@storybook/test' + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + '@storybook/preset-react-webpack@8.3.4(@storybook/test@8.3.4(storybook@8.3.4))(esbuild@0.23.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.6.2)': dependencies: '@storybook/core-webpack': 8.3.4(storybook@8.3.4) @@ -19305,6 +19487,20 @@ snapshots: dependencies: storybook: 8.3.4 + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))': + dependencies: + debug: 4.3.7 + endent: 2.1.0 + find-cache-dir: 3.3.2 + flat-cache: 3.2.0 + micromatch: 4.0.8 + react-docgen-typescript: 2.2.2(typescript@5.6.2) + tslib: 2.7.0 + typescript: 5.6.2 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + transitivePeerDependencies: + - supports-color + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.6.2)(webpack@5.95.0(esbuild@0.23.1))': dependencies: debug: 4.3.7 @@ -20637,6 +20833,13 @@ snapshots: transitivePeerDependencies: - supports-color + babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + '@babel/core': 7.25.2 + find-cache-dir: 4.0.0 + schema-utils: 4.2.0 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.95.0(esbuild@0.23.1)): dependencies: '@babel/core': 7.25.2 @@ -21449,6 +21652,19 @@ snapshots: semver: 7.6.3 webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.47) + postcss-modules-local-by-default: 4.0.5(postcss@8.4.47) + postcss-modules-scope: 3.2.0(postcss@8.4.47) + postcss-modules-values: 4.0.0(postcss@8.4.47) + postcss-value-parser: 4.2.0 + semver: 7.6.3 + optionalDependencies: + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + css-loader@6.11.0(webpack@5.95.0(esbuild@0.23.1)): dependencies: icss-utils: 5.1.0(postcss@8.4.47) @@ -23154,12 +23370,6 @@ snapshots: schema-utils: 3.3.0 webpack: 5.95.0(esbuild@0.23.1) - file-loader@6.2.0(webpack@5.95.0): - dependencies: - loader-utils: 2.0.4 - schema-utils: 3.3.0 - webpack: 5.95.0 - file-type@16.5.4: dependencies: readable-web-to-node-stream: 3.0.2 @@ -23271,6 +23481,23 @@ snapshots: forever-agent@0.6.1: {} + fork-ts-checker-webpack-plugin@8.0.0(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + '@babel/code-frame': 7.24.7 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.2 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.6.3 + tapable: 2.2.1 + typescript: 5.6.2 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + fork-ts-checker-webpack-plugin@8.0.0(typescript@5.6.2)(webpack@5.95.0(esbuild@0.23.1)): dependencies: '@babel/code-frame': 7.24.7 @@ -25989,18 +26216,18 @@ snapshots: optionalDependencies: nodemailer: 6.9.8 + next-images@1.8.5(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + next-images@1.8.5(webpack@5.95.0(esbuild@0.23.1)): dependencies: file-loader: 6.2.0(webpack@5.95.0(esbuild@0.23.1)) url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0(esbuild@0.23.1)))(webpack@5.95.0(esbuild@0.23.1)) webpack: 5.95.0(esbuild@0.23.1) - next-images@1.8.5(webpack@5.95.0): - dependencies: - file-loader: 6.2.0(webpack@5.95.0) - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - webpack: 5.95.0 - next-seo@6.6.0(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: next: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4) @@ -26105,6 +26332,35 @@ snapshots: node-int64@0.4.0: {} + node-polyfill-webpack-plugin@2.0.1(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + assert: 2.1.0 + browserify-zlib: 0.2.0 + buffer: 6.0.3 + console-browserify: 1.2.0 + constants-browserify: 1.0.0 + crypto-browserify: 3.12.0 + domain-browser: 4.23.0 + events: 3.3.0 + filter-obj: 2.0.2 + https-browserify: 1.0.0 + os-browserify: 0.3.0 + path-browserify: 1.0.1 + process: 0.11.10 + punycode: 2.3.1 + querystring-es3: 0.2.1 + readable-stream: 4.5.2 + stream-browserify: 3.0.0 + stream-http: 3.2.0 + string_decoder: 1.3.0 + timers-browserify: 2.0.12 + tty-browserify: 0.0.1 + type-fest: 2.19.0 + url: 0.11.4 + util: 0.12.5 + vm-browserify: 1.1.2 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + node-polyfill-webpack-plugin@2.0.1(webpack@5.95.0(esbuild@0.23.1)): dependencies: assert: 2.1.0 @@ -27026,6 +27282,17 @@ snapshots: semver: 7.6.3 webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + postcss-loader@8.1.1(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + cosmiconfig: 9.0.0(typescript@5.6.2) + jiti: 1.21.6 + postcss: 8.4.47 + semver: 7.6.3 + optionalDependencies: + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + transitivePeerDependencies: + - typescript + postcss-loader@8.1.1(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(esbuild@0.23.1)): dependencies: cosmiconfig: 9.0.0(typescript@5.6.2) @@ -28092,6 +28359,13 @@ snapshots: optionalDependencies: sass: 1.69.4 + sass-loader@13.3.3(sass@1.69.4)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + neo-async: 2.6.2 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + optionalDependencies: + sass: 1.69.4 + sass-loader@13.3.3(sass@1.69.4)(webpack@5.95.0(esbuild@0.23.1)): dependencies: neo-async: 2.6.2 @@ -28665,6 +28939,10 @@ snapshots: schema-utils: 3.3.0 webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + style-loader@3.3.4(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + style-loader@3.3.4(webpack@5.95.0(esbuild@0.23.1)): dependencies: webpack: 5.95.0(esbuild@0.23.1) @@ -28717,16 +28995,16 @@ snapshots: svg-parser@2.0.4: {} + svg-url-loader@8.0.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + svg-url-loader@8.0.0(webpack@5.95.0(esbuild@0.23.1)): dependencies: file-loader: 6.2.0(webpack@5.95.0(esbuild@0.23.1)) webpack: 5.95.0(esbuild@0.23.1) - svg-url-loader@8.0.0(webpack@5.95.0): - dependencies: - file-loader: 6.2.0(webpack@5.95.0) - webpack: 5.95.0 - svgo@3.3.2: dependencies: '@trysound/sax': 0.2.0 @@ -29348,15 +29626,6 @@ snapshots: optionalDependencies: file-loader: 6.2.0(webpack@5.95.0(esbuild@0.23.1)) - url-loader@4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0): - dependencies: - loader-utils: 2.0.4 - mime-types: 2.1.35 - schema-utils: 3.3.0 - webpack: 5.95.0 - optionalDependencies: - file-loader: 6.2.0(webpack@5.95.0) - url-parse@1.5.10: dependencies: querystringify: 2.2.0 @@ -30188,6 +30457,16 @@ snapshots: optionalDependencies: webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + webpack-dev-middleware@6.1.3(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + colorette: 2.0.20 + memfs: 3.5.3 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 4.2.0 + optionalDependencies: + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))) + webpack-dev-middleware@6.1.3(webpack@5.95.0(esbuild@0.23.1)): dependencies: colorette: 2.0.20 From 8b7c93e2be4fd18866a34a3a27ee559645819a9e Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:15:50 +0300 Subject: [PATCH 2/6] Fix formatting --- apps/climatemappedafrica/payload.config.ts | 22 +++++++++------------- apps/climatemappedafrica/server.ts | 3 ++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/apps/climatemappedafrica/payload.config.ts b/apps/climatemappedafrica/payload.config.ts index e8d132076..85f6eb030 100644 --- a/apps/climatemappedafrica/payload.config.ts +++ b/apps/climatemappedafrica/payload.config.ts @@ -16,7 +16,6 @@ import { defaultLocale, locales } from "./src/payload/utils/locales"; import Media from "./src/payload/collections/Media"; import Users from "./src/payload/collections/Users"; - dotenv.config(); dotenv.config({ path: path.resolve(__dirname, "./.env.local") }); @@ -32,7 +31,7 @@ const csrf = ?.map((d) => d.trim()) ?.filter(Boolean) ?? []; - const adapter = s3Adapter({ +const adapter = s3Adapter({ config: { region: process?.env?.S3_REGION, credentials: { @@ -44,20 +43,17 @@ const csrf = } as any); export default buildConfig({ - serverURL: appURL, - editor: slateEditor({}), - routes: { + serverURL: appURL, + editor: slateEditor({}), + routes: { admin: "/admin", }, db: mongooseAdapter({ url: process.env.MONGO_URL, migrationDir: process.env.MIGRATIONS_DIR, }), - collections:[ - Media, - Users, - ]as CollectionConfig[], - globals: []as GlobalConfig[], + collections: [Media, Users] as CollectionConfig[], + globals: [] as GlobalConfig[], ...(locales?.length ? { localization: { @@ -67,7 +63,7 @@ export default buildConfig({ }, } : undefined), - admin: { + admin: { webpack: (config) => ({ ...config, resolve: { @@ -82,7 +78,7 @@ export default buildConfig({ }), bundler: webpackBundler(), }, - cors, + cors, csrf, i18n: { fallbackLng: "en", // default @@ -122,4 +118,4 @@ export default buildConfig({ docs.reduce((url, doc) => `${url}/${doc.slug}`, ""), }), ], -}) +}); diff --git a/apps/climatemappedafrica/server.ts b/apps/climatemappedafrica/server.ts index fc699e90a..ed6a43202 100644 --- a/apps/climatemappedafrica/server.ts +++ b/apps/climatemappedafrica/server.ts @@ -32,7 +32,8 @@ const start = async (): Promise => { transportOptions: nodemailerSendgrid({ apiKey: sendGridAPIKey, }), - fromName: process.env.SENDGRID_FROM_NAME || "ClimateMapped Africa CMS", + fromName: + process.env.SENDGRID_FROM_NAME || "ClimateMapped Africa CMS", fromAddress: process.env.SENDGRID_FROM_EMAIL || "noreply@dodeforafrica.org", }, From a12ad775fc77212782f0f024404063a1a1c79dd6 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:10:10 +0300 Subject: [PATCH 3/6] Update Jest Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- apps/climatemappedafrica/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/climatemappedafrica/package.json b/apps/climatemappedafrica/package.json index 083893ab3..e55175324 100644 --- a/apps/climatemappedafrica/package.json +++ b/apps/climatemappedafrica/package.json @@ -28,7 +28,7 @@ "dev": "NODE_OPTIONS='--inspect' ts-node --project tsconfig.server.json server.ts", "lint-check": "TIMING=1 eslint './'", "lint": "TIMING=1 eslint --fix './'", - "jest": "jest", + "jest": "jest --passWithNoTests", "playwright": "npx playwright test", "clean": "rm -rf .next .turbo node_modules" }, From 6b04792bffad84c8d96db757070b61682d16680c Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:46:51 +0300 Subject: [PATCH 4/6] Fix failing build --- apps/climatemappedafrica/package.json | 3 +++ apps/climatemappedafrica/tsconfig.json | 4 +++- pnpm-lock.yaml | 29 +++++++++++++++++--------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/apps/climatemappedafrica/package.json b/apps/climatemappedafrica/package.json index e55175324..e50f97bcb 100644 --- a/apps/climatemappedafrica/package.json +++ b/apps/climatemappedafrica/package.json @@ -44,6 +44,7 @@ "@mui/material": "catalog:mui-styles", "@mui/styles": "catalog:mui-styles", "@mui/utils": "catalog:mui-styles", + "@next/env": "catalog:", "@payloadcms/bundler-webpack": "catalog:", "@payloadcms/db-mongodb": "catalog:", "@payloadcms/plugin-cloud-storage": "catalog:", @@ -57,11 +58,13 @@ "d3-format": "catalog:", "deepmerge": "catalog:", "dotenv": "catalog:", + "express": "catalog:", "leaflet": "catalog:", "lodash": "catalog:", "next": "catalog:", "next-images": "catalog:", "next-seo": "catalog:", + "nodemailer-sendgrid": "catalog:", "papaparse": "catalog:", "payload": "catalog:", "plaiceholder": "catalog:", diff --git a/apps/climatemappedafrica/tsconfig.json b/apps/climatemappedafrica/tsconfig.json index 189d8a6a0..7c4d8bfa1 100644 --- a/apps/climatemappedafrica/tsconfig.json +++ b/apps/climatemappedafrica/tsconfig.json @@ -17,7 +17,9 @@ "paths": { "@/climatemappedafrica/*": ["./src/*"], "@/commons-ui/core/*": ["../../packages/commons-ui-core/src/*"], - "@/commons-ui/next/*": ["../../packages/commons-ui-next/src/*"] + "@/commons-ui/next/*": ["../../packages/commons-ui-next/src/*"], + "@/hurumap/core/*": ["../../packages/hurumap-core/src/*"], + "@/hurumap/next/*": ["../../packages/hurumap-next/src/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a50b55cd5..c43b40054 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1073,6 +1073,9 @@ importers: '@mui/utils': specifier: catalog:mui-styles version: 5.16.6(@types/react@18.3.10)(react@18.3.1) + '@next/env': + specifier: 'catalog:' + version: 14.2.13 '@payloadcms/bundler-webpack': specifier: 'catalog:' version: 1.0.7(@swc/core@1.7.26(@swc/helpers@0.5.5))(ajv@8.17.1)(payload@2.30.0(@swc/helpers@0.5.5)(@types/react@18.3.10)(encoding@0.1.13)(typescript@5.6.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(sass@1.69.4) @@ -1112,6 +1115,9 @@ importers: dotenv: specifier: 'catalog:' version: 16.4.5 + express: + specifier: 'catalog:' + version: 4.21.0 leaflet: specifier: 'catalog:' version: 1.9.4 @@ -1127,6 +1133,9 @@ importers: next-seo: specifier: 'catalog:' version: 6.6.0(next@14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nodemailer-sendgrid: + specifier: 'catalog:' + version: 1.0.3 papaparse: specifier: 'catalog:' version: 5.4.1 @@ -16777,7 +16786,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.16.10 + '@types/node': 22.7.4 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -16862,7 +16871,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.16.10 + '@types/node': 22.7.4 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -19882,7 +19891,7 @@ snapshots: '@types/connect@3.4.36': dependencies: - '@types/node': 20.16.10 + '@types/node': 22.7.4 '@types/connect@3.4.38': dependencies: @@ -20032,7 +20041,7 @@ snapshots: '@types/mysql@2.15.26': dependencies: - '@types/node': 20.16.10 + '@types/node': 22.7.4 '@types/node@12.20.55': {} @@ -20062,7 +20071,7 @@ snapshots: '@types/pg@8.6.1': dependencies: - '@types/node': 20.16.10 + '@types/node': 22.7.4 pg-protocol: 1.7.0 pg-types: 2.2.0 @@ -20092,7 +20101,7 @@ snapshots: '@types/request@2.48.12': dependencies: '@types/caseless': 0.12.5 - '@types/node': 20.16.10 + '@types/node': 22.7.4 '@types/tough-cookie': 4.0.5 form-data: 2.5.1 @@ -24903,7 +24912,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.10 + '@types/node': 22.7.4 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -24931,7 +24940,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.10 + '@types/node': 22.7.4 chalk: 4.1.2 cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 @@ -24996,7 +25005,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.10 + '@types/node': 22.7.4 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -25005,7 +25014,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 20.16.10 + '@types/node': 22.7.4 merge-stream: 2.0.0 supports-color: 8.1.1 From 1cb2dd5a65686b88fb8aab9185b8a0c16042358b Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:57:40 +0300 Subject: [PATCH 5/6] Add Pages --- apps/climatemappedafrica/payload.config.ts | 3 +- .../src/payload/collections/Pages.js | 42 +++++++++++++++++++ .../src/payload/fields/fullTitle/index.js | 22 ++++++++++ .../fields/fullTitle/populateFullTitle.js | 17 ++++++++ .../src/payload/fields/slug/formatSlug.js | 34 +++++++++++++++ .../src/payload/fields/slug/index.js | 22 ++++++++++ .../src/payload/utils/formatDraftUrl.js | 16 +++++++ .../src/payload/utils/formatPagePath.js | 33 +++++++++++++++ apps/climatemappedafrica/turbo.json | 1 + 9 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 apps/climatemappedafrica/src/payload/collections/Pages.js create mode 100644 apps/climatemappedafrica/src/payload/fields/fullTitle/index.js create mode 100644 apps/climatemappedafrica/src/payload/fields/fullTitle/populateFullTitle.js create mode 100644 apps/climatemappedafrica/src/payload/fields/slug/formatSlug.js create mode 100644 apps/climatemappedafrica/src/payload/fields/slug/index.js create mode 100644 apps/climatemappedafrica/src/payload/utils/formatDraftUrl.js create mode 100644 apps/climatemappedafrica/src/payload/utils/formatPagePath.js diff --git a/apps/climatemappedafrica/payload.config.ts b/apps/climatemappedafrica/payload.config.ts index 85f6eb030..eee88b93c 100644 --- a/apps/climatemappedafrica/payload.config.ts +++ b/apps/climatemappedafrica/payload.config.ts @@ -14,6 +14,7 @@ import { sentry } from "@payloadcms/plugin-sentry"; import { defaultLocale, locales } from "./src/payload/utils/locales"; import Media from "./src/payload/collections/Media"; +import Pages from "./src/payload/collections/Pages"; import Users from "./src/payload/collections/Users"; dotenv.config(); @@ -52,7 +53,7 @@ export default buildConfig({ url: process.env.MONGO_URL, migrationDir: process.env.MIGRATIONS_DIR, }), - collections: [Media, Users] as CollectionConfig[], + collections: [Media, Pages, Users] as CollectionConfig[], globals: [] as GlobalConfig[], ...(locales?.length ? { diff --git a/apps/climatemappedafrica/src/payload/collections/Pages.js b/apps/climatemappedafrica/src/payload/collections/Pages.js new file mode 100644 index 000000000..9aadce21e --- /dev/null +++ b/apps/climatemappedafrica/src/payload/collections/Pages.js @@ -0,0 +1,42 @@ +import fullTitle from "../fields/fullTitle"; +import slug from "../fields/slug"; +import formatDraftUrl from "../utils/formatDraftUrl"; + +const Pages = { + slug: "pages", + access: { + read: () => true, + create: () => true, + update: () => true, + }, + admin: { + defaultColumns: ["fullTitle", "updatedAt"], + group: "Publication", + preview: (doc, options) => formatDraftUrl("pages", doc, options), + useAsTitle: "title", + }, + fields: [ + { + name: "title", + type: "text", + required: true, + localized: true, + }, + fullTitle({ overrides: { localized: true } }), + slug(), + { + name: "blocks", + type: "blocks", + blocks: [], + localized: true, + admin: { + initCollapsed: true, + }, + }, + ], + versions: { + drafts: true, + }, +}; + +export default Pages; diff --git a/apps/climatemappedafrica/src/payload/fields/fullTitle/index.js b/apps/climatemappedafrica/src/payload/fields/fullTitle/index.js new file mode 100644 index 000000000..8074aadae --- /dev/null +++ b/apps/climatemappedafrica/src/payload/fields/fullTitle/index.js @@ -0,0 +1,22 @@ +import { deepmerge } from "@mui/utils"; + +import populateFullTitle from "./populateFullTitle"; + +function fullTitle({ overrides = undefined } = {}) { + const fullTitleResult = { + name: "fullTitle", + type: "text", + hooks: { + beforeChange: [populateFullTitle], + }, + admin: { + components: { + Field: () => null, + }, + }, + }; + + return deepmerge(fullTitleResult, overrides); +} + +export default fullTitle; diff --git a/apps/climatemappedafrica/src/payload/fields/fullTitle/populateFullTitle.js b/apps/climatemappedafrica/src/payload/fields/fullTitle/populateFullTitle.js new file mode 100644 index 000000000..703529fe8 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/fields/fullTitle/populateFullTitle.js @@ -0,0 +1,17 @@ +export function generateFullTitle(breadcrumbs) { + if (Array.isArray(breadcrumbs)) { + return breadcrumbs.reduce((title, breadcrumb, i) => { + if (i === 0) { + return `${breadcrumb.label}`; + } + return `${title} > ${breadcrumb.label}`; + }, ""); + } + return undefined; +} + +async function populateFullTitle({ data, originalDoc }) { + return generateFullTitle(data?.breadcrumbs || originalDoc?.breadcrumbs); +} + +export default populateFullTitle; diff --git a/apps/climatemappedafrica/src/payload/fields/slug/formatSlug.js b/apps/climatemappedafrica/src/payload/fields/slug/formatSlug.js new file mode 100644 index 000000000..e1b07e3a6 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/fields/slug/formatSlug.js @@ -0,0 +1,34 @@ +const format = (val) => + val + .replace(/ /g, "-") + .replace(/[^\w-]+/g, "") + .toLowerCase(); + +const getFallbackData = ({ fallback, originalDoc, data }) => { + const fallbackValues = fallback.map( + (value) => (data && data[value]) || (originalDoc && originalDoc[value]), + ); + return fallbackValues.join("-"); +}; + +const formatSlug = + (fallback) => + ({ value, originalDoc, data }) => { + if (value && typeof value === "string") { + return format(value); + } + + const validFallback = typeof fallback === "string" ? [fallback] : fallback; + const fallbackData = getFallbackData({ + fallback: validFallback, + originalDoc, + data, + }); + + if (fallbackData && typeof fallbackData === "string") { + return format(fallbackData); + } + return value; + }; + +export default formatSlug; diff --git a/apps/climatemappedafrica/src/payload/fields/slug/index.js b/apps/climatemappedafrica/src/payload/fields/slug/index.js new file mode 100644 index 000000000..ef953b843 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/fields/slug/index.js @@ -0,0 +1,22 @@ +import { deepmerge } from "@mui/utils"; + +import formatSlug from "./formatSlug"; + +function slug({ fieldToUse = "title", overrides = undefined } = {}) { + const slugResult = { + name: "slug", + type: "text", + index: true, + unique: true, + admin: { + position: "sidebar", + }, + hooks: { + beforeValidate: [formatSlug(fieldToUse)], + }, + }; + + return deepmerge(slugResult, overrides); +} + +export default slug; diff --git a/apps/climatemappedafrica/src/payload/utils/formatDraftUrl.js b/apps/climatemappedafrica/src/payload/utils/formatDraftUrl.js new file mode 100644 index 000000000..1774323c6 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/utils/formatDraftUrl.js @@ -0,0 +1,16 @@ +import formatPagePath from "./formatPagePath"; + +function formatDraftUrl(collection, doc) { + const pagePath = formatPagePath(collection, doc); + if (pagePath) { + const slug = pagePath; + const url = new URL( + `/api/v1/draft?slug=${slug}`, + process.env.PAYLOAD_PUBLIC_APP_URL, + ); + return url.href; + } + return null; +} + +export default formatDraftUrl; diff --git a/apps/climatemappedafrica/src/payload/utils/formatPagePath.js b/apps/climatemappedafrica/src/payload/utils/formatPagePath.js new file mode 100644 index 000000000..7ff21f882 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/utils/formatPagePath.js @@ -0,0 +1,33 @@ +function fullSlugFromParents(doc) { + const { slug, parent } = doc; + if (!parent) { + return slug; + } + return `${fullSlugFromParents(parent)}/${slug}`; +} + +function fullSlugFromBreadcrumbs({ breadcrumbs } = {}) { + const fullSlug = breadcrumbs?.[breadcrumbs.length - 1]?.url?.slice(1); + return fullSlug; +} + +function formatPagePath(collection, doc) { + let pageSlug = fullSlugFromBreadcrumbs(doc) || fullSlugFromParents(doc) || ""; + if (pageSlug === "index") { + pageSlug = ""; + } + let prefix = ""; + if (collection) { + switch (collection) { + case "pages": + // Empty prefix for pages + break; + default: + prefix = `/${collection}`; + } + } + + return `${prefix}/${pageSlug}`; +} + +export default formatPagePath; diff --git a/apps/climatemappedafrica/turbo.json b/apps/climatemappedafrica/turbo.json index 697c4610e..69419a4f7 100644 --- a/apps/climatemappedafrica/turbo.json +++ b/apps/climatemappedafrica/turbo.json @@ -14,6 +14,7 @@ "NEXT_PUBLIC_IMAGE_UNOPTIMIZED", "NEXT_PUBLIC_IMAGE_SCALE_FACTOR", "PAYLOAD_PUBLIC_LOCALES", + "PAYLOAD_PUBLIC_APP_URL", "NEXT_PUBLIC_OPENAFRICA_DOMAINS", "NEXT_PUBLIC_SOURCEAFRICA_DOMAINS", "NEXT_PUBLIC_VERCEL_ENV", From d602808f6613ee15d74a50db6244c9f5fd291e96 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:31:55 +0300 Subject: [PATCH 6/6] Use next/env instead of dotenv --- apps/climatemappedafrica/package.json | 1 - apps/climatemappedafrica/payload.config.ts | 8 +++----- pnpm-lock.yaml | 3 --- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/apps/climatemappedafrica/package.json b/apps/climatemappedafrica/package.json index e50f97bcb..1cff399af 100644 --- a/apps/climatemappedafrica/package.json +++ b/apps/climatemappedafrica/package.json @@ -57,7 +57,6 @@ "clsx": "catalog:", "d3-format": "catalog:", "deepmerge": "catalog:", - "dotenv": "catalog:", "express": "catalog:", "leaflet": "catalog:", "lodash": "catalog:", diff --git a/apps/climatemappedafrica/payload.config.ts b/apps/climatemappedafrica/payload.config.ts index eee88b93c..be284f509 100644 --- a/apps/climatemappedafrica/payload.config.ts +++ b/apps/climatemappedafrica/payload.config.ts @@ -1,7 +1,5 @@ -import path from "path"; - import { buildConfig } from "payload/config"; -import dotenv from "dotenv"; +import { loadEnvConfig } from "@next/env"; import { cloudStorage } from "@payloadcms/plugin-cloud-storage"; import { s3Adapter } from "@payloadcms/plugin-cloud-storage/s3"; import { slateEditor } from "@payloadcms/richtext-slate"; @@ -17,8 +15,8 @@ import Media from "./src/payload/collections/Media"; import Pages from "./src/payload/collections/Pages"; import Users from "./src/payload/collections/Users"; -dotenv.config(); -dotenv.config({ path: path.resolve(__dirname, "./.env.local") }); +const projectDir = process.cwd(); +loadEnvConfig(projectDir); const appURL = process.env.PAYLOAD_PUBLIC_APP_URL; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c43b40054..98ceaebc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1112,9 +1112,6 @@ importers: deepmerge: specifier: 'catalog:' version: 4.3.1 - dotenv: - specifier: 'catalog:' - version: 16.4.5 express: specifier: 'catalog:' version: 4.21.0