Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ export default async function generateExampleApp({
const app = await fs.readJSON(path.join(directory, 'app.json'));

app.expo.name = `${config.project.name} Example`;
app.expo.slug = `${config.project.slug}-example`;
app.expo.slug = `${config.project.identifier}-example`;
app.expo.android = app.expo.android ?? {};
app.expo.android.package = `${config.project.package}.example`;
app.expo.ios = app.expo.ios ?? {};
Expand Down
5 changes: 4 additions & 1 deletion packages/create-react-native-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ async function create() {

let addedNitro = false;

if (config.project.moduleConfig === 'nitro-modules') {
if (
config.project.moduleConfig === 'nitro-modules' ||
config.project.viewConfig === 'nitro-view'
) {
addedNitro = await addNitroDependencyToLocalLibrary(config);
}

Expand Down
13 changes: 12 additions & 1 deletion packages/create-react-native-library/src/inform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export function printLocalLibNextSteps({
addedNitro: boolean;
packageManager: string;
}) {
const isNitro =
config.project.moduleConfig === 'nitro-modules' ||
config.project.viewConfig === 'nitro-view';

console.log(
dedent(`
${kleur.magenta(
Expand All @@ -64,11 +68,18 @@ export function printLocalLibNextSteps({
: `- Link the library at ${kleur.blue(
path.relative(process.cwd(), folder)
)} based on your project setup\n`) +
(config.project.moduleConfig === 'nitro-modules' && !addedNitro
(isNitro && !addedNitro
? `- Run ${kleur.blue(
`${packageManager} add react-native-nitro-modules`
)} and ${kleur.blue(
`${packageManager} add --dev nitrogen`
)} to install nitro modules \n`
: '') +
(isNitro
? `- Run ${kleur.blue(
`cd ${path.relative(process.cwd(), folder)} && npx nitrogen`
)} to generate the nitro code \n`
: '') +
`- Run ${kleur.blue(
'pod install --project-directory=ios'
)} to install dependencies with CocoaPods\n` +
Expand Down
14 changes: 11 additions & 3 deletions packages/create-react-native-library/src/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,17 @@ export const prompt = create(['[name]'], {

return undefined;
},
validate: (input) =>
validateNpmPackage(input).validForNewPackages ||
'Must be a valid npm package name',
validate: (input) => {
if (!validateNpmPackage(input).validForNewPackages) {
return 'Must be a valid npm package name';
}

if (!/^[a-z]/.test(input.replace(/^(react-native-|@[^/]+\/)/, ''))) {
return 'Must start with a letter after the scope or the react-native- prefix';
}

return true;
},
required: true,
},
description: {
Expand Down
124 changes: 36 additions & 88 deletions packages/create-react-native-library/src/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ export type TemplateVersions = {
nitro: string | undefined;
};

export type ModuleConfig =
'native-modules' | 'turbo-modules' | 'nitro-modules' | null;
export type ModuleConfig = 'turbo-modules' | 'nitro-modules' | null;

export type ViewConfig = 'paper-view' | 'fabric-view' | 'nitro-view' | null;
export type ViewConfig = 'fabric-view' | 'nitro-view' | null;

// Please think at least 5 times before introducing a new config key
// You can just reuse the existing ones most of the time
Expand Down Expand Up @@ -201,9 +200,10 @@ export function generateTemplateConfiguration({
? // If the project name is already in PascalCase, use it as-is
basename
: // Otherwise, convert it to PascalCase and remove any non-alphanumeric characters
`${project.charAt(0).toUpperCase()}${project
.replace(/[^a-z0-9](\w)/g, (_, $1: string) => $1.toUpperCase())
.slice(1)}`,
project
.split(/[^a-z0-9]+/)
.map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)
.join(''),
package: pack,
package_dir: pack.replace(/\./g, path.sep),
package_cpp: pack.replace(/\./g, '_'),
Expand Down Expand Up @@ -277,104 +277,52 @@ export async function applyTemplates(
}
}

if (answers.languages === 'js') {
await applyTemplate(config, JS_FILES, folder);

if (config.example != null) {
if (config.example === 'expo') {
await applyTemplate(config, EXAMPLE_EXPO_FILES, folder);
} else {
await applyTemplate(config, EXAMPLE_BARE_FILES, folder);
}
if (config.example != null) {
if (config.example === 'expo') {
await applyTemplate(config, EXAMPLE_EXPO_FILES, folder);
} else {
await applyTemplate(config, EXAMPLE_BARE_FILES, folder);
}
} else {
if (answers.languages === 'cpp') {
if (config.example === 'expo') {
await applyTemplate(config, EXAMPLE_EXPO_FILES, folder);

if (config.project.native) {
await applyTemplate(config, EXAMPLE_NATIVE_COMMON_FILES, folder);
}
} else if (config.example != null) {
await applyTemplate(config, EXAMPLE_BARE_FILES, folder);

if (config.project.native) {
await applyTemplate(config, EXAMPLE_NATIVE_COMMON_FILES, folder);
}
}

await applyTemplate(config, NATIVE_FILES['module_new'], folder);
await applyTemplate(config, CPP_FILES, folder);

if (config.example === 'expo' || config.tools.includes('vite')) {
await applyTemplate(config, JS_FILES, folder);
}

return;
if (config.project.native) {
await applyTemplate(config, EXAMPLE_NATIVE_COMMON_FILES, folder);
}
}

await applyTemplate(config, NATIVE_COMMON_FILES, folder);

if (config.example === 'expo') {
await applyTemplate(config, EXAMPLE_EXPO_FILES, folder);
if (answers.languages === 'js') {
await applyTemplate(config, JS_FILES, folder);

if (config.project.native) {
await applyTemplate(config, EXAMPLE_NATIVE_COMMON_FILES, folder);
}
} else if (config.example != null) {
await applyTemplate(config, EXAMPLE_BARE_FILES, folder);
return;
}

if (config.project.native) {
await applyTemplate(config, EXAMPLE_NATIVE_COMMON_FILES, folder);
}
}
if (answers.languages === 'cpp') {
await applyTemplate(config, NATIVE_FILES['module_new'], folder);
await applyTemplate(config, CPP_FILES, folder);
} else {
await applyTemplate(config, NATIVE_COMMON_FILES, folder);

if (config.project.moduleConfig === 'nitro-modules') {
await applyTemplate(config, NITRO_COMMON_FILES, folder);
await applyTemplate(config, NATIVE_FILES['module_nitro'], folder);

if (config.example === 'expo' || config.tools.includes('vite')) {
await applyTemplate(config, JS_FILES, folder);
}

return;
}

if (config.project.viewConfig === 'nitro-view') {
} else if (config.project.viewConfig === 'nitro-view') {
await applyTemplate(config, NITRO_COMMON_FILES, folder);
await applyTemplate(config, NATIVE_FILES['view_nitro'], folder);

if (config.example === 'expo' || config.tools.includes('vite')) {
await applyTemplate(config, JS_VIEW_FILES, folder);
}

return;
}

if (config.project.moduleConfig !== null) {
await applyTemplate(config, NATIVE_FILES[`module_new`], folder);
} else if (config.project.moduleConfig !== null) {
await applyTemplate(config, NATIVE_FILES['module_new'], folder);
await applyTemplate(config, OBJC_FILES['module_common'], folder);
await applyTemplate(config, KOTLIN_FILES['module_new'], folder);
} else {
await applyTemplate(config, NATIVE_FILES[`view_new`], folder);
await applyTemplate(config, NATIVE_FILES['view_new'], folder);
await applyTemplate(config, OBJC_FILES['view_new'], folder);
await applyTemplate(config, KOTLIN_FILES['view_new'], folder);
}
}

if (config.project.moduleConfig !== null) {
await applyTemplate(config, OBJC_FILES[`module_common`], folder);
if (config.example === 'expo' || config.tools.includes('vite')) {
if (config.project.viewConfig !== null) {
await applyTemplate(config, JS_VIEW_FILES, folder);
} else {
await applyTemplate(config, OBJC_FILES[`view_new`], folder);
}

const templateType = `${
config.project.moduleConfig !== null ? 'module' : 'view'
}_new` as const;

await applyTemplate(config, KOTLIN_FILES[templateType], folder);

if (config.example === 'expo' || config.tools.includes('vite')) {
if (config.project.viewConfig !== null) {
await applyTemplate(config, JS_VIEW_FILES, folder);
} else {
await applyTemplate(config, JS_FILES, folder);
}
await applyTemplate(config, JS_FILES, folder);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/create-react-native-library/src/utils/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { TemplateConfiguration } from '../template.ts';

type PackageJson = {
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
};

/** @returns `true` if successfull */
Expand All @@ -21,10 +22,13 @@ export async function addNitroDependencyToLocalLibrary(

const appPackageJson: PackageJson = await fs.readJson(appPackageJsonPath);
const dependencies = appPackageJson['dependencies'] ?? {};
const devDependencies = appPackageJson['devDependencies'] ?? {};

dependencies['react-native-nitro-modules'] = config.versions.nitro;
devDependencies['nitrogen'] = config.versions.nitro;

appPackageJson['dependencies'] = dependencies;
appPackageJson['devDependencies'] = devDependencies;
await fs.writeJson(appPackageJsonPath, appPackageJson, {
spaces: 2,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { spawn } from './spawn.ts';
export async function resolveNpmPackageVersion(
name: string,
fallback: string,
timeout: number = 1000
timeout: number = 5000
): Promise<string> {
let result: string;

Expand All @@ -14,7 +14,7 @@ export async function resolveNpmPackageVersion(
new Promise<string>((resolve) => {
setTimeout(() => {
resolve(fallback);
}, timeout);
}, timeout).unref();
}),
promise,
]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "<%- project.slug -%>",
"version": "0.0.0",
"description": "<%- project.description %>",
"description": <%- JSON.stringify(project.description) %>,
"main": "src/index",
<% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%>
"codegenConfig": {
"name": "<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
"type": <%- project.viewConfig !== null ? '"all"': '"modules"' %>,
Expand All @@ -20,6 +21,7 @@
<% } -%>
}
},
<% } -%>
"author": "<%- author.name -%> <<%- author.email -%>> (<%- author.url -%>)",
"license": "UNLICENSED",
"homepage": "<%- repo -%>#readme"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ runs:
using: composite
steps:
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: .nvmrc

- name: Restore dependencies
id: yarn-cache
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
**/node_modules
Expand All @@ -28,7 +28,7 @@ runs:

- name: Cache dependencies
if: steps.yarn-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
**/node_modules
Expand Down
Loading
Loading