Skip to content

Commit 012de5e

Browse files
committed
Organize presets into classes
1 parent 95c60a2 commit 012de5e

File tree

9 files changed

+147
-106
lines changed

9 files changed

+147
-106
lines changed

src/init-app.ts

+11-106
Original file line numberDiff line numberDiff line change
@@ -10,100 +10,8 @@ import * as path from "path";
1010
import * as fs from "fs";
1111
import * as url from 'url';
1212

13-
type AppOptions = {
14-
'public-dir': string | undefined,
15-
'static-dir': string | undefined,
16-
spa: string | null | undefined,
17-
'not-found-page': string | null | ((options: AppOptions) => string | undefined) | undefined,
18-
'auto-index': string[] | null | undefined,
19-
'auto-ext': string[] | null | undefined,
20-
name: string,
21-
author: string,
22-
description: string,
23-
'service-id': string | undefined,
24-
};
25-
26-
type Preset = {
27-
name: string,
28-
inherit?: string,
29-
check?: PresetCheckFunc | undefined,
30-
defaultOptions?: Partial<AppOptions>,
31-
};
32-
33-
type PresetCheckFunc = (packageJson: any | null, options: AppOptions) => boolean;
34-
35-
const presets: Record<string, Preset | string> = {
36-
'cra': {
37-
name: 'Create React App',
38-
defaultOptions: {
39-
'public-dir': './build',
40-
'static-dir': './build/static',
41-
spa: undefined,
42-
name: 'my-create-react-app',
43-
description: 'Compute@Edge static site from create-react-app',
44-
},
45-
check: (packageJson, options) => {
46-
if(packageJson == null) {
47-
console.error("❌ Can't read/parse package.json");
48-
console.error("Run this from a create-react-app project directory.");
49-
return false;
50-
}
51-
if(packageJson?.dependencies?.['react-scripts'] == null) {
52-
console.error("❌ Can't find react-scripts in dependencies");
53-
console.error("Run this from a create-react-app project directory.");
54-
console.log("If this is a project created with create-react-app and has since been ejected, specify preset cra-eject to skip this check.")
55-
return false;
56-
}
57-
return true;
58-
},
59-
},
60-
'cra-eject': {
61-
name: 'Create React App (Ejected)',
62-
inherit: 'cra',
63-
check: undefined,
64-
},
65-
'create-react-app': 'cra',
66-
'vite': {
67-
name: 'Vite',
68-
defaultOptions: {
69-
'public-dir': './dist',
70-
'static-dir': undefined,
71-
spa: undefined,
72-
},
73-
},
74-
'sveltekit': {
75-
name: 'SvelteKit',
76-
defaultOptions: {
77-
'public-dir': './dist',
78-
'static-dir': undefined,
79-
spa: undefined,
80-
},
81-
},
82-
'next': {
83-
name: 'Next.js',
84-
defaultOptions: {
85-
'public-dir': './out',
86-
'static-dir': undefined,
87-
spa: undefined,
88-
},
89-
},
90-
'gatsby': {
91-
name: 'Gatsby',
92-
defaultOptions: {
93-
'public-dir': './public',
94-
'static-dir': undefined,
95-
spa: undefined,
96-
},
97-
},
98-
'docusaurus': {
99-
name: 'Docusaurus',
100-
defaultOptions: {
101-
'public-dir': './build',
102-
'static-dir': undefined,
103-
spa: undefined,
104-
},
105-
},
106-
};
13+
import { AppOptions, IPresetBase } from './presets/preset-base.js';
14+
import { presets } from './presets/index.js';
10715

10816
const defaultOptions: AppOptions = {
10917
'public-dir': undefined,
@@ -137,23 +45,18 @@ function pickKeys(keys: string[], object: Record<string, any>): Record<string, a
13745
export function initApp(commandLineValues: CommandLineOptions) {
13846

13947
let options: AppOptions = defaultOptions;
140-
let check: PresetCheckFunc | undefined = undefined;
48+
let preset: IPresetBase | null = null;
14149

14250
const presetName = (commandLineValues['preset'] as string | null) ?? 'none';
14351
if(presetName !== 'none') {
144-
if(presets[presetName] == null) {
52+
const presetClass = presets[presetName];
53+
if(presetClass == null) {
14554
console.error('Unknown preset name.');
14655
console.error("--preset must be one of: none, " + (Object.keys(presets).join(', ')));
14756
process.exit(1);
57+
return;
14858
}
149-
150-
let presetDef: string | Preset = presetName;
151-
while(typeof presetDef === 'string') {
152-
presetDef = presets[presetDef];
153-
}
154-
155-
options = { ...options, ...presetDef.defaultOptions };
156-
check = presetDef.check;
59+
preset = new presetClass();
15760
}
15861

15962
let packageJson;
@@ -167,6 +70,7 @@ export function initApp(commandLineValues: CommandLineOptions) {
16770

16871
options = {
16972
...options,
73+
...(preset != null ? preset.defaultOptions : {}),
17074
...pickKeys(['author', 'name', 'description'], packageJson ?? {}),
17175
...pickKeys(['public-dir', 'static-dir', 'spa', 'not-found-page', 'auto-index', 'auto-ext', 'author', 'name', 'description', 'service-id'], commandLineValues)
17276
};
@@ -176,10 +80,11 @@ export function initApp(commandLineValues: CommandLineOptions) {
17680
options['not-found-page'] = options['not-found-page'](options);
17781
}
17882

179-
if(check != null) {
180-
if(!check(packageJson, options)) {
83+
if(preset != null) {
84+
if(!preset.check(packageJson, options)) {
18185
console.log("Failed preset check.");
18286
process.exit(1);
87+
return;
18388
}
18489
}
18590

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { IPresetBase } from '../preset-base.js';
2+
3+
export class CreateReactAppPreset implements IPresetBase {
4+
name = 'Create React App';
5+
defaultOptions = {
6+
'public-dir': './build',
7+
'static-dir': './build/static',
8+
spa: undefined,
9+
name: 'my-create-react-app',
10+
description: 'Compute@Edge static site from create-react-app',
11+
};
12+
13+
check(packageJson: any): boolean {
14+
if(packageJson == null) {
15+
console.error("❌ Can't read/parse package.json");
16+
console.error("Run this from a create-react-app project directory.");
17+
return false;
18+
}
19+
if(packageJson?.dependencies?.['react-scripts'] == null) {
20+
console.error("❌ Can't find react-scripts in dependencies");
21+
console.error("Run this from a create-react-app project directory.");
22+
console.log("If this is a project created with create-react-app and has since been ejected, specify preset cra-eject to skip this check.")
23+
return false;
24+
}
25+
return true;
26+
}
27+
28+
}
29+
30+
export class CreateReactAppEjectedPreset extends CreateReactAppPreset {
31+
name = 'Create React App (Ejected)';
32+
check() {
33+
return true;
34+
}
35+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IPresetBase } from '../preset-base.js';
2+
3+
export class DocusaurusPreset implements IPresetBase {
4+
name = 'Docusaurus';
5+
defaultOptions = {
6+
'public-dir': './build',
7+
'static-dir': undefined,
8+
spa: undefined,
9+
};
10+
check() {
11+
return true;
12+
}
13+
}

src/presets/implementations/gatsby.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IPresetBase } from '../preset-base.js';
2+
3+
export class GatsbyPreset implements IPresetBase {
4+
name = 'Gatsby';
5+
defaultOptions = {
6+
'public-dir': './public',
7+
'static-dir': undefined,
8+
spa: undefined,
9+
};
10+
check() {
11+
return true;
12+
}
13+
}

src/presets/implementations/next.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IPresetBase } from '../preset-base.js';
2+
3+
export class NextJsPreset implements IPresetBase {
4+
name = 'Next.js';
5+
defaultOptions = {
6+
'public-dir': './out',
7+
'static-dir': undefined,
8+
spa: undefined,
9+
};
10+
check() {
11+
return true;
12+
}
13+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IPresetBase } from '../preset-base.js';
2+
3+
export class SvelteKitPreset implements IPresetBase {
4+
name = 'SvelteKit';
5+
defaultOptions = {
6+
'public-dir': './dist',
7+
'static-dir': undefined,
8+
spa: undefined,
9+
};
10+
check() {
11+
return true;
12+
}
13+
}

src/presets/implementations/vite.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IPresetBase } from '../preset-base.js';
2+
3+
export class VitePreset implements IPresetBase {
4+
name = 'Vite';
5+
defaultOptions = {
6+
'public-dir': './dist',
7+
'static-dir': undefined,
8+
spa: undefined,
9+
};
10+
check() {
11+
return true;
12+
}
13+
}

src/presets/index.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { IPresetBase } from './preset-base.js';
2+
import { CreateReactAppPreset, CreateReactAppEjectedPreset } from './implementations/create-react-app.js';
3+
import { VitePreset } from './implementations/vite.js';
4+
import { SvelteKitPreset } from './implementations/sveltekit.js';
5+
import { NextJsPreset } from './implementations/next.js';
6+
import { GatsbyPreset } from './implementations/gatsby.js';
7+
import { DocusaurusPreset } from './implementations/docusaurus.js';
8+
9+
export const presets: Record<string, new() => IPresetBase> = {
10+
'cra': CreateReactAppPreset,
11+
'create-react-app': CreateReactAppPreset,
12+
'cra-eject': CreateReactAppEjectedPreset,
13+
'vite': VitePreset,
14+
'sveltekit': SvelteKitPreset,
15+
'next': NextJsPreset,
16+
'gatsby': GatsbyPreset,
17+
'docusaurus': DocusaurusPreset,
18+
};

src/presets/preset-base.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export type AppOptions = {
2+
'public-dir': string | undefined,
3+
'static-dir': string | undefined,
4+
spa: string | null | undefined,
5+
'not-found-page': string | null | ((options: AppOptions) => string | undefined) | undefined,
6+
'auto-index': string[] | null | undefined,
7+
'auto-ext': string[] | null | undefined,
8+
name: string,
9+
author: string,
10+
description: string,
11+
'service-id': string | undefined,
12+
};
13+
14+
export interface IPresetBase {
15+
name: string;
16+
defaultOptions: Partial<AppOptions>;
17+
check(packageJson: any | null, options: AppOptions): boolean;
18+
}

0 commit comments

Comments
 (0)