Skip to content

Commit b36cb93

Browse files
committed
refactor: move config into template
1 parent 839c88a commit b36cb93

File tree

4 files changed

+130
-145
lines changed

4 files changed

+130
-145
lines changed

packages/create-react-native-library/src/config.ts

Lines changed: 0 additions & 102 deletions
This file was deleted.

packages/create-react-native-library/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import { addCodegenBuildScript } from './exampleApp/addCodegenBuildScript';
99
import { createInitialGitCommit } from './utils/initialCommit';
1010
import { assertAnswers, assertNpx } from './utils/assert';
1111
import { resolveBobVersionWithFallback } from './utils/promiseWithFallback';
12-
import { generateTemplateConfiguration } from './config';
13-
import { applyTemplates } from './template';
12+
import { applyTemplates, generateTemplateConfiguration } from './template';
1413
import {
1514
createQuestions,
1615
createMetadata,

packages/create-react-native-library/src/nextSteps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'path';
22
import fs from 'fs-extra';
33
import dedent from 'dedent';
4-
import type { TemplateConfiguration } from './config';
4+
import type { TemplateConfiguration } from './template';
55
import kleur from 'kleur';
66

77
export async function printNextSteps(

packages/create-react-native-library/src/template.ts

Lines changed: 128 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,162 @@
11
import path from 'path';
22
import fs from 'fs-extra';
33
import ejs from 'ejs';
4-
import type { TemplateConfiguration } from './config';
5-
import type { Answers } from './input';
4+
import type { Answers, ExampleApp, SupportedArchitecture } from './input';
5+
6+
// Please think at least 5 times before introducing a new config key
7+
// You can just reuse the existing ones most of the time
8+
export type TemplateConfiguration = {
9+
bob: {
10+
version: string;
11+
};
12+
project: {
13+
slug: string;
14+
description: string;
15+
name: string;
16+
package: string;
17+
package_dir: string;
18+
package_cpp: string;
19+
identifier: string;
20+
native: boolean;
21+
arch: SupportedArchitecture;
22+
cpp: boolean;
23+
swift: boolean;
24+
view: boolean;
25+
module: boolean;
26+
};
27+
author: {
28+
name: string;
29+
email: string;
30+
url: string;
31+
};
32+
repo: string;
33+
example: ExampleApp;
34+
year: number;
35+
};
636

737
const BINARIES = [
838
/(gradlew|\.(jar|keystore|png|jpg|gif))$/,
939
/\$\.yarn(?![a-z])/,
1040
];
1141

12-
const COMMON_FILES = path.resolve(__dirname, '../../templates/common');
42+
const COMMON_FILES = path.resolve(__dirname, '../templates/common');
1343
const COMMON_EXAMPLE_FILES = path.resolve(
1444
__dirname,
15-
'../../templates/common-example'
16-
);
17-
const COMMON_LOCAL_FILES = path.resolve(
18-
__dirname,
19-
'../../templates/common-local'
45+
'../templates/common-example'
2046
);
21-
const JS_FILES = path.resolve(__dirname, '../../templates/js-library');
22-
const EXPO_FILES = path.resolve(__dirname, '../../templates/expo-library');
23-
const CPP_FILES = path.resolve(__dirname, '../../templates/cpp-library');
47+
const COMMON_LOCAL_FILES = path.resolve(__dirname, '../templates/common-local');
48+
const JS_FILES = path.resolve(__dirname, '../templates/js-library');
49+
const EXPO_FILES = path.resolve(__dirname, '../templates/expo-library');
50+
const CPP_FILES = path.resolve(__dirname, '../templates/cpp-library');
2451
const NATIVE_COMMON_FILES = path.resolve(
2552
__dirname,
26-
'../../templates/native-common'
53+
'../templates/native-common'
2754
);
2855
const NATIVE_COMMON_EXAMPLE_FILES = path.resolve(
2956
__dirname,
30-
'../../templates/native-common-example'
57+
'../templates/native-common-example'
3158
);
3259

3360
const NATIVE_FILES = {
34-
module_legacy: path.resolve(
35-
__dirname,
36-
'../../templates/native-library-legacy'
37-
),
38-
module_new: path.resolve(__dirname, '../../templates/native-library-new'),
39-
module_mixed: path.resolve(__dirname, '../../templates/native-library-mixed'),
40-
view_legacy: path.resolve(__dirname, '../../templates/native-view-legacy'),
41-
view_mixed: path.resolve(__dirname, '../../templates/native-view-mixed'),
42-
view_new: path.resolve(__dirname, '../../templates/native-view-new'),
61+
module_legacy: path.resolve(__dirname, '../templates/native-library-legacy'),
62+
module_new: path.resolve(__dirname, '../templates/native-library-new'),
63+
module_mixed: path.resolve(__dirname, '../templates/native-library-mixed'),
64+
view_legacy: path.resolve(__dirname, '../templates/native-view-legacy'),
65+
view_mixed: path.resolve(__dirname, '../templates/native-view-mixed'),
66+
view_new: path.resolve(__dirname, '../templates/native-view-new'),
4367
} as const;
4468

4569
const OBJC_FILES = {
46-
module_common: path.resolve(__dirname, '../../templates/objc-library'),
47-
view_legacy: path.resolve(__dirname, '../../templates/objc-view-legacy'),
48-
view_mixed: path.resolve(__dirname, '../../templates/objc-view-mixed'),
49-
view_new: path.resolve(__dirname, '../../templates/objc-view-new'),
70+
module_common: path.resolve(__dirname, '../templates/objc-library'),
71+
view_legacy: path.resolve(__dirname, '../templates/objc-view-legacy'),
72+
view_mixed: path.resolve(__dirname, '../templates/objc-view-mixed'),
73+
view_new: path.resolve(__dirname, '../templates/objc-view-new'),
5074
} as const;
5175

5276
const KOTLIN_FILES = {
53-
module_legacy: path.resolve(
54-
__dirname,
55-
'../../templates/kotlin-library-legacy'
56-
),
57-
module_new: path.resolve(__dirname, '../../templates/kotlin-library-new'),
58-
module_mixed: path.resolve(__dirname, '../../templates/kotlin-library-mixed'),
59-
view_legacy: path.resolve(__dirname, '../../templates/kotlin-view-legacy'),
60-
view_mixed: path.resolve(__dirname, '../../templates/kotlin-view-mixed'),
61-
view_new: path.resolve(__dirname, '../../templates/kotlin-view-new'),
77+
module_legacy: path.resolve(__dirname, '../templates/kotlin-library-legacy'),
78+
module_new: path.resolve(__dirname, '../templates/kotlin-library-new'),
79+
module_mixed: path.resolve(__dirname, '../templates/kotlin-library-mixed'),
80+
view_legacy: path.resolve(__dirname, '../templates/kotlin-view-legacy'),
81+
view_mixed: path.resolve(__dirname, '../templates/kotlin-view-mixed'),
82+
view_new: path.resolve(__dirname, '../templates/kotlin-view-new'),
6283
} as const;
6384

6485
const SWIFT_FILES = {
65-
module_legacy: path.resolve(
66-
__dirname,
67-
'../../templates/swift-library-legacy'
68-
),
69-
view_legacy: path.resolve(__dirname, '../../templates/swift-view-legacy'),
86+
module_legacy: path.resolve(__dirname, '../templates/swift-library-legacy'),
87+
view_legacy: path.resolve(__dirname, '../templates/swift-view-legacy'),
7088
} as const;
7189

90+
export function generateTemplateConfiguration({
91+
bobVersion,
92+
basename,
93+
answers,
94+
}: {
95+
bobVersion: string;
96+
basename: string;
97+
answers: Required<Answers>;
98+
}): TemplateConfiguration {
99+
const { slug, languages, type } = answers;
100+
101+
const arch =
102+
type === 'module-new' || type === 'view-new'
103+
? 'new'
104+
: type === 'module-mixed' || type === 'view-mixed'
105+
? 'mixed'
106+
: 'legacy';
107+
108+
const project = slug.replace(/^(react-native-|@[^/]+\/)/, '');
109+
let namespace: string | undefined;
110+
111+
if (slug.startsWith('@') && slug.includes('/')) {
112+
namespace = slug
113+
.split('/')[0]
114+
?.replace(/[^a-z0-9]/g, '')
115+
.toLowerCase();
116+
}
117+
118+
// Create a package identifier with specified namespace when possible
119+
const pack = `${namespace ? `${namespace}.` : ''}${project
120+
.replace(/[^a-z0-9]/g, '')
121+
.toLowerCase()}`;
122+
123+
return {
124+
bob: {
125+
version: bobVersion,
126+
},
127+
project: {
128+
slug,
129+
description: answers.description,
130+
name:
131+
/^[A-Z]/.test(basename) && /^[a-z0-9]+$/i.test(basename)
132+
? // If the project name is already in PascalCase, use it as-is
133+
basename
134+
: // Otherwise, convert it to PascalCase and remove any non-alphanumeric characters
135+
`${project.charAt(0).toUpperCase()}${project
136+
.replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase())
137+
.slice(1)}`,
138+
package: pack,
139+
package_dir: pack.replace(/\./g, '/'),
140+
package_cpp: pack.replace(/\./g, '_'),
141+
identifier: slug.replace(/[^a-z0-9]+/g, '-').replace(/^-/, ''),
142+
native: languages !== 'js',
143+
arch,
144+
cpp: languages === 'cpp',
145+
swift: languages === 'kotlin-swift',
146+
view: answers.type.startsWith('view'),
147+
module: answers.type.startsWith('module'),
148+
},
149+
author: {
150+
name: answers.authorName,
151+
email: answers.authorEmail,
152+
url: answers.authorUrl,
153+
},
154+
repo: answers.repoUrl,
155+
example: answers.example,
156+
year: new Date().getFullYear(),
157+
};
158+
}
159+
72160
export async function applyTemplates(
73161
answers: Answers,
74162
config: TemplateConfiguration,

0 commit comments

Comments
 (0)