bsmnt 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/add-integration/index.d.ts +24 -6
- package/dist/application/add-integration/index.d.ts.map +1 -1
- package/dist/application/add-integration/index.js +130 -82
- package/dist/application/add-integration/index.js.map +1 -1
- package/dist/application/create-project/map-selection-to-registry.js +1 -1
- package/dist/application/create-project/map-selection-to-registry.js.map +1 -1
- package/dist/application/shared/project-detection.d.ts +2 -2
- package/dist/application/shared/project-detection.d.ts.map +1 -1
- package/dist/application/shared/project-detection.js +2 -2
- package/dist/application/shared/project-detection.js.map +1 -1
- package/dist/core/create/internal-ids.d.ts +4 -1
- package/dist/core/create/internal-ids.d.ts.map +1 -1
- package/dist/core/create/internal-ids.js +6 -1
- package/dist/core/create/internal-ids.js.map +1 -1
- package/dist/domain/cms.d.ts +0 -7
- package/dist/domain/cms.d.ts.map +1 -1
- package/dist/domain/cms.js.map +1 -1
- package/dist/domain/forms.d.ts +17 -0
- package/dist/domain/forms.d.ts.map +1 -0
- package/dist/domain/forms.js +13 -0
- package/dist/domain/forms.js.map +1 -0
- package/dist/domain/integration.d.ts +30 -0
- package/dist/domain/integration.d.ts.map +1 -0
- package/dist/domain/integration.js +12 -0
- package/dist/domain/integration.js.map +1 -0
- package/dist/domain/skills.d.ts +32 -0
- package/dist/domain/skills.d.ts.map +1 -1
- package/dist/domain/skills.js +39 -0
- package/dist/domain/skills.js.map +1 -1
- package/dist/index.js +95 -37
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/agents/register-sanity-mcp.js +9 -6
- package/dist/infrastructure/agents/register-sanity-mcp.js.map +1 -1
- package/dist/infrastructure/create/apply-package-json.d.ts.map +1 -1
- package/dist/infrastructure/create/apply-package-json.js +19 -0
- package/dist/infrastructure/create/apply-package-json.js.map +1 -1
- package/dist/infrastructure/create/install-dependencies.d.ts.map +1 -1
- package/dist/infrastructure/create/install-dependencies.js +4 -0
- package/dist/infrastructure/create/install-dependencies.js.map +1 -1
- package/dist/infrastructure/create/merge-registry.d.ts.map +1 -1
- package/dist/infrastructure/create/merge-registry.js +8 -0
- package/dist/infrastructure/create/merge-registry.js.map +1 -1
- package/dist/infrastructure/create/setup-agent.d.ts.map +1 -1
- package/dist/infrastructure/create/setup-agent.js +29 -6
- package/dist/infrastructure/create/setup-agent.js.map +1 -1
- package/dist/infrastructure/create/setup-sanity.d.ts.map +1 -1
- package/dist/infrastructure/create/setup-sanity.js +3 -0
- package/dist/infrastructure/create/setup-sanity.js.map +1 -1
- package/dist/infrastructure/integrations/inject-integration.d.ts +3 -3
- package/dist/infrastructure/integrations/inject-integration.d.ts.map +1 -1
- package/dist/infrastructure/integrations/inject-integration.js +81 -37
- package/dist/infrastructure/integrations/inject-integration.js.map +1 -1
- package/dist/modules/features/cms/sanity/config.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity/config.js +11 -5
- package/dist/modules/features/cms/sanity/config.js.map +1 -1
- package/dist/modules/features/cms/sanity/index.js +8 -2
- package/dist/modules/features/cms/sanity/index.js.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.d.ts +13 -0
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.d.ts.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.js +38 -0
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.js.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/knip.d.ts +12 -0
- package/dist/modules/features/cms/sanity/mergers/knip.d.ts.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/knip.js +38 -0
- package/dist/modules/features/cms/sanity/mergers/knip.js.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/layout.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/layout.js +7 -3
- package/dist/modules/features/cms/sanity/mergers/layout.js.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts +3 -3
- package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/sitemap.js +48 -62
- package/dist/modules/features/cms/sanity/mergers/sitemap.js.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder/config.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder/config.js +8 -5
- package/dist/modules/features/cms/sanity-pagebuilder/config.js.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder/index.js +2 -2
- package/dist/modules/features/cms/sanity-pagebuilder/index.js.map +1 -1
- package/dist/modules/features/forms/hubspot/config.d.ts +31 -0
- package/dist/modules/features/forms/hubspot/config.d.ts.map +1 -0
- package/dist/modules/features/forms/hubspot/config.js +25 -0
- package/dist/modules/features/forms/hubspot/config.js.map +1 -0
- package/dist/paths.d.ts +8 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +8 -0
- package/dist/paths.js.map +1 -1
- package/index.js +2 -2
- package/package.json +17 -9
- package/src/assets/check-node-version.mjs +22 -0
- package/src/modules/features/cms/sanity/files/app/blog/page.tsx +54 -0
- package/src/modules/features/cms/sanity/files/app/feed.xml/route.ts +36 -0
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/components/disable-draft-mode.tsx +3 -3
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/schemas/article.ts +7 -7
- package/src/modules/features/cms/sanity/files/lib/scripts/setup-ci-secrets.ts +117 -0
- package/src/modules/features/cms/sanity/files/lib/utils/rss.ts +96 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/.knip.json +8 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/[[...slug]]/route.ts +100 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/draft-mode/disable/route.ts +7 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/draft-mode/enable/route.ts +20 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/revalidate/route.ts +126 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/feed.xml/route.ts +40 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/sitemap.md/route.ts +124 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/studio/[[...tool]]/page.tsx +8 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/draft-mode-toggle.tsx +27 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/rich-text.tsx +87 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/visual-editing.tsx +28 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/ui/sanity-image/index.tsx +41 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/check-integration.ts +5 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/client.ts +27 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/disable-draft-mode.tsx +23 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/page-builder-input.tsx +39 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/page-category-input.tsx +50 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/slug-field.tsx +18 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/slug-input.tsx +14 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/confirm-publish-action.ts +40 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/env.ts +34 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/fetchers/layout.ts +48 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/fetchers/redirects.ts +17 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/icons.ts +62 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/live/index.tsx +88 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/markdown-proxy.config.ts +50 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-builder-config.ts +130 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-category.ts +28 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-tree-pane.tsx +420 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/pinned-pages.ts +54 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/presentation.ts +119 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/queries.ts +385 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/sanity.cli.ts +29 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/sanity.config.ts +113 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/index.ts +4 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/reusable/blog-content.ts +89 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/reusable/description.ts +29 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/reusable/hero.ts +28 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/singleton/content-collection.ts +45 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/content/author.ts +70 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/content/blog-category.ts +55 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/index.ts +96 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/company-data.ts +62 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/footer.ts +79 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/navbar.ts +75 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/redirect.ts +120 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/link.ts +125 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/logo-field.ts +9 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/metadata.ts +68 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/nav-objects.ts +192 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page-builder.ts +39 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page-folder.ts +124 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page.ts +242 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/richText.ts +63 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/singletons.ts +39 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/structure.ts +330 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/utils/image.ts +8 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/utils/link.ts +140 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/utils/page-builder-markdown.ts +81 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/scripts/sanity-typegen.ts +45 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/check-redirect.ts +30 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/json-ld.tsx +212 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/metadata.ts +167 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/rss.ts +96 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/sitemap.ts +40 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/proxy.ts +81 -0
- package/src/templates/next-default/.github/workflows/ci.yml +62 -0
- package/src/templates/next-default/README.md +22 -0
- package/src/templates/next-default/knip.json +14 -0
- package/src/templates/next-default/lefthook.yml +5 -0
- package/src/templates/next-default/package.json +8 -4
- package/src/templates/next-experiments/.github/workflows/ci.yml +62 -0
- package/src/templates/next-experiments/README.md +22 -0
- package/src/templates/next-experiments/knip.json +14 -0
- package/src/templates/next-experiments/lefthook.yml +30 -0
- package/src/templates/next-experiments/package.json +10 -2
- package/src/templates/next-pagebuilder/.github/workflows/ci.yml +70 -0
- package/src/templates/next-pagebuilder/README.md +34 -0
- package/src/templates/next-pagebuilder/app/(content)/[[...slug]]/page.tsx +6 -1
- package/src/templates/next-pagebuilder/app/(content)/layout.tsx +3 -12
- package/src/templates/next-pagebuilder/components/layout/footer/index.tsx +11 -10
- package/src/templates/next-pagebuilder/components/layout/header/index.tsx +5 -3
- package/src/templates/next-pagebuilder/components/layout/json-ld/index.tsx +9 -10
- package/src/templates/next-pagebuilder/components/layout/wrapper/index.tsx +3 -11
- package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/index.tsx +1 -1
- package/src/templates/next-pagebuilder/knip.json +27 -0
- package/src/templates/next-pagebuilder/lefthook.yml +5 -0
- package/src/templates/next-pagebuilder/lib/scripts/setup-ci-secrets.ts +117 -0
- package/src/templates/next-pagebuilder/package.json +9 -3
- package/src/templates/next-webgl/.github/workflows/ci.yml +62 -0
- package/src/templates/next-webgl/README.md +22 -0
- package/src/templates/next-webgl/knip.json +13 -0
- package/src/templates/next-webgl/lefthook.yml +5 -0
- package/src/templates/next-webgl/package.json +8 -4
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
import { JsonLd } from "@/components/layout/json-ld"
|
|
2
2
|
import { Wrapper } from "@/components/layout/wrapper"
|
|
3
3
|
import { SanityVisualEditing } from "@/components/sanity/visual-editing"
|
|
4
|
-
import { getSiteLayoutData } from "@/lib/integrations/sanity/fetchers/layout"
|
|
5
|
-
|
|
6
|
-
const Layout = async ({ children }: { children: React.ReactNode }) => {
|
|
7
|
-
const layoutData = await getSiteLayoutData()
|
|
8
4
|
|
|
5
|
+
const Layout = ({ children }: { children: React.ReactNode }) => {
|
|
9
6
|
return (
|
|
10
7
|
<>
|
|
11
|
-
<JsonLd
|
|
12
|
-
<Wrapper
|
|
13
|
-
navbar={layoutData.navbar}
|
|
14
|
-
footer={layoutData.footer}
|
|
15
|
-
companyData={layoutData.companyData}
|
|
16
|
-
>
|
|
17
|
-
{children}
|
|
18
|
-
</Wrapper>
|
|
8
|
+
<JsonLd />
|
|
9
|
+
<Wrapper>{children}</Wrapper>
|
|
19
10
|
<SanityVisualEditing />
|
|
20
11
|
</>
|
|
21
12
|
)
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { Link } from "@/components/ui/link"
|
|
2
2
|
import { SanityImage } from "@/components/ui/sanity-image"
|
|
3
|
-
import
|
|
4
|
-
CompanyData,
|
|
5
|
-
FooterData,
|
|
3
|
+
import {
|
|
4
|
+
type CompanyData,
|
|
5
|
+
type FooterData,
|
|
6
|
+
getCompanyData,
|
|
7
|
+
getFooterData,
|
|
6
8
|
} from "@/lib/integrations/sanity/fetchers/layout"
|
|
7
9
|
|
|
8
10
|
type FooterLinkGroup = NonNullable<FooterData["links"]>[number]
|
|
9
11
|
type FooterLinkItem = NonNullable<FooterLinkGroup["items"]>[number]
|
|
10
12
|
type SocialLink = NonNullable<CompanyData["socialLinks"]>[number]
|
|
11
13
|
|
|
12
|
-
export const Footer = ({
|
|
13
|
-
footer,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}) => {
|
|
14
|
+
export const Footer = async () => {
|
|
15
|
+
const [footer, companyData] = await Promise.all([
|
|
16
|
+
getFooterData(),
|
|
17
|
+
getCompanyData(),
|
|
18
|
+
])
|
|
19
|
+
|
|
19
20
|
const links = footer?.links ?? []
|
|
20
21
|
|
|
21
22
|
return (
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { getNavbarData } from "@/lib/integrations/sanity/fetchers/layout"
|
|
2
2
|
import { HeaderClient } from "./header-client"
|
|
3
3
|
|
|
4
|
-
export const Header = (
|
|
5
|
-
|
|
4
|
+
export const Header = async () => {
|
|
5
|
+
const navbar = await getNavbarData()
|
|
6
|
+
|
|
7
|
+
return <HeaderClient data={navbar} />
|
|
6
8
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { stegaClean } from "next-sanity"
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
getCompanyData,
|
|
4
|
+
getNavbarData,
|
|
5
5
|
} from "@/lib/integrations/sanity/fetchers/layout"
|
|
6
6
|
import {
|
|
7
7
|
generateOrganizationJsonLd,
|
|
@@ -12,13 +12,12 @@ import {
|
|
|
12
12
|
const APP_DESCRIPTION =
|
|
13
13
|
"Basement is the AI-native platform for audit and advisory firms. Automate engagement workflows using AI agents trusted by 50% of top 100 firms."
|
|
14
14
|
|
|
15
|
-
export const JsonLd = ({
|
|
16
|
-
navbar,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}) => {
|
|
15
|
+
export const JsonLd = async () => {
|
|
16
|
+
const [navbar, companyData] = await Promise.all([
|
|
17
|
+
getNavbarData(),
|
|
18
|
+
getCompanyData(),
|
|
19
|
+
])
|
|
20
|
+
|
|
22
21
|
const sameAs = companyData?.socialLinks
|
|
23
22
|
?.map((link) => stegaClean(link.url))
|
|
24
23
|
.filter((url): url is string => Boolean(url))
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import Link from "next/link"
|
|
2
2
|
import { Footer } from "@/components/layout/footer"
|
|
3
3
|
import { Header } from "@/components/layout/header"
|
|
4
|
-
import type { SiteLayoutData } from "@/lib/integrations/sanity/fetchers/layout"
|
|
5
4
|
import { cn } from "@/lib/styles/cn"
|
|
6
5
|
|
|
7
|
-
interface WrapperProps
|
|
8
|
-
extends React.HTMLAttributes<HTMLDivElement>,
|
|
9
|
-
SiteLayoutData {}
|
|
10
|
-
|
|
11
6
|
const SkipToMainContent = () => (
|
|
12
7
|
<Link
|
|
13
8
|
href="#main-content"
|
|
@@ -20,14 +15,11 @@ const SkipToMainContent = () => (
|
|
|
20
15
|
export const Wrapper = ({
|
|
21
16
|
children,
|
|
22
17
|
className,
|
|
23
|
-
navbar,
|
|
24
|
-
footer,
|
|
25
|
-
companyData,
|
|
26
18
|
...props
|
|
27
|
-
}:
|
|
19
|
+
}: React.HTMLAttributes<HTMLDivElement>) => (
|
|
28
20
|
<>
|
|
29
21
|
<SkipToMainContent />
|
|
30
|
-
<Header
|
|
22
|
+
<Header />
|
|
31
23
|
<main
|
|
32
24
|
id="main-content"
|
|
33
25
|
className={cn("relative flex grow flex-col", className)}
|
|
@@ -35,6 +27,6 @@ export const Wrapper = ({
|
|
|
35
27
|
>
|
|
36
28
|
{children}
|
|
37
29
|
</main>
|
|
38
|
-
<Footer
|
|
30
|
+
<Footer />
|
|
39
31
|
</>
|
|
40
32
|
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/knip@6/schema.json",
|
|
3
|
+
"entry": [
|
|
4
|
+
"lib/integrations/sanity/**/*.{ts,tsx}",
|
|
5
|
+
"lib/scripts/**/*.{ts,tsx}",
|
|
6
|
+
"lib/utils/**/*.{ts,tsx}",
|
|
7
|
+
"components/**/*.{ts,tsx}",
|
|
8
|
+
"app/actions/**/*.{ts,tsx}"
|
|
9
|
+
],
|
|
10
|
+
"ignoreDependencies": [
|
|
11
|
+
"zod",
|
|
12
|
+
"react-use",
|
|
13
|
+
"@portabletext/types",
|
|
14
|
+
"@portabletext/react",
|
|
15
|
+
"@portabletext/markdown",
|
|
16
|
+
"@sanity/vision",
|
|
17
|
+
"@sanity/visual-editing",
|
|
18
|
+
"@sanity/ui",
|
|
19
|
+
"@svgr/webpack",
|
|
20
|
+
"postcss-functions",
|
|
21
|
+
"clsx",
|
|
22
|
+
"rxjs"
|
|
23
|
+
],
|
|
24
|
+
"ignoreBinaries": [
|
|
25
|
+
"gh"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push CI environment to GitHub Actions for this repository.
|
|
3
|
+
*
|
|
4
|
+
* Reads values from `.env.local` and sets them on the current repo via the
|
|
5
|
+
* GitHub CLI (`gh`), matching the `build` step in `.github/workflows/ci.yml`:
|
|
6
|
+
* the public Sanity project ID and dataset become repository *variables*, and
|
|
7
|
+
* the read token becomes a *secret*.
|
|
8
|
+
*
|
|
9
|
+
* Run once the repo exists on GitHub: `bun run ci:secrets`
|
|
10
|
+
* Requires the GitHub CLI, authenticated (`gh auth login`).
|
|
11
|
+
*/
|
|
12
|
+
import { execFileSync } from "node:child_process"
|
|
13
|
+
import { existsSync, readFileSync } from "node:fs"
|
|
14
|
+
import path from "node:path"
|
|
15
|
+
|
|
16
|
+
const ENV_FILE = ".env.local"
|
|
17
|
+
|
|
18
|
+
/** Public config — stored as GitHub Actions repository variables. */
|
|
19
|
+
const VARIABLES = [
|
|
20
|
+
"NEXT_PUBLIC_SANITY_PROJECT_ID",
|
|
21
|
+
"NEXT_PUBLIC_SANITY_DATASET",
|
|
22
|
+
] as const
|
|
23
|
+
|
|
24
|
+
/** Sensitive config — stored as GitHub Actions secrets. */
|
|
25
|
+
const SECRETS = ["SANITY_API_READ_TOKEN"] as const
|
|
26
|
+
|
|
27
|
+
function parseEnvFile(file: string): Record<string, string> {
|
|
28
|
+
const env: Record<string, string> = {}
|
|
29
|
+
if (!existsSync(file)) return env
|
|
30
|
+
|
|
31
|
+
for (const rawLine of readFileSync(file, "utf8").split("\n")) {
|
|
32
|
+
const line = rawLine.trim()
|
|
33
|
+
if (!line || line.startsWith("#")) continue
|
|
34
|
+
|
|
35
|
+
const eq = line.indexOf("=")
|
|
36
|
+
if (eq === -1) continue
|
|
37
|
+
|
|
38
|
+
const key = line.slice(0, eq).trim()
|
|
39
|
+
let value = line.slice(eq + 1).trim()
|
|
40
|
+
if (
|
|
41
|
+
(value.startsWith('"') && value.endsWith('"')) ||
|
|
42
|
+
(value.startsWith("'") && value.endsWith("'"))
|
|
43
|
+
) {
|
|
44
|
+
value = value.slice(1, -1)
|
|
45
|
+
}
|
|
46
|
+
env[key] = value
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return env
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function ensureGitHubRepo(): void {
|
|
53
|
+
try {
|
|
54
|
+
execFileSync("gh", ["--version"], { stdio: "pipe" })
|
|
55
|
+
} catch {
|
|
56
|
+
console.error(
|
|
57
|
+
"✖ GitHub CLI (gh) not found. Install it: https://cli.github.com",
|
|
58
|
+
)
|
|
59
|
+
process.exit(1)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
execFileSync("gh", ["repo", "view", "--json", "nameWithOwner"], {
|
|
64
|
+
stdio: "pipe",
|
|
65
|
+
})
|
|
66
|
+
} catch {
|
|
67
|
+
console.error("✖ No GitHub repository detected for this directory.")
|
|
68
|
+
console.error(
|
|
69
|
+
" Create and push the repo first (e.g. `gh repo create`), then re-run.",
|
|
70
|
+
)
|
|
71
|
+
process.exit(1)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
ensureGitHubRepo()
|
|
76
|
+
|
|
77
|
+
const env = parseEnvFile(path.resolve(ENV_FILE))
|
|
78
|
+
let pushed = 0
|
|
79
|
+
let skipped = 0
|
|
80
|
+
|
|
81
|
+
for (const name of VARIABLES) {
|
|
82
|
+
const value = env[name] ?? process.env[name]
|
|
83
|
+
if (!value) {
|
|
84
|
+
console.info(`- ${name}: not found in ${ENV_FILE}, skipping`)
|
|
85
|
+
skipped++
|
|
86
|
+
continue
|
|
87
|
+
}
|
|
88
|
+
// Public value — safe to pass on the command line.
|
|
89
|
+
execFileSync("gh", ["variable", "set", name, "--body", value], {
|
|
90
|
+
stdio: "pipe",
|
|
91
|
+
})
|
|
92
|
+
console.info(`✓ variable ${name}`)
|
|
93
|
+
pushed++
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const name of SECRETS) {
|
|
97
|
+
const value = env[name] ?? process.env[name]
|
|
98
|
+
if (!value) {
|
|
99
|
+
console.info(`- ${name}: not found in ${ENV_FILE}, skipping`)
|
|
100
|
+
skipped++
|
|
101
|
+
continue
|
|
102
|
+
}
|
|
103
|
+
// Sensitive — pipe via stdin so the token never appears in the process args.
|
|
104
|
+
execFileSync("gh", ["secret", "set", name], { input: value, stdio: "pipe" })
|
|
105
|
+
console.info(`✓ secret ${name}`)
|
|
106
|
+
pushed++
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (pushed === 0) {
|
|
110
|
+
console.info(
|
|
111
|
+
`\nNothing to sync. Add your Sanity values to ${ENV_FILE} (or run Sanity setup) first.`,
|
|
112
|
+
)
|
|
113
|
+
} else {
|
|
114
|
+
console.info(
|
|
115
|
+
`\nDone — ${String(pushed)} value(s) pushed to GitHub Actions${skipped ? `, ${String(skipped)} skipped` : ""}.`,
|
|
116
|
+
)
|
|
117
|
+
}
|
|
@@ -3,14 +3,19 @@
|
|
|
3
3
|
"description": "Basement Next.js starter template",
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"private": true,
|
|
6
|
+
"packageManager": "bun@1.3.14",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=24"
|
|
9
|
+
},
|
|
6
10
|
"scripts": {
|
|
7
11
|
"analyze": "cross-env ANALYZE=true bun run build",
|
|
8
12
|
"analyze:experimental": "next experimental-analyze",
|
|
9
13
|
"build": "next build",
|
|
14
|
+
"ci:secrets": "bun ./lib/scripts/setup-ci-secrets.ts",
|
|
10
15
|
"dev": "next dev",
|
|
11
16
|
"format": "biome format --write .",
|
|
12
|
-
"knip": "
|
|
13
|
-
"knip:fix": "
|
|
17
|
+
"knip": "knip",
|
|
18
|
+
"knip:fix": "knip --fix",
|
|
14
19
|
"lighthouse": "bunx @unlighthouse/cli --site http://localhost:3000",
|
|
15
20
|
"lint": "biome lint --max-diagnostics=200",
|
|
16
21
|
"lint:fix": "biome check --write --unsafe --max-diagnostics=200",
|
|
@@ -37,12 +42,13 @@
|
|
|
37
42
|
"@svgr/webpack": "^8.1.0",
|
|
38
43
|
"@tailwindcss/postcss": "^4.2.2",
|
|
39
44
|
"@types/bun": "^1.3.11",
|
|
40
|
-
"@types/node": "^
|
|
45
|
+
"@types/node": "^24.13.1",
|
|
41
46
|
"@types/react": "^19.2.14",
|
|
42
47
|
"@types/react-dom": "^19.2.3",
|
|
43
48
|
"@typescript/native-preview": "^7.0.0-dev.20260323.1",
|
|
44
49
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
45
50
|
"cross-env": "^10.1.0",
|
|
51
|
+
"knip": "^6.16.1",
|
|
46
52
|
"lefthook": "^1.13.0",
|
|
47
53
|
"postcss-functions": "^4.0.2",
|
|
48
54
|
"postcss-preset-env": "^11.2.0",
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
ci:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
# Node version is read from .nvmrc — the single source of truth.
|
|
20
|
+
- name: Setup Node
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version-file: ".nvmrc"
|
|
24
|
+
|
|
25
|
+
# Bun version is read from package.json's "packageManager" field — the
|
|
26
|
+
# single source of truth. Do NOT pin a version here, or the two can drift.
|
|
27
|
+
- name: Setup Bun
|
|
28
|
+
uses: oven-sh/setup-bun@v2
|
|
29
|
+
|
|
30
|
+
# Cache Bun's global install cache so dependencies aren't re-downloaded
|
|
31
|
+
# on every run. Keyed on the lockfile so it busts when deps change.
|
|
32
|
+
- name: Cache Bun dependencies
|
|
33
|
+
uses: actions/cache@v4
|
|
34
|
+
with:
|
|
35
|
+
path: ~/.bun/install/cache
|
|
36
|
+
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
|
|
37
|
+
restore-keys: |
|
|
38
|
+
${{ runner.os }}-bun-
|
|
39
|
+
|
|
40
|
+
- name: Install dependencies
|
|
41
|
+
run: bun install --frozen-lockfile
|
|
42
|
+
|
|
43
|
+
- name: Type check
|
|
44
|
+
run: bun run typecheck:compare
|
|
45
|
+
|
|
46
|
+
- name: Lint
|
|
47
|
+
run: bun run lint
|
|
48
|
+
|
|
49
|
+
- name: Build
|
|
50
|
+
run: bun run build
|
|
51
|
+
|
|
52
|
+
# Runs your tests if any exist; a fresh project with none passes cleanly.
|
|
53
|
+
- name: Test
|
|
54
|
+
run: |
|
|
55
|
+
if git ls-files '*.test.*' '*.spec.*' '*_test.*' '*_spec.*' | grep -q .; then
|
|
56
|
+
bun test
|
|
57
|
+
else
|
|
58
|
+
echo "No test files found — skipping bun test."
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
- name: Knip
|
|
62
|
+
run: bun run knip
|
|
@@ -49,3 +49,25 @@ lib/
|
|
|
49
49
|
- Edit `lib/styles/tokens.css` for theme variables, breakpoints, and custom Tailwind utilities.
|
|
50
50
|
- Edit `lib/styles/global.css` for reset rules and app-wide global styles.
|
|
51
51
|
- `lib/styles/fonts.ts` handles font variables.
|
|
52
|
+
|
|
53
|
+
## Continuous Integration
|
|
54
|
+
|
|
55
|
+
A GitHub Actions workflow (`.github/workflows/ci.yml`) runs on every pull request to `main` and on pushes to `main`. It runs type checking, linting, the production build, tests, and `knip`.
|
|
56
|
+
|
|
57
|
+
The workflow takes its runtime versions from your manifests, so there's a single source of truth and nothing to keep in sync by hand:
|
|
58
|
+
|
|
59
|
+
- **Node** comes from `.nvmrc`.
|
|
60
|
+
- **Bun** comes from the `packageManager` field in `package.json`.
|
|
61
|
+
|
|
62
|
+
It also caches Bun's install cache between runs, and the test step is a no-op until you add real test files.
|
|
63
|
+
|
|
64
|
+
### Branch protection
|
|
65
|
+
|
|
66
|
+
To block merges when CI fails, enable branch protection on `main`:
|
|
67
|
+
|
|
68
|
+
1. Go to **Settings → Branches → Add branch ruleset** (or **Add rule**).
|
|
69
|
+
2. Target the `main` branch.
|
|
70
|
+
3. Enable **Require status checks to pass before merging** and select the **CI** check.
|
|
71
|
+
4. (Recommended) Enable **Require a pull request before merging**.
|
|
72
|
+
|
|
73
|
+
Pull requests then cannot be merged until the CI workflow passes.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/knip@6/schema.json",
|
|
3
|
+
"entry": [
|
|
4
|
+
"lib/scripts/**/*.{ts,tsx}",
|
|
5
|
+
"lib/hooks/**/*.{ts,tsx}",
|
|
6
|
+
"lib/utils/**/*.{ts,tsx}",
|
|
7
|
+
"components/**/*.{ts,tsx}"
|
|
8
|
+
],
|
|
9
|
+
"ignoreDependencies": [
|
|
10
|
+
"zod",
|
|
11
|
+
"@svgr/webpack"
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
"description": "Basement Next.js starter template",
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"private": true,
|
|
6
|
-
"packageManager": "bun@1.3.
|
|
6
|
+
"packageManager": "bun@1.3.14",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=24"
|
|
9
|
+
},
|
|
7
10
|
"scripts": {
|
|
8
11
|
"analyze": "cross-env ANALYZE=true bun run build",
|
|
9
12
|
"analyze:experimental": "next experimental-analyze",
|
|
@@ -12,8 +15,8 @@
|
|
|
12
15
|
"dev:https": "bun ./lib/scripts/dev.ts --https",
|
|
13
16
|
"dev:inspect": "bun ./lib/scripts/dev.ts --inspect",
|
|
14
17
|
"format": "biome format --write .",
|
|
15
|
-
"knip": "
|
|
16
|
-
"knip:fix": "
|
|
18
|
+
"knip": "knip",
|
|
19
|
+
"knip:fix": "knip --fix",
|
|
17
20
|
"lighthouse": "bunx @unlighthouse/cli --site http://localhost:3000",
|
|
18
21
|
"lint": "biome lint --max-diagnostics=200",
|
|
19
22
|
"lint:fix": "biome check --write --unsafe --max-diagnostics=200",
|
|
@@ -42,13 +45,14 @@
|
|
|
42
45
|
"@svgr/webpack": "^8.1.0",
|
|
43
46
|
"@tailwindcss/postcss": "^4",
|
|
44
47
|
"@types/bun": "^1.3.6",
|
|
45
|
-
"@types/node": "^
|
|
48
|
+
"@types/node": "^24.13.1",
|
|
46
49
|
"@types/react": "^19.2.9",
|
|
47
50
|
"@types/react-dom": "^19.2.3",
|
|
48
51
|
"@types/three": "^0.182.0",
|
|
49
52
|
"@typescript/native-preview": "^7.0.0-dev.20260122.3",
|
|
50
53
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
51
54
|
"cross-env": "^10.1.0",
|
|
55
|
+
"knip": "^6.16.1",
|
|
52
56
|
"lefthook": "^1.13.0",
|
|
53
57
|
"postcss-preset-env": "^10.6.1",
|
|
54
58
|
"schema-dts": "^2.0.0",
|