@sntlr/registry-shell 1.0.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/LICENSE +21 -0
- package/README.md +200 -0
- package/dist/adapter/custom.d.ts +47 -0
- package/dist/adapter/custom.js +53 -0
- package/dist/adapter/custom.js.map +1 -0
- package/dist/adapter/default.d.ts +40 -0
- package/dist/adapter/default.js +202 -0
- package/dist/adapter/default.js.map +1 -0
- package/dist/cli/build.d.ts +1 -0
- package/dist/cli/build.js +31 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/dev.d.ts +1 -0
- package/dist/cli/dev.js +26 -0
- package/dist/cli/dev.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.js +49 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +70 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/shared.d.ts +33 -0
- package/dist/cli/shared.js +278 -0
- package/dist/cli/shared.js.map +1 -0
- package/dist/cli/start.d.ts +1 -0
- package/dist/cli/start.js +24 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/config-loader.d.ts +49 -0
- package/dist/config-loader.js +140 -0
- package/dist/define-config.d.ts +188 -0
- package/dist/define-config.js +21 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +9 -0
- package/package.json +124 -0
- package/src/adapter/custom.ts +90 -0
- package/src/adapter/default.ts +241 -0
- package/src/cli/build.ts +38 -0
- package/src/cli/dev.ts +38 -0
- package/src/cli/index.ts +52 -0
- package/src/cli/init.ts +76 -0
- package/src/cli/shared.ts +306 -0
- package/src/cli/start.ts +28 -0
- package/src/config-loader.ts +190 -0
- package/src/define-config.ts +206 -0
- package/src/index.ts +17 -0
- package/src/next-app/app/[...asset]/route.ts +81 -0
- package/src/next-app/app/_user-global.css +6 -0
- package/src/next-app/app/_user-sources.css +9 -0
- package/src/next-app/app/a11y/[name]/route.ts +19 -0
- package/src/next-app/app/api/search-index/route.ts +19 -0
- package/src/next-app/app/components/[name]/page.tsx +61 -0
- package/src/next-app/app/components/layout.tsx +18 -0
- package/src/next-app/app/docs/[slug]/page.tsx +53 -0
- package/src/next-app/app/docs/layout.tsx +18 -0
- package/src/next-app/app/globals.css +329 -0
- package/src/next-app/app/layout.tsx +102 -0
- package/src/next-app/app/page.tsx +9 -0
- package/src/next-app/app/preview-snapshot/[name]/page.tsx +20 -0
- package/src/next-app/app/preview-snapshot/layout.tsx +17 -0
- package/src/next-app/app/props/[name]/route.ts +19 -0
- package/src/next-app/app/r/[name]/route.ts +14 -0
- package/src/next-app/app/tests/[name]/route.ts +19 -0
- package/src/next-app/components/a11y-info.tsx +287 -0
- package/src/next-app/components/a11y-provider.tsx +39 -0
- package/src/next-app/components/component-breadcrumb.tsx +55 -0
- package/src/next-app/components/component-icon.tsx +140 -0
- package/src/next-app/components/component-preview.tsx +13 -0
- package/src/next-app/components/component-tabs.tsx +209 -0
- package/src/next-app/components/docs-toc.tsx +86 -0
- package/src/next-app/components/global-mobile-sidebar.tsx +35 -0
- package/src/next-app/components/header.tsx +188 -0
- package/src/next-app/components/heading-anchor.tsx +52 -0
- package/src/next-app/components/homepage-demo.tsx +180 -0
- package/src/next-app/components/locale-toggle.tsx +35 -0
- package/src/next-app/components/localized-mdx-client.tsx +14 -0
- package/src/next-app/components/localized-mdx.tsx +27 -0
- package/src/next-app/components/mobile-sidebar.tsx +22 -0
- package/src/next-app/components/nav-data-provider.tsx +37 -0
- package/src/next-app/components/navigation-progress.tsx +62 -0
- package/src/next-app/components/preview-canvas.tsx +368 -0
- package/src/next-app/components/preview-controls.tsx +94 -0
- package/src/next-app/components/preview-layout.tsx +218 -0
- package/src/next-app/components/props-table.tsx +134 -0
- package/src/next-app/components/resizable-preview.tsx +101 -0
- package/src/next-app/components/search.tsx +177 -0
- package/src/next-app/components/settings-modal.tsx +98 -0
- package/src/next-app/components/shell-ui/accordion.tsx +70 -0
- package/src/next-app/components/shell-ui/backdrop.tsx +29 -0
- package/src/next-app/components/shell-ui/badge.tsx +55 -0
- package/src/next-app/components/shell-ui/breadcrumb.tsx +120 -0
- package/src/next-app/components/shell-ui/button.tsx +64 -0
- package/src/next-app/components/shell-ui/card.tsx +127 -0
- package/src/next-app/components/shell-ui/checkbox.tsx +33 -0
- package/src/next-app/components/shell-ui/dialog.tsx +171 -0
- package/src/next-app/components/shell-ui/empty-state.tsx +66 -0
- package/src/next-app/components/shell-ui/input.tsx +27 -0
- package/src/next-app/components/shell-ui/kbd.tsx +30 -0
- package/src/next-app/components/shell-ui/label.tsx +25 -0
- package/src/next-app/components/shell-ui/select.tsx +204 -0
- package/src/next-app/components/shell-ui/separator.tsx +32 -0
- package/src/next-app/components/shell-ui/skeleton.tsx +18 -0
- package/src/next-app/components/shell-ui/table.tsx +124 -0
- package/src/next-app/components/shell-ui/tabs.tsx +102 -0
- package/src/next-app/components/shell-ui/toggle.tsx +56 -0
- package/src/next-app/components/sidebar-layout.tsx +37 -0
- package/src/next-app/components/sidebar-provider.tsx +75 -0
- package/src/next-app/components/sidebar.tsx +222 -0
- package/src/next-app/components/snapshot-preview.tsx +28 -0
- package/src/next-app/components/test-info.tsx +155 -0
- package/src/next-app/components/theme-provider.tsx +16 -0
- package/src/next-app/components/theme-toggle.tsx +21 -0
- package/src/next-app/components/translated-text.tsx +8 -0
- package/src/next-app/fallback/homepage.tsx +112 -0
- package/src/next-app/fallback/previews.ts +17 -0
- package/src/next-app/hooks/use-active-section.ts +23 -0
- package/src/next-app/hooks/use-controls.ts +72 -0
- package/src/next-app/hooks/use-mobile.ts +19 -0
- package/src/next-app/lib/branding.ts +52 -0
- package/src/next-app/lib/components-nav.ts +8 -0
- package/src/next-app/lib/docs.ts +16 -0
- package/src/next-app/lib/github.ts +38 -0
- package/src/next-app/lib/i18n.tsx +630 -0
- package/src/next-app/lib/locales.ts +17 -0
- package/src/next-app/lib/preview-loader.ts +7 -0
- package/src/next-app/lib/registry-adapter.ts +199 -0
- package/src/next-app/lib/utils.ts +6 -0
- package/src/next-app/next-env.d.ts +6 -0
- package/src/next-app/next.config.ts +101 -0
- package/src/next-app/postcss.config.mjs +7 -0
- package/src/next-app/public/favicon.ico +0 -0
- package/src/next-app/public/favicon_dark.svg +3 -0
- package/src/next-app/public/favicon_light.svg +3 -0
- package/src/next-app/registry.config.ts +50 -0
- package/src/next-app/tsconfig.json +29 -0
- package/src/next-app/user-aliases.d.ts +17 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from "react"
|
|
2
|
+
|
|
3
|
+
/** One entry in the registry's navigation — a UI component or a block. */
|
|
4
|
+
export interface ComponentMeta {
|
|
5
|
+
/** URL-safe slug, e.g. `"button"` or `"auth-login"`. */
|
|
6
|
+
name: string
|
|
7
|
+
/** Human-readable title, e.g. `"Button"` or `"Auth Login"`. */
|
|
8
|
+
label: string
|
|
9
|
+
/**
|
|
10
|
+
* `"component"` for low-level UI primitives (Button, Dialog), `"block"` for
|
|
11
|
+
* composed screens/patterns (Auth Login, Data Table). Shell groups these
|
|
12
|
+
* into separate sidebar sections.
|
|
13
|
+
*/
|
|
14
|
+
kind: "component" | "block"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Doc page metadata (frontmatter + slug). Drives the docs sidebar. */
|
|
18
|
+
export interface DocMeta {
|
|
19
|
+
/** URL-safe slug, matches the `.mdx` filename without extension. */
|
|
20
|
+
slug: string
|
|
21
|
+
/** Default-locale title (typically English). */
|
|
22
|
+
title: string
|
|
23
|
+
description: string
|
|
24
|
+
/** Sidebar sort order. Lower = higher up. Default 999. */
|
|
25
|
+
order: number
|
|
26
|
+
/** Per-locale titles, e.g. `{ en: "Getting Started", fr: "Démarrage" }`. */
|
|
27
|
+
titles: Record<string, string>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Full MDX body of a doc for one locale, plus its metadata. */
|
|
31
|
+
export interface DocContent {
|
|
32
|
+
meta: Omit<DocMeta, "titles">
|
|
33
|
+
/** Raw MDX string — the shell renders it via `next-mdx-remote`. */
|
|
34
|
+
content: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Renders interactive component previews on the detail pages. The registry
|
|
39
|
+
* owns the dynamic-import map (see `sntlr-registry/components/previews/index.ts`
|
|
40
|
+
* for a reference implementation) because Next.js `dynamic()` needs string
|
|
41
|
+
* literal paths at compile time.
|
|
42
|
+
*/
|
|
43
|
+
export interface PreviewLoader {
|
|
44
|
+
/**
|
|
45
|
+
* Stable wrapper component. Use this in shell code:
|
|
46
|
+
* `<Preview name={compName} fallback={<EmptyState/>} />`. Avoids the
|
|
47
|
+
* `react-hooks/static-components` lint that fires when a component type is
|
|
48
|
+
* looked up inside render.
|
|
49
|
+
*/
|
|
50
|
+
Preview: ComponentType<{ name: string; fallback?: ReactNode }>
|
|
51
|
+
/** All names for which `load()` returns a component. */
|
|
52
|
+
names(): string[]
|
|
53
|
+
/** Low-level lookup. Prefer `Preview`; exposed for edge cases. */
|
|
54
|
+
load(name: string): ComponentType | null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Props the shell passes to an optional custom `HomePage` component. */
|
|
58
|
+
export interface HomePageProps {
|
|
59
|
+
/** Slug of the first doc (lowest `order`), so the homepage can link to it. */
|
|
60
|
+
firstDocSlug?: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Branding displayed in the shell chrome (header, favicon, HTML title) and on
|
|
65
|
+
* the built-in Getting Started landing. Pure data — safe to import from client
|
|
66
|
+
* components.
|
|
67
|
+
*/
|
|
68
|
+
export interface GithubConfig {
|
|
69
|
+
owner: string
|
|
70
|
+
repo: string
|
|
71
|
+
label?: string
|
|
72
|
+
showStars?: boolean
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface BrandingConfig {
|
|
76
|
+
/** Full product name, e.g. `"Scintillar UI"`. Used in HTML title. */
|
|
77
|
+
siteName: string
|
|
78
|
+
/** Short breadcrumb label, e.g. `"UI"`. Shown next to the logo. */
|
|
79
|
+
shortName: string
|
|
80
|
+
/** Canonical URL of the deployed registry, e.g. `"https://ui.sntlr.app"`. */
|
|
81
|
+
siteUrl?: string
|
|
82
|
+
/** SEO description. Used in `<meta name="description">`, OG, Twitter. */
|
|
83
|
+
description?: string
|
|
84
|
+
/** OG image URL (1200×630 recommended). */
|
|
85
|
+
ogImage?: string
|
|
86
|
+
/** Twitter handle without the `@`. */
|
|
87
|
+
twitterHandle?: string
|
|
88
|
+
/** Optional GitHub link button in the header. */
|
|
89
|
+
github?: GithubConfig
|
|
90
|
+
/** Accessible alt text for the logo image. */
|
|
91
|
+
logoAlt?: string
|
|
92
|
+
/** Public path to the dark-theme SVG favicon. */
|
|
93
|
+
faviconDark?: string
|
|
94
|
+
/** Public path to the light-theme SVG favicon. */
|
|
95
|
+
faviconLight?: string
|
|
96
|
+
/** Public path to a fallback `.ico` favicon. */
|
|
97
|
+
faviconIco?: string
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Client-safe slice of a registry — bundles everything the shell renders in
|
|
102
|
+
* the browser (without pulling in the server-only adapter that uses `fs`).
|
|
103
|
+
* Wire this in `ui-registry/registry.client.ts`.
|
|
104
|
+
*
|
|
105
|
+
* A registry package typically exposes this via a `client.ts` module that
|
|
106
|
+
* re-exports `branding`, `previewLoader`, a default `HomePage`, and optional
|
|
107
|
+
* `extraTranslations`. See `sntlr-registry/client.ts` for a reference.
|
|
108
|
+
*/
|
|
109
|
+
export interface RegistryClient {
|
|
110
|
+
branding: BrandingConfig
|
|
111
|
+
previewLoader: PreviewLoader
|
|
112
|
+
/**
|
|
113
|
+
* Optional custom homepage component. When set, the shell's `/` route
|
|
114
|
+
* renders this instead of the built-in Getting Started / generic index.
|
|
115
|
+
* When `undefined`/`null`, the shell uses `GenericIndexPage` (a plain
|
|
116
|
+
* component/block listing).
|
|
117
|
+
*/
|
|
118
|
+
HomePage?: ComponentType<HomePageProps> | null
|
|
119
|
+
/**
|
|
120
|
+
* Locale → key → value dictionaries merged into the shell's i18n table.
|
|
121
|
+
* Use this to ship marketing/homepage copy; the shell owns the generic UI
|
|
122
|
+
* keys (sidebar, header, search, a11y, etc.). Invariant: if `HomePage` is
|
|
123
|
+
* set, this must include every key the homepage references.
|
|
124
|
+
*/
|
|
125
|
+
extraTranslations?: Record<string, Record<string, string>>
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The complete server-side contract the shell consumes. A registry package
|
|
130
|
+
* implements this (typically in `adapter.ts`) and the shell imports the
|
|
131
|
+
* default export via `ui-registry/registry.config.ts`.
|
|
132
|
+
*
|
|
133
|
+
* All filesystem reads, registry-JSON serving, and MDX parsing live here —
|
|
134
|
+
* the shell never touches the registry's files directly. This is what makes
|
|
135
|
+
* the shell swappable across arbitrary registries.
|
|
136
|
+
*/
|
|
137
|
+
export interface RegistryAdapter {
|
|
138
|
+
/**
|
|
139
|
+
* Full list of navigable items (components + blocks). Typically scans the
|
|
140
|
+
* registry's `components/ui` and `registry/STYLE/blocks` folders at build
|
|
141
|
+
* time, where STYLE is e.g. "new-york" or "default".
|
|
142
|
+
*/
|
|
143
|
+
getAllComponents(): ComponentMeta[]
|
|
144
|
+
|
|
145
|
+
/** Full list of MDX docs with their frontmatter. */
|
|
146
|
+
getAllDocs(): DocMeta[]
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Return doc content for one slug, preferring the requested locale. Fall
|
|
150
|
+
* back to the default locale when the localized file doesn't exist. Return
|
|
151
|
+
* `null` when the slug is unknown so the shell can `notFound()`.
|
|
152
|
+
*/
|
|
153
|
+
getDocBySlug(slug: string, locale?: string): DocContent | null
|
|
154
|
+
|
|
155
|
+
/** Return `{ [locale]: rawMdx }` for all locales a doc is translated into. */
|
|
156
|
+
getDocAllLocales(slug: string): Record<string, string>
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Raw source of a component/block file for the "Code" tab. Should check
|
|
160
|
+
* both the component directory and the primitives/blocks directories.
|
|
161
|
+
* Return `null` if unknown.
|
|
162
|
+
*/
|
|
163
|
+
getComponentSource(name: string): string | null
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Return the shadcn-format JSON for a registry item. Usually reads the
|
|
167
|
+
* pre-built `public/r/{name}.json` produced by `shadcn build`. Accepts the
|
|
168
|
+
* slug with or without a trailing `.json`.
|
|
169
|
+
*/
|
|
170
|
+
getRegistryItem(name: string): Promise<unknown | null>
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Return the a11y metadata JSON for a component. Powers the Accessibility
|
|
174
|
+
* tab. Convention: `public/a11y/{name}.json` generated from
|
|
175
|
+
* `content/a11y/{name}.yaml` by the registry's `generate:a11y` script.
|
|
176
|
+
*/
|
|
177
|
+
getA11yData?(name: string): Promise<unknown | null>
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Return the test summary JSON for a component. Powers the Tests tab.
|
|
181
|
+
* Convention: `public/tests/{name}.json` generated by `generate:tests`.
|
|
182
|
+
*/
|
|
183
|
+
getTestData?(name: string): Promise<unknown | null>
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Return the prop-documentation JSON for a component. Powers the props
|
|
187
|
+
* table inside the Docs tab. Convention: `public/props/{name}.json`
|
|
188
|
+
* generated by `generate:props`.
|
|
189
|
+
*/
|
|
190
|
+
getPropsData?(name: string): Promise<unknown | null>
|
|
191
|
+
|
|
192
|
+
previewLoader: PreviewLoader
|
|
193
|
+
branding: BrandingConfig
|
|
194
|
+
|
|
195
|
+
/** See `RegistryClient.HomePage`. */
|
|
196
|
+
homePage?: ComponentType<HomePageProps> | null
|
|
197
|
+
/** See `RegistryClient.extraTranslations`. */
|
|
198
|
+
extraTranslations?: Record<string, Record<string, string>>
|
|
199
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="next" />
|
|
2
|
+
/// <reference types="next/image-types/global" />
|
|
3
|
+
/// <reference path="./.next/types/routes.d.ts" />
|
|
4
|
+
|
|
5
|
+
// NOTE: This file should not be edited
|
|
6
|
+
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { NextConfig } from "next"
|
|
2
|
+
import fs from "node:fs"
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
import { fileURLToPath } from "node:url"
|
|
5
|
+
|
|
6
|
+
const HERE = path.dirname(fileURLToPath(import.meta.url))
|
|
7
|
+
const USER_ROOT = process.env.USER_REGISTRY_ROOT
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a virtual `@user/*` alias to the user's file when it exists, else
|
|
11
|
+
* to a shell-bundled fallback under `fallback/`. Called once at Next boot.
|
|
12
|
+
*/
|
|
13
|
+
function toPosix(p: string): string {
|
|
14
|
+
// Turbopack on Windows rejects backslash absolute paths.
|
|
15
|
+
return p.replace(/\\/g, "/")
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Common ancestor directory of two absolute paths. */
|
|
19
|
+
function findCommonRoot(a: string, b: string): string {
|
|
20
|
+
const pa = path.resolve(a).split(path.sep)
|
|
21
|
+
const pb = path.resolve(b).split(path.sep)
|
|
22
|
+
const common: string[] = []
|
|
23
|
+
for (let i = 0; i < Math.min(pa.length, pb.length); i++) {
|
|
24
|
+
if (pa[i] !== pb[i]) break
|
|
25
|
+
common.push(pa[i])
|
|
26
|
+
}
|
|
27
|
+
return common.join(path.sep) || path.sep
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function resolveUserModule(relativePath: string, fallback: string): string {
|
|
31
|
+
if (USER_ROOT) {
|
|
32
|
+
// Try a few extensions since users may write .ts or .tsx.
|
|
33
|
+
const candidates = [relativePath, `${relativePath}.ts`, `${relativePath}.tsx`]
|
|
34
|
+
for (const c of candidates) {
|
|
35
|
+
const abs = path.isAbsolute(c) ? c : path.join(USER_ROOT, c)
|
|
36
|
+
if (fs.existsSync(abs) && fs.statSync(abs).isFile()) return toPosix(abs)
|
|
37
|
+
const indexTs = path.join(abs, "index.ts")
|
|
38
|
+
if (fs.existsSync(indexTs)) return toPosix(indexTs)
|
|
39
|
+
const indexTsx = path.join(abs, "index.tsx")
|
|
40
|
+
if (fs.existsSync(indexTsx)) return toPosix(indexTsx)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return toPosix(path.join(HERE, fallback))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const USER_PREVIEWS = resolveUserModule("components/previews", "fallback/previews.ts")
|
|
47
|
+
const USER_HOMEPAGE = process.env.USER_HOMEPAGE_PATH
|
|
48
|
+
? resolveUserModule(process.env.USER_HOMEPAGE_PATH, "fallback/homepage.tsx")
|
|
49
|
+
: toPosix(path.join(HERE, "fallback/homepage.tsx"))
|
|
50
|
+
|
|
51
|
+
// The CLI's `build` / `start` commands set USER_DIST_DIR to
|
|
52
|
+
// `<user-project>/.next` so Next writes its output (and reads it back on
|
|
53
|
+
// start) at the user's project root, not inside node_modules. Absolute
|
|
54
|
+
// path — Next accepts that for `distDir`.
|
|
55
|
+
const USER_DIST_DIR = process.env.USER_DIST_DIR
|
|
56
|
+
|
|
57
|
+
const nextConfig: NextConfig = {
|
|
58
|
+
output: process.env.BUILD_STANDALONE === "true" ? "standalone" : undefined,
|
|
59
|
+
...(USER_DIST_DIR ? { distDir: toPosix(USER_DIST_DIR) } : {}),
|
|
60
|
+
|
|
61
|
+
// When installed as an external package (link:../registry-shell, npm, etc.),
|
|
62
|
+
// the shell's TSX lives under the user's node_modules and Next won't
|
|
63
|
+
// transpile it by default. The registry can list additional packages via
|
|
64
|
+
// `transpilePackages` in its config (CLI forwards as USER_TRANSPILE_PACKAGES).
|
|
65
|
+
transpilePackages: [
|
|
66
|
+
"@sntlr/registry-shell",
|
|
67
|
+
...(process.env.USER_TRANSPILE_PACKAGES
|
|
68
|
+
? process.env.USER_TRANSPILE_PACKAGES.split(",").filter(Boolean)
|
|
69
|
+
: []),
|
|
70
|
+
],
|
|
71
|
+
|
|
72
|
+
// Turbopack root: walk up until we find a dir that contains both the shell
|
|
73
|
+
// package and the user's project. For a pnpm workspace setup that's the
|
|
74
|
+
// workspace root. Falls back to process.cwd() (which is the user's project
|
|
75
|
+
// when run via `registry-shell dev`).
|
|
76
|
+
turbopack: {
|
|
77
|
+
root: process.env.TURBOPACK_ROOT
|
|
78
|
+
? toPosix(process.env.TURBOPACK_ROOT)
|
|
79
|
+
: toPosix(findCommonRoot(HERE, USER_ROOT ?? process.cwd())),
|
|
80
|
+
resolveAlias: {
|
|
81
|
+
"@user/previews": USER_PREVIEWS,
|
|
82
|
+
"@user/homepage": USER_HOMEPAGE,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
webpack: (config) => {
|
|
87
|
+
config.resolve = config.resolve ?? {}
|
|
88
|
+
config.resolve.alias = {
|
|
89
|
+
...(config.resolve.alias ?? {}),
|
|
90
|
+
"@user/previews": USER_PREVIEWS,
|
|
91
|
+
"@user/homepage": USER_HOMEPAGE,
|
|
92
|
+
// Shell's internal alias — its own files.
|
|
93
|
+
"@shell": toPosix(HERE),
|
|
94
|
+
// shadcn convention: user files use `@/` for their own project root.
|
|
95
|
+
...(USER_ROOT ? { "@": toPosix(USER_ROOT) } : {}),
|
|
96
|
+
}
|
|
97
|
+
return config
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export default nextConfig
|
|
Binary file
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="128" height="82" viewBox="0 0 128 82" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M95.7812 3.18066C97.3554 1.60657 99.9073 1.60659 101.481 3.18066C103.056 4.7548 103.056 7.30671 101.481 8.88086L79.3223 31.04C73.7739 36.5884 73.774 45.5844 79.3223 51.1328L100.905 72.7158C102.508 74.3181 102.508 76.9163 100.905 78.5186C99.3031 80.1203 96.7057 80.1204 95.1035 78.5186L73.5205 56.9346C67.9722 51.3864 58.9761 51.3864 53.4277 56.9346L32.3223 78.041C30.7481 79.6152 28.1952 79.6152 26.6211 78.041C25.047 76.4669 25.047 73.914 26.6211 72.3398L47.7275 51.2344C53.2757 45.686 53.2759 36.6899 47.7275 31.1416L26.041 9.45605C24.4388 7.85382 24.4388 5.25556 26.041 3.65332C27.6433 2.0512 30.2415 2.05112 31.8438 3.65332L53.5293 25.3398C59.0777 30.8882 68.0737 30.8882 73.6221 25.3398L95.7812 3.18066ZM61.0986 69.4502C62.7013 67.8476 65.2988 67.8476 66.9014 69.4502C68.504 71.0528 68.504 73.6513 66.9014 75.2539C65.2989 76.856 62.7012 76.856 61.0986 75.2539C59.496 73.6513 59.496 71.0528 61.0986 69.4502ZM4.98926 33.3418C8.97557 29.3555 15.4395 29.3555 19.4258 33.3418C23.4117 37.3281 23.4119 43.7911 19.4258 47.7773C15.4395 51.7637 8.97557 51.7637 4.98926 47.7773C1.00321 43.7912 1.00342 37.3281 4.98926 33.3418ZM108.574 33.3418C112.561 29.3555 119.024 29.3555 123.011 33.3418C126.997 37.3281 126.997 43.7912 123.011 47.7773C119.024 51.7637 112.561 51.7637 108.574 47.7773C104.588 43.7911 104.588 37.3281 108.574 33.3418Z" stroke="#005E3E" stroke-width="4"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="128" height="82" viewBox="0 0 128 82" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M95.7812 3.18066C97.3554 1.60657 99.9073 1.60659 101.481 3.18066C103.056 4.7548 103.056 7.30671 101.481 8.88086L79.3223 31.04C73.7739 36.5884 73.774 45.5844 79.3223 51.1328L100.905 72.7158C102.508 74.3181 102.508 76.9163 100.905 78.5186C99.3031 80.1203 96.7057 80.1204 95.1035 78.5186L73.5205 56.9346C67.9722 51.3864 58.9761 51.3864 53.4277 56.9346L32.3223 78.041C30.7481 79.6152 28.1952 79.6152 26.6211 78.041C25.047 76.4669 25.047 73.914 26.6211 72.3398L47.7275 51.2344C53.2757 45.686 53.2759 36.6899 47.7275 31.1416L26.041 9.45605C24.4388 7.85382 24.4388 5.25556 26.041 3.65332C27.6433 2.0512 30.2415 2.05112 31.8438 3.65332L53.5293 25.3398C59.0777 30.8882 68.0737 30.8882 73.6221 25.3398L95.7812 3.18066ZM61.0986 69.4502C62.7013 67.8476 65.2988 67.8476 66.9014 69.4502C68.504 71.0528 68.504 73.6513 66.9014 75.2539C65.2989 76.856 62.7012 76.856 61.0986 75.2539C59.496 73.6513 59.496 71.0528 61.0986 69.4502ZM4.98926 33.3418C8.97557 29.3555 15.4395 29.3555 19.4258 33.3418C23.4117 37.3281 23.4119 43.7911 19.4258 47.7773C15.4395 51.7637 8.97557 51.7637 4.98926 47.7773C1.00321 43.7912 1.00342 37.3281 4.98926 33.3418ZM108.574 33.3418C112.561 29.3555 119.024 29.3555 123.011 33.3418C126.997 37.3281 126.997 43.7912 123.011 47.7773C119.024 51.7637 112.561 51.7637 108.574 47.7773C104.588 43.7911 104.588 37.3281 108.574 33.3418Z" stroke="#5CD6AD" stroke-width="4"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side registry adapter. Not user-editable anymore — the shell reads
|
|
3
|
+
* the user's `registry-shell.config.ts` via env vars set by the CLI and
|
|
4
|
+
* instantiates the default convention-based adapter (or a user-supplied
|
|
5
|
+
* custom one).
|
|
6
|
+
*
|
|
7
|
+
* Loaded once at Next.js module init.
|
|
8
|
+
*/
|
|
9
|
+
import "server-only"
|
|
10
|
+
import type { RegistryAdapter } from "@shell/lib/registry-adapter"
|
|
11
|
+
import { loadResolvedConfig } from "../config-loader"
|
|
12
|
+
import { createDefaultAdapter } from "../adapter/default"
|
|
13
|
+
import { loadCustomAdapterOverrides } from "../adapter/custom"
|
|
14
|
+
|
|
15
|
+
function buildAdapter(): RegistryAdapter | null {
|
|
16
|
+
const resolved = loadResolvedConfig()
|
|
17
|
+
if (!resolved) return null
|
|
18
|
+
|
|
19
|
+
const base = createDefaultAdapter(resolved)
|
|
20
|
+
// Shallow-merged on top of `base` so a custom adapter can override one
|
|
21
|
+
// method (e.g. getAllComponents from a DB) and keep the defaults for the
|
|
22
|
+
// rest. Loaded via jiti — the adapter file can be plain TS.
|
|
23
|
+
const overrides = loadCustomAdapterOverrides(resolved) as Partial<RegistryAdapter>
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
getAllComponents: overrides.getAllComponents ?? base.getAllComponents,
|
|
27
|
+
getAllDocs: overrides.getAllDocs ?? base.getAllDocs,
|
|
28
|
+
getDocBySlug: overrides.getDocBySlug ?? base.getDocBySlug,
|
|
29
|
+
getDocAllLocales: overrides.getDocAllLocales ?? base.getDocAllLocales,
|
|
30
|
+
getComponentSource: overrides.getComponentSource ?? base.getComponentSource,
|
|
31
|
+
getRegistryItem: overrides.getRegistryItem ?? base.getRegistryItem,
|
|
32
|
+
getA11yData: overrides.getA11yData ?? base.getA11yData,
|
|
33
|
+
getTestData: overrides.getTestData ?? base.getTestData,
|
|
34
|
+
getPropsData: overrides.getPropsData ?? base.getPropsData,
|
|
35
|
+
previewLoader: UNUSED_SERVER_SIDE_PREVIEW_LOADER,
|
|
36
|
+
branding: base.branding,
|
|
37
|
+
extraTranslations: overrides.extraTranslations ?? base.extraTranslations,
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// The adapter's `previewLoader` field is never read on the server — previews
|
|
42
|
+
// are imported directly from the `@user/previews` alias in client code (see
|
|
43
|
+
// lib/preview-loader.ts). This placeholder satisfies the interface.
|
|
44
|
+
const UNUSED_SERVER_SIDE_PREVIEW_LOADER: RegistryAdapter["previewLoader"] = {
|
|
45
|
+
Preview: () => null,
|
|
46
|
+
load: () => null,
|
|
47
|
+
names: () => [],
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const registry: RegistryAdapter | null = buildAdapter()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"incremental": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"isolatedModules": true,
|
|
15
|
+
"jsx": "preserve",
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": {
|
|
18
|
+
"@shell/*": ["./*"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": [
|
|
22
|
+
"next-env.d.ts",
|
|
23
|
+
"user-aliases.d.ts",
|
|
24
|
+
".next/types/**/*.ts",
|
|
25
|
+
"**/*.ts",
|
|
26
|
+
"**/*.tsx"
|
|
27
|
+
],
|
|
28
|
+
"exclude": ["node_modules"]
|
|
29
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virtual modules resolved by next.config.ts based on `USER_REGISTRY_ROOT`.
|
|
3
|
+
* At build time they point at the user's files; if the user has none, they
|
|
4
|
+
* fall back to shell-bundled stubs under `fallback/`.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
declare module "@user/previews" {
|
|
8
|
+
import type { PreviewLoader } from "@shell/lib/registry-adapter"
|
|
9
|
+
export const previewLoader: PreviewLoader
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
declare module "@user/homepage" {
|
|
13
|
+
import type { ComponentType } from "react"
|
|
14
|
+
import type { HomePageProps } from "@shell/lib/registry-adapter"
|
|
15
|
+
const HomePage: ComponentType<HomePageProps>
|
|
16
|
+
export default HomePage
|
|
17
|
+
}
|