Merged in feat/enable-live-preview (pull request #15)
Feat/enable live preview Approved-by: Simon.Emanuelsson
This commit is contained in:
@@ -2,3 +2,5 @@ CMS_ACCESS_TOKEN=""
|
|||||||
CMS_API_KEY=""
|
CMS_API_KEY=""
|
||||||
CMS_ENVIRONMENT="development"
|
CMS_ENVIRONMENT="development"
|
||||||
CMS_URL="https://eu-graphql.contentstack.com/stacks/${CMS_API_KEY}?environment=${CMS_ENVIRONMENT}"
|
CMS_URL="https://eu-graphql.contentstack.com/stacks/${CMS_API_KEY}?environment=${CMS_ENVIRONMENT}"
|
||||||
|
CMS_PREVIEW_URL="https://graphql-preview.contentstack.com/stacks/${CMS_API_KEY}?environment=${CMS_ENVIRONMENT}";
|
||||||
|
CMS_PREVIEW_TOKEN=""
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
import { request } from "@/lib/request"
|
import { request } from "@/lib/request";
|
||||||
import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphql"
|
import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphql";
|
||||||
|
|
||||||
import Aside from "@/components/Current/Aside"
|
import Aside from "@/components/Current/Aside"
|
||||||
import Blocks from "@/components/Current/Blocks"
|
import Blocks from "@/components/Current/Blocks"
|
||||||
@@ -23,10 +23,13 @@ export default async function CurrentContentPage({
|
|||||||
throw new Error("Bad URI")
|
throw new Error("Bad URI")
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await request<GetCurrentBlockPageData>(GetCurrentBlockPage, {
|
const response = await request<GetCurrentBlockPageData>(
|
||||||
locale: params.lang,
|
GetCurrentBlockPage,
|
||||||
url: searchParams.uri,
|
{
|
||||||
})
|
locale: params.lang,
|
||||||
|
url: searchParams.uri,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (!response.data?.all_current_blocks_page?.total) {
|
if (!response.data?.all_current_blocks_page?.total) {
|
||||||
console.log("#### DATA ####")
|
console.log("#### DATA ####")
|
||||||
@@ -44,13 +47,18 @@ export default async function CurrentContentPage({
|
|||||||
<>
|
<>
|
||||||
<Header lang={params.lang} pathname={searchParams.uri} />
|
<Header lang={params.lang} pathname={searchParams.uri} />
|
||||||
{images?.totalCount ? <Hero images={images.edges} /> : null}
|
{images?.totalCount ? <Hero images={images.edges} /> : null}
|
||||||
<main
|
<main className="main l-sections-wrapper" id="maincontent" role="main">
|
||||||
className="main l-sections-wrapper"
|
<input
|
||||||
id="maincontent"
|
id="lbl-personalized-areas"
|
||||||
role="main"
|
name="lbl-personalized-areas"
|
||||||
>
|
type="hidden"
|
||||||
<input id="lbl-personalized-areas" name="lbl-personalized-areas" type="hidden" value="" />
|
value=""
|
||||||
<SubnavMobile breadcrumbs={breadcrumbs} parent={parent} title={page.breadcrumbs.title} />
|
/>
|
||||||
|
<SubnavMobile
|
||||||
|
breadcrumbs={breadcrumbs}
|
||||||
|
parent={parent}
|
||||||
|
title={page.breadcrumbs.title}
|
||||||
|
/>
|
||||||
<Preamble
|
<Preamble
|
||||||
breadcrumbs={breadcrumbs}
|
breadcrumbs={breadcrumbs}
|
||||||
breadcrumbParent={parent}
|
breadcrumbParent={parent}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../core.css";
|
import "../../core.css";
|
||||||
import "../scandic.css";
|
import "../../scandic.css";
|
||||||
|
|
||||||
import Footer from "@/components/Current/Footer";
|
import Footer from "@/components/Current/Footer";
|
||||||
import LangPopup from "@/components/Current/LangPopup";
|
import LangPopup from "@/components/Current/LangPopup";
|
||||||
9
app/[lang]/(preview)/error.tsx
Normal file
9
app/[lang]/(preview)/error.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
export default function Error({ error }: { error: Error }) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>Something went wrong!</h2>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
55
app/[lang]/(preview)/layout.tsx
Normal file
55
app/[lang]/(preview)/layout.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import "../../core.css";
|
||||||
|
import "../../scandic.css";
|
||||||
|
|
||||||
|
import Footer from "@/components/Current/Footer";
|
||||||
|
import LangPopup from "@/components/Current/LangPopup";
|
||||||
|
import Script from "next/script";
|
||||||
|
import SkipToMainContent from "@/components/SkipToMainContent";
|
||||||
|
|
||||||
|
import type { Metadata } from "next";
|
||||||
|
import type { LangParams, LayoutArgs } from "@/types/params";
|
||||||
|
import InitLivePreview from "@/components/Current/LivePreview";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
description: "New web",
|
||||||
|
title: "Scandic Hotels New Web",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
params,
|
||||||
|
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
||||||
|
return (
|
||||||
|
<html lang={params.lang}>
|
||||||
|
<head>
|
||||||
|
<Script
|
||||||
|
data-cookieconsent="ignore"
|
||||||
|
src="/Static/dist/js/inline.js?00133e5a37de35c51a5d"
|
||||||
|
/>
|
||||||
|
<Script
|
||||||
|
data-cookieconsent="ignore"
|
||||||
|
src="/Static/dist/js/main.js?89d0030e1a04b3b46d0b"
|
||||||
|
/>
|
||||||
|
<Script
|
||||||
|
data-cookieconsent="ignore"
|
||||||
|
src="/Static/dist/js/ng/polyfills.js?1705409330990"
|
||||||
|
/>
|
||||||
|
<Script
|
||||||
|
data-cookieconsent="ignore"
|
||||||
|
src="/Static/dist/js/ng/runtime.js?1705409330990"
|
||||||
|
/>
|
||||||
|
<Script
|
||||||
|
data-cookieconsent="ignore"
|
||||||
|
src="/Static/dist/js/ng/main.js?1705409330990"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<InitLivePreview />
|
||||||
|
<LangPopup lang={params.lang} />
|
||||||
|
<SkipToMainContent lang={params.lang} />
|
||||||
|
{children}
|
||||||
|
<Footer lang={params.lang} />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)
|
||||||
|
}
|
||||||
8
app/[lang]/(preview)/not-found.tsx
Normal file
8
app/[lang]/(preview)/not-found.tsx
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export default function NotFound() {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<h2>Not Found</h2>
|
||||||
|
<p>Could not find requested resource</p>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
58
app/[lang]/(preview)/preview/page.tsx
Normal file
58
app/[lang]/(preview)/preview/page.tsx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
|
import { previewRequest } from "@/lib/previewRequest"
|
||||||
|
import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphql"
|
||||||
|
|
||||||
|
import Aside from "@/components/Current/Aside"
|
||||||
|
import Blocks from "@/components/Current/Blocks"
|
||||||
|
import Header from "@/components/Current/Header"
|
||||||
|
import Hero from "@/components/Current/Hero"
|
||||||
|
|
||||||
|
import type { PageArgs, LangParams, UriParams } from "@/types/params"
|
||||||
|
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
|
||||||
|
import ContentstackLivePreview from "@contentstack/live-preview-utils"
|
||||||
|
import LoadingPreview from "@/components/Current/LoadingPreview"
|
||||||
|
|
||||||
|
export default async function CurrentContentPage({
|
||||||
|
params,
|
||||||
|
searchParams,
|
||||||
|
}: PageArgs<LangParams, UriParams>) {
|
||||||
|
try {
|
||||||
|
ContentstackLivePreview.setConfigFromParams(searchParams)
|
||||||
|
|
||||||
|
if (!searchParams.uri) {
|
||||||
|
return <LoadingPreview />
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await previewRequest<GetCurrentBlockPageData>(
|
||||||
|
GetCurrentBlockPage,
|
||||||
|
{ locale: params.lang, uid: searchParams.uri }
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!response.data?.all_current_blocks_page?.total) {
|
||||||
|
console.log("#### DATA ####")
|
||||||
|
console.log(response.data)
|
||||||
|
console.log("SearchParams URI: ", searchParams.uri)
|
||||||
|
throw new Error("Not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
const page = response.data.all_current_blocks_page.items[0]
|
||||||
|
const images = page.hero?.imagesConnection
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Header lang={params.lang} pathname={searchParams.uri} />
|
||||||
|
{images?.totalCount ? <Hero images={images.edges} /> : null}
|
||||||
|
<main className="main l-sections-wrapper" id="maincontent" role="main">
|
||||||
|
<h1>{page.title}</h1>
|
||||||
|
<Blocks blocks={page.blocks} />
|
||||||
|
<Aside blocks={page.aside} />
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
// TODO: throw 500
|
||||||
|
console.error(error)
|
||||||
|
throw new Error("Something went wrong")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export default async function Home() {
|
|
||||||
return (
|
|
||||||
<main>
|
|
||||||
<h1>Hello world!</h1>
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
14
components/Current/LivePreview/index.tsx
Normal file
14
components/Current/LivePreview/index.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect } from "react"
|
||||||
|
import ContentstackLivePreview from "@contentstack/live-preview-utils"
|
||||||
|
|
||||||
|
export default function InitLivePreview() {
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ContentstackLivePreview.livePreview) {
|
||||||
|
ContentstackLivePreview.init()
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
22
components/Current/LoadingPreview/index.tsx
Normal file
22
components/Current/LoadingPreview/index.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import styles from "./loading.module.css"
|
||||||
|
|
||||||
|
export default function LoadingPreview() {
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.spinner}>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
90
components/Current/LoadingPreview/loading.module.css
Normal file
90
components/Current/LoadingPreview/loading.module.css
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner div {
|
||||||
|
transform-origin: 40px 40px;
|
||||||
|
animation: spinnerAnimation 1.2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner div::after {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 3px;
|
||||||
|
left: 37px;
|
||||||
|
width: 6px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 20%;
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner div:nth-child(1) {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
animation-delay: -1.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner div:nth-child(2) {
|
||||||
|
transform: rotate(30deg);
|
||||||
|
animation-delay: -1s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(3) {
|
||||||
|
transform: rotate(60deg);
|
||||||
|
animation-delay: -0.9s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(4) {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
animation-delay: -0.8s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(5) {
|
||||||
|
transform: rotate(120deg);
|
||||||
|
animation-delay: -0.7s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(6) {
|
||||||
|
transform: rotate(150deg);
|
||||||
|
animation-delay: -0.6s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(7) {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
animation-delay: -0.5s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(8) {
|
||||||
|
transform: rotate(210deg);
|
||||||
|
animation-delay: -0.4s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(9) {
|
||||||
|
transform: rotate(240deg);
|
||||||
|
animation-delay: -0.3s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(10) {
|
||||||
|
transform: rotate(270deg);
|
||||||
|
animation-delay: -0.2s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(11) {
|
||||||
|
transform: rotate(300deg);
|
||||||
|
animation-delay: -0.1s;
|
||||||
|
}
|
||||||
|
.spinner div:nth-child(12) {
|
||||||
|
transform: rotate(330deg);
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@keyframes spinnerAnimation {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
env/schema.mjs
vendored
6
env/schema.mjs
vendored
@@ -10,6 +10,8 @@ export const serverSchema = z.object({
|
|||||||
CMS_API_KEY: z.string(),
|
CMS_API_KEY: z.string(),
|
||||||
CMS_ENVIRONMENT: z.enum(["development", "production", "staging", "test"]),
|
CMS_ENVIRONMENT: z.enum(["development", "production", "staging", "test"]),
|
||||||
CMS_URL: z.string(),
|
CMS_URL: z.string(),
|
||||||
|
CMS_PREVIEW_URL: z.string(),
|
||||||
|
CMS_PREVIEW_TOKEN: z.string(),
|
||||||
NODE_ENV: z.enum(["development", "test", "production"]),
|
NODE_ENV: z.enum(["development", "test", "production"]),
|
||||||
PRINT_QUERY: z.boolean().default(false),
|
PRINT_QUERY: z.boolean().default(false),
|
||||||
})
|
})
|
||||||
@@ -24,9 +26,11 @@ export const serverEnv = {
|
|||||||
CMS_API_KEY: process.env.CMS_API_KEY,
|
CMS_API_KEY: process.env.CMS_API_KEY,
|
||||||
CMS_ENVIRONMENT: process.env.CMS_ENVIRONMENT,
|
CMS_ENVIRONMENT: process.env.CMS_ENVIRONMENT,
|
||||||
CMS_URL: process.env.CMS_URL,
|
CMS_URL: process.env.CMS_URL,
|
||||||
|
CMS_PREVIEW_URL: process.env.CMS_PREVIEW_URL,
|
||||||
|
CMS_PREVIEW_TOKEN: process.env.CMS_PREVIEW_TOKEN,
|
||||||
NODE_ENV: process.env.NODE_ENV,
|
NODE_ENV: process.env.NODE_ENV,
|
||||||
PRINT_QUERY: process.env.PRINT_QUERY,
|
PRINT_QUERY: process.env.PRINT_QUERY,
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify your client-side environment variables schema here.
|
* Specify your client-side environment variables schema here.
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ query GetCurrentBlockPage($locale: String!, $url: String!) {
|
|||||||
...Preamble
|
...Preamble
|
||||||
title
|
title
|
||||||
url
|
url
|
||||||
|
system {
|
||||||
|
uid
|
||||||
|
content_type_uid
|
||||||
|
}
|
||||||
}
|
}
|
||||||
total
|
total
|
||||||
}
|
}
|
||||||
|
|||||||
39
lib/previewRequest.ts
Normal file
39
lib/previewRequest.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import "server-only";
|
||||||
|
import { request as graphqlRequest } from "graphql-request";
|
||||||
|
|
||||||
|
import { env } from "@/env/server.mjs";
|
||||||
|
|
||||||
|
import type { Data } from "@/types/request";
|
||||||
|
import type { DocumentNode } from "graphql";
|
||||||
|
import ContentstackLivePreview from "@contentstack/live-preview-utils";
|
||||||
|
|
||||||
|
export async function previewRequest<T>(
|
||||||
|
query: string | DocumentNode,
|
||||||
|
variables?: {}
|
||||||
|
): Promise<Data<T>> {
|
||||||
|
try {
|
||||||
|
const hash = ContentstackLivePreview.hash
|
||||||
|
|
||||||
|
if (!hash) {
|
||||||
|
throw new Error("No hash received")
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = new Headers({
|
||||||
|
access_token: env.CMS_ACCESS_TOKEN,
|
||||||
|
preview_token: env.CMS_PREVIEW_TOKEN,
|
||||||
|
live_preview: hash,
|
||||||
|
})
|
||||||
|
|
||||||
|
const response = await graphqlRequest<T>({
|
||||||
|
document: query,
|
||||||
|
requestHeaders: headers,
|
||||||
|
url: env.CMS_PREVIEW_URL,
|
||||||
|
variables,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { data: response }
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
throw new Error("Something went wrong");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import ContentstackLivePreview from "@contentstack/live-preview-utils";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import type { NextRequest } from "next/server";
|
import type { NextRequest } from "next/server";
|
||||||
|
|
||||||
@@ -6,17 +7,17 @@ export async function middleware(request: NextRequest) {
|
|||||||
// const locales = await fetch(CMS_API, {
|
// const locales = await fetch(CMS_API, {
|
||||||
// locales: true
|
// locales: true
|
||||||
// })
|
// })
|
||||||
const locales = ["en", "sv", "no", "fi", "da", "de"];
|
const locales = ["en", "sv", "no", "fi", "da", "de"]
|
||||||
|
|
||||||
const locale = locales.find(
|
const locale = locales.find(
|
||||||
(locale) =>
|
(locale) =>
|
||||||
request.nextUrl.pathname.startsWith(`/${locale}/`) ||
|
request.nextUrl.pathname.startsWith(`/${locale}/`) ||
|
||||||
request.nextUrl.pathname === `/${locale}`
|
request.nextUrl.pathname === `/${locale}`
|
||||||
);
|
)
|
||||||
|
|
||||||
if (!locale) {
|
if (!locale) {
|
||||||
//return <LocalePicker />
|
//return <LocalePicker />
|
||||||
return Response.json("Not found!!!", { status: 404 });
|
return Response.json("Not found!!!", { status: 404 })
|
||||||
}
|
}
|
||||||
|
|
||||||
// const data = await fetch(CMS_API, {
|
// const data = await fetch(CMS_API, {
|
||||||
@@ -25,14 +26,23 @@ export async function middleware(request: NextRequest) {
|
|||||||
// }).json()
|
// }).json()
|
||||||
|
|
||||||
//const contentType = data.response.meta.contentType;
|
//const contentType = data.response.meta.contentType;
|
||||||
const contentType = "currentContentPage";
|
const contentType = "currentContentPage"
|
||||||
|
|
||||||
const pathNameWithoutLocale = request.nextUrl.pathname.replace(
|
const pathNameWithoutLocale = request.nextUrl.pathname.replace(
|
||||||
`/${locale}`,
|
`/${locale}`,
|
||||||
""
|
""
|
||||||
);
|
)
|
||||||
|
|
||||||
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
||||||
|
|
||||||
|
if (request.nextUrl.pathname.includes("preview")) {
|
||||||
|
searchParams.set("uri", pathNameWithoutLocale.replace("/preview", ""))
|
||||||
|
|
||||||
|
return NextResponse.rewrite(
|
||||||
|
new URL(`/${locale}/preview?${searchParams.toString()}`, request.url)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
searchParams.set("uri", pathNameWithoutLocale)
|
searchParams.set("uri", pathNameWithoutLocale)
|
||||||
|
|
||||||
switch (contentType) {
|
switch (contentType) {
|
||||||
@@ -42,9 +52,9 @@ export async function middleware(request: NextRequest) {
|
|||||||
`/${locale}/current-content-page?${searchParams.toString()}`,
|
`/${locale}/current-content-page?${searchParams.toString()}`,
|
||||||
request.url
|
request.url
|
||||||
)
|
)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
return NextResponse.redirect(new URL("/home", request.url));
|
return NextResponse.redirect(new URL("/home", request.url))
|
||||||
}
|
}
|
||||||
|
|
||||||
// See "Matching Paths" below to learn more
|
// See "Matching Paths" below to learn more
|
||||||
|
|||||||
38
package-lock.json
generated
38
package-lock.json
generated
@@ -8,6 +8,7 @@
|
|||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@contentstack/live-preview-utils": "^1.4.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"graphql": "16.8.1",
|
"graphql": "16.8.1",
|
||||||
"graphql-request": "6.1.0",
|
"graphql-request": "6.1.0",
|
||||||
@@ -51,6 +52,17 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@contentstack/live-preview-utils": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@contentstack/live-preview-utils/-/live-preview-utils-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-74N9ACoUwSrvmbtqoy8CkX7H/OmA3cjnOmaKMq6qoVI1r9kJjO+gqQevBPxs17nurbNL2XjXU56hbHZagWL4nw==",
|
||||||
|
"dependencies": {
|
||||||
|
"just-camel-case": "^4.0.2",
|
||||||
|
"morphdom": "^2.6.1",
|
||||||
|
"mustache": "^4.2.0",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
@@ -2498,6 +2510,11 @@
|
|||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/just-camel-case": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/just-camel-case/-/just-camel-case-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-df6QI/EIq+6uHe/wtaa9Qq7/pp4wr4pJC/r1+7XhVL6m5j03G6h9u9/rIZr8rDASX7CxwDPQnZjffCo2e6PRLw=="
|
||||||
|
},
|
||||||
"node_modules/keyv": {
|
"node_modules/keyv": {
|
||||||
"version": "4.5.4",
|
"version": "4.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||||
@@ -2625,12 +2642,25 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/morphdom": {
|
||||||
|
"version": "2.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.2.tgz",
|
||||||
|
"integrity": "sha512-Dqb/lHFyTi7SZpY0a5R4I/0Edo+iPMbaUexsHHsLAByyixCDiLHPHyVoKVmrpL0THcT7V9Cgev9y21TQYq6wQg=="
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/mustache": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
|
||||||
|
"bin": {
|
||||||
|
"mustache": "bin/mustache"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.7",
|
"version": "3.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||||
@@ -3681,6 +3711,14 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
|
"@contentstack/live-preview-utils": "^1.4.0",
|
||||||
"graphql": "16.8.1",
|
"graphql": "16.8.1",
|
||||||
"graphql-request": "6.1.0",
|
"graphql-request": "6.1.0",
|
||||||
"graphql-tag": "2.12.6",
|
"graphql-tag": "2.12.6",
|
||||||
|
|||||||
Reference in New Issue
Block a user