@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Scintillar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# @sntlr/registry-shell
|
|
2
|
+
|
|
3
|
+
A generic Next.js viewer for shadcn-compatible component registries. Drop a
|
|
4
|
+
single config file into your registry project, run one command, and get a
|
|
5
|
+
full components + blocks + docs site on `localhost:3000` — no wiring, no
|
|
6
|
+
shell code to fork.
|
|
7
|
+
|
|
8
|
+
## Quickstart
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cd my-registry/
|
|
12
|
+
npm install -D @sntlr/registry-shell
|
|
13
|
+
npx registry-shell init # scaffolds registry-shell.config.ts + scripts
|
|
14
|
+
npm run shell # boots the shell against your project
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Visit <http://localhost:3000> — you'll see your components, blocks, and MDX
|
|
18
|
+
docs rendered with the shell's chrome (sidebar, topbar, locale toggle, dark
|
|
19
|
+
mode, install command, preview + source tabs).
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
Edit `registry-shell.config.ts` at the root of your registry:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { defineConfig } from "@sntlr/registry-shell"
|
|
27
|
+
|
|
28
|
+
export default defineConfig({
|
|
29
|
+
branding: {
|
|
30
|
+
siteName: "My UI",
|
|
31
|
+
shortName: "UI",
|
|
32
|
+
siteUrl: "https://ui.example.com",
|
|
33
|
+
github: { owner: "my-org", repo: "my-ui" },
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
// All path overrides are optional — these are the defaults:
|
|
37
|
+
// paths: {
|
|
38
|
+
// components: "components/ui",
|
|
39
|
+
// blocks: "registry/new-york/blocks",
|
|
40
|
+
// previews: "components/previews/index.ts",
|
|
41
|
+
// docs: "content/docs",
|
|
42
|
+
// registryJson: "public/r",
|
|
43
|
+
// globalCss: "./styles/theme.css", // optional, see "Custom CSS"
|
|
44
|
+
// buildOutput: ".next", // optional, override if `.next` collides
|
|
45
|
+
// },
|
|
46
|
+
|
|
47
|
+
// Optional custom homepage (relative to this file):
|
|
48
|
+
// homePage: "./components/homepage",
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The only required field is `branding`. Everything else follows shadcn
|
|
53
|
+
conventions out of the box.
|
|
54
|
+
|
|
55
|
+
## How it works
|
|
56
|
+
|
|
57
|
+
The shell is a published Next.js app. The CLI (`registry-shell`) resolves
|
|
58
|
+
the bundled app inside `node_modules/@sntlr/registry-shell`, injects
|
|
59
|
+
environment variables pointing at your project (`USER_REGISTRY_ROOT`,
|
|
60
|
+
`USER_CONFIG_PATH`), and spawns `next dev` / `next build` / `next start`
|
|
61
|
+
against it.
|
|
62
|
+
|
|
63
|
+
A convention-based adapter inside the shell reads your filesystem at server
|
|
64
|
+
startup: `components/ui/*.tsx` for components, `registry/new-york/blocks/*/`
|
|
65
|
+
for blocks, `content/docs/*.mdx` for docs, `public/r/*.json` for the
|
|
66
|
+
shadcn-compatible registry JSON. Everything is pull-based — the shell never
|
|
67
|
+
writes to your project (except a `.next` build cache inside its own install
|
|
68
|
+
location).
|
|
69
|
+
|
|
70
|
+
Previews are imported from your project's `components/previews/index.ts` via
|
|
71
|
+
a Next.js alias, so `next/dynamic()` with string-literal paths keeps working.
|
|
72
|
+
A custom homepage module (if you set `homePage` in the config) is loaded the
|
|
73
|
+
same way.
|
|
74
|
+
|
|
75
|
+
## Commands
|
|
76
|
+
|
|
77
|
+
| Command | What it does |
|
|
78
|
+
|--------------------------|-----------------------------------------------------|
|
|
79
|
+
| `registry-shell init` | Scaffold `registry-shell.config.ts` + npm scripts |
|
|
80
|
+
| `registry-shell dev` | Dev server on `localhost:3000` |
|
|
81
|
+
| `registry-shell build` | Production `next build` |
|
|
82
|
+
| `registry-shell start` | `next start` against a prior build |
|
|
83
|
+
|
|
84
|
+
If your registry has no config file, the shell runs in "shell-only" mode and
|
|
85
|
+
renders its built-in getting-started docs so you can preview the chrome
|
|
86
|
+
before wiring anything up.
|
|
87
|
+
|
|
88
|
+
## Custom CSS / theme tokens
|
|
89
|
+
|
|
90
|
+
To add brand fonts, override design tokens, or register extra
|
|
91
|
+
Tailwind `@source` scan paths, set `paths.globalCss` to a `.css` file in
|
|
92
|
+
your project:
|
|
93
|
+
|
|
94
|
+
```css
|
|
95
|
+
/* styles/theme.css */
|
|
96
|
+
@font-face {
|
|
97
|
+
font-family: "Brand Sans";
|
|
98
|
+
src: url("/fonts/brand-sans.woff2") format("woff2");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* Override the shell's primary color (light + dark) */
|
|
102
|
+
:root { --primary: oklch(0.6 0.2 280); }
|
|
103
|
+
.dark { --primary: oklch(0.75 0.18 280); }
|
|
104
|
+
|
|
105
|
+
/* Scan an extra directory for Tailwind utilities */
|
|
106
|
+
@source "../content/marketing";
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The file is `@import`ed at the very end of the shell's `globals.css`, so
|
|
110
|
+
your `:root` token redefinitions win the cascade against the shell's
|
|
111
|
+
defaults. Edits require a CLI restart to pick up (the CSS path is resolved
|
|
112
|
+
at boot); the file's contents are hot-reloaded as usual.
|
|
113
|
+
|
|
114
|
+
## Advanced: custom adapters
|
|
115
|
+
|
|
116
|
+
For non-convention registries (database-backed metadata, non-MDX docs, etc.)
|
|
117
|
+
point `adapter` at a TypeScript module:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
// registry-shell.config.ts
|
|
121
|
+
export default defineConfig({
|
|
122
|
+
branding: { ... },
|
|
123
|
+
adapter: "./custom-adapter",
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
// custom-adapter.ts
|
|
129
|
+
import type { ResolvedShellConfig } from "@sntlr/registry-shell"
|
|
130
|
+
|
|
131
|
+
export default function (_resolved: ResolvedShellConfig) {
|
|
132
|
+
return {
|
|
133
|
+
// Override only the methods you need — the rest fall through to the
|
|
134
|
+
// convention-based defaults.
|
|
135
|
+
getAllComponents: () => [
|
|
136
|
+
{ name: "my-button", label: "Button", kind: "component" as const },
|
|
137
|
+
],
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The factory is called once at server startup with the resolved config. It
|
|
143
|
+
may return any subset of the adapter interface; omitted methods use the
|
|
144
|
+
defaults.
|
|
145
|
+
|
|
146
|
+
## Requirements
|
|
147
|
+
|
|
148
|
+
- Node.js ≥ 18.18
|
|
149
|
+
- Your project uses Next.js 15 conventions (or at least its `public/`,
|
|
150
|
+
`components/`, `content/` layout — the shell doesn't care if you use
|
|
151
|
+
Next.js itself).
|
|
152
|
+
|
|
153
|
+
## Deploying to Vercel
|
|
154
|
+
|
|
155
|
+
The shell's `registry-shell build` writes its Next.js output to
|
|
156
|
+
`<your-project>/.next`, so any Next-aware host (Vercel, Netlify's Next runtime,
|
|
157
|
+
self-hosted Node, etc.) finds it where they expect. On Vercel specifically:
|
|
158
|
+
|
|
159
|
+
1. **Add `next` to your project's devDependencies.** Vercel auto-detects
|
|
160
|
+
Next.js by scanning `package.json`; without a direct `next` entry it may
|
|
161
|
+
miss the framework and default to static hosting.
|
|
162
|
+
```bash
|
|
163
|
+
npm install -D next
|
|
164
|
+
```
|
|
165
|
+
2. **In the Vercel dashboard** (New Project → your repo), set:
|
|
166
|
+
- **Framework Preset**: Next.js
|
|
167
|
+
- **Build Command**: `npm run shell:build` (or `registry-shell build`)
|
|
168
|
+
- **Output Directory**: leave blank (defaults to `.next`)
|
|
169
|
+
- **Install Command**: leave default
|
|
170
|
+
3. Deploy. Vercel runs your build command, Next writes `.next/` at the
|
|
171
|
+
project root, and Vercel picks it up like a standard Next.js project.
|
|
172
|
+
|
|
173
|
+
`registry-shell start` also respects the same output location, so
|
|
174
|
+
self-hosted deployments work with `npm run shell:build && npm run shell:start`.
|
|
175
|
+
|
|
176
|
+
Need the output somewhere other than `.next`? Set `paths.buildOutput` in
|
|
177
|
+
your config (e.g. `"dist-shell"`). Just remember to point your host's
|
|
178
|
+
Output Directory setting at the same path.
|
|
179
|
+
|
|
180
|
+
## Releasing
|
|
181
|
+
|
|
182
|
+
Publishing is tag-triggered via GitHub Actions. To cut a release:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
npm version patch # or minor / major — bumps package.json, commits, tags
|
|
186
|
+
git push --follow-tags # pushes the commit + the new tag together
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The push of `v*` fires `.github/workflows/publish.yml`, which reruns lint +
|
|
190
|
+
type-check + tests, verifies the tag matches `package.json`'s version, and
|
|
191
|
+
publishes to npm with provenance. Requires an `NPM_TOKEN` secret in the
|
|
192
|
+
repo (npm automation token with write access to the `@sntlr` scope).
|
|
193
|
+
|
|
194
|
+
Every push to `main` and every PR also runs `.github/workflows/test.yml`
|
|
195
|
+
(lint, type-check, build, unit tests) — that's the gate the release
|
|
196
|
+
workflow leans on, so green there means a tag push will publish cleanly.
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
MIT
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom adapter loader.
|
|
3
|
+
*
|
|
4
|
+
* When a user's `registry-shell.config.ts` sets `adapter: "./my-adapter"`, the
|
|
5
|
+
* shell calls `loadCustomAdapterOverrides(resolved)` to resolve that module
|
|
6
|
+
* and extract method overrides. The overrides are then shallow-merged on top
|
|
7
|
+
* of the default convention-based adapter's methods.
|
|
8
|
+
*
|
|
9
|
+
* The user's module should default-export one of:
|
|
10
|
+
* • A factory `(resolved) => Partial<AdapterMethods>` — preferred. Gets the
|
|
11
|
+
* resolved config so it can build paths against `resolved.paths`, decide
|
|
12
|
+
* based on `resolved.root`, etc.
|
|
13
|
+
* • A plain `Partial<AdapterMethods>` object — also accepted for simple
|
|
14
|
+
* static overrides that don't need the resolved config.
|
|
15
|
+
*
|
|
16
|
+
* Only the methods a user supplies are taken; any method they omit falls
|
|
17
|
+
* through to the built-in default. That means you can override just
|
|
18
|
+
* `getAllComponents` to serve from a database and keep convention-based
|
|
19
|
+
* doc/registry-item loading for the rest.
|
|
20
|
+
*
|
|
21
|
+
* Loaded via jiti so the user can write the adapter in TypeScript without
|
|
22
|
+
* their own build step — same approach we use for the config file itself.
|
|
23
|
+
*/
|
|
24
|
+
import "server-only";
|
|
25
|
+
import type { ResolvedShellConfig } from "../config-loader.js";
|
|
26
|
+
/**
|
|
27
|
+
* Shape of what a custom adapter module may override. Mirrors the public
|
|
28
|
+
* methods on RegistryAdapter (defined inside next-app/lib) minus the fields
|
|
29
|
+
* that are wired via other mechanisms (previewLoader via `@user/previews`
|
|
30
|
+
* alias, branding from config, homePage via `@user/homepage` alias).
|
|
31
|
+
*
|
|
32
|
+
* Typed with `unknown` args on the server side — the Next app re-applies
|
|
33
|
+
* its stricter RegistryAdapter types when consuming this.
|
|
34
|
+
*/
|
|
35
|
+
export interface AdapterOverrides {
|
|
36
|
+
getAllComponents?: () => unknown[];
|
|
37
|
+
getAllDocs?: () => unknown[];
|
|
38
|
+
getDocBySlug?: (slug: string, locale?: string) => unknown | null;
|
|
39
|
+
getDocAllLocales?: (slug: string) => Record<string, string>;
|
|
40
|
+
getComponentSource?: (name: string) => string | null;
|
|
41
|
+
getRegistryItem?: (name: string) => Promise<unknown | null>;
|
|
42
|
+
getA11yData?: (name: string) => Promise<unknown | null>;
|
|
43
|
+
getTestData?: (name: string) => Promise<unknown | null>;
|
|
44
|
+
getPropsData?: (name: string) => Promise<unknown | null>;
|
|
45
|
+
extraTranslations?: Record<string, Record<string, string>>;
|
|
46
|
+
}
|
|
47
|
+
export declare function loadCustomAdapterOverrides(resolved: ResolvedShellConfig): AdapterOverrides;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom adapter loader.
|
|
3
|
+
*
|
|
4
|
+
* When a user's `registry-shell.config.ts` sets `adapter: "./my-adapter"`, the
|
|
5
|
+
* shell calls `loadCustomAdapterOverrides(resolved)` to resolve that module
|
|
6
|
+
* and extract method overrides. The overrides are then shallow-merged on top
|
|
7
|
+
* of the default convention-based adapter's methods.
|
|
8
|
+
*
|
|
9
|
+
* The user's module should default-export one of:
|
|
10
|
+
* • A factory `(resolved) => Partial<AdapterMethods>` — preferred. Gets the
|
|
11
|
+
* resolved config so it can build paths against `resolved.paths`, decide
|
|
12
|
+
* based on `resolved.root`, etc.
|
|
13
|
+
* • A plain `Partial<AdapterMethods>` object — also accepted for simple
|
|
14
|
+
* static overrides that don't need the resolved config.
|
|
15
|
+
*
|
|
16
|
+
* Only the methods a user supplies are taken; any method they omit falls
|
|
17
|
+
* through to the built-in default. That means you can override just
|
|
18
|
+
* `getAllComponents` to serve from a database and keep convention-based
|
|
19
|
+
* doc/registry-item loading for the rest.
|
|
20
|
+
*
|
|
21
|
+
* Loaded via jiti so the user can write the adapter in TypeScript without
|
|
22
|
+
* their own build step — same approach we use for the config file itself.
|
|
23
|
+
*/
|
|
24
|
+
import "server-only";
|
|
25
|
+
import { createJiti } from "jiti";
|
|
26
|
+
export function loadCustomAdapterOverrides(resolved) {
|
|
27
|
+
if (!resolved.adapter)
|
|
28
|
+
return {};
|
|
29
|
+
const jiti = createJiti(import.meta.url, { interopDefault: true });
|
|
30
|
+
let loaded;
|
|
31
|
+
try {
|
|
32
|
+
loaded = jiti(resolved.adapter);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw new Error(`[registry-shell] Failed to load custom adapter at ${resolved.adapter}: ` +
|
|
36
|
+
(err instanceof Error ? err.message : String(err)));
|
|
37
|
+
}
|
|
38
|
+
const extracted = loaded && typeof loaded === "object" && "default" in loaded
|
|
39
|
+
? loaded.default
|
|
40
|
+
: loaded;
|
|
41
|
+
if (typeof extracted === "function") {
|
|
42
|
+
const overrides = extracted(resolved);
|
|
43
|
+
if (!overrides || typeof overrides !== "object") {
|
|
44
|
+
throw new Error(`[registry-shell] Custom adapter factory at ${resolved.adapter} did not return an object.`);
|
|
45
|
+
}
|
|
46
|
+
return overrides;
|
|
47
|
+
}
|
|
48
|
+
if (extracted && typeof extracted === "object") {
|
|
49
|
+
return extracted;
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`[registry-shell] Custom adapter at ${resolved.adapter} must default-export a factory function or an object.`);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=custom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom.js","sourceRoot":"","sources":["../../src/adapter/custom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,aAAa,CAAA;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AA2BjC,MAAM,UAAU,0BAA0B,CACxC,QAA6B;IAE7B,IAAI,CAAC,QAAQ,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IAEhC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAA;IAClE,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,qDAAqD,QAAQ,CAAC,OAAO,IAAI;YACvE,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CACrD,CAAA;IACH,CAAC;IAED,MAAM,SAAS,GACb,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,MAAM;QACzD,CAAC,CAAE,MAA+B,CAAC,OAAO;QAC1C,CAAC,CAAC,MAAM,CAAA;IAEZ,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,MAAM,SAAS,GAAI,SAA4B,CAAC,QAAQ,CAAC,CAAA;QACzD,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CACb,8CAA8C,QAAQ,CAAC,OAAO,4BAA4B,CAC3F,CAAA;QACH,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC/C,OAAO,SAA6B,CAAA;IACtC,CAAC;IAED,MAAM,IAAI,KAAK,CACb,sCAAsC,QAAQ,CAAC,OAAO,uDAAuD,CAC9G,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default convention-based RegistryAdapter implementation.
|
|
3
|
+
*
|
|
4
|
+
* Builds a RegistryAdapter from a `ResolvedShellConfig`: scans the filesystem
|
|
5
|
+
* paths declared in the user's config, parses MDX frontmatter, and reads
|
|
6
|
+
* registry JSON. The `previewLoader` and `homePage` are wired separately via
|
|
7
|
+
* Next.js aliases (see next-app/next.config.ts) because Next's `dynamic()`
|
|
8
|
+
* needs string literal imports.
|
|
9
|
+
*/
|
|
10
|
+
import "server-only";
|
|
11
|
+
import type { ResolvedShellConfig } from "../config-loader.js";
|
|
12
|
+
export interface ComponentMeta {
|
|
13
|
+
name: string;
|
|
14
|
+
label: string;
|
|
15
|
+
kind: "component" | "block";
|
|
16
|
+
}
|
|
17
|
+
export interface DocMeta {
|
|
18
|
+
slug: string;
|
|
19
|
+
title: string;
|
|
20
|
+
description: string;
|
|
21
|
+
order: number;
|
|
22
|
+
titles: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
export interface DocContent {
|
|
25
|
+
meta: Omit<DocMeta, "titles">;
|
|
26
|
+
content: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function createDefaultAdapter(resolved: ResolvedShellConfig): {
|
|
29
|
+
getAllComponents: () => ComponentMeta[];
|
|
30
|
+
getAllDocs: () => DocMeta[];
|
|
31
|
+
getDocBySlug: (slug: string, locale?: string) => DocContent | null;
|
|
32
|
+
getDocAllLocales: (slug: string) => Record<string, string>;
|
|
33
|
+
getComponentSource: (name: string) => string | null;
|
|
34
|
+
getRegistryItem: (name: string) => Promise<unknown | null>;
|
|
35
|
+
getA11yData: (name: string) => Promise<unknown | null>;
|
|
36
|
+
getTestData: (name: string) => Promise<unknown | null>;
|
|
37
|
+
getPropsData: (name: string) => Promise<unknown | null>;
|
|
38
|
+
branding: Required<import("../define-config.js").BrandingConfig>;
|
|
39
|
+
extraTranslations: Record<string, Record<string, string>>;
|
|
40
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default convention-based RegistryAdapter implementation.
|
|
3
|
+
*
|
|
4
|
+
* Builds a RegistryAdapter from a `ResolvedShellConfig`: scans the filesystem
|
|
5
|
+
* paths declared in the user's config, parses MDX frontmatter, and reads
|
|
6
|
+
* registry JSON. The `previewLoader` and `homePage` are wired separately via
|
|
7
|
+
* Next.js aliases (see next-app/next.config.ts) because Next's `dynamic()`
|
|
8
|
+
* needs string literal imports.
|
|
9
|
+
*/
|
|
10
|
+
import "server-only";
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import matter from "gray-matter";
|
|
14
|
+
function titleCase(slug) {
|
|
15
|
+
return slug
|
|
16
|
+
.split("-")
|
|
17
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
18
|
+
.join(" ");
|
|
19
|
+
}
|
|
20
|
+
export function createDefaultAdapter(resolved) {
|
|
21
|
+
const { paths } = resolved;
|
|
22
|
+
const isMulti = resolved.multilocale;
|
|
23
|
+
const defaultLocale = resolved.defaultLocale;
|
|
24
|
+
/** In multilocale mode, return all locale subfolder names. */
|
|
25
|
+
function listLocales() {
|
|
26
|
+
if (!isMulti || !fs.existsSync(paths.docs))
|
|
27
|
+
return [];
|
|
28
|
+
return fs
|
|
29
|
+
.readdirSync(paths.docs, { withFileTypes: true })
|
|
30
|
+
.filter((d) => d.isDirectory())
|
|
31
|
+
.map((d) => d.name);
|
|
32
|
+
}
|
|
33
|
+
/** Path to the directory holding `.mdx` files for a given locale (multi mode). */
|
|
34
|
+
function localeDir(locale) {
|
|
35
|
+
return path.join(paths.docs, locale);
|
|
36
|
+
}
|
|
37
|
+
function getAllComponents() {
|
|
38
|
+
const items = [];
|
|
39
|
+
if (fs.existsSync(paths.components)) {
|
|
40
|
+
for (const filename of fs.readdirSync(paths.components).filter((f) => f.endsWith(".tsx"))) {
|
|
41
|
+
const name = filename.replace(/\.tsx$/, "");
|
|
42
|
+
items.push({ name, label: titleCase(name), kind: "component" });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (fs.existsSync(paths.blocks)) {
|
|
46
|
+
for (const dir of fs.readdirSync(paths.blocks, { withFileTypes: true })) {
|
|
47
|
+
if (!dir.isDirectory() || paths.skipBlocks.has(dir.name))
|
|
48
|
+
continue;
|
|
49
|
+
items.push({ name: dir.name, label: titleCase(dir.name), kind: "block" });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return items.sort((a, b) => a.label.localeCompare(b.label));
|
|
53
|
+
}
|
|
54
|
+
function getAllDocs() {
|
|
55
|
+
if (!fs.existsSync(paths.docs))
|
|
56
|
+
return [];
|
|
57
|
+
if (isMulti) {
|
|
58
|
+
const dir = localeDir(defaultLocale);
|
|
59
|
+
if (!fs.existsSync(dir))
|
|
60
|
+
return [];
|
|
61
|
+
const otherLocales = listLocales().filter((l) => l !== defaultLocale);
|
|
62
|
+
return fs
|
|
63
|
+
.readdirSync(dir)
|
|
64
|
+
.filter((f) => f.endsWith(".mdx"))
|
|
65
|
+
.map((filename) => {
|
|
66
|
+
const slug = filename.replace(/\.mdx$/, "");
|
|
67
|
+
const { data } = matter(fs.readFileSync(path.join(dir, filename), "utf-8"));
|
|
68
|
+
const titles = { [defaultLocale]: data.title ?? slug };
|
|
69
|
+
for (const loc of otherLocales) {
|
|
70
|
+
const p = path.join(localeDir(loc), filename);
|
|
71
|
+
if (!fs.existsSync(p))
|
|
72
|
+
continue;
|
|
73
|
+
const { data: locData } = matter(fs.readFileSync(p, "utf-8"));
|
|
74
|
+
if (locData.title)
|
|
75
|
+
titles[loc] = locData.title;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
slug,
|
|
79
|
+
title: data.title ?? slug,
|
|
80
|
+
description: data.description ?? "",
|
|
81
|
+
order: data.order ?? 999,
|
|
82
|
+
titles,
|
|
83
|
+
};
|
|
84
|
+
})
|
|
85
|
+
.sort((a, b) => a.order - b.order);
|
|
86
|
+
}
|
|
87
|
+
// Single-folder mode: one locale, no variant scanning.
|
|
88
|
+
return fs
|
|
89
|
+
.readdirSync(paths.docs)
|
|
90
|
+
.filter((f) => f.endsWith(".mdx"))
|
|
91
|
+
.map((filename) => {
|
|
92
|
+
const slug = filename.replace(/\.mdx$/, "");
|
|
93
|
+
const { data } = matter(fs.readFileSync(path.join(paths.docs, filename), "utf-8"));
|
|
94
|
+
return {
|
|
95
|
+
slug,
|
|
96
|
+
title: data.title ?? slug,
|
|
97
|
+
description: data.description ?? "",
|
|
98
|
+
order: data.order ?? 999,
|
|
99
|
+
titles: { en: data.title ?? slug },
|
|
100
|
+
};
|
|
101
|
+
})
|
|
102
|
+
.sort((a, b) => a.order - b.order);
|
|
103
|
+
}
|
|
104
|
+
function getDocBySlug(slug, locale) {
|
|
105
|
+
if (isMulti) {
|
|
106
|
+
const want = locale && locale !== defaultLocale ? locale : defaultLocale;
|
|
107
|
+
const candidates = [
|
|
108
|
+
path.join(localeDir(want), `${slug}.mdx`),
|
|
109
|
+
path.join(localeDir(defaultLocale), `${slug}.mdx`),
|
|
110
|
+
];
|
|
111
|
+
return readDocFile(slug, candidates);
|
|
112
|
+
}
|
|
113
|
+
// Single-folder mode: `locale` is ignored, only `{slug}.mdx` matters.
|
|
114
|
+
return readDocFile(slug, [path.join(paths.docs, `${slug}.mdx`)]);
|
|
115
|
+
}
|
|
116
|
+
function getDocAllLocales(slug) {
|
|
117
|
+
if (!fs.existsSync(paths.docs))
|
|
118
|
+
return {};
|
|
119
|
+
if (isMulti) {
|
|
120
|
+
const out = {};
|
|
121
|
+
for (const loc of listLocales()) {
|
|
122
|
+
const p = path.join(localeDir(loc), `${slug}.mdx`);
|
|
123
|
+
if (fs.existsSync(p)) {
|
|
124
|
+
out[loc] = matter(fs.readFileSync(p, "utf-8")).content;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
// Single-folder mode: exactly one file, keyed under `en` so the client
|
|
130
|
+
// renderer's fallback chain works without needing a special case.
|
|
131
|
+
const p = path.join(paths.docs, `${slug}.mdx`);
|
|
132
|
+
if (!fs.existsSync(p))
|
|
133
|
+
return {};
|
|
134
|
+
return { en: matter(fs.readFileSync(p, "utf-8")).content };
|
|
135
|
+
}
|
|
136
|
+
function getComponentSource(name) {
|
|
137
|
+
const candidates = [
|
|
138
|
+
path.join(paths.components, `${name}.tsx`),
|
|
139
|
+
path.join(paths.blocks, name, `${name}.tsx`),
|
|
140
|
+
];
|
|
141
|
+
for (const p of candidates) {
|
|
142
|
+
if (fs.existsSync(p))
|
|
143
|
+
return fs.readFileSync(p, "utf-8");
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
async function getRegistryItem(name) {
|
|
148
|
+
return readJson(paths.registryJson, name);
|
|
149
|
+
}
|
|
150
|
+
async function getA11yData(name) {
|
|
151
|
+
return readJson(paths.a11y, name);
|
|
152
|
+
}
|
|
153
|
+
async function getTestData(name) {
|
|
154
|
+
return readJson(paths.tests, name);
|
|
155
|
+
}
|
|
156
|
+
async function getPropsData(name) {
|
|
157
|
+
return readJson(paths.props, name);
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
getAllComponents,
|
|
161
|
+
getAllDocs,
|
|
162
|
+
getDocBySlug,
|
|
163
|
+
getDocAllLocales,
|
|
164
|
+
getComponentSource,
|
|
165
|
+
getRegistryItem,
|
|
166
|
+
getA11yData,
|
|
167
|
+
getTestData,
|
|
168
|
+
getPropsData,
|
|
169
|
+
branding: resolved.branding,
|
|
170
|
+
extraTranslations: resolved.extraTranslations,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async function readJson(dir, name) {
|
|
174
|
+
const base = name.replace(/\.json$/, "");
|
|
175
|
+
const filePath = path.join(dir, `${base}.json`);
|
|
176
|
+
try {
|
|
177
|
+
const data = await fs.promises.readFile(filePath, "utf-8");
|
|
178
|
+
return JSON.parse(data);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/** Try each candidate path; return the first that parses to a DocContent. */
|
|
185
|
+
function readDocFile(slug, candidates) {
|
|
186
|
+
for (const p of candidates) {
|
|
187
|
+
if (!fs.existsSync(p))
|
|
188
|
+
continue;
|
|
189
|
+
const { data, content } = matter(fs.readFileSync(p, "utf-8"));
|
|
190
|
+
return {
|
|
191
|
+
meta: {
|
|
192
|
+
slug,
|
|
193
|
+
title: data.title ?? slug,
|
|
194
|
+
description: data.description ?? "",
|
|
195
|
+
order: data.order ?? 999,
|
|
196
|
+
},
|
|
197
|
+
content,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/adapter/default.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function run(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `registry-shell build` — run `next build` against the user's project.
|
|
3
|
+
*
|
|
4
|
+
* Writes the Next build output to `<user-project>/.next` via `distDir` so
|
|
5
|
+
* generic Next.js hosts (Vercel, self-hosted) find it where they expect.
|
|
6
|
+
* Without this, the output would land inside
|
|
7
|
+
* `node_modules/@sntlr/registry-shell/src/next-app/.next` and no external
|
|
8
|
+
* host could discover it.
|
|
9
|
+
*/
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { spawn } from "node:child_process";
|
|
12
|
+
import { NEXT_BIN, buildEnvVars, clearStaleNextCacheIfModeChanged, loadUserConfig, nextAppDir, writeUserSourcesCss, } from "./shared.js";
|
|
13
|
+
export async function run(args) {
|
|
14
|
+
const loaded = loadUserConfig();
|
|
15
|
+
clearStaleNextCacheIfModeChanged(loaded);
|
|
16
|
+
writeUserSourcesCss(loaded);
|
|
17
|
+
const userDistDir = loaded
|
|
18
|
+
? path.resolve(loaded.root, loaded.config.paths?.buildOutput ?? ".next")
|
|
19
|
+
: undefined;
|
|
20
|
+
const env = {
|
|
21
|
+
...process.env,
|
|
22
|
+
...buildEnvVars(loaded),
|
|
23
|
+
...(userDistDir ? { USER_DIST_DIR: userDistDir } : {}),
|
|
24
|
+
};
|
|
25
|
+
const child = spawn(process.execPath, [NEXT_BIN, "build", nextAppDir(), ...args], {
|
|
26
|
+
stdio: "inherit",
|
|
27
|
+
env,
|
|
28
|
+
});
|
|
29
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,gCAAgC,EAChC,cAAc,EACd,UAAU,EACV,mBAAmB,GACpB,MAAM,aAAa,CAAA;AAEpB,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAC3B,MAAM,WAAW,GAAG,MAAM;QACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,IAAI,OAAO,CAAC;QACxE,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,GAAG,YAAY,CAAC,MAAM,CAAC;QACvB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAA;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE;QAChF,KAAK,EAAE,SAAS;QAChB,GAAG;KACJ,CAAC,CAAA;IACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function run(args: string[]): Promise<void>;
|
package/dist/cli/dev.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `registry-shell dev` — run `next dev` against the user's project.
|
|
3
|
+
*/
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { NEXT_BIN, buildEnvVars, clearStaleNextCacheIfModeChanged, loadUserConfig, nextAppDir, writeUserSourcesCss, } from "./shared.js";
|
|
6
|
+
export async function run(args) {
|
|
7
|
+
const loaded = loadUserConfig();
|
|
8
|
+
if (loaded) {
|
|
9
|
+
console.log(`[registry-shell] Using config: ${loaded.configPath}`);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
console.log(`[registry-shell] No registry-shell.config.ts found — running in shell-only mode.`);
|
|
13
|
+
}
|
|
14
|
+
clearStaleNextCacheIfModeChanged(loaded);
|
|
15
|
+
writeUserSourcesCss(loaded);
|
|
16
|
+
const env = { ...process.env, ...buildEnvVars(loaded) };
|
|
17
|
+
const portArgs = loaded?.config.port ? ["-p", String(loaded.config.port)] : [];
|
|
18
|
+
// Webpack by default. Turbopack currently can't compile files reached via
|
|
19
|
+
// the `@user/*` cross-project aliases — it treats them as native Node ESM
|
|
20
|
+
// and crashes on `next/dynamic`. Set UI_SHELL_TURBOPACK=1 to opt in once
|
|
21
|
+
// Turbopack supports this (track https://github.com/vercel/next.js).
|
|
22
|
+
const turbopackArgs = process.env.UI_SHELL_TURBOPACK ? ["--turbopack"] : [];
|
|
23
|
+
const child = spawn(process.execPath, [NEXT_BIN, "dev", nextAppDir(), ...turbopackArgs, ...portArgs, ...args], { stdio: "inherit", env });
|
|
24
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,gCAAgC,EAChC,cAAc,EACd,UAAU,EACV,mBAAmB,GACpB,MAAM,aAAa,CAAA;AAEpB,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,kCAAkC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;IACpE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAA;IACjG,CAAC;IAED,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACxC,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAC3B,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,CAAA;IACvD,MAAM,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9E,0EAA0E;IAC1E,0EAA0E;IAC1E,yEAAyE;IACzE,qEAAqE;IACrE,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC3E,MAAM,KAAK,GAAG,KAAK,CACjB,OAAO,CAAC,QAAQ,EAChB,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,aAAa,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,EACvE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAC1B,CAAA;IAED,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC"}
|