Skip to content

Commit 968fae8

Browse files
committed
feat: overlays
1 parent 4aab0cd commit 968fae8

File tree

6 files changed

+57
-18
lines changed

6 files changed

+57
-18
lines changed

src/add-ons.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ function loadAddOn(addOn: AddOn): AddOn {
139139
return addOn
140140
}
141141

142-
async function loadRemoteAddOn(url: string): Promise<AddOn> {
142+
export async function loadRemoteAddOn(url: string): Promise<AddOn> {
143143
const response = await fetch(url)
144144
const fileContent = await response.json()
145145
fileContent.id = url

src/cli.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export function cli() {
114114
},
115115
)
116116
.option('--list-add-ons', 'list all available add-ons', false)
117+
.option('--overlay [url]', 'add an overlay from a URL', false)
117118
.option('--mcp', 'run the MCP server', false)
118119
.option('--mcp-sse', 'run the MCP server in SSE mode', false)
119120
.action(async (projectName: string, options: CliOptions) => {

src/config-file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type PersistedOptions = Exclude<
1515
export async function writeConfigFile(
1616
environment: Environment,
1717
targetDir: string,
18-
options: Required<Options>,
18+
options: Options,
1919
) {
2020
const persistedOptions: PersistedOptions = {
2121
...options,

src/create-app.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function jsSafeName(name: string) {
4343
function createTemplateFile(
4444
environment: Environment,
4545
projectName: string,
46-
options: Required<Options>,
46+
options: Options,
4747
targetDir: string,
4848
) {
4949
return async function templateFile(
@@ -140,7 +140,7 @@ function createTemplateFile(
140140
async function createPackageJSON(
141141
environment: Environment,
142142
projectName: string,
143-
options: Required<Options>,
143+
options: Options,
144144
templateDir: string,
145145
routerDir: string,
146146
targetDir: string,
@@ -278,7 +278,7 @@ async function copyAddOnFile(
278278
}
279279

280280
export async function createApp(
281-
options: Required<Options>,
281+
options: Options,
282282
{
283283
silent = false,
284284
environment,
@@ -486,6 +486,13 @@ export async function createApp(
486486
}
487487
}
488488
}
489+
if (options.overlay) {
490+
if (options.overlay.shadcnComponents) {
491+
for (const component of options.overlay.shadcnComponents) {
492+
shadcnComponents.add(component)
493+
}
494+
}
495+
}
489496

490497
if (shadcnComponents.size > 0) {
491498
s?.start(
@@ -664,13 +671,11 @@ export async function createApp(
664671
// Create the README.md
665672
await templateFile(templateDirBase, 'README.md.ejs')
666673

667-
// Adding overlays
668-
for (const addOn of options.chosenAddOns.filter(
669-
(addOn) => addOn.type === 'overlay',
670-
)) {
671-
s?.start(`Setting up overlay ${addOn.name}...`)
672-
await runAddOn(addOn)
673-
s?.stop(`Overlay ${addOn.name} setup complete`)
674+
// Adding overlay
675+
if (options.overlay) {
676+
s?.start(`Setting up overlay ${options.overlay.name}...`)
677+
await runAddOn(options.overlay)
678+
s?.stop(`Overlay ${options.overlay.name} setup complete`)
674679
}
675680

676681
// Install dependencies

src/options.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ import {
1414
} from './package-manager.js'
1515
import { DEFAULT_TOOLCHAIN, SUPPORTED_TOOLCHAINS } from './toolchain.js'
1616
import { CODE_ROUTER, DEFAULT_FRAMEWORK, FILE_ROUTER } from './constants.js'
17-
import { finalizeAddOns, getAllAddOns } from './add-ons.js'
17+
import { finalizeAddOns, getAllAddOns, loadRemoteAddOn } from './add-ons.js'
1818

19-
import type { AddOn, CliOptions, Options, Variable } from './types.js'
19+
import type { AddOn, CliOptions, Options, Overlay, Variable } from './types.js'
2020

2121
// If all CLI options are provided, use them directly
2222
export async function normalizeOptions(
2323
cliOptions: CliOptions,
24-
): Promise<Required<Options> | undefined> {
24+
): Promise<Options | undefined> {
2525
// in some cases, if you use windows/powershell, the argument for addons
2626
// if sepparated by comma is not really passed as an array, but as a string
2727
// with spaces, We need to normalize this edge case.
@@ -42,14 +42,32 @@ export async function normalizeOptions(
4242
tailwind = true
4343
}
4444

45+
let mode: typeof FILE_ROUTER | typeof CODE_ROUTER =
46+
cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER
47+
48+
const overlay = cliOptions.overlay
49+
? ((await loadRemoteAddOn(cliOptions.overlay)) as Overlay)
50+
: undefined
51+
52+
if (overlay) {
53+
tailwind = overlay.tailwind
54+
typescript = overlay.typescript
55+
cliOptions.framework = overlay.framework
56+
mode = overlay.mode
57+
}
58+
4559
let addOns = false
4660
let chosenAddOns: Array<AddOn> = []
47-
if (Array.isArray(cliOptions.addOns)) {
61+
if (Array.isArray(cliOptions.addOns) || overlay?.dependsOn) {
4862
addOns = true
63+
let finalAddOns = [...(overlay?.dependsOn || [])]
64+
if (cliOptions.addOns && Array.isArray(cliOptions.addOns)) {
65+
finalAddOns = [...finalAddOns, ...cliOptions.addOns]
66+
}
4967
chosenAddOns = await finalizeAddOns(
5068
cliOptions.framework || DEFAULT_FRAMEWORK,
5169
cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER,
52-
cliOptions.addOns,
70+
finalAddOns,
5371
)
5472
tailwind = true
5573
typescript = true
@@ -65,11 +83,12 @@ export async function normalizeOptions(
6583
getPackageManager() ||
6684
DEFAULT_PACKAGE_MANAGER,
6785
toolchain: cliOptions.toolchain || DEFAULT_TOOLCHAIN,
68-
mode: cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER,
86+
mode,
6987
git: !!cliOptions.git,
7088
addOns,
7189
chosenAddOns,
7290
variableValues: {},
91+
overlay,
7392
}
7493
}
7594
}

src/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface Options {
1616
chosenAddOns: Array<AddOn>
1717
git: boolean
1818
variableValues: Record<string, string | number | boolean>
19+
overlay?: AddOn | undefined
1920
}
2021

2122
export interface CliOptions {
@@ -30,6 +31,7 @@ export interface CliOptions {
3031
listAddOns?: boolean
3132
mcp?: boolean
3233
mcpSse?: boolean
34+
overlay?: string
3335
}
3436

3537
export type Environment = {
@@ -102,3 +104,15 @@ export type AddOn = {
102104
files?: Record<string, string>
103105
deletedFiles?: Array<string>
104106
}
107+
108+
export type Overlay = AddOn & {
109+
type: 'overlay'
110+
version: string
111+
author: string
112+
link: string
113+
license: string
114+
mode: typeof CODE_ROUTER | typeof FILE_ROUTER
115+
framework: Framework
116+
typescript: boolean
117+
tailwind: boolean
118+
}

0 commit comments

Comments
 (0)