From 1066adc8d05f8a4de31a0ad661cdc980799b600f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?=
Date: Sat, 9 Mar 2024 13:53:06 +0100
Subject: [PATCH 01/47] feat: init baca cli
---
.eslintignore | 2 +-
package.json | 1 +
scripts/cli/actions/bootstrap.ts | 3 +
scripts/cli/actions/generate.ts | 39 ++++++++++
scripts/cli/actions/index.ts | 19 +++++
scripts/cli/build/actions/bootstrap.js | 7 ++
scripts/cli/build/actions/generate.js | 76 +++++++++++++++++++
scripts/cli/build/actions/index.js | 20 +++++
scripts/cli/build/actions/parseAction.js | 11 +++
.../cli/build/commands/generate.command.js | 1 +
.../cli/build/commands/generateIconTypes.js | 22 ++++++
scripts/cli/build/constants/index.js | 4 +
scripts/cli/build/index.js | 34 +++++++++
scripts/cli/build/types/index.js | 2 +
scripts/cli/commands/generateIconTypes.ts | 17 +++++
scripts/cli/commands/generateScreen.ts | 3 +
scripts/cli/commands/index.ts | 2 +
scripts/cli/constants/index.ts | 1 +
scripts/cli/index.ts | 14 ++++
scripts/cli/tsconfig.cli.json | 13 ++++
scripts/cli/types/index.ts | 2 +
src/types/icon.d.ts | 5 --
yarn.lock | 5 ++
23 files changed, 297 insertions(+), 6 deletions(-)
create mode 100644 scripts/cli/actions/bootstrap.ts
create mode 100644 scripts/cli/actions/generate.ts
create mode 100644 scripts/cli/actions/index.ts
create mode 100644 scripts/cli/build/actions/bootstrap.js
create mode 100644 scripts/cli/build/actions/generate.js
create mode 100644 scripts/cli/build/actions/index.js
create mode 100644 scripts/cli/build/actions/parseAction.js
create mode 100644 scripts/cli/build/commands/generate.command.js
create mode 100644 scripts/cli/build/commands/generateIconTypes.js
create mode 100644 scripts/cli/build/constants/index.js
create mode 100644 scripts/cli/build/index.js
create mode 100644 scripts/cli/build/types/index.js
create mode 100644 scripts/cli/commands/generateIconTypes.ts
create mode 100644 scripts/cli/commands/generateScreen.ts
create mode 100644 scripts/cli/commands/index.ts
create mode 100644 scripts/cli/constants/index.ts
create mode 100644 scripts/cli/index.ts
create mode 100644 scripts/cli/tsconfig.cli.json
create mode 100644 scripts/cli/types/index.ts
diff --git a/.eslintignore b/.eslintignore
index 5b465972..923ce12e 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,4 +3,4 @@ node_modules/
babel.config.js
webpack.config.js
docs
-
+scripts/cli/build/
\ No newline at end of file
diff --git a/package.json b/package.json
index e636b4da..a718c382 100644
--- a/package.json
+++ b/package.json
@@ -172,6 +172,7 @@
"babel-loader": "^9.1.3",
"babel-plugin-module-resolver": "^5.0.0",
"babel-preset-expo": "^10.0.0",
+ "commander": "^12.0.0",
"cross-env": "^7.0.3",
"dotenv": "^16.4.1",
"eslint": "^8.56.0",
diff --git a/scripts/cli/actions/bootstrap.ts b/scripts/cli/actions/bootstrap.ts
new file mode 100644
index 00000000..419e225e
--- /dev/null
+++ b/scripts/cli/actions/bootstrap.ts
@@ -0,0 +1,3 @@
+export const bootstrap = () => {
+ console.log('Bootstrap')
+}
diff --git a/scripts/cli/actions/generate.ts b/scripts/cli/actions/generate.ts
new file mode 100644
index 00000000..eeab04f3
--- /dev/null
+++ b/scripts/cli/actions/generate.ts
@@ -0,0 +1,39 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+import selectPrompt from 'select-prompt'
+
+import { generateIconTypes } from '../commands/generateIconTypes'
+
+const generatePrompts = [
+ {
+ title: 'Screen',
+ value: 'screen',
+ },
+ {
+ title: 'Component',
+ value: 'component',
+ },
+ {
+ title: 'Icon types',
+ value: 'icon-types',
+ },
+]
+
+const commands = {
+ screen: () => {
+ console.log('Generate Screen')
+ },
+ component: () => {
+ console.log('Generate Component')
+ },
+ 'icon-types': generateIconTypes,
+}
+
+export const generate = () => {
+ selectPrompt('What do you want to generate?', generatePrompts).on(
+ 'submit',
+ async (value: keyof typeof commands) => {
+ commands[value]()
+ }
+ )
+}
diff --git a/scripts/cli/actions/index.ts b/scripts/cli/actions/index.ts
new file mode 100644
index 00000000..a089e1eb
--- /dev/null
+++ b/scripts/cli/actions/index.ts
@@ -0,0 +1,19 @@
+import { bootstrap } from './bootstrap'
+import { generate } from './generate'
+import { CLI_ACTIONS } from '../constants'
+import { CliActions } from '../types'
+
+const actions = {
+ generate,
+ g: generate,
+ bootstrap,
+ b: bootstrap,
+}
+
+export const parseAction = (action: CliActions) => {
+ if (!CLI_ACTIONS.includes(action)) {
+ console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
+ return
+ }
+ actions[action]()
+}
diff --git a/scripts/cli/build/actions/bootstrap.js b/scripts/cli/build/actions/bootstrap.js
new file mode 100644
index 00000000..99a3125d
--- /dev/null
+++ b/scripts/cli/build/actions/bootstrap.js
@@ -0,0 +1,7 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.bootstrap = void 0
+const bootstrap = () => {
+ console.log('Bootstrap')
+}
+exports.bootstrap = bootstrap
diff --git a/scripts/cli/build/actions/generate.js b/scripts/cli/build/actions/generate.js
new file mode 100644
index 00000000..79265a0b
--- /dev/null
+++ b/scripts/cli/build/actions/generate.js
@@ -0,0 +1,76 @@
+'use strict'
+var __awaiter =
+ (this && this.__awaiter) ||
+ function (thisArg, _arguments, P, generator) {
+ function adopt(value) {
+ return value instanceof P
+ ? value
+ : new P(function (resolve) {
+ resolve(value)
+ })
+ }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) {
+ try {
+ step(generator.next(value))
+ } catch (e) {
+ reject(e)
+ }
+ }
+ function rejected(value) {
+ try {
+ step(generator['throw'](value))
+ } catch (e) {
+ reject(e)
+ }
+ }
+ function step(result) {
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
+ }
+ step((generator = generator.apply(thisArg, _arguments || [])).next())
+ })
+ }
+var __importDefault =
+ (this && this.__importDefault) ||
+ function (mod) {
+ return mod && mod.__esModule ? mod : { default: mod }
+ }
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.generate = void 0
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+const select_prompt_1 = __importDefault(require('select-prompt'))
+const generateIconTypes_1 = require('../commands/generateIconTypes')
+const generatePrompts = [
+ {
+ title: 'Screen',
+ value: 'screen',
+ },
+ {
+ title: 'Component',
+ value: 'component',
+ },
+ {
+ title: 'Icon types',
+ value: 'icon-types',
+ },
+]
+const commands = {
+ screen: () => {
+ console.log('Generate Screen')
+ },
+ component: () => {
+ console.log('Generate Component')
+ },
+ 'icon-types': generateIconTypes_1.generateIconTypes,
+}
+const generate = () => {
+ ;(0, select_prompt_1.default)('What do you want to generate?', generatePrompts).on(
+ 'submit',
+ (value) =>
+ __awaiter(void 0, void 0, void 0, function* () {
+ commands[value]()
+ })
+ )
+}
+exports.generate = generate
diff --git a/scripts/cli/build/actions/index.js b/scripts/cli/build/actions/index.js
new file mode 100644
index 00000000..9a92f899
--- /dev/null
+++ b/scripts/cli/build/actions/index.js
@@ -0,0 +1,20 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.parseAction = void 0
+const bootstrap_1 = require('./bootstrap')
+const generate_1 = require('./generate')
+const constants_1 = require('../constants')
+const actions = {
+ generate: generate_1.generate,
+ g: generate_1.generate,
+ bootstrap: bootstrap_1.bootstrap,
+ b: bootstrap_1.bootstrap,
+}
+const parseAction = (action) => {
+ if (!constants_1.CLI_ACTIONS.includes(action)) {
+ console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
+ return
+ }
+ actions[action]()
+}
+exports.parseAction = parseAction
diff --git a/scripts/cli/build/actions/parseAction.js b/scripts/cli/build/actions/parseAction.js
new file mode 100644
index 00000000..b2439ccd
--- /dev/null
+++ b/scripts/cli/build/actions/parseAction.js
@@ -0,0 +1,11 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.parseAction = void 0
+const constants_1 = require('../constants')
+const parseAction = (action) => {
+ if (!constants_1.CLI_ACTIONS.includes(action)) {
+ console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
+ return
+ }
+}
+exports.parseAction = parseAction
diff --git a/scripts/cli/build/commands/generate.command.js b/scripts/cli/build/commands/generate.command.js
new file mode 100644
index 00000000..ccacec30
--- /dev/null
+++ b/scripts/cli/build/commands/generate.command.js
@@ -0,0 +1 @@
+'use strict'
diff --git a/scripts/cli/build/commands/generateIconTypes.js b/scripts/cli/build/commands/generateIconTypes.js
new file mode 100644
index 00000000..bb8c96c2
--- /dev/null
+++ b/scripts/cli/build/commands/generateIconTypes.js
@@ -0,0 +1,22 @@
+'use strict'
+var __importDefault =
+ (this && this.__importDefault) ||
+ function (mod) {
+ return mod && mod.__esModule ? mod : { default: mod }
+ }
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.generateIconTypes = void 0
+const fs_1 = __importDefault(require('fs'))
+const prefix = `export type IconNames =
+ | `
+const generateIconTypes = () => {
+ const json = fs_1.default.readFileSync('./assets/icomoon/selection.json')
+ const types = JSON.parse(json.toString())
+ .icons.map((icon) => `'${icon.properties.name}'`)
+ .join('\n | ')
+ .concat('\n')
+ const content = prefix + types
+ fs_1.default.writeFileSync('./src/types/icon.d.ts', content)
+ console.log('Icon types generated')
+}
+exports.generateIconTypes = generateIconTypes
diff --git a/scripts/cli/build/constants/index.js b/scripts/cli/build/constants/index.js
new file mode 100644
index 00000000..37e91333
--- /dev/null
+++ b/scripts/cli/build/constants/index.js
@@ -0,0 +1,4 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.CLI_ACTIONS = void 0
+exports.CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
diff --git a/scripts/cli/build/index.js b/scripts/cli/build/index.js
new file mode 100644
index 00000000..389511b8
--- /dev/null
+++ b/scripts/cli/build/index.js
@@ -0,0 +1,34 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+const commander_1 = require('commander')
+const actions_1 = require('./actions')
+const program = new commander_1.Command()
+program
+ .argument('')
+ .option('-d, --debug', 'Set the debug level')
+ .action((action, options, command) => {
+ ;(0, actions_1.parseAction)(action)
+ // TODO: Parse all actions
+ // Start with generate
+ // console.log({ action, options, command })
+ // if (!['g', 'generate'].includes(action)) {
+ // console.log({ action })
+ // throw new Error('Invalid action')
+ // }
+ // if (options.debug) {
+ // console.error('Called %s with options %o', command.name(), options)
+ // }
+ // selectPrompt('What do you want to generate?', [
+ // {
+ // title: 'Screen',
+ // value: 'screen',
+ // },
+ // {
+ // title: 'Component',
+ // value: 'component',
+ // },
+ // ]).on('submit', async (value: string) => {
+ // console.log(`You want me to generate a ${value}!`)
+ // })
+ })
+program.parse()
diff --git a/scripts/cli/build/types/index.js b/scripts/cli/build/types/index.js
new file mode 100644
index 00000000..0a483a32
--- /dev/null
+++ b/scripts/cli/build/types/index.js
@@ -0,0 +1,2 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
diff --git a/scripts/cli/commands/generateIconTypes.ts b/scripts/cli/commands/generateIconTypes.ts
new file mode 100644
index 00000000..e0c23a56
--- /dev/null
+++ b/scripts/cli/commands/generateIconTypes.ts
@@ -0,0 +1,17 @@
+import fs from 'fs'
+
+const prefix = `export type IconNames =
+ | `
+
+export const generateIconTypes = () => {
+ const json = fs.readFileSync('./assets/icomoon/selection.json')
+
+ const types = JSON.parse(json.toString())
+ .icons.map((icon: { properties: { name: string } }) => `'${icon.properties.name}'`)
+ .join('\n | ')
+ .concat('\n')
+
+ const content = prefix + types
+
+ fs.writeFileSync('./src/types/icon.d.ts', content)
+}
diff --git a/scripts/cli/commands/generateScreen.ts b/scripts/cli/commands/generateScreen.ts
new file mode 100644
index 00000000..fc248719
--- /dev/null
+++ b/scripts/cli/commands/generateScreen.ts
@@ -0,0 +1,3 @@
+export const generateScreen = () => {
+ console.log('generateScreen')
+}
diff --git a/scripts/cli/commands/index.ts b/scripts/cli/commands/index.ts
new file mode 100644
index 00000000..a20c51e2
--- /dev/null
+++ b/scripts/cli/commands/index.ts
@@ -0,0 +1,2 @@
+export * from './generateIconTypes'
+export * from './generateScreen'
diff --git a/scripts/cli/constants/index.ts b/scripts/cli/constants/index.ts
new file mode 100644
index 00000000..31fd1f28
--- /dev/null
+++ b/scripts/cli/constants/index.ts
@@ -0,0 +1 @@
+export const CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
diff --git a/scripts/cli/index.ts b/scripts/cli/index.ts
new file mode 100644
index 00000000..2efb2a2e
--- /dev/null
+++ b/scripts/cli/index.ts
@@ -0,0 +1,14 @@
+import { Command } from 'commander'
+
+import { parseAction } from './actions'
+
+const program = new Command()
+
+program
+ .argument('')
+ .option('-d, --debug', 'Set the debug level')
+ .action((action, options, command) => {
+ parseAction(action)
+ })
+
+program.parse()
diff --git a/scripts/cli/tsconfig.cli.json b/scripts/cli/tsconfig.cli.json
new file mode 100644
index 00000000..5fb1b807
--- /dev/null
+++ b/scripts/cli/tsconfig.cli.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "rootDir": ".",
+ "outDir": "build",
+ "strict": true,
+ "target": "es6",
+ "module": "commonjs",
+ "sourceMap": false,
+ "esModuleInterop": true,
+ "moduleResolution": "node",
+ "skipLibCheck": true
+ }
+}
diff --git a/scripts/cli/types/index.ts b/scripts/cli/types/index.ts
new file mode 100644
index 00000000..dbaa4ee3
--- /dev/null
+++ b/scripts/cli/types/index.ts
@@ -0,0 +1,2 @@
+// TODO: get the union from CLI_ACTIONS const
+export type CliActions = 'generate' | 'g' | 'bootstrap' | 'b'
diff --git a/src/types/icon.d.ts b/src/types/icon.d.ts
index 1da43419..1de1dbb9 100644
--- a/src/types/icon.d.ts
+++ b/src/types/icon.d.ts
@@ -1,8 +1,3 @@
-/**
- * @see https://remixicon.com/
- * You can find visually all icons that you need
- */
-
export type IconNames =
| 'layout-right-2-line'
| 'drag-drop-line'
diff --git a/yarn.lock b/yarn.lock
index a994f169..7b7c66ec 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5456,6 +5456,11 @@ commander@2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
+commander@^12.0.0:
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-12.0.0.tgz#b929db6df8546080adfd004ab215ed48cf6f2592"
+ integrity sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==
+
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
From 8100efff0cefbfaf67cf94c0a04f04c928231788 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?=
Date: Sat, 9 Mar 2024 16:22:51 +0100
Subject: [PATCH 02/47] feat: add screen generator
---
package.json | 1 +
scripts/cli/actions/generate.ts | 5 +-
scripts/cli/actions/index.ts | 5 +
scripts/cli/build/actions/generate.js | 5 +-
scripts/cli/build/actions/index.js | 5 +
.../cli/build/commands/generateIconTypes.js | 1 -
scripts/cli/build/commands/generateScreen.js | 162 ++++++++++++++++++
scripts/cli/build/commands/index.js | 31 ++++
scripts/cli/build/constants/index.js | 9 +-
scripts/cli/build/index.js | 22 ---
scripts/cli/build/utils/getDirectoryNames.js | 31 ++++
scripts/cli/build/utils/getFolderNames.js | 31 ++++
scripts/cli/build/utils/index.js | 30 ++++
scripts/cli/commands/generateScreen.ts | 134 ++++++++++++++-
scripts/cli/constants/index.ts | 4 +
scripts/cli/tsconfig.cli.json | 1 +
scripts/cli/utils/getDirectoryNames.ts | 25 +++
scripts/cli/utils/index.ts | 1 +
templates/screen_template.tsx | 17 +-
yarn.lock | 5 +
20 files changed, 479 insertions(+), 46 deletions(-)
create mode 100644 scripts/cli/build/commands/generateScreen.js
create mode 100644 scripts/cli/build/commands/index.js
create mode 100644 scripts/cli/build/utils/getDirectoryNames.js
create mode 100644 scripts/cli/build/utils/getFolderNames.js
create mode 100644 scripts/cli/build/utils/index.js
create mode 100644 scripts/cli/utils/getDirectoryNames.ts
create mode 100644 scripts/cli/utils/index.ts
diff --git a/package.json b/package.json
index a718c382..23e05e34 100644
--- a/package.json
+++ b/package.json
@@ -163,6 +163,7 @@
"@testing-library/jest-native": "^5.4.2",
"@testing-library/react-native": "^12.4.3",
"@types/jest": "^29.5.3",
+ "@types/prompt-sync": "^4.2.3",
"@types/react": "~18.2.45",
"@types/react-native": "^0.72.2",
"@types/react-test-renderer": "^18.0.0",
diff --git a/scripts/cli/actions/generate.ts b/scripts/cli/actions/generate.ts
index eeab04f3..093ed69f 100644
--- a/scripts/cli/actions/generate.ts
+++ b/scripts/cli/actions/generate.ts
@@ -3,6 +3,7 @@
import selectPrompt from 'select-prompt'
import { generateIconTypes } from '../commands/generateIconTypes'
+import { generateScreen } from '../commands/generateScreen'
const generatePrompts = [
{
@@ -20,9 +21,7 @@ const generatePrompts = [
]
const commands = {
- screen: () => {
- console.log('Generate Screen')
- },
+ screen: generateScreen,
component: () => {
console.log('Generate Component')
},
diff --git a/scripts/cli/actions/index.ts b/scripts/cli/actions/index.ts
index a089e1eb..6b025266 100644
--- a/scripts/cli/actions/index.ts
+++ b/scripts/cli/actions/index.ts
@@ -10,6 +10,11 @@ const actions = {
b: bootstrap,
}
+/**
+ * Parses and executes the specified CLI action.
+ *
+ * @param action - The CLI action to parse and execute.
+ */
export const parseAction = (action: CliActions) => {
if (!CLI_ACTIONS.includes(action)) {
console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
diff --git a/scripts/cli/build/actions/generate.js b/scripts/cli/build/actions/generate.js
index 79265a0b..12d8d7fa 100644
--- a/scripts/cli/build/actions/generate.js
+++ b/scripts/cli/build/actions/generate.js
@@ -41,6 +41,7 @@ exports.generate = void 0
// @ts-ignore
const select_prompt_1 = __importDefault(require('select-prompt'))
const generateIconTypes_1 = require('../commands/generateIconTypes')
+const generateScreen_1 = require('../commands/generateScreen')
const generatePrompts = [
{
title: 'Screen',
@@ -56,9 +57,7 @@ const generatePrompts = [
},
]
const commands = {
- screen: () => {
- console.log('Generate Screen')
- },
+ screen: generateScreen_1.generateScreen,
component: () => {
console.log('Generate Component')
},
diff --git a/scripts/cli/build/actions/index.js b/scripts/cli/build/actions/index.js
index 9a92f899..cc412521 100644
--- a/scripts/cli/build/actions/index.js
+++ b/scripts/cli/build/actions/index.js
@@ -10,6 +10,11 @@ const actions = {
bootstrap: bootstrap_1.bootstrap,
b: bootstrap_1.bootstrap,
}
+/**
+ * Parses and executes the specified CLI action.
+ *
+ * @param action - The CLI action to parse and execute.
+ */
const parseAction = (action) => {
if (!constants_1.CLI_ACTIONS.includes(action)) {
console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
diff --git a/scripts/cli/build/commands/generateIconTypes.js b/scripts/cli/build/commands/generateIconTypes.js
index bb8c96c2..9717bc93 100644
--- a/scripts/cli/build/commands/generateIconTypes.js
+++ b/scripts/cli/build/commands/generateIconTypes.js
@@ -17,6 +17,5 @@ const generateIconTypes = () => {
.concat('\n')
const content = prefix + types
fs_1.default.writeFileSync('./src/types/icon.d.ts', content)
- console.log('Icon types generated')
}
exports.generateIconTypes = generateIconTypes
diff --git a/scripts/cli/build/commands/generateScreen.js b/scripts/cli/build/commands/generateScreen.js
new file mode 100644
index 00000000..ad4fcad1
--- /dev/null
+++ b/scripts/cli/build/commands/generateScreen.js
@@ -0,0 +1,162 @@
+'use strict'
+var __awaiter =
+ (this && this.__awaiter) ||
+ function (thisArg, _arguments, P, generator) {
+ function adopt(value) {
+ return value instanceof P
+ ? value
+ : new P(function (resolve) {
+ resolve(value)
+ })
+ }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) {
+ try {
+ step(generator.next(value))
+ } catch (e) {
+ reject(e)
+ }
+ }
+ function rejected(value) {
+ try {
+ step(generator['throw'](value))
+ } catch (e) {
+ reject(e)
+ }
+ }
+ function step(result) {
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
+ }
+ step((generator = generator.apply(thisArg, _arguments || [])).next())
+ })
+ }
+var __importDefault =
+ (this && this.__importDefault) ||
+ function (mod) {
+ return mod && mod.__esModule ? mod : { default: mod }
+ }
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.generateScreen = void 0
+const fs_1 = __importDefault(require('fs'))
+const prompt_sync_1 = __importDefault(require('prompt-sync'))
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+const select_prompt_1 = __importDefault(require('select-prompt'))
+const constants_1 = require('../constants')
+const utils_1 = require('../utils')
+/**
+ * Recursively prompts the user to select a subdirectory and calls itself with the selected subdirectory path.
+ *
+ * @param basePath - The path of the current directory.
+ */
+const selectPath = (basePath) =>
+ new Promise((resolve) => {
+ let result = basePath
+ const subDirectories = (0, utils_1.getDirectoryNames)(basePath)
+ if (subDirectories.length) {
+ const subDirectoryPrompt = subDirectories.map((directoryName) => ({
+ title: directoryName,
+ value: directoryName,
+ }))
+ if (basePath !== constants_1.APP_ROUTER_DIRECTORY) {
+ subDirectoryPrompt.unshift({ title: '.', value: '.' })
+ }
+ ;(0, select_prompt_1.default)(
+ `Select a directory (${basePath.split(process.cwd())[1]})`,
+ subDirectoryPrompt,
+ {
+ cursor: 0,
+ }
+ ).on('submit', (subValue) => {
+ if (subValue === '.') {
+ result = basePath
+ resolve(result) // Return the result when subValue is '.'
+ return
+ }
+ selectPath(`${basePath}/${subValue}`).then((subResult) => {
+ result = subResult
+ resolve(result) // Return the result when subValue is not '.'
+ })
+ })
+ } else {
+ resolve(result) // Return the result when there are no subdirectories
+ }
+ })
+/**
+ * Validates if a route with the given name already exists in the specified path.
+ * @param routeName - The name of the route.
+ * @param routePath - The path where the route should be generated.
+ * @throws Error if the route already exists in the specified path.
+ */
+const validateRoute = (routeName, routePath) => {
+ const filePath = `${routePath}/${routeName}.tsx`
+ if (fs_1.default.existsSync(filePath)) {
+ throw new Error(`Route ${routeName} already exists in ${routePath}`)
+ }
+}
+/**
+ * Creates a route file with the given route name and path.
+ * @param {string} routeName - The name of the route.
+ * @param {string} routePath - The path where the route file will be created.
+ */
+const createRouteFile = (routeName, routePath) => {
+ // TODO: Check if its the tab - if so - add under new directory
+ const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
+ fs_1.default.writeFileSync(
+ `${routePath}/${routeName.toLowerCase()}.tsx`,
+ `import { ${screenName} } from '@baca/screens'
+
+export default ${screenName}
+`
+ )
+}
+/**
+ * Validates if a screen with the given name already exists.
+ * @param screenName - The name of the screen.
+ * @throws Error if the screen already exists.
+ */
+const validateScreen = (screenName) => {
+ const filePath = `${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`
+ if (fs_1.default.existsSync(filePath)) {
+ throw new Error(`Screen ${screenName} already exists in ${constants_1.SCREENS_DIRECTORY}`)
+ }
+}
+/**
+ * Creates a screen file with the given screen name.
+ * @param {string} screenName - The name of the screen.
+ */
+const createScreenFile = (baseName) => {
+ const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
+ const screenFromFile = fs_1.default.readFileSync('./templates/screen_template.tsx', 'utf8')
+ const screenContent = screenFromFile
+ .replaceAll('_NAME_', screenName)
+ .replace("// @ts-expect-error: it's a template and will be removed", '')
+ fs_1.default.writeFileSync(`${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent, {
+ encoding: 'utf-8',
+ flag: 'w',
+ })
+}
+const addToScreensIndex = (baseName) => {
+ const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
+ const indexFilePath = `${constants_1.SCREENS_DIRECTORY}/index.ts`
+ const indexFile = fs_1.default.readFileSync(indexFilePath, 'utf8')
+ const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
+ console.log({ indexFile, newIndexFile })
+ fs_1.default.writeFileSync(indexFilePath, newIndexFile)
+}
+/**
+ * Generates a screen based on user input.
+ * Prompts the user to enter a screen name and selects a screen path.
+ * Validates the screen name and path.
+ */
+const generateScreen = () =>
+ __awaiter(void 0, void 0, void 0, function* () {
+ const screenName = (0, prompt_sync_1.default)()('Enter screen name: ')
+ const routePath = yield selectPath(constants_1.APP_ROUTER_DIRECTORY)
+ validateRoute(screenName, routePath)
+ createRouteFile(screenName, routePath)
+ validateScreen(screenName)
+ createScreenFile(screenName)
+ addToScreensIndex(screenName)
+ })
+exports.generateScreen = generateScreen
diff --git a/scripts/cli/build/commands/index.js b/scripts/cli/build/commands/index.js
new file mode 100644
index 00000000..c38b9d85
--- /dev/null
+++ b/scripts/cli/build/commands/index.js
@@ -0,0 +1,31 @@
+'use strict'
+var __createBinding =
+ (this && this.__createBinding) ||
+ (Object.create
+ ? function (o, m, k, k2) {
+ if (k2 === undefined) k2 = k
+ var desc = Object.getOwnPropertyDescriptor(m, k)
+ if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = {
+ enumerable: true,
+ get: function () {
+ return m[k]
+ },
+ }
+ }
+ Object.defineProperty(o, k2, desc)
+ }
+ : function (o, m, k, k2) {
+ if (k2 === undefined) k2 = k
+ o[k2] = m[k]
+ })
+var __exportStar =
+ (this && this.__exportStar) ||
+ function (m, exports) {
+ for (var p in m)
+ if (p !== 'default' && !Object.prototype.hasOwnProperty.call(exports, p))
+ __createBinding(exports, m, p)
+ }
+Object.defineProperty(exports, '__esModule', { value: true })
+__exportStar(require('./generateIconTypes'), exports)
+__exportStar(require('./generateScreen'), exports)
diff --git a/scripts/cli/build/constants/index.js b/scripts/cli/build/constants/index.js
index 37e91333..3b00dc1b 100644
--- a/scripts/cli/build/constants/index.js
+++ b/scripts/cli/build/constants/index.js
@@ -1,4 +1,11 @@
'use strict'
Object.defineProperty(exports, '__esModule', { value: true })
-exports.CLI_ACTIONS = void 0
+exports.NAVIGATION_CONFIG_PATH =
+ exports.SCREENS_DIRECTORY =
+ exports.APP_ROUTER_DIRECTORY =
+ exports.CLI_ACTIONS =
+ void 0
exports.CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
+exports.APP_ROUTER_DIRECTORY = `${process.cwd()}/app/(app)`
+exports.SCREENS_DIRECTORY = `${process.cwd()}/src/screens`
+exports.NAVIGATION_CONFIG_PATH = `${process.cwd()}/navigation/tabNavigator/navigation-config.ts`
diff --git a/scripts/cli/build/index.js b/scripts/cli/build/index.js
index 389511b8..1b59c541 100644
--- a/scripts/cli/build/index.js
+++ b/scripts/cli/build/index.js
@@ -8,27 +8,5 @@ program
.option('-d, --debug', 'Set the debug level')
.action((action, options, command) => {
;(0, actions_1.parseAction)(action)
- // TODO: Parse all actions
- // Start with generate
- // console.log({ action, options, command })
- // if (!['g', 'generate'].includes(action)) {
- // console.log({ action })
- // throw new Error('Invalid action')
- // }
- // if (options.debug) {
- // console.error('Called %s with options %o', command.name(), options)
- // }
- // selectPrompt('What do you want to generate?', [
- // {
- // title: 'Screen',
- // value: 'screen',
- // },
- // {
- // title: 'Component',
- // value: 'component',
- // },
- // ]).on('submit', async (value: string) => {
- // console.log(`You want me to generate a ${value}!`)
- // })
})
program.parse()
diff --git a/scripts/cli/build/utils/getDirectoryNames.js b/scripts/cli/build/utils/getDirectoryNames.js
new file mode 100644
index 00000000..667950de
--- /dev/null
+++ b/scripts/cli/build/utils/getDirectoryNames.js
@@ -0,0 +1,31 @@
+'use strict'
+var __importDefault =
+ (this && this.__importDefault) ||
+ function (mod) {
+ return mod && mod.__esModule ? mod : { default: mod }
+ }
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.getDirectoryNames = void 0
+const fs_1 = __importDefault(require('fs'))
+/**
+ * Retrieves the names of all sub-directories in the specified directory.
+ *
+ * @param directoryPath - The path of the directory to retrieve directory names from.
+ * @returns An array of directory names.
+ */
+const getDirectoryNames = (directoryPath) => {
+ try {
+ // Read the contents of the directory
+ const contents = fs_1.default.readdirSync(directoryPath)
+ // Filter out only directories
+ const folderNames = contents.filter((item) => {
+ const stat = fs_1.default.statSync(`${directoryPath}/${item}`)
+ return stat.isDirectory()
+ })
+ return folderNames
+ } catch (err) {
+ console.error(`Error reading directory: ${err}`)
+ return []
+ }
+}
+exports.getDirectoryNames = getDirectoryNames
diff --git a/scripts/cli/build/utils/getFolderNames.js b/scripts/cli/build/utils/getFolderNames.js
new file mode 100644
index 00000000..78b9895b
--- /dev/null
+++ b/scripts/cli/build/utils/getFolderNames.js
@@ -0,0 +1,31 @@
+'use strict'
+var __importDefault =
+ (this && this.__importDefault) ||
+ function (mod) {
+ return mod && mod.__esModule ? mod : { default: mod }
+ }
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.getFolderNames = void 0
+const fs_1 = __importDefault(require('fs'))
+/**
+ * Retrieves the names of all folders in the specified directory.
+ *
+ * @param directoryPath - The path of the directory to retrieve folder names from.
+ * @returns An array of folder names.
+ */
+const getFolderNames = (directoryPath) => {
+ try {
+ // Read the contents of the directory
+ const contents = fs_1.default.readdirSync(directoryPath)
+ // Filter out only directories
+ const folderNames = contents.filter((item) => {
+ const stat = fs_1.default.statSync(`${directoryPath}/${item}`)
+ return stat.isDirectory()
+ })
+ return folderNames
+ } catch (err) {
+ console.error(`Error reading directory: ${err}`)
+ return []
+ }
+}
+exports.getFolderNames = getFolderNames
diff --git a/scripts/cli/build/utils/index.js b/scripts/cli/build/utils/index.js
new file mode 100644
index 00000000..187d247e
--- /dev/null
+++ b/scripts/cli/build/utils/index.js
@@ -0,0 +1,30 @@
+'use strict'
+var __createBinding =
+ (this && this.__createBinding) ||
+ (Object.create
+ ? function (o, m, k, k2) {
+ if (k2 === undefined) k2 = k
+ var desc = Object.getOwnPropertyDescriptor(m, k)
+ if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = {
+ enumerable: true,
+ get: function () {
+ return m[k]
+ },
+ }
+ }
+ Object.defineProperty(o, k2, desc)
+ }
+ : function (o, m, k, k2) {
+ if (k2 === undefined) k2 = k
+ o[k2] = m[k]
+ })
+var __exportStar =
+ (this && this.__exportStar) ||
+ function (m, exports) {
+ for (var p in m)
+ if (p !== 'default' && !Object.prototype.hasOwnProperty.call(exports, p))
+ __createBinding(exports, m, p)
+ }
+Object.defineProperty(exports, '__esModule', { value: true })
+__exportStar(require('./getDirectoryNames'), exports)
diff --git a/scripts/cli/commands/generateScreen.ts b/scripts/cli/commands/generateScreen.ts
index fc248719..e797f85b 100644
--- a/scripts/cli/commands/generateScreen.ts
+++ b/scripts/cli/commands/generateScreen.ts
@@ -1,3 +1,133 @@
-export const generateScreen = () => {
- console.log('generateScreen')
+import fs from 'fs'
+import prompt from 'prompt-sync'
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+import selectPrompt from 'select-prompt'
+
+import { APP_ROUTER_DIRECTORY, SCREENS_DIRECTORY } from '../constants'
+import { getDirectoryNames } from '../utils'
+
+/**
+ * Recursively prompts the user to select a subdirectory and calls itself with the selected subdirectory path.
+ *
+ * @param basePath - The path of the current directory.
+ */
+const selectPath = (basePath: string) =>
+ new Promise((resolve) => {
+ let result = basePath
+ const subDirectories = getDirectoryNames(basePath)
+ if (subDirectories.length) {
+ const subDirectoryPrompt = subDirectories.map((directoryName) => ({
+ title: directoryName,
+ value: directoryName,
+ }))
+
+ if (basePath !== APP_ROUTER_DIRECTORY) {
+ subDirectoryPrompt.unshift({ title: '.', value: '.' })
+ }
+
+ selectPrompt(`Select a directory (${basePath.split(process.cwd())[1]})`, subDirectoryPrompt, {
+ cursor: 0,
+ }).on('submit', (subValue: string) => {
+ if (subValue === '.') {
+ result = basePath
+ resolve(result) // Return the result when subValue is '.'
+ return
+ }
+ selectPath(`${basePath}/${subValue}`).then((subResult) => {
+ result = subResult
+ resolve(result) // Return the result when subValue is not '.'
+ })
+ })
+ } else {
+ resolve(result) // Return the result when there are no subdirectories
+ }
+ })
+
+/**
+ * Validates if a route with the given name already exists in the specified path.
+ * @param routeName - The name of the route.
+ * @param routePath - The path where the route should be generated.
+ * @throws Error if the route already exists in the specified path.
+ */
+const validateRoute = (routeName: string, routePath: string) => {
+ const filePath = `${routePath}/${routeName}.tsx`
+ if (fs.existsSync(filePath)) {
+ throw new Error(`Route ${routeName} already exists in ${routePath}`)
+ }
+}
+
+/**
+ * Creates a route file with the given route name and path.
+ * @param {string} routeName - The name of the route.
+ * @param {string} routePath - The path where the route file will be created.
+ */
+const createRouteFile = (routeName: string, routePath: string) => {
+ // TODO: Check if its the tab - if so - add under new directory
+ const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
+ fs.writeFileSync(
+ `${routePath}/${routeName.toLowerCase()}.tsx`,
+ `import { ${screenName} } from '@baca/screens'
+
+export default ${screenName}
+`
+ )
+}
+
+/**
+ * Validates if a screen with the given name already exists.
+ * @param screenName - The name of the screen.
+ * @throws Error if the screen already exists.
+ */
+const validateScreen = (screenName: string) => {
+ const filePath = `${SCREENS_DIRECTORY}/${screenName}.tsx`
+ if (fs.existsSync(filePath)) {
+ throw new Error(`Screen ${screenName} already exists in ${SCREENS_DIRECTORY}`)
+ }
+}
+
+/**
+ * Creates a screen file with the given screen name.
+ * @param {string} screenName - The name of the screen.
+ */
+const createScreenFile = (baseName: string) => {
+ const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
+ const screenFromFile = fs.readFileSync('./templates/screen_template.tsx', 'utf8')
+ const screenContent = screenFromFile
+ .replaceAll('_NAME_', screenName)
+ .replace("// @ts-expect-error: it's a template and will be removed", '')
+
+ fs.writeFileSync(`${SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent, {
+ encoding: 'utf-8',
+ flag: 'w',
+ })
+}
+
+const addToScreensIndex = (baseName: string) => {
+ const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
+ const indexFilePath = `${SCREENS_DIRECTORY}/index.ts`
+ const indexFile = fs.readFileSync(indexFilePath, 'utf8')
+ const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
+
+ console.log({ indexFile, newIndexFile })
+
+ fs.writeFileSync(indexFilePath, newIndexFile)
+}
+
+/**
+ * Generates a screen based on user input.
+ * Prompts the user to enter a screen name and selects a screen path.
+ * Validates the screen name and path.
+ */
+export const generateScreen = async () => {
+ const screenName = prompt()('Enter screen name: ')
+ const routePath = await selectPath(APP_ROUTER_DIRECTORY)
+
+ validateRoute(screenName, routePath)
+ createRouteFile(screenName, routePath)
+
+ validateScreen(screenName)
+ createScreenFile(screenName)
+
+ addToScreensIndex(screenName)
}
diff --git a/scripts/cli/constants/index.ts b/scripts/cli/constants/index.ts
index 31fd1f28..3c04f4e9 100644
--- a/scripts/cli/constants/index.ts
+++ b/scripts/cli/constants/index.ts
@@ -1 +1,5 @@
export const CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
+
+export const APP_ROUTER_DIRECTORY = `${process.cwd()}/app/(app)`
+export const SCREENS_DIRECTORY = `${process.cwd()}/src/screens`
+export const NAVIGATION_CONFIG_PATH = `${process.cwd()}/navigation/tabNavigator/navigation-config.ts`
diff --git a/scripts/cli/tsconfig.cli.json b/scripts/cli/tsconfig.cli.json
index 5fb1b807..1382bc7a 100644
--- a/scripts/cli/tsconfig.cli.json
+++ b/scripts/cli/tsconfig.cli.json
@@ -3,6 +3,7 @@
"rootDir": ".",
"outDir": "build",
"strict": true,
+ "lib": ["ESNext"],
"target": "es6",
"module": "commonjs",
"sourceMap": false,
diff --git a/scripts/cli/utils/getDirectoryNames.ts b/scripts/cli/utils/getDirectoryNames.ts
new file mode 100644
index 00000000..acdc7a3f
--- /dev/null
+++ b/scripts/cli/utils/getDirectoryNames.ts
@@ -0,0 +1,25 @@
+import fs from 'fs'
+
+/**
+ * Retrieves the names of all sub-directories in the specified directory.
+ *
+ * @param directoryPath - The path of the directory to retrieve directory names from.
+ * @returns An array of directory names.
+ */
+export const getDirectoryNames = (directoryPath: string): string[] => {
+ try {
+ // Read the contents of the directory
+ const contents = fs.readdirSync(directoryPath)
+
+ // Filter out only directories
+ const folderNames = contents.filter((item) => {
+ const stat = fs.statSync(`${directoryPath}/${item}`)
+ return stat.isDirectory()
+ })
+
+ return folderNames
+ } catch (err) {
+ console.error(`Error reading directory: ${err}`)
+ return []
+ }
+}
diff --git a/scripts/cli/utils/index.ts b/scripts/cli/utils/index.ts
new file mode 100644
index 00000000..c92afe7c
--- /dev/null
+++ b/scripts/cli/utils/index.ts
@@ -0,0 +1 @@
+export * from './getDirectoryNames'
diff --git a/templates/screen_template.tsx b/templates/screen_template.tsx
index 0e6ad613..113ac472 100644
--- a/templates/screen_template.tsx
+++ b/templates/screen_template.tsx
@@ -1,24 +1,13 @@
-import { Button, Center, Text } from '@baca/design-system'
-import { useCallback, useTranslation } from '@baca/hooks'
-
+import { Center, Text } from '@baca/design-system'
+import { useTranslation } from '@baca/hooks'
// @ts-expect-error: it's a template and will be removed
-export const _NAME_Screen = (props: _NAME_ScreenProps): JSX.Element => {
- const {
- navigation: { navigate },
- } = props
+export const _NAME_ = (): JSX.Element => {
const { t } = useTranslation()
- const navigateToDetails = useCallback(() => {
- navigate('Home')
- }, [navigate])
-
return (
_NAME_{t('hello')}
-
)
}
diff --git a/yarn.lock b/yarn.lock
index 7b7c66ec..a5706e23 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3683,6 +3683,11 @@
dependencies:
undici-types "~5.26.4"
+"@types/prompt-sync@^4.2.3":
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/@types/prompt-sync/-/prompt-sync-4.2.3.tgz#b6a9fe88fc4b4cacb8ab59f87f2614d6e674e177"
+ integrity sha512-Ox77gCSx0YyeakGt/qfOZUSFNSSi+sh3ABoGOiCwiO2KODx492BJnUm9oIXS+AHJtqp12iM4RduY6viTJ9bYwA==
+
"@types/prop-types@*":
version "15.7.11"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
From 3704957e52a2a5ceed4f1e4d712bd7e1c71bfbf5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?=
Date: Sat, 9 Mar 2024 17:08:04 +0100
Subject: [PATCH 03/47] feat: handle tab navigation config
---
scripts/cli/build/commands/generateScreen.js | 173 +++++++++++-------
scripts/cli/commands/generateScreen.ts | 80 +++++---
.../tabNavigator/navigation-config.ts | 2 +-
3 files changed, 162 insertions(+), 93 deletions(-)
diff --git a/scripts/cli/build/commands/generateScreen.js b/scripts/cli/build/commands/generateScreen.js
index ad4fcad1..2db602bd 100644
--- a/scripts/cli/build/commands/generateScreen.js
+++ b/scripts/cli/build/commands/generateScreen.js
@@ -44,6 +44,9 @@ const prompt_sync_1 = __importDefault(require('prompt-sync'))
const select_prompt_1 = __importDefault(require('select-prompt'))
const constants_1 = require('../constants')
const utils_1 = require('../utils')
+const addAfter = (content, searchText, textToAdd) => {
+ return content.replace(searchText, searchText + textToAdd)
+}
/**
* Recursively prompts the user to select a subdirectory and calls itself with the selected subdirectory path.
*
@@ -51,13 +54,15 @@ const utils_1 = require('../utils')
*/
const selectPath = (basePath) =>
new Promise((resolve) => {
- let result = basePath
const subDirectories = (0, utils_1.getDirectoryNames)(basePath)
if (subDirectories.length) {
const subDirectoryPrompt = subDirectories.map((directoryName) => ({
title: directoryName,
value: directoryName,
}))
+ if (basePath.includes('tabs')) {
+ subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
+ }
if (basePath !== constants_1.APP_ROUTER_DIRECTORY) {
subDirectoryPrompt.unshift({ title: '.', value: '.' })
}
@@ -68,81 +73,98 @@ const selectPath = (basePath) =>
cursor: 0,
}
).on('submit', (subValue) => {
+ // Return the result when subValue is '.'
if (subValue === '.') {
- result = basePath
- resolve(result) // Return the result when subValue is '.'
+ resolve(basePath)
return
}
+ // Return the result when subValue is not '.'
selectPath(`${basePath}/${subValue}`).then((subResult) => {
- result = subResult
- resolve(result) // Return the result when subValue is not '.'
+ resolve(subResult)
})
})
+ // Return the result when there are no subdirectories
} else {
- resolve(result) // Return the result when there are no subdirectories
+ resolve(basePath)
}
})
-/**
- * Validates if a route with the given name already exists in the specified path.
- * @param routeName - The name of the route.
- * @param routePath - The path where the route should be generated.
- * @throws Error if the route already exists in the specified path.
- */
-const validateRoute = (routeName, routePath) => {
- const filePath = `${routePath}/${routeName}.tsx`
- if (fs_1.default.existsSync(filePath)) {
- throw new Error(`Route ${routeName} already exists in ${routePath}`)
+// /**
+// * Validates if a route with the given name already exists in the specified path.
+// * @param routeName - The name of the route.
+// * @param routePath - The path where the route should be generated.
+// * @throws Error if the route already exists in the specified path.
+// */
+// const validateRoute = (routeName: string, routePath: string) => {
+// const filePath = `${routePath}/${routeName}.tsx`
+// if (fs.existsSync(filePath)) {
+// throw new Error(`Route ${routeName} already exists in ${routePath}`)
+// }
+// }
+// /**
+// * Creates a route file with the given route name and path.
+// * @param {string} routeName - The name of the route.
+// * @param {string} routePath - The path where the route file will be created.
+// */
+// const createRouteFile = (routeName: string, routePath: string) => {
+// const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
+// fs.writeFileSync(
+// `${routePath}/${routeName.toLowerCase()}.tsx`,
+// `import { ${screenName} } from '@baca/screens'
+// export default ${screenName}
+// `,
+// {
+// encoding: 'utf-8',
+// flag: 'w',
+// }
+// )
+// }
+// /**
+// * Validates if a screen with the given name already exists.
+// * @param screenName - The name of the screen.
+// * @throws Error if the screen already exists.
+// */
+// const validateScreen = (screenName: string) => {
+// const filePath = `${SCREENS_DIRECTORY}/${screenName}.tsx`
+// if (fs.existsSync(filePath)) {
+// throw new Error(`Screen ${screenName} already exists in ${SCREENS_DIRECTORY}`)
+// }
+// }
+// /**
+// * Creates a screen file with the given screen name.
+// * @param {string} screenName - The name of the screen.
+// */
+// const createScreenFile = (screenName: string) => {
+// const screenFromFile = fs.readFileSync('./templates/screen_template.tsx', 'utf8')
+// const screenContent = screenFromFile
+// .replaceAll('_NAME_', screenName)
+// .replace("// @ts-expect-error: it's a template and will be removed", '')
+// fs.writeFileSync(`${SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent)
+// }
+// const addToScreensIndex = (screenName: string) => {
+// const indexFilePath = `${SCREENS_DIRECTORY}/index.ts`
+// const indexFile = fs.readFileSync(indexFilePath, 'utf8')
+// const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
+// fs.writeFileSync(indexFilePath, newIndexFile)
+// }
+const createNewNavTab = () => {
+ const tabName = (0, prompt_sync_1.default)()('Enter tab name: ')
+ if (!tabName) {
+ throw new Error('Tab name is required')
}
-}
-/**
- * Creates a route file with the given route name and path.
- * @param {string} routeName - The name of the route.
- * @param {string} routePath - The path where the route file will be created.
- */
-const createRouteFile = (routeName, routePath) => {
- // TODO: Check if its the tab - if so - add under new directory
- const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
- fs_1.default.writeFileSync(
- `${routePath}/${routeName.toLowerCase()}.tsx`,
- `import { ${screenName} } from '@baca/screens'
-
-export default ${screenName}
-`
+ const navigationConfigFile = fs_1.default.readFileSync(
+ './src/navigation/tabNavigator/navigation-config.ts',
+ 'utf8'
)
-}
-/**
- * Validates if a screen with the given name already exists.
- * @param screenName - The name of the screen.
- * @throws Error if the screen already exists.
- */
-const validateScreen = (screenName) => {
- const filePath = `${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`
- if (fs_1.default.existsSync(filePath)) {
- throw new Error(`Screen ${screenName} already exists in ${constants_1.SCREENS_DIRECTORY}`)
- }
-}
-/**
- * Creates a screen file with the given screen name.
- * @param {string} screenName - The name of the screen.
- */
-const createScreenFile = (baseName) => {
- const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
- const screenFromFile = fs_1.default.readFileSync('./templates/screen_template.tsx', 'utf8')
- const screenContent = screenFromFile
- .replaceAll('_NAME_', screenName)
- .replace("// @ts-expect-error: it's a template and will be removed", '')
- fs_1.default.writeFileSync(`${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent, {
- encoding: 'utf-8',
- flag: 'w',
- })
-}
-const addToScreensIndex = (baseName) => {
- const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
- const indexFilePath = `${constants_1.SCREENS_DIRECTORY}/index.ts`
- const indexFile = fs_1.default.readFileSync(indexFilePath, 'utf8')
- const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
- console.log({ indexFile, newIndexFile })
- fs_1.default.writeFileSync(indexFilePath, newIndexFile)
+ const tabContent = `
+ {
+ displayedName: '${tabName.charAt(0).toUpperCase() + tabName.slice(1)}',
+ icon: 'zzz-line', // CONFIG: Add your icon name here
+ iconFocused: 'zzz-fill', // CONFIG: Add your icon name here
+ id: '${tabName}',
+ name: '${tabName}',
+ },`
+ const newContent = addAfter(navigationConfigFile, '// UPPER SIDE TABS', tabContent)
+ fs_1.default.writeFileSync('./src/navigation/tabNavigator/navigation-config.ts', newContent)
}
/**
* Generates a screen based on user input.
@@ -151,12 +173,21 @@ const addToScreensIndex = (baseName) => {
*/
const generateScreen = () =>
__awaiter(void 0, void 0, void 0, function* () {
- const screenName = (0, prompt_sync_1.default)()('Enter screen name: ')
+ const routeName = (0, prompt_sync_1.default)()('Enter screen name: ')
+ if (!routeName) {
+ throw new Error('Screen name is required')
+ }
const routePath = yield selectPath(constants_1.APP_ROUTER_DIRECTORY)
- validateRoute(screenName, routePath)
- createRouteFile(screenName, routePath)
- validateScreen(screenName)
- createScreenFile(screenName)
- addToScreensIndex(screenName)
+ console.log({ routeName, routePath })
+ const isNewTab = routePath.includes('tabs') && routePath.includes('new-tab')
+ if (isNewTab) {
+ createNewNavTab()
+ }
+ // validateRoute(routeName, routePath)
+ // createRouteFile(routeName, routePath)
+ // const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
+ // validateScreen(screenName)
+ // createScreenFile(screenName)
+ // addToScreensIndex(screenName)
})
exports.generateScreen = generateScreen
diff --git a/scripts/cli/commands/generateScreen.ts b/scripts/cli/commands/generateScreen.ts
index e797f85b..e1d14d3d 100644
--- a/scripts/cli/commands/generateScreen.ts
+++ b/scripts/cli/commands/generateScreen.ts
@@ -7,6 +7,10 @@ import selectPrompt from 'select-prompt'
import { APP_ROUTER_DIRECTORY, SCREENS_DIRECTORY } from '../constants'
import { getDirectoryNames } from '../utils'
+const addAfter = (content: string, searchText: string, textToAdd: string) => {
+ return content.replace(searchText, searchText + textToAdd)
+}
+
/**
* Recursively prompts the user to select a subdirectory and calls itself with the selected subdirectory path.
*
@@ -14,7 +18,6 @@ import { getDirectoryNames } from '../utils'
*/
const selectPath = (basePath: string) =>
new Promise((resolve) => {
- let result = basePath
const subDirectories = getDirectoryNames(basePath)
if (subDirectories.length) {
const subDirectoryPrompt = subDirectories.map((directoryName) => ({
@@ -22,6 +25,10 @@ const selectPath = (basePath: string) =>
value: directoryName,
}))
+ if (basePath.includes('tabs')) {
+ subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
+ }
+
if (basePath !== APP_ROUTER_DIRECTORY) {
subDirectoryPrompt.unshift({ title: '.', value: '.' })
}
@@ -29,18 +36,19 @@ const selectPath = (basePath: string) =>
selectPrompt(`Select a directory (${basePath.split(process.cwd())[1]})`, subDirectoryPrompt, {
cursor: 0,
}).on('submit', (subValue: string) => {
+ // Return the result when subValue is '.'
if (subValue === '.') {
- result = basePath
- resolve(result) // Return the result when subValue is '.'
+ resolve(basePath)
return
}
+ // Return the result when subValue is not '.'
selectPath(`${basePath}/${subValue}`).then((subResult) => {
- result = subResult
- resolve(result) // Return the result when subValue is not '.'
+ resolve(subResult)
})
})
+ // Return the result when there are no subdirectories
} else {
- resolve(result) // Return the result when there are no subdirectories
+ resolve(basePath)
}
})
@@ -63,14 +71,17 @@ const validateRoute = (routeName: string, routePath: string) => {
* @param {string} routePath - The path where the route file will be created.
*/
const createRouteFile = (routeName: string, routePath: string) => {
- // TODO: Check if its the tab - if so - add under new directory
const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
fs.writeFileSync(
`${routePath}/${routeName.toLowerCase()}.tsx`,
`import { ${screenName} } from '@baca/screens'
export default ${screenName}
-`
+`,
+ {
+ encoding: 'utf-8',
+ flag: 'w',
+ }
)
}
@@ -90,42 +101,69 @@ const validateScreen = (screenName: string) => {
* Creates a screen file with the given screen name.
* @param {string} screenName - The name of the screen.
*/
-const createScreenFile = (baseName: string) => {
- const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
+const createScreenFile = (screenName: string) => {
const screenFromFile = fs.readFileSync('./templates/screen_template.tsx', 'utf8')
const screenContent = screenFromFile
.replaceAll('_NAME_', screenName)
.replace("// @ts-expect-error: it's a template and will be removed", '')
- fs.writeFileSync(`${SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent, {
- encoding: 'utf-8',
- flag: 'w',
- })
+ fs.writeFileSync(`${SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent)
}
-const addToScreensIndex = (baseName: string) => {
- const screenName = `${baseName.charAt(0).toUpperCase() + baseName.slice(1)}Screen`
+const addToScreensIndex = (screenName: string) => {
const indexFilePath = `${SCREENS_DIRECTORY}/index.ts`
const indexFile = fs.readFileSync(indexFilePath, 'utf8')
const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
- console.log({ indexFile, newIndexFile })
-
fs.writeFileSync(indexFilePath, newIndexFile)
}
+const createNewNavTab = () => {
+ const tabName = prompt()('Enter tab name: ')
+ if (!tabName) {
+ throw new Error('Tab name is required')
+ }
+
+ const navigationConfigFile = fs.readFileSync(
+ './src/navigation/tabNavigator/navigation-config.ts',
+ 'utf8'
+ )
+
+ const tabContent = `
+ {
+ displayedName: '${tabName.charAt(0).toUpperCase() + tabName.slice(1)}',
+ icon: 'zzz-line', // CONFIG: Add your icon name here
+ iconFocused: 'zzz-fill', // CONFIG: Add your icon name here
+ id: '${tabName}',
+ name: '${tabName}',
+ },`
+
+ const newContent = addAfter(navigationConfigFile, '// UPPER SIDE TABS', tabContent)
+ fs.writeFileSync('./src/navigation/tabNavigator/navigation-config.ts', newContent)
+}
+
/**
* Generates a screen based on user input.
* Prompts the user to enter a screen name and selects a screen path.
* Validates the screen name and path.
*/
export const generateScreen = async () => {
- const screenName = prompt()('Enter screen name: ')
+ const routeName = prompt()('Enter screen name: ')
+ if (!routeName) {
+ throw new Error('Screen name is required')
+ }
+
const routePath = await selectPath(APP_ROUTER_DIRECTORY)
- validateRoute(screenName, routePath)
- createRouteFile(screenName, routePath)
+ const isNewTab = routePath.includes('tabs') && routePath.includes('new-tab')
+ if (isNewTab) {
+ createNewNavTab()
+ }
+
+ validateRoute(routeName, routePath)
+ createRouteFile(routeName, routePath)
+ const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
validateScreen(screenName)
createScreenFile(screenName)
diff --git a/src/navigation/tabNavigator/navigation-config.ts b/src/navigation/tabNavigator/navigation-config.ts
index 061f97d3..8d89f0b3 100644
--- a/src/navigation/tabNavigator/navigation-config.ts
+++ b/src/navigation/tabNavigator/navigation-config.ts
@@ -14,6 +14,7 @@ type Tabs = Tab[]
// name with '/' at the begging will not be resolved as 'bottom tab', will be as usual screen
export const upperSideTabs: Tabs = [
+ // UPPER SIDE TABS
{
displayedName: 'Home',
icon: 'home-3-line',
@@ -49,7 +50,6 @@ export const upperSideTabs: Tabs = [
id: 'profile',
name: 'profile',
},
-
// In case you want to navigate to screen with params you can do this like this
// {
// displayedName: 'Details',
From 26bee65a4594f718e4567faeea10125e2076bb99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?=
Date: Sat, 9 Mar 2024 19:39:03 +0100
Subject: [PATCH 04/47] feat: handle tab creation
---
package.json | 2 +
scripts/cli/actions/index.ts | 6 +-
scripts/cli/build/actions/index.js | 9 +-
scripts/cli/build/commands/generateScreen.js | 202 +++++++++----------
scripts/cli/build/constants.js | 11 +
scripts/cli/build/index.js | 9 +-
scripts/cli/build/types.js | 2 +
scripts/cli/build/utils/content.js | 38 ++++
scripts/cli/build/utils/getDirectoryNames.js | 4 +-
scripts/cli/build/utils/index.js | 2 +
scripts/cli/build/utils/logger.js | 21 ++
scripts/cli/commands/generateScreen.ts | 92 +++++----
scripts/cli/constants.ts | 5 +
scripts/cli/constants/index.ts | 5 -
scripts/cli/index.ts | 11 +-
scripts/cli/types/index.ts | 2 -
scripts/cli/utils/content.ts | 34 ++++
scripts/cli/utils/getDirectoryNames.ts | 5 +-
scripts/cli/utils/index.ts | 2 +
scripts/cli/utils/logger.ts | 19 ++
20 files changed, 306 insertions(+), 175 deletions(-)
create mode 100644 scripts/cli/build/constants.js
create mode 100644 scripts/cli/build/types.js
create mode 100644 scripts/cli/build/utils/content.js
create mode 100644 scripts/cli/build/utils/logger.js
create mode 100644 scripts/cli/constants.ts
delete mode 100644 scripts/cli/constants/index.ts
delete mode 100644 scripts/cli/types/index.ts
create mode 100644 scripts/cli/utils/content.ts
create mode 100644 scripts/cli/utils/logger.ts
diff --git a/package.json b/package.json
index 23e05e34..52b49106 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,8 @@
"deploy:staging:ios": "yarn prepare:staging && eas build --platform ios --profile staging --auto-submit --non-interactive",
"deploy:staging": "yarn prepare:staging && eas build --platform all --profile staging --auto-submit --non-interactive",
"eas-build-pre-install": "base64 --help && echo $ANDROID_FIREBASE_CONFIG | base64 --decode > google-services.json && cat google-services.json && echo $IOS_FIREBASE_CONFIG | base64 --decode > GoogleService-Info.plist && cat GoogleService-Info.plist",
+ "baca:generate": "node ./scripts/cli/build generate",
+ "generate:query": "yarn orval --config ./orval.config.ts",
"generate:component": "node ./scripts/create_new_component.js && yarn eslint src --fix && yarn tsc",
"generate:env:production": "scripts/generate_dotenv.sh production",
"generate:env:qa": "scripts/generate_dotenv.sh qa",
diff --git a/scripts/cli/actions/index.ts b/scripts/cli/actions/index.ts
index 6b025266..1fe5edeb 100644
--- a/scripts/cli/actions/index.ts
+++ b/scripts/cli/actions/index.ts
@@ -1,7 +1,7 @@
import { bootstrap } from './bootstrap'
import { generate } from './generate'
import { CLI_ACTIONS } from '../constants'
-import { CliActions } from '../types'
+import { logger } from '../utils'
const actions = {
generate,
@@ -15,9 +15,9 @@ const actions = {
*
* @param action - The CLI action to parse and execute.
*/
-export const parseAction = (action: CliActions) => {
+export const executeAction = (action: keyof typeof actions) => {
if (!CLI_ACTIONS.includes(action)) {
- console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
+ logger.error(`Action ${action} is not supported.`)
return
}
actions[action]()
diff --git a/scripts/cli/build/actions/index.js b/scripts/cli/build/actions/index.js
index cc412521..8ee49f5c 100644
--- a/scripts/cli/build/actions/index.js
+++ b/scripts/cli/build/actions/index.js
@@ -1,9 +1,10 @@
'use strict'
Object.defineProperty(exports, '__esModule', { value: true })
-exports.parseAction = void 0
+exports.executeAction = void 0
const bootstrap_1 = require('./bootstrap')
const generate_1 = require('./generate')
const constants_1 = require('../constants')
+const utils_1 = require('../utils')
const actions = {
generate: generate_1.generate,
g: generate_1.generate,
@@ -15,11 +16,11 @@ const actions = {
*
* @param action - The CLI action to parse and execute.
*/
-const parseAction = (action) => {
+const executeAction = (action) => {
if (!constants_1.CLI_ACTIONS.includes(action)) {
- console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
+ utils_1.logger.error(`Action ${action} is not supported.`)
return
}
actions[action]()
}
-exports.parseAction = parseAction
+exports.executeAction = executeAction
diff --git a/scripts/cli/build/commands/generateScreen.js b/scripts/cli/build/commands/generateScreen.js
index 2db602bd..f129abfd 100644
--- a/scripts/cli/build/commands/generateScreen.js
+++ b/scripts/cli/build/commands/generateScreen.js
@@ -55,102 +55,99 @@ const addAfter = (content, searchText, textToAdd) => {
const selectPath = (basePath) =>
new Promise((resolve) => {
const subDirectories = (0, utils_1.getDirectoryNames)(basePath)
- if (subDirectories.length) {
- const subDirectoryPrompt = subDirectories.map((directoryName) => ({
- title: directoryName,
- value: directoryName,
- }))
- if (basePath.includes('tabs')) {
- subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
- }
- if (basePath !== constants_1.APP_ROUTER_DIRECTORY) {
- subDirectoryPrompt.unshift({ title: '.', value: '.' })
- }
- ;(0, select_prompt_1.default)(
- `Select a directory (${basePath.split(process.cwd())[1]})`,
- subDirectoryPrompt,
- {
- cursor: 0,
- }
- ).on('submit', (subValue) => {
- // Return the result when subValue is '.'
- if (subValue === '.') {
- resolve(basePath)
- return
- }
- // Return the result when subValue is not '.'
- selectPath(`${basePath}/${subValue}`).then((subResult) => {
- resolve(subResult)
- })
- })
- // Return the result when there are no subdirectories
- } else {
+ const hasSubDirectories = subDirectories.length > 0
+ // Return the result when there are no subdirectories
+ if (!hasSubDirectories) {
resolve(basePath)
+ return
+ }
+ const subDirectoryPrompt = subDirectories.map((directoryName) => ({
+ title: directoryName,
+ value: directoryName,
+ }))
+ if (basePath.includes('tabs')) {
+ subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
+ }
+ if (basePath !== constants_1.APP_ROUTER_DIRECTORY) {
+ subDirectoryPrompt.unshift({ title: '.', value: '.' })
}
+ ;(0, select_prompt_1.default)(`Select a directory (${basePath})`, subDirectoryPrompt, {
+ cursor: 0,
+ }).on('submit', (subValue) => {
+ // Return the result when user selects current directory
+ if (subValue === '.') {
+ resolve(basePath)
+ return
+ }
+ // Recursively execute path selection when subValue is not the current directory
+ selectPath(`${basePath}/${subValue}`).then((subResult) => {
+ resolve(subResult)
+ })
+ })
})
-// /**
-// * Validates if a route with the given name already exists in the specified path.
-// * @param routeName - The name of the route.
-// * @param routePath - The path where the route should be generated.
-// * @throws Error if the route already exists in the specified path.
-// */
-// const validateRoute = (routeName: string, routePath: string) => {
-// const filePath = `${routePath}/${routeName}.tsx`
-// if (fs.existsSync(filePath)) {
-// throw new Error(`Route ${routeName} already exists in ${routePath}`)
-// }
-// }
-// /**
-// * Creates a route file with the given route name and path.
-// * @param {string} routeName - The name of the route.
-// * @param {string} routePath - The path where the route file will be created.
-// */
-// const createRouteFile = (routeName: string, routePath: string) => {
-// const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
-// fs.writeFileSync(
-// `${routePath}/${routeName.toLowerCase()}.tsx`,
-// `import { ${screenName} } from '@baca/screens'
-// export default ${screenName}
-// `,
-// {
-// encoding: 'utf-8',
-// flag: 'w',
-// }
-// )
-// }
-// /**
-// * Validates if a screen with the given name already exists.
-// * @param screenName - The name of the screen.
-// * @throws Error if the screen already exists.
-// */
-// const validateScreen = (screenName: string) => {
-// const filePath = `${SCREENS_DIRECTORY}/${screenName}.tsx`
-// if (fs.existsSync(filePath)) {
-// throw new Error(`Screen ${screenName} already exists in ${SCREENS_DIRECTORY}`)
-// }
-// }
-// /**
-// * Creates a screen file with the given screen name.
-// * @param {string} screenName - The name of the screen.
-// */
-// const createScreenFile = (screenName: string) => {
-// const screenFromFile = fs.readFileSync('./templates/screen_template.tsx', 'utf8')
-// const screenContent = screenFromFile
-// .replaceAll('_NAME_', screenName)
-// .replace("// @ts-expect-error: it's a template and will be removed", '')
-// fs.writeFileSync(`${SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent)
-// }
-// const addToScreensIndex = (screenName: string) => {
-// const indexFilePath = `${SCREENS_DIRECTORY}/index.ts`
-// const indexFile = fs.readFileSync(indexFilePath, 'utf8')
-// const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
-// fs.writeFileSync(indexFilePath, newIndexFile)
-// }
-const createNewNavTab = () => {
+/**
+ * Validates if a route with the given name already exists in the specified path.
+ * @param routeName - The name of the route.
+ * @param routePath - The path where the route should be generated.
+ * @throws Error if the route already exists in the specified path.
+ */
+const validateRoute = (routeName, routePath) => {
+ const filePath = `${routePath}/${routeName}.tsx`
+ if (fs_1.default.existsSync(filePath)) {
+ utils_1.logger.error(`Route ${routeName} already exists in ${routePath}`)
+ }
+}
+/**
+ * Creates a route file with the given route name and path.
+ * @param {string} routeName - The name of the route.
+ * @param {string} routePath - The path where the route file will be created.
+ */
+const createRouteFile = (routeName, routePath) => {
+ const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
+ fs_1.default.writeFileSync(
+ `${routePath}/${routeName.toLowerCase()}.tsx`,
+ `import { ${screenName} } from '@baca/screens'
+
+export default ${screenName}
+`
+ )
+}
+/**
+ * Validates if a screen with the given name already exists.
+ * @param screenName - The name of the screen.
+ * @throws Error if the screen already exists.
+ */
+const validateScreen = (screenName) => {
+ const filePath = `${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`
+ if (fs_1.default.existsSync(filePath)) {
+ utils_1.logger.error(`Screen ${screenName} already exists`)
+ }
+}
+/**
+ * Creates a screen file with the given screen name.
+ * @param {string} screenName - The name of the screen.
+ */
+const createScreenFile = (screenName) => {
+ const screenFromFile = fs_1.default.readFileSync('./templates/screen_template.tsx', 'utf8')
+ const screenContent = screenFromFile
+ .replaceAll('_NAME_', screenName)
+ .replace("// @ts-expect-error: it's a template and will be removed", '')
+ fs_1.default.writeFileSync(`${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent)
+}
+const addToScreensIndex = (screenName) => {
+ const indexFilePath = `${constants_1.SCREENS_DIRECTORY}/index.ts`
+ const indexFile = fs_1.default.readFileSync(indexFilePath, 'utf8')
+ const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
+ fs_1.default.writeFileSync(indexFilePath, newIndexFile)
+}
+const promptTabName = () => {
const tabName = (0, prompt_sync_1.default)()('Enter tab name: ')
if (!tabName) {
throw new Error('Tab name is required')
}
+ return tabName
+}
+const createNewNavTab = (tabName) => {
const navigationConfigFile = fs_1.default.readFileSync(
'./src/navigation/tabNavigator/navigation-config.ts',
'utf8'
@@ -174,20 +171,21 @@ const createNewNavTab = () => {
const generateScreen = () =>
__awaiter(void 0, void 0, void 0, function* () {
const routeName = (0, prompt_sync_1.default)()('Enter screen name: ')
- if (!routeName) {
- throw new Error('Screen name is required')
- }
- const routePath = yield selectPath(constants_1.APP_ROUTER_DIRECTORY)
- console.log({ routeName, routePath })
- const isNewTab = routePath.includes('tabs') && routePath.includes('new-tab')
+ let routePath = yield selectPath(constants_1.APP_ROUTER_DIRECTORY)
+ const isNewTab = routePath.includes('(tabs)') && routePath.includes('new-tab')
if (isNewTab) {
- createNewNavTab()
+ const tabName = promptTabName()
+ createNewNavTab(tabName)
+ const newTabPath = routePath.replace('/new-tab', `/${tabName}`)
+ routePath = newTabPath
+ console.log({ newTabPath, routePath })
+ fs_1.default.mkdirSync(newTabPath)
}
- // validateRoute(routeName, routePath)
- // createRouteFile(routeName, routePath)
- // const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
- // validateScreen(screenName)
- // createScreenFile(screenName)
- // addToScreensIndex(screenName)
+ validateRoute(routeName, routePath)
+ createRouteFile(routeName, routePath)
+ const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
+ validateScreen(screenName)
+ createScreenFile(screenName)
+ addToScreensIndex(screenName)
})
exports.generateScreen = generateScreen
diff --git a/scripts/cli/build/constants.js b/scripts/cli/build/constants.js
new file mode 100644
index 00000000..2004b55a
--- /dev/null
+++ b/scripts/cli/build/constants.js
@@ -0,0 +1,11 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.NAVIGATION_CONFIG_PATH =
+ exports.SCREENS_DIRECTORY =
+ exports.APP_ROUTER_DIRECTORY =
+ exports.CLI_ACTIONS =
+ void 0
+exports.CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
+exports.APP_ROUTER_DIRECTORY = 'app/(app)'
+exports.SCREENS_DIRECTORY = 'src/screens'
+exports.NAVIGATION_CONFIG_PATH = 'navigation/tabNavigator/navigation-config.ts'
diff --git a/scripts/cli/build/index.js b/scripts/cli/build/index.js
index 1b59c541..26dba5af 100644
--- a/scripts/cli/build/index.js
+++ b/scripts/cli/build/index.js
@@ -3,10 +3,7 @@ Object.defineProperty(exports, '__esModule', { value: true })
const commander_1 = require('commander')
const actions_1 = require('./actions')
const program = new commander_1.Command()
-program
- .argument('')
- .option('-d, --debug', 'Set the debug level')
- .action((action, options, command) => {
- ;(0, actions_1.parseAction)(action)
- })
+program.argument('').action((action) => {
+ ;(0, actions_1.executeAction)(action)
+})
program.parse()
diff --git a/scripts/cli/build/types.js b/scripts/cli/build/types.js
new file mode 100644
index 00000000..0a483a32
--- /dev/null
+++ b/scripts/cli/build/types.js
@@ -0,0 +1,2 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
diff --git a/scripts/cli/build/utils/content.js b/scripts/cli/build/utils/content.js
new file mode 100644
index 00000000..88b6e409
--- /dev/null
+++ b/scripts/cli/build/utils/content.js
@@ -0,0 +1,38 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.deleteText = exports.addBefore = exports.addAfter = void 0
+/**
+ * Adds the specified text after the first occurrence of the search text in the content.
+ *
+ * @param content - The original content string.
+ * @param searchText - The text to search for in the content.
+ * @param textToAdd - The text to add after the first occurrence of the search text.
+ * @returns The modified content string with the text added.
+ */
+const addAfter = (content, searchText, textToAdd) => {
+ return content.replace(searchText, searchText + textToAdd)
+}
+exports.addAfter = addAfter
+/**
+ * Adds the specified text before the first occurrence of the search text in the content.
+ *
+ * @param content - The original content string.
+ * @param searchText - The text to search for in the content.
+ * @param textToAdd - The text to add before the first occurrence of the search text.
+ * @returns The modified content string with the text added before the first occurrence of the search text.
+ */
+const addBefore = (content, searchText, textToAdd) => {
+ return content.replace(searchText, textToAdd + searchText)
+}
+exports.addBefore = addBefore
+/**
+ * Deletes all occurrences of a specified search text from the given content.
+ *
+ * @param content - The content from which to delete the search text.
+ * @param searchText - The text to be deleted from the content.
+ * @returns The updated content with all occurrences of the search text removed.
+ */
+const deleteText = (content, searchText) => {
+ return content.replace(searchText, '')
+}
+exports.deleteText = deleteText
diff --git a/scripts/cli/build/utils/getDirectoryNames.js b/scripts/cli/build/utils/getDirectoryNames.js
index 667950de..aa233144 100644
--- a/scripts/cli/build/utils/getDirectoryNames.js
+++ b/scripts/cli/build/utils/getDirectoryNames.js
@@ -7,6 +7,7 @@ var __importDefault =
Object.defineProperty(exports, '__esModule', { value: true })
exports.getDirectoryNames = void 0
const fs_1 = __importDefault(require('fs'))
+const logger_1 = require('./logger')
/**
* Retrieves the names of all sub-directories in the specified directory.
*
@@ -15,6 +16,7 @@ const fs_1 = __importDefault(require('fs'))
*/
const getDirectoryNames = (directoryPath) => {
try {
+ if (directoryPath.includes('new-tab')) return []
// Read the contents of the directory
const contents = fs_1.default.readdirSync(directoryPath)
// Filter out only directories
@@ -24,7 +26,7 @@ const getDirectoryNames = (directoryPath) => {
})
return folderNames
} catch (err) {
- console.error(`Error reading directory: ${err}`)
+ logger_1.logger.error(`Error reading directory: ${err}`)
return []
}
}
diff --git a/scripts/cli/build/utils/index.js b/scripts/cli/build/utils/index.js
index 187d247e..3b11ce9e 100644
--- a/scripts/cli/build/utils/index.js
+++ b/scripts/cli/build/utils/index.js
@@ -28,3 +28,5 @@ var __exportStar =
}
Object.defineProperty(exports, '__esModule', { value: true })
__exportStar(require('./getDirectoryNames'), exports)
+__exportStar(require('./content'), exports)
+__exportStar(require('./logger'), exports)
diff --git a/scripts/cli/build/utils/logger.js b/scripts/cli/build/utils/logger.js
new file mode 100644
index 00000000..e0100c0a
--- /dev/null
+++ b/scripts/cli/build/utils/logger.js
@@ -0,0 +1,21 @@
+'use strict'
+Object.defineProperty(exports, '__esModule', { value: true })
+exports.logger = void 0
+const LCERROR = '\x1b[31m%s\x1b[0m' //red
+const LCWARN = '\x1b[33m%s\x1b[0m' //yellow
+const LCINFO = '\x1b[36m%s\x1b[0m' //cyan
+const LCSUCCESS = '\x1b[32m%s\x1b[0m' //green
+exports.logger = {
+ error: (message, ...optionalParams) => {
+ console.error(LCERROR, message, ...optionalParams)
+ },
+ warn: (message, ...optionalParams) => {
+ console.warn(LCWARN, message, ...optionalParams)
+ },
+ info: (message, ...optionalParams) => {
+ console.info(LCINFO, message, ...optionalParams)
+ },
+ success: (message, ...optionalParams) => {
+ console.info(LCSUCCESS, message, ...optionalParams)
+ },
+}
diff --git a/scripts/cli/commands/generateScreen.ts b/scripts/cli/commands/generateScreen.ts
index e1d14d3d..b2d70637 100644
--- a/scripts/cli/commands/generateScreen.ts
+++ b/scripts/cli/commands/generateScreen.ts
@@ -5,7 +5,7 @@ import prompt from 'prompt-sync'
import selectPrompt from 'select-prompt'
import { APP_ROUTER_DIRECTORY, SCREENS_DIRECTORY } from '../constants'
-import { getDirectoryNames } from '../utils'
+import { getDirectoryNames, logger } from '../utils'
const addAfter = (content: string, searchText: string, textToAdd: string) => {
return content.replace(searchText, searchText + textToAdd)
@@ -19,37 +19,40 @@ const addAfter = (content: string, searchText: string, textToAdd: string) => {
const selectPath = (basePath: string) =>
new Promise((resolve) => {
const subDirectories = getDirectoryNames(basePath)
- if (subDirectories.length) {
- const subDirectoryPrompt = subDirectories.map((directoryName) => ({
- title: directoryName,
- value: directoryName,
- }))
-
- if (basePath.includes('tabs')) {
- subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
- }
-
- if (basePath !== APP_ROUTER_DIRECTORY) {
- subDirectoryPrompt.unshift({ title: '.', value: '.' })
- }
+ const hasSubDirectories = subDirectories.length > 0
- selectPrompt(`Select a directory (${basePath.split(process.cwd())[1]})`, subDirectoryPrompt, {
- cursor: 0,
- }).on('submit', (subValue: string) => {
- // Return the result when subValue is '.'
- if (subValue === '.') {
- resolve(basePath)
- return
- }
- // Return the result when subValue is not '.'
- selectPath(`${basePath}/${subValue}`).then((subResult) => {
- resolve(subResult)
- })
- })
- // Return the result when there are no subdirectories
- } else {
+ // Return the result when there are no subdirectories
+ if (!hasSubDirectories) {
resolve(basePath)
+ return
+ }
+
+ const subDirectoryPrompt = subDirectories.map((directoryName) => ({
+ title: directoryName,
+ value: directoryName,
+ }))
+
+ if (basePath.includes('tabs')) {
+ subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
+ }
+
+ if (basePath !== APP_ROUTER_DIRECTORY) {
+ subDirectoryPrompt.unshift({ title: '.', value: '.' })
}
+
+ selectPrompt(`Select a directory (${basePath})`, subDirectoryPrompt, {
+ cursor: 0,
+ }).on('submit', (subValue: string) => {
+ // Return the result when user selects current directory
+ if (subValue === '.') {
+ resolve(basePath)
+ return
+ }
+ // Recursively execute path selection when subValue is not the current directory
+ selectPath(`${basePath}/${subValue}`).then((subResult) => {
+ resolve(subResult)
+ })
+ })
})
/**
@@ -61,7 +64,7 @@ const selectPath = (basePath: string) =>
const validateRoute = (routeName: string, routePath: string) => {
const filePath = `${routePath}/${routeName}.tsx`
if (fs.existsSync(filePath)) {
- throw new Error(`Route ${routeName} already exists in ${routePath}`)
+ logger.error(`Route ${routeName} already exists in ${routePath}`)
}
}
@@ -77,11 +80,7 @@ const createRouteFile = (routeName: string, routePath: string) => {
`import { ${screenName} } from '@baca/screens'
export default ${screenName}
-`,
- {
- encoding: 'utf-8',
- flag: 'w',
- }
+`
)
}
@@ -93,7 +92,7 @@ export default ${screenName}
const validateScreen = (screenName: string) => {
const filePath = `${SCREENS_DIRECTORY}/${screenName}.tsx`
if (fs.existsSync(filePath)) {
- throw new Error(`Screen ${screenName} already exists in ${SCREENS_DIRECTORY}`)
+ logger.error(`Screen ${screenName} already exists`)
}
}
@@ -118,12 +117,15 @@ const addToScreensIndex = (screenName: string) => {
fs.writeFileSync(indexFilePath, newIndexFile)
}
-const createNewNavTab = () => {
+const promptTabName = () => {
const tabName = prompt()('Enter tab name: ')
if (!tabName) {
throw new Error('Tab name is required')
}
+ return tabName
+}
+const createNewNavTab = (tabName: string) => {
const navigationConfigFile = fs.readFileSync(
'./src/navigation/tabNavigator/navigation-config.ts',
'utf8'
@@ -149,15 +151,17 @@ const createNewNavTab = () => {
*/
export const generateScreen = async () => {
const routeName = prompt()('Enter screen name: ')
- if (!routeName) {
- throw new Error('Screen name is required')
- }
+ let routePath = await selectPath(APP_ROUTER_DIRECTORY)
- const routePath = await selectPath(APP_ROUTER_DIRECTORY)
-
- const isNewTab = routePath.includes('tabs') && routePath.includes('new-tab')
+ const isNewTab = routePath.includes('(tabs)') && routePath.includes('new-tab')
if (isNewTab) {
- createNewNavTab()
+ const tabName = promptTabName()
+ createNewNavTab(tabName)
+
+ const newTabPath = routePath.replace('/new-tab', `/${tabName}`)
+ routePath = newTabPath
+ console.log({ newTabPath, routePath })
+ fs.mkdirSync(newTabPath)
}
validateRoute(routeName, routePath)
diff --git a/scripts/cli/constants.ts b/scripts/cli/constants.ts
new file mode 100644
index 00000000..0cc00849
--- /dev/null
+++ b/scripts/cli/constants.ts
@@ -0,0 +1,5 @@
+export const CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
+
+export const APP_ROUTER_DIRECTORY = 'app/(app)'
+export const SCREENS_DIRECTORY = 'src/screens'
+export const NAVIGATION_CONFIG_PATH = 'navigation/tabNavigator/navigation-config.ts'
diff --git a/scripts/cli/constants/index.ts b/scripts/cli/constants/index.ts
deleted file mode 100644
index 3c04f4e9..00000000
--- a/scripts/cli/constants/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export const CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
-
-export const APP_ROUTER_DIRECTORY = `${process.cwd()}/app/(app)`
-export const SCREENS_DIRECTORY = `${process.cwd()}/src/screens`
-export const NAVIGATION_CONFIG_PATH = `${process.cwd()}/navigation/tabNavigator/navigation-config.ts`
diff --git a/scripts/cli/index.ts b/scripts/cli/index.ts
index 2efb2a2e..d4d712d2 100644
--- a/scripts/cli/index.ts
+++ b/scripts/cli/index.ts
@@ -1,14 +1,11 @@
import { Command } from 'commander'
-import { parseAction } from './actions'
+import { executeAction } from './actions'
const program = new Command()
-program
- .argument('')
- .option('-d, --debug', 'Set the debug level')
- .action((action, options, command) => {
- parseAction(action)
- })
+program.argument('').action((action) => {
+ executeAction(action)
+})
program.parse()
diff --git a/scripts/cli/types/index.ts b/scripts/cli/types/index.ts
deleted file mode 100644
index dbaa4ee3..00000000
--- a/scripts/cli/types/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// TODO: get the union from CLI_ACTIONS const
-export type CliActions = 'generate' | 'g' | 'bootstrap' | 'b'
diff --git a/scripts/cli/utils/content.ts b/scripts/cli/utils/content.ts
new file mode 100644
index 00000000..105bd1c0
--- /dev/null
+++ b/scripts/cli/utils/content.ts
@@ -0,0 +1,34 @@
+/**
+ * Adds the specified text after the first occurrence of the search text in the content.
+ *
+ * @param content - The original content string.
+ * @param searchText - The text to search for in the content.
+ * @param textToAdd - The text to add after the first occurrence of the search text.
+ * @returns The modified content string with the text added.
+ */
+export const addAfter = (content: string, searchText: string, textToAdd: string) => {
+ return content.replace(searchText, searchText + textToAdd)
+}
+
+/**
+ * Adds the specified text before the first occurrence of the search text in the content.
+ *
+ * @param content - The original content string.
+ * @param searchText - The text to search for in the content.
+ * @param textToAdd - The text to add before the first occurrence of the search text.
+ * @returns The modified content string with the text added before the first occurrence of the search text.
+ */
+export const addBefore = (content: string, searchText: string, textToAdd: string) => {
+ return content.replace(searchText, textToAdd + searchText)
+}
+
+/**
+ * Deletes all occurrences of a specified search text from the given content.
+ *
+ * @param content - The content from which to delete the search text.
+ * @param searchText - The text to be deleted from the content.
+ * @returns The updated content with all occurrences of the search text removed.
+ */
+export const deleteText = (content: string, searchText: string) => {
+ return content.replace(searchText, '')
+}
diff --git a/scripts/cli/utils/getDirectoryNames.ts b/scripts/cli/utils/getDirectoryNames.ts
index acdc7a3f..494b7ba0 100644
--- a/scripts/cli/utils/getDirectoryNames.ts
+++ b/scripts/cli/utils/getDirectoryNames.ts
@@ -1,5 +1,7 @@
import fs from 'fs'
+import { logger } from './logger'
+
/**
* Retrieves the names of all sub-directories in the specified directory.
*
@@ -8,6 +10,7 @@ import fs from 'fs'
*/
export const getDirectoryNames = (directoryPath: string): string[] => {
try {
+ if (directoryPath.includes('new-tab')) return []
// Read the contents of the directory
const contents = fs.readdirSync(directoryPath)
@@ -19,7 +22,7 @@ export const getDirectoryNames = (directoryPath: string): string[] => {
return folderNames
} catch (err) {
- console.error(`Error reading directory: ${err}`)
+ logger.error(`Error reading directory: ${err}`)
return []
}
}
diff --git a/scripts/cli/utils/index.ts b/scripts/cli/utils/index.ts
index c92afe7c..b2d0878f 100644
--- a/scripts/cli/utils/index.ts
+++ b/scripts/cli/utils/index.ts
@@ -1 +1,3 @@
export * from './getDirectoryNames'
+export * from './content'
+export * from './logger'
diff --git a/scripts/cli/utils/logger.ts b/scripts/cli/utils/logger.ts
new file mode 100644
index 00000000..f55b9dd1
--- /dev/null
+++ b/scripts/cli/utils/logger.ts
@@ -0,0 +1,19 @@
+const LCERROR = '\x1b[31m%s\x1b[0m' //red
+const LCWARN = '\x1b[33m%s\x1b[0m' //yellow
+const LCINFO = '\x1b[36m%s\x1b[0m' //cyan
+const LCSUCCESS = '\x1b[32m%s\x1b[0m' //green
+
+export const logger = {
+ error: (message: string, ...optionalParams: unknown[]) => {
+ console.error(LCERROR, message, ...optionalParams)
+ },
+ warn: (message: string, ...optionalParams: unknown[]) => {
+ console.warn(LCWARN, message, ...optionalParams)
+ },
+ info: (message: string, ...optionalParams: unknown[]) => {
+ console.info(LCINFO, message, ...optionalParams)
+ },
+ success: (message: string, ...optionalParams: unknown[]) => {
+ console.info(LCSUCCESS, message, ...optionalParams)
+ },
+}
From 2b68ed5176c69d4e5c3cafec2c63d1319c78085a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?=
Date: Sat, 9 Mar 2024 19:41:52 +0100
Subject: [PATCH 05/47] feat: migrate bootstrap script to typescript
---
.github/pull_request_template.md | 47 +---
package.json | 16 +-
scripts/README.md | 11 +-
scripts/bootstrap.js | 200 ----------------
scripts/cli/actions/bootstrap.ts | 206 +++++++++++++++-
scripts/cli/build/actions/bootstrap.js | 196 ++++++++++++++-
scripts/cli/build/constants.js | 15 +-
scripts/cli/constants.ts | 8 +
scripts/create_new_screen.js | 318 -------------------------
scripts/generate_icon_types.js | 17 --
10 files changed, 439 insertions(+), 595 deletions(-)
delete mode 100644 scripts/bootstrap.js
delete mode 100644 scripts/create_new_screen.js
delete mode 100644 scripts/generate_icon_types.js
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index c3e00217..f2df2a52 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,44 +1,11 @@
-# Description
+# Describe your changes
-Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.
+# Issue ticket number or link
-Fixes # (issue)
+# Checklist before requesting a review
-## Type of change
+- [ ] I did self-review of my code.
+- [ ] Do the tests work ?
+- [ ] Does lint work ?, it doesn't find any bugs or problems.
-Please delete options that are not relevant.
-
-- [ ] Bug fix (non-breaking change which fixes an issue)
-- [ ] New feature (non-breaking change which adds functionality)
-- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
-- [ ] This change requires a documentation update
-
-# How Has This Been Tested?
-
-Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
-
-- [ ] Test A
-- [ ] Test B
-
-# Screenshot(s)
-
-Please attach some screenshot or a movie if provided changes affects UI.
-
-**Test Configuration**:
-
-- Firmware version:
-- Hardware:
-- Toolchain:
-- SDK:
-
-# Checklist:
-
-- [ ] Add correct label to your pull request
-- [ ] My code follows the style guidelines of this project
-- [ ] I have performed a self-review of my code
-- [ ] I have commented my code, particularly in hard-to-understand areas
-- [ ] I have made corresponding changes to the documentation
-- [ ] My changes generate no new warnings
-- [ ] I have added tests that prove my fix is effective or that my feature works
-- [ ] New and existing unit tests pass locally with my changes
-- [ ] Any dependent changes have been merged and published in downstream modules
+# Do any blockers exist ? if yes, describe it below.
diff --git a/package.json b/package.json
index 52b49106..ce2ddaf2 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,9 @@
"license": "MIT",
"scripts": {
"android:dev-client": "IS_DEV=1 npx expo run:android",
- "bootstrap:new_app": "yarn && node ./scripts/bootstrap.js",
+ "baca:bootstrap": "node ./scripts/cli/build bootstrap",
+ "baca:generate": "node ./scripts/cli/build generate",
+ "build:baca-cli": "npx tsc -p ./scripts/cli/tsconfig.cli.json",
"build:production:android": "yarn prepare:production && eas build --platform android --profile production",
"build:production:ios": "yarn prepare:production && eas build --platform ios --profile production",
"build:production": "yarn prepare:production && eas build --platform all --profile production",
@@ -43,20 +45,16 @@
"deploy:staging:android": "yarn prepare:staging && eas build --platform android --profile staging --auto-submit --non-interactive",
"deploy:staging:ios": "yarn prepare:staging && eas build --platform ios --profile staging --auto-submit --non-interactive",
"deploy:staging": "yarn prepare:staging && eas build --platform all --profile staging --auto-submit --non-interactive",
- "eas-build-pre-install": "base64 --help && echo $ANDROID_FIREBASE_CONFIG | base64 --decode > google-services.json && cat google-services.json && echo $IOS_FIREBASE_CONFIG | base64 --decode > GoogleService-Info.plist && cat GoogleService-Info.plist",
- "baca:generate": "node ./scripts/cli/build generate",
"generate:query": "yarn orval --config ./orval.config.ts",
"generate:component": "node ./scripts/create_new_component.js && yarn eslint src --fix && yarn tsc",
"generate:env:production": "scripts/generate_dotenv.sh production",
"generate:env:qa": "scripts/generate_dotenv.sh qa",
"generate:env:staging": "scripts/generate_dotenv.sh staging",
- "generate:google-services-config": "./scripts/generate_firebase_config.sh",
- "generate:icon:types": "node ./scripts/generate_icon_types.js",
- "generate:query": "yarn orval --config ./orval.config.ts",
- "generate:screen": "node ./scripts/create_new_screen.js && yarn eslint src --fix && yarn tsc",
- "lint:fix": "eslint src --fix",
"lint": "eslint src && yarn tsc",
- "postinstall": "patch-package",
+ "lint:fix": "eslint src --fix",
+ "login": "expo login",
+ "logout": "expo logout",
+ "postinstall": "patch-package && yarn build:baca-cli",
"prebuild:android": "IS_DEV=1 npx expo prebuild --clean -p android",
"prebuild:ios": "IS_DEV=1 npx expo prebuild --clean -p ios",
"prepare:env_file": "cp ./templates/doppler_variables_template.sh ./scripts/doppler_variables.sh",
diff --git a/scripts/README.md b/scripts/README.md
index cb481bef..03911a21 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -44,20 +44,15 @@ yarn prepare:qa
yarn prepare:staging
```
-## 3. `generate_icon_types.sh`
-
-This script has to be executed when new icons where added to the icomoon.ttf icons set in case to provide proper types for components which use icons.
-If script won't be executed typescript will throw an error when trying to use newly added icon.
-
## 4. generators
```bash
## Create new component
-yarn generate:screen
+yarn generate:component
## Create new screen
-yarn generate:component
+yarn baca:generate
## Bootstrap the app
-yarn bootstrap:new_app
+yarn baca:bootstrap
```
diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js
deleted file mode 100644
index f7919222..00000000
--- a/scripts/bootstrap.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/* eslint-disable @typescript-eslint/no-var-requires */
-const fs = require('fs')
-const prompt = require('prompt-sync')()
-
-const { logger, addAfter } = require('./utils')
-
-const paths = {
- appJson: './app.json',
- appConfig: './app.config.ts',
- readme: './README.md',
- readmeTemplate: './templates/readme_template.md',
- pullRequestTemplate: './.github/pull_request_template.md',
- newPullReuestTemplate: './templates/pull_request_template.md',
-}
-
-// 1.
-const replaceReadme = (appName, organizationOwner) => {
- let contents = fs.readFileSync(paths.readmeTemplate, 'utf8')
- contents = contents.replaceAll('_NAME_', appName)
- contents = contents.replaceAll('_OWNER_', organizationOwner)
-
- fs.writeFileSync(paths.readme, contents)
-}
-
-// 2.
-const setUpAppConfig = (appName, bundleId, androidPackageName, scheme, easId, androidIconColor) => {
- let contents = fs.readFileSync(paths.appConfig, 'utf8')
-
- const appConfig = `
-export const APP_CONFIG = {
- androidPackageName: '${androidPackageName}', // CONFIG: Add your android package name here
- appName: '${appName}', // CONFIG: Add your app name here
- easProjectId: '${easId}', // CONFIG: Add your eas project ID here
- iosBundleIdentifier: '${bundleId}', // CONFIG: Add your ios bundle identifier here
- scheme: '${scheme}', // CONFIG: Add your url scheme to link to your app
- adaptiveIconBackgroundColor: '${androidIconColor}', // CONFIG: Add your url scheme to link to your app
-} as const
-`
-
- contents = contents.replace(/(\/\/ APP_CONFIG_START)[\s\S]*?(\/\/ APP_CONFIG_END)/g, '$1$2')
-
- contents = addAfter(contents, '// APP_CONFIG_START', `${appConfig}`)
- fs.writeFileSync(paths.appConfig, contents)
-}
-
-// 3.
-const replatePullRequestTemplate = () => {
- const contents = fs.readFileSync(paths.newPullReuestTemplate, 'utf8')
-
- fs.writeFileSync(paths.pullRequestTemplate, contents)
-}
-
-// 4.
-const changeAppJson = (appName, appSlug, organizationOwner) => {
- const newAppJson = JSON.parse(fs.readFileSync(paths.appJson, 'utf8'))
- newAppJson.expo.slug = appSlug
- newAppJson.expo.name = appName
- newAppJson.expo.owner = organizationOwner
- newAppJson.version = '1.0.0'
- fs.writeFileSync(paths.appJson, JSON.stringify(newAppJson, null, 2))
-}
-
-// 5.
-const changePackageJson = (appName, organizationOwner) => {
- const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'))
- packageJson.name = `@${organizationOwner}/${appName}`
- packageJson.description = `App created from expo-template powered by binarapps`
- packageJson.version = '1.0.0'
-
- delete packageJson.repository
- delete packageJson.bugs
- delete packageJson.keywords
-
- fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2))
-}
-
-// 6.
-const removeIssueTemplates = () => {
- fs.rm('./.github/ISSUE_TEMPLATE', { recursive: true, force: true }, () => {})
-}
-
-// 7.
-const removeDocsFolder = () => {
- fs.rm('./documentation', { recursive: true, force: true }, () => {})
-}
-
-const setUpProject = async (
- appName,
- bundleId,
- androidPackageName,
- scheme,
- easId,
- organizationOwner,
- androidIconColor,
- appSlug
-) => {
- // START
- logger.success('Start ...')
-
- // 1. Delete readme -> and create new, with new app name etc.
- logger.info('Generating new readme file')
- replaceReadme(appName, organizationOwner)
-
- // 2. Replace appName, bundleId, androidPackageName,scheme and easProjectId in app.config.ts file
- logger.info('Change project variables in app.config.ts file')
- setUpAppConfig(appName, bundleId, androidPackageName, scheme, easId, androidIconColor)
-
- // 3. Delete exist pull request template -> generate the new
- logger.info('Generating new pull request template file')
- replatePullRequestTemplate()
-
- // 4. Change app.json file
- logger.info('Change app.json file')
- changeAppJson(appName, appSlug, organizationOwner)
-
- // 5. Change package.json file
- logger.info('Change package.json file')
- changePackageJson(appName, organizationOwner)
-
- // 6. Remove issue templates
- logger.info('Remove issue templates')
- removeIssueTemplates()
-
- // 7. Remove docs folder
- logger.info('Remove docs folder')
- removeDocsFolder()
-
- //Finish
- logger.success(`Config your project has been success`)
-}
-
-const bootstrap = () => {
- logger.info('Please give me this information to setup your project:')
- const appName = prompt('App name: ')
- if (!appName) {
- return logger.error('Please write correct app name')
- }
-
- const appSlug = prompt('App slug (from expo dashboard): ')
- if (!appSlug) {
- return logger.error('Please write app slug')
- }
-
- const organizationOwner = prompt('Organization owner (from expo dashboard): ')
- if (!organizationOwner) {
- return logger.error('Please write organziation owner')
- }
-
- const easId = prompt('EAS project ID (from expo dashboard): ')
- if (!easId) {
- return logger.error('Please write correct eas project ID')
- }
-
- const androidIconColor =
- prompt('Android adaptive icon color (you can leave it empty and fill it later): ') ||
- '#2E7AF0CC'
-
- const bundleId = prompt('Bundle ID (ios): ')
- if (!bundleId) {
- return logger.error('Please write correct bundle ID')
- }
-
- const androidPackageName = prompt('Package name (android): ')
- if (!androidPackageName) {
- return logger.error('Please write correct android package name')
- }
-
- const scheme = prompt('URL scheme (for deeplinking): ')
- if (!scheme) {
- return logger.error('Please write correct scheme')
- }
-
- // 1. Setup project -> set ( appName, bundleId, androidPackageName, appScheme, easProjectId, organizationOwner, androidIconColor )
- setUpProject(
- appName,
- bundleId,
- androidPackageName,
- scheme,
- easId,
- organizationOwner,
- androidIconColor,
- appSlug
- )
-
- logger.info(
- '\nYou can also add images right now, go to assets folder and replace images to match your app \n'
- )
- logger.info('\nPlease verify the changes made by this script and commit it to your repository \n')
-}
-
-bootstrap()
-
-// INSTRUCTION:
-// 1. Delete readme and write the new one
-// 2. Setup app.config.ts file
-// 3. Setup pull_request_template.md
-// 4. Setup app.json file
-// 5. Setup package.json file
-// 6. Remove issue templates
-// 7. Remove docs folder
diff --git a/scripts/cli/actions/bootstrap.ts b/scripts/cli/actions/bootstrap.ts
index 419e225e..64a3b09f 100644
--- a/scripts/cli/actions/bootstrap.ts
+++ b/scripts/cli/actions/bootstrap.ts
@@ -1,3 +1,207 @@
+import fs from 'fs'
+import promptSync from 'prompt-sync'
+
+import {
+ README_PATH,
+ APP_CONFIG_PATH,
+ NEW_PULL_REQUEST_TEMPLATE_PATH,
+ PULL_REQUEST_TEMPLATE_PATH,
+ APP_JSON_PATH,
+} from '../constants'
+import { logger, addAfter } from '../utils'
+
+const prompt = promptSync()
+
+/**
+ * Replaces placeholders in the README file with the provided app name and organization owner.
+ *
+ * @param appName - The name of the app.
+ * @param organizationOwner - The owner of the organization.
+ */
+const replaceReadme = (appName: string, organizationOwner: string) => {
+ let contents = fs.readFileSync(README_PATH, 'utf-8')
+
+ contents = contents.replaceAll('_NAME_', appName)
+ contents = contents.replaceAll('_OWNER_', organizationOwner)
+
+ fs.writeFileSync(README_PATH, contents)
+}
+
+/**
+ * Sets up the app configuration by updating the contents of the app config file.
+ *
+ * @param appName - The name of the app.
+ * @param bundleId - The bundle identifier for iOS.
+ * @param androidPackageName - The package name for Android.
+ * @param scheme - The URL scheme to link to the app.
+ * @param easId - The EAS project ID.
+ * @param androidIconColor - The background color for the adaptive icon on Android.
+ */
+const setUpAppConfig = (
+ appName: string,
+ bundleId: string,
+ androidPackageName: string,
+ scheme: string,
+ easId: string,
+ androidIconColor: string
+) => {
+ let contents = fs.readFileSync(APP_CONFIG_PATH, 'utf8')
+
+ const appConfig = `
+export const APP_CONFIG = {
+ androidPackageName: '${androidPackageName}', // CONFIG: Add your android package name here
+ appName: '${appName}', // CONFIG: Add your app name here
+ easProjectId: '${easId}', // CONFIG: Add your eas project ID here
+ iosBundleIdentifier: '${bundleId}', // CONFIG: Add your ios bundle identifier here
+ scheme: '${scheme}', // CONFIG: Add your url scheme to link to your app
+ adaptiveIconBackgroundColor: '${androidIconColor}', // CONFIG: Add your url scheme to link to your app
+} as const
+`
+
+ contents = contents.replace(/(\/\/ APP_CONFIG_START)[\s\S]*?(\/\/ APP_CONFIG_END)/g, '$1$2')
+
+ contents = addAfter(contents, '// APP_CONFIG_START', `${appConfig}`)
+ fs.writeFileSync(APP_CONFIG_PATH, contents)
+}
+
+/**
+ * Replaces the contents of the pull request template file with the contents of a new pull request template file.
+ */
+const replacePullRequestTemplate = () => {
+ const contents = fs.readFileSync(NEW_PULL_REQUEST_TEMPLATE_PATH, 'utf8')
+
+ fs.writeFileSync(PULL_REQUEST_TEMPLATE_PATH, contents)
+}
+
+const changeAppJson = (appName: string, appSlug: string, organizationOwner: string) => {
+ const newAppJson = JSON.parse(fs.readFileSync(APP_JSON_PATH, 'utf8'))
+ newAppJson.expo.slug = appSlug
+ newAppJson.expo.name = appName
+ newAppJson.expo.owner = organizationOwner
+ newAppJson.version = '1.0.0'
+ fs.writeFileSync(APP_JSON_PATH, JSON.stringify(newAppJson, null, 2))
+}
+
+const changePackageJson = (appName: string, organizationOwner: string) => {
+ const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'))
+ packageJson.name = `@${organizationOwner}/${appName}`
+ packageJson.description = `App created from expo-template powered by binarapps`
+ packageJson.version = '1.0.0'
+
+ delete packageJson.repository
+ delete packageJson.bugs
+ delete packageJson.keywords
+
+ fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2))
+}
+
+const removeIssueTemplates = () => {
+ fs.rm('./.github/ISSUE_TEMPLATE', { recursive: true, force: true }, () => {})
+}
+
+const removeDocsFolder = () => {
+ fs.rm('./documentation', { recursive: true, force: true }, () => {})
+}
+
+const setUpProject = async (
+ appName: string,
+ bundleId: string,
+ androidPackageName: string,
+ scheme: string,
+ easId: string,
+ organizationOwner: string,
+ androidIconColor: string,
+ appSlug: string
+) => {
+ // START
+ logger.success('Start ...')
+
+ // 1. Delete readme -> and create new, with new app name etc.
+ logger.info('Generating new readme file')
+ replaceReadme(appName, organizationOwner)
+
+ // 2. Replace appName, bundleId, androidPackageName,scheme and easProjectId in app.config.ts file
+ logger.info('Change project variables in app.config.ts file')
+ setUpAppConfig(appName, bundleId, androidPackageName, scheme, easId, androidIconColor)
+
+ // 3. Delete exist pull request template -> generate the new
+ logger.info('Generating new pull request template file')
+ replacePullRequestTemplate()
+
+ // 4. Change app.json file
+ logger.info('Change app.json file')
+ changeAppJson(appName, appSlug, organizationOwner)
+
+ // 5. Change package.json file
+ logger.info('Change package.json file')
+ changePackageJson(appName, organizationOwner)
+
+ // 6. Remove issue templates
+ logger.info('Remove issue templates')
+ removeIssueTemplates()
+
+ // 7. Remove docs folder
+ logger.info('Remove docs folder')
+ removeDocsFolder()
+
+ //Finish
+ logger.success(`Config your project has been success`)
+}
+
export const bootstrap = () => {
- console.log('Bootstrap')
+ logger.info('Please give me this information to setup your project:')
+ const appName = prompt('App name: ')
+ if (!appName) {
+ return logger.error('Please write correct app name')
+ }
+
+ const appSlug = prompt('App slug (from expo dashboard): ')
+ if (!appSlug) {
+ return logger.error('Please write app slug')
+ }
+
+ const organizationOwner = prompt('Organization owner (from expo dashboard): ')
+ if (!organizationOwner) {
+ return logger.error('Please write organziation owner')
+ }
+
+ const easId = prompt('EAS project ID (from expo dashboard): ')
+ if (!easId) {
+ return logger.error('Please write correct eas project ID')
+ }
+
+ const androidIconColor =
+ prompt('Android adaptive icon color (you can leave it empty and fill it later): ') ||
+ '#2E7AF0CC'
+
+ const bundleId = prompt('Bundle ID (ios): ')
+ if (!bundleId) {
+ return logger.error('Please write correct bundle ID')
+ }
+
+ const androidPackageName = prompt('Package name (android): ')
+ if (!androidPackageName) {
+ return logger.error('Please write correct android package name')
+ }
+
+ const scheme = prompt('URL scheme (for deeplinking): ')
+ if (!scheme) {
+ return logger.error('Please write correct scheme')
+ }
+
+ setUpProject(
+ appName,
+ bundleId,
+ androidPackageName,
+ scheme,
+ easId,
+ organizationOwner,
+ androidIconColor,
+ appSlug
+ )
+
+ logger.info(
+ '\nYou can also add images right now, go to assets folder and replace images to match your app \n'
+ )
+ logger.info('\nPlease verify the changes made by this script and commit it to your repository \n')
}
diff --git a/scripts/cli/build/actions/bootstrap.js b/scripts/cli/build/actions/bootstrap.js
index 99a3125d..8c364e69 100644
--- a/scripts/cli/build/actions/bootstrap.js
+++ b/scripts/cli/build/actions/bootstrap.js
@@ -1,7 +1,201 @@
'use strict'
+var __awaiter =
+ (this && this.__awaiter) ||
+ function (thisArg, _arguments, P, generator) {
+ function adopt(value) {
+ return value instanceof P
+ ? value
+ : new P(function (resolve) {
+ resolve(value)
+ })
+ }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) {
+ try {
+ step(generator.next(value))
+ } catch (e) {
+ reject(e)
+ }
+ }
+ function rejected(value) {
+ try {
+ step(generator['throw'](value))
+ } catch (e) {
+ reject(e)
+ }
+ }
+ function step(result) {
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
+ }
+ step((generator = generator.apply(thisArg, _arguments || [])).next())
+ })
+ }
+var __importDefault =
+ (this && this.__importDefault) ||
+ function (mod) {
+ return mod && mod.__esModule ? mod : { default: mod }
+ }
Object.defineProperty(exports, '__esModule', { value: true })
exports.bootstrap = void 0
+const fs_1 = __importDefault(require('fs'))
+const prompt_sync_1 = __importDefault(require('prompt-sync'))
+const constants_1 = require('../constants')
+const utils_1 = require('../utils')
+const prompt = (0, prompt_sync_1.default)()
+/**
+ * Replaces placeholders in the README file with the provided app name and organization owner.
+ *
+ * @param appName - The name of the app.
+ * @param organizationOwner - The owner of the organization.
+ */
+const replaceReadme = (appName, organizationOwner) => {
+ let contents = fs_1.default.readFileSync(constants_1.README_PATH, 'utf-8')
+ contents = contents.replaceAll('_NAME_', appName)
+ contents = contents.replaceAll('_OWNER_', organizationOwner)
+ fs_1.default.writeFileSync(constants_1.README_PATH, contents)
+}
+/**
+ * Sets up the app configuration by updating the contents of the app config file.
+ *
+ * @param appName - The name of the app.
+ * @param bundleId - The bundle identifier for iOS.
+ * @param androidPackageName - The package name for Android.
+ * @param scheme - The URL scheme to link to the app.
+ * @param easId - The EAS project ID.
+ * @param androidIconColor - The background color for the adaptive icon on Android.
+ */
+const setUpAppConfig = (appName, bundleId, androidPackageName, scheme, easId, androidIconColor) => {
+ let contents = fs_1.default.readFileSync(constants_1.APP_CONFIG_PATH, 'utf8')
+ const appConfig = `
+export const APP_CONFIG = {
+ androidPackageName: '${androidPackageName}', // CONFIG: Add your android package name here
+ appName: '${appName}', // CONFIG: Add your app name here
+ easProjectId: '${easId}', // CONFIG: Add your eas project ID here
+ iosBundleIdentifier: '${bundleId}', // CONFIG: Add your ios bundle identifier here
+ scheme: '${scheme}', // CONFIG: Add your url scheme to link to your app
+ adaptiveIconBackgroundColor: '${androidIconColor}', // CONFIG: Add your url scheme to link to your app
+} as const
+`
+ contents = contents.replace(/(\/\/ APP_CONFIG_START)[\s\S]*?(\/\/ APP_CONFIG_END)/g, '$1$2')
+ contents = (0, utils_1.addAfter)(contents, '// APP_CONFIG_START', `${appConfig}`)
+ fs_1.default.writeFileSync(constants_1.APP_CONFIG_PATH, contents)
+}
+/**
+ * Replaces the contents of the pull request template file with the contents of a new pull request template file.
+ */
+const replacePullRequestTemplate = () => {
+ const contents = fs_1.default.readFileSync(constants_1.NEW_PULL_REQUEST_TEMPLATE_PATH, 'utf8')
+ fs_1.default.writeFileSync(constants_1.PULL_REQUEST_TEMPLATE_PATH, contents)
+}
+const changeAppJson = (appName, appSlug, organizationOwner) => {
+ const newAppJson = JSON.parse(fs_1.default.readFileSync(constants_1.APP_JSON_PATH, 'utf8'))
+ newAppJson.expo.slug = appSlug
+ newAppJson.expo.name = appName
+ newAppJson.expo.owner = organizationOwner
+ newAppJson.version = '1.0.0'
+ fs_1.default.writeFileSync(constants_1.APP_JSON_PATH, JSON.stringify(newAppJson, null, 2))
+}
+const changePackageJson = (appName, organizationOwner) => {
+ const packageJson = JSON.parse(fs_1.default.readFileSync('./package.json', 'utf8'))
+ packageJson.name = `@${organizationOwner}/${appName}`
+ packageJson.description = `App created from expo-template powered by binarapps`
+ packageJson.version = '1.0.0'
+ delete packageJson.repository
+ delete packageJson.bugs
+ delete packageJson.keywords
+ fs_1.default.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2))
+}
+const removeIssueTemplates = () => {
+ fs_1.default.rm('./.github/ISSUE_TEMPLATE', { recursive: true, force: true }, () => {})
+}
+const removeDocsFolder = () => {
+ fs_1.default.rm('./documentation', { recursive: true, force: true }, () => {})
+}
+const setUpProject = (
+ appName,
+ bundleId,
+ androidPackageName,
+ scheme,
+ easId,
+ organizationOwner,
+ androidIconColor,
+ appSlug
+) =>
+ __awaiter(void 0, void 0, void 0, function* () {
+ // START
+ utils_1.logger.success('Start ...')
+ // 1. Delete readme -> and create new, with new app name etc.
+ utils_1.logger.info('Generating new readme file')
+ replaceReadme(appName, organizationOwner)
+ // 2. Replace appName, bundleId, androidPackageName,scheme and easProjectId in app.config.ts file
+ utils_1.logger.info('Change project variables in app.config.ts file')
+ setUpAppConfig(appName, bundleId, androidPackageName, scheme, easId, androidIconColor)
+ // 3. Delete exist pull request template -> generate the new
+ utils_1.logger.info('Generating new pull request template file')
+ replacePullRequestTemplate()
+ // 4. Change app.json file
+ utils_1.logger.info('Change app.json file')
+ changeAppJson(appName, appSlug, organizationOwner)
+ // 5. Change package.json file
+ utils_1.logger.info('Change package.json file')
+ changePackageJson(appName, organizationOwner)
+ // 6. Remove issue templates
+ utils_1.logger.info('Remove issue templates')
+ removeIssueTemplates()
+ // 7. Remove docs folder
+ utils_1.logger.info('Remove docs folder')
+ removeDocsFolder()
+ //Finish
+ utils_1.logger.success(`Config your project has been success`)
+ })
const bootstrap = () => {
- console.log('Bootstrap')
+ utils_1.logger.info('Please give me this information to setup your project:')
+ const appName = prompt('App name: ')
+ if (!appName) {
+ return utils_1.logger.error('Please write correct app name')
+ }
+ const appSlug = prompt('App slug (from expo dashboard): ')
+ if (!appSlug) {
+ return utils_1.logger.error('Please write app slug')
+ }
+ const organizationOwner = prompt('Organization owner (from expo dashboard): ')
+ if (!organizationOwner) {
+ return utils_1.logger.error('Please write organziation owner')
+ }
+ const easId = prompt('EAS project ID (from expo dashboard): ')
+ if (!easId) {
+ return utils_1.logger.error('Please write correct eas project ID')
+ }
+ const androidIconColor =
+ prompt('Android adaptive icon color (you can leave it empty and fill it later): ') ||
+ '#2E7AF0CC'
+ const bundleId = prompt('Bundle ID (ios): ')
+ if (!bundleId) {
+ return utils_1.logger.error('Please write correct bundle ID')
+ }
+ const androidPackageName = prompt('Package name (android): ')
+ if (!androidPackageName) {
+ return utils_1.logger.error('Please write correct android package name')
+ }
+ const scheme = prompt('URL scheme (for deeplinking): ')
+ if (!scheme) {
+ return utils_1.logger.error('Please write correct scheme')
+ }
+ setUpProject(
+ appName,
+ bundleId,
+ androidPackageName,
+ scheme,
+ easId,
+ organizationOwner,
+ androidIconColor,
+ appSlug
+ )
+ utils_1.logger.info(
+ '\nYou can also add images right now, go to assets folder and replace images to match your app \n'
+ )
+ utils_1.logger.info(
+ '\nPlease verify the changes made by this script and commit it to your repository \n'
+ )
}
exports.bootstrap = bootstrap
diff --git a/scripts/cli/build/constants.js b/scripts/cli/build/constants.js
index 2004b55a..8ded1cf5 100644
--- a/scripts/cli/build/constants.js
+++ b/scripts/cli/build/constants.js
@@ -1,6 +1,12 @@
'use strict'
Object.defineProperty(exports, '__esModule', { value: true })
-exports.NAVIGATION_CONFIG_PATH =
+exports.NEW_PULL_REQUEST_TEMPLATE_PATH =
+ exports.PULL_REQUEST_TEMPLATE_PATH =
+ exports.README_TEMPLATE_PATH =
+ exports.README_PATH =
+ exports.APP_CONFIG_PATH =
+ exports.APP_JSON_PATH =
+ exports.NAVIGATION_CONFIG_PATH =
exports.SCREENS_DIRECTORY =
exports.APP_ROUTER_DIRECTORY =
exports.CLI_ACTIONS =
@@ -8,4 +14,11 @@ exports.NAVIGATION_CONFIG_PATH =
exports.CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
exports.APP_ROUTER_DIRECTORY = 'app/(app)'
exports.SCREENS_DIRECTORY = 'src/screens'
+// Paths
exports.NAVIGATION_CONFIG_PATH = 'navigation/tabNavigator/navigation-config.ts'
+exports.APP_JSON_PATH = 'app.json'
+exports.APP_CONFIG_PATH = 'app.config.ts'
+exports.README_PATH = 'README.md'
+exports.README_TEMPLATE_PATH = 'templates/README.md'
+exports.PULL_REQUEST_TEMPLATE_PATH = '.github/pull_request_template.md'
+exports.NEW_PULL_REQUEST_TEMPLATE_PATH = 'templates/pull_request_template.md'
diff --git a/scripts/cli/constants.ts b/scripts/cli/constants.ts
index 0cc00849..d856b514 100644
--- a/scripts/cli/constants.ts
+++ b/scripts/cli/constants.ts
@@ -2,4 +2,12 @@ export const CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
export const APP_ROUTER_DIRECTORY = 'app/(app)'
export const SCREENS_DIRECTORY = 'src/screens'
+
+// Paths
export const NAVIGATION_CONFIG_PATH = 'navigation/tabNavigator/navigation-config.ts'
+export const APP_JSON_PATH = 'app.json'
+export const APP_CONFIG_PATH = 'app.config.ts'
+export const README_PATH = 'README.md'
+export const README_TEMPLATE_PATH = 'templates/README.md'
+export const PULL_REQUEST_TEMPLATE_PATH = '.github/pull_request_template.md'
+export const NEW_PULL_REQUEST_TEMPLATE_PATH = 'templates/pull_request_template.md'
diff --git a/scripts/create_new_screen.js b/scripts/create_new_screen.js
deleted file mode 100644
index 04579139..00000000
--- a/scripts/create_new_screen.js
+++ /dev/null
@@ -1,318 +0,0 @@
-/* eslint-disable @typescript-eslint/no-var-requires */
-const fs = require('fs')
-const prompt = require('prompt-sync')()
-const selectPrompt = require('select-prompt')
-
-const Content = require('./contents/content')
-const { addAfter, addBefore, execPromise, logger } = require('./utils')
-
-const enumsFileSrc = './src/navigation/config/enums.ts'
-const screensFileSrc = './src/navigation/config/screens.ts'
-const tabsFileSrc = './src/navigation/config/tabs.ts'
-const typesFileSrc = './src/navigation/config/navigation.d.ts'
-const screensIndexFileSrc = './src/screens/index.ts'
-
-/**
- * @param {string} name
- */
-const validateScreen = (name) => {
- const enumsFile = require('./temp/enums')
-
- Object.values(enumsFile).forEach((enumValue) => {
- if (enumValue[name]) {
- logger.error(`Screen with name ${name} already exists`)
- process.exit(1)
- }
- })
-}
-
-/**
- * @typedef {{
- * "tabs",
- * "tabs_new",
- * "root",
- * }} TYPES
- */
-
-const createScreenFile = (name) => {
- const screenFromFile = fs.readFileSync('./templates/screen_template.tsx', 'utf8')
- const screenContent = screenFromFile
- .replaceAll('_NAME_', name)
- .replace("// @ts-expect-error: it's a template and will be removed", '')
-
- fs.writeFileSync(`./src/screens/${name}Screen.tsx`, screenContent)
-}
-
-/**
- * @param {string} name
- * @param {Object} screenType
- * @param {string} screenType.value
- * @param {keyof TYPES} screenType.type
- */
-const addToEnums = (name, screenType) => {
- const enumsFile = require('./temp/enums')
- const contents = fs.readFileSync(enumsFileSrc, 'utf8')
- const StackScreens =
- screenType.type === 'root' ? 'RootStackScreens' : screenType.value + 'Screens'
-
- // 3. a) LOGIC WHEN ADDING NEW TAB
- if (screenType.type === 'tabs_new') {
- let newContents = addAfter(
- contents,
- 'export const BottomTabsScreens = {',
- Content.bottomTab(screenType.value)
- )
-
- newContents = addBefore(
- newContents,
- '// ExamplesStack_SCREENS',
- Content.tabEnum(screenType.value, StackScreens, name)
- )
-
- fs.writeFileSync(enumsFileSrc, newContents)
- return
- }
-
- // 1. a), 2. a) LOGIC WHEN ADDING ONLY NEW SCREEN - ROOT STACK AND BOTTOM TABS
- const startIdx = contents.indexOf(`export const ${StackScreens} = {`)
- const endIdxString = '} as const'
- const endIdx = contents.indexOf(endIdxString, startIdx) + endIdxString.length
- const rootStackScreensData = enumsFile[StackScreens]
- rootStackScreensData[name] = name
-
- // Convert the updated object back to a string
- const updatedRootStackScreensDataStr = `export const ${StackScreens} = ${JSON.stringify(
- rootStackScreensData,
- null,
- 2
- )} as const`
-
- // Write the updated contents back to the file
- fs.writeFileSync(
- enumsFileSrc,
- contents.substring(0, startIdx) + updatedRootStackScreensDataStr + contents.substring(endIdx)
- )
-}
-
-/**
- * @param {string} name
- * @param {Object} screenType
- * @param {string} screenType.value
- * @param {keyof TYPES} screenType.type
- */
-const addToScreens = (name, screenType) => {
- const screenNameType = screenType.type === 'root' ? 'RootStack' : screenType.value
- const newScreen = Content.screenOptions(name, screenNameType)
- let contents =
- screenType.type === 'root'
- ? fs.readFileSync(screensFileSrc, 'utf8')
- : fs.readFileSync(tabsFileSrc, 'utf8')
-
- if (screenType.type === 'tabs_new') {
- // 3. c) Add new tab to bottomTabs and create stack with screen
- contents = addBefore(contents, '// StackEnums', Content.screenEnumImport(screenType.value))
- contents = addBefore(contents, "} from '@baca/screens'", Content.screenNameImport(name))
- contents = addBefore(
- contents,
- '// ExamplesStack_SCREENS_START',
- Content.newTab(screenType.value, newScreen)
- )
- contents = addBefore(contents, '// BottomTab_SCREENS_END', Content.tabOptions(screenType.value))
- } else {
- // 1. c), 2. c) Add screen to specific group (screens or tabs)
- const typeToSearch = `// ${screenType.value}_SCREENS_END`
-
- typeToSearch.replace(screenType.value, screenType.value)
- contents = addBefore(contents, typeToSearch, newScreen)
- contents = addBefore(contents, "} from '@baca/screens'", Content.screenNameImport(name))
- }
-
- const path = screenType.type === 'root' ? screensFileSrc : tabsFileSrc
- fs.writeFileSync(path, contents)
-}
-
-/**
- * @param {string} name
- * @param {Object} screenType
- * @param {string} screenType.value
- * @param {keyof TYPES} screenType.type
- */
-const addToTypes = (name, screenType) => {
- let contents = fs.readFileSync(typesFileSrc, 'utf8')
- // 1. b) Add screen to navigation types
- if (screenType.type === 'root') {
- contents = addAfter(contents, `// Root_${screenType.value}`, Content.newAuthorizedScreen(name))
- contents = addAfter(contents, ' // RootStack_SCREENS', Content.screenComposite(name))
- }
- // 2. b) Add screen to certain params list in navigation types
- if (screenType.type === 'tabs') {
- contents = addAfter(
- contents,
- `type ${screenType.value}ParamList = {`,
- Content.newAuthorizedScreen(name)
- )
- contents = addAfter(contents, ` // ${screenType.value}_SCREENS`, Content.screenComposite(name))
- }
-
- // 3. b) Add stack param list with new screen
- if (screenType.type === 'tabs_new') {
- contents = addAfter(contents, '// PARAMS', Content.bottomTabParamsList(screenType.value, name))
- contents = addBefore(
- contents,
- ' // BottomTabScreenProps END',
- Content.bottomTabScreenProps(screenType.value)
- )
- contents = addBefore(
- contents,
- ' ExamplesStackParamList) = keyof RootStackParamList',
- Content.screenCompositeKey(screenType.value)
- )
- contents = addAfter(
- contents,
- '> = StackScreenProps<',
- Content.screenCompositeValue(screenType.value)
- )
- contents = addBefore(
- contents,
- '// MainTabParamList END',
- Content.navigatorScreenParams(screenType.value)
- )
- contents = addBefore(contents, '// WebTabParamListEnd', Content.webTabBar(screenType.value))
- contents = addBefore(
- contents,
- ` // HomeStack_SCREENS`,
- Content.newBottomTabScreenComposite(screenType.value, name)
- )
- }
-
- fs.writeFileSync(typesFileSrc, contents)
-}
-
-const addToIndex = (name) => {
- const newExport = `
-export * from './${name}Screen'`
-
- const contents = fs.readFileSync(screensIndexFileSrc, 'utf8')
-
- fs.writeFileSync(screensIndexFileSrc, contents + newExport)
-}
-
-const makeFirstLetterUppercase = (name) => {
- return name.charAt(0).toUpperCase() + name.slice(1)
-}
-
-/**
- * @param {string} name
- * @param {Object} screenType
- * @param {string} screenType.value
- * @param {keyof TYPES} screenType.type
- */
-const generateScreen = async (name, screenType) => {
- // Make the first letter of the screen name uppercase
- const newScreenName = makeFirstLetterUppercase(name)
-
- // VALIDATE IF SCREEN NAME IS VALID
- validateScreen(newScreenName)
-
- // GENERATE SCREEN FILE
- logger.info('Generating screen files')
- createScreenFile(newScreenName)
-
- // ADD SCREEN TO INDEX, ENUMS, SCREENS, TYPES
- addToIndex(newScreenName)
- addToEnums(newScreenName, screenType)
- addToScreens(newScreenName, screenType)
- addToTypes(newScreenName, screenType)
-
- // Remove temp files
- logger.info('Removing temp files')
- await execPromise('rm -rf ./scripts/temp')
-
- // FISNISH
- logger.success(`Screen ${name} created successfully`)
-}
-
-const generateNewScreen = async () => {
- logger.info('Creating temp files files')
- await execPromise(`yarn tsc ${enumsFileSrc} --outDir ./scripts/temp --skipLibCheck`)
-
- const rootVsBottomTabs = [
- { title: 'Root stack', value: 'root' },
- { title: 'Bottom tabs', value: 'tabs' },
- ]
-
- const rootScreenTypes = [
- { title: 'Authorized', value: 'authorized' },
- { title: 'Not authorized', value: 'unauthorized' },
- { title: 'Modal', value: 'modals' },
- { title: 'Normal - authorized and not authorized', value: 'normal' },
- ]
-
- const enumsFile = require('./temp/enums')
-
- const bottomTabsScreens = Object.keys(enumsFile.BottomTabsScreens)
- const bottomTabsTypes = bottomTabsScreens
- .map((tab) => ({ title: tab, value: tab }))
- .concat({ title: 'New tab', value: '_new' })
-
- selectPrompt('Do you want this screen on root stack or on bottom tabs?', rootVsBottomTabs, {
- cursor: 0,
- }).on('submit', async (stackType) => {
- if (stackType === 'root') {
- selectPrompt('Select what type is this screen', rootScreenTypes, {
- cursor: 1,
- }).on('submit', async (screenType) => {
- const name = prompt('What is screen name? ')
- if (!name) {
- return logger.error('No screen name passed')
- }
- // 1. NEW root screen -> screen_name + screen_type (authorized | not_authorized | modal | normal)
- generateScreen(name, { type: 'root', value: screenType })
- })
- }
-
- if (stackType === 'tabs') {
- selectPrompt('Select what type is this screen', bottomTabsTypes, {
- cursor: 1,
- }).on('submit', async (screenType) => {
- const name = prompt('What is screen name? ')
- if (!name) {
- return console.log('No screen name passed')
- }
-
- // Logic when adding new tab
- if (screenType === '_new') {
- const bottomTabName = prompt('What is bottom tab name? ')
- // 2. New bottom tab screen - screen_name + bottom_tab_name
- generateScreen(name, { type: 'tabs_new', value: bottomTabName + 'Stack' })
- return
- }
-
- // 3. New bottom tab => screen_name + bottom_tab_name
- generateScreen(name, { type: 'tabs', value: screenType })
- })
- }
- })
-}
-
-generateNewScreen()
-
-// INSTRUCTION
-// 0. Common
-// a) index.ts -> export
-// b) screen_name.ts -> screen_name component
-
-// 1. NEW root screen -> screen_name + screen_type (authorized | not_authorized | modal | normal)
-// a) enums.ts -> const RootStackScreens = {
-// b) navigation.d.ts -> type RootStackParamList = {
-// c) screens.ts -> import + rootStackScreensData.authorized
-
-// 2. New bottom tab screen - screen_name + bottom_tab_name (ExampleStack)
-// a) enums.ts -> const {bottom_tab_name}Screens = {
-// b) navigation.d.ts -> type {bottom_tab_name}ParamList = {
-// c) tabs.ts -> import + // HomeStack_SCREENS_END (before)
-
-// 3. New bottom tab => screen_name + bottom_tab_name
-// a) enums.ts -> const {bottom_tab_name}StackScreens = { + export const BottomTabsScreens = { (after)
-// b) navigation.d.ts -> type {bottom_tab_name}ParamList = {
-// c) tabs.ts -> import + // ${bottom_tab_name}_SCREENS_END (before)
diff --git a/scripts/generate_icon_types.js b/scripts/generate_icon_types.js
deleted file mode 100644
index aaa50f06..00000000
--- a/scripts/generate_icon_types.js
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env node
-
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const fs = require('fs')
-
-const prefix = `export type IconNames =
- | `
-const json = fs.readFileSync('./assets/icomoon/selection.json')
-
-const types = JSON.parse(json)
- .icons.map((icon) => `'${icon.properties.name}'`)
- .join('\n | ')
- .concat('\n')
-
-const content = prefix + types
-
-fs.writeFileSync('./src/types/icon.d.ts', content)
From 1f0e49f41989511097e4824cf139a77a4fcb2c66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?=
Date: Sat, 9 Mar 2024 19:42:31 +0100
Subject: [PATCH 06/47] feat: code cleanup
---
.github/pull_request_template.md | 47 +++-
.gitignore | 5 +-
scripts/cli/actions/generate.ts | 6 +-
scripts/cli/build/actions/bootstrap.js | 201 ------------------
scripts/cli/build/actions/generate.js | 75 -------
scripts/cli/build/actions/index.js | 26 ---
scripts/cli/build/actions/parseAction.js | 11 -
.../cli/build/commands/generate.command.js | 1 -
.../cli/build/commands/generateIconTypes.js | 21 --
scripts/cli/build/commands/generateScreen.js | 191 -----------------
scripts/cli/build/commands/index.js | 31 ---
scripts/cli/build/constants.js | 24 ---
scripts/cli/build/constants/index.js | 11 -
scripts/cli/build/index.js | 9 -
scripts/cli/build/types.js | 2 -
scripts/cli/build/types/index.js | 2 -
scripts/cli/build/utils/content.js | 38 ----
scripts/cli/build/utils/getDirectoryNames.js | 33 ---
scripts/cli/build/utils/getFolderNames.js | 31 ---
scripts/cli/build/utils/index.js | 32 ---
scripts/cli/build/utils/logger.js | 21 --
scripts/cli/commands/generateScreen.ts | 2 +-
22 files changed, 49 insertions(+), 771 deletions(-)
delete mode 100644 scripts/cli/build/actions/bootstrap.js
delete mode 100644 scripts/cli/build/actions/generate.js
delete mode 100644 scripts/cli/build/actions/index.js
delete mode 100644 scripts/cli/build/actions/parseAction.js
delete mode 100644 scripts/cli/build/commands/generate.command.js
delete mode 100644 scripts/cli/build/commands/generateIconTypes.js
delete mode 100644 scripts/cli/build/commands/generateScreen.js
delete mode 100644 scripts/cli/build/commands/index.js
delete mode 100644 scripts/cli/build/constants.js
delete mode 100644 scripts/cli/build/constants/index.js
delete mode 100644 scripts/cli/build/index.js
delete mode 100644 scripts/cli/build/types.js
delete mode 100644 scripts/cli/build/types/index.js
delete mode 100644 scripts/cli/build/utils/content.js
delete mode 100644 scripts/cli/build/utils/getDirectoryNames.js
delete mode 100644 scripts/cli/build/utils/getFolderNames.js
delete mode 100644 scripts/cli/build/utils/index.js
delete mode 100644 scripts/cli/build/utils/logger.js
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index f2df2a52..c3e00217 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,11 +1,44 @@
-# Describe your changes
+# Description
-# Issue ticket number or link
+Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.
-# Checklist before requesting a review
+Fixes # (issue)
-- [ ] I did self-review of my code.
-- [ ] Do the tests work ?
-- [ ] Does lint work ?, it doesn't find any bugs or problems.
+## Type of change
-# Do any blockers exist ? if yes, describe it below.
+Please delete options that are not relevant.
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] This change requires a documentation update
+
+# How Has This Been Tested?
+
+Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
+
+- [ ] Test A
+- [ ] Test B
+
+# Screenshot(s)
+
+Please attach some screenshot or a movie if provided changes affects UI.
+
+**Test Configuration**:
+
+- Firmware version:
+- Hardware:
+- Toolchain:
+- SDK:
+
+# Checklist:
+
+- [ ] Add correct label to your pull request
+- [ ] My code follows the style guidelines of this project
+- [ ] I have performed a self-review of my code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] I have made corresponding changes to the documentation
+- [ ] My changes generate no new warnings
+- [ ] I have added tests that prove my fix is effective or that my feature works
+- [ ] New and existing unit tests pass locally with my changes
+- [ ] Any dependent changes have been merged and published in downstream modules
diff --git a/.gitignore b/.gitignore
index c49f35d8..473b3704 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,4 +39,7 @@ GoogleService-Info.plist
scripts/doppler_variables.sh
.env
-env.json
\ No newline at end of file
+env.json
+
+# baca-cli build
+scripts/cli/build/
\ No newline at end of file
diff --git a/scripts/cli/actions/generate.ts b/scripts/cli/actions/generate.ts
index 093ed69f..66ca715b 100644
--- a/scripts/cli/actions/generate.ts
+++ b/scripts/cli/actions/generate.ts
@@ -4,6 +4,7 @@ import selectPrompt from 'select-prompt'
import { generateIconTypes } from '../commands/generateIconTypes'
import { generateScreen } from '../commands/generateScreen'
+import { logger } from '../utils'
const generatePrompts = [
{
@@ -11,7 +12,7 @@ const generatePrompts = [
value: 'screen',
},
{
- title: 'Component',
+ title: 'Component TBD',
value: 'component',
},
{
@@ -23,7 +24,8 @@ const generatePrompts = [
const commands = {
screen: generateScreen,
component: () => {
- console.log('Generate Component')
+ logger.info('Not implemented yet.')
+ logger.info('Please use the `yarn generate:component` command.')
},
'icon-types': generateIconTypes,
}
diff --git a/scripts/cli/build/actions/bootstrap.js b/scripts/cli/build/actions/bootstrap.js
deleted file mode 100644
index 8c364e69..00000000
--- a/scripts/cli/build/actions/bootstrap.js
+++ /dev/null
@@ -1,201 +0,0 @@
-'use strict'
-var __awaiter =
- (this && this.__awaiter) ||
- function (thisArg, _arguments, P, generator) {
- function adopt(value) {
- return value instanceof P
- ? value
- : new P(function (resolve) {
- resolve(value)
- })
- }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) {
- try {
- step(generator.next(value))
- } catch (e) {
- reject(e)
- }
- }
- function rejected(value) {
- try {
- step(generator['throw'](value))
- } catch (e) {
- reject(e)
- }
- }
- function step(result) {
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
- }
- step((generator = generator.apply(thisArg, _arguments || [])).next())
- })
- }
-var __importDefault =
- (this && this.__importDefault) ||
- function (mod) {
- return mod && mod.__esModule ? mod : { default: mod }
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.bootstrap = void 0
-const fs_1 = __importDefault(require('fs'))
-const prompt_sync_1 = __importDefault(require('prompt-sync'))
-const constants_1 = require('../constants')
-const utils_1 = require('../utils')
-const prompt = (0, prompt_sync_1.default)()
-/**
- * Replaces placeholders in the README file with the provided app name and organization owner.
- *
- * @param appName - The name of the app.
- * @param organizationOwner - The owner of the organization.
- */
-const replaceReadme = (appName, organizationOwner) => {
- let contents = fs_1.default.readFileSync(constants_1.README_PATH, 'utf-8')
- contents = contents.replaceAll('_NAME_', appName)
- contents = contents.replaceAll('_OWNER_', organizationOwner)
- fs_1.default.writeFileSync(constants_1.README_PATH, contents)
-}
-/**
- * Sets up the app configuration by updating the contents of the app config file.
- *
- * @param appName - The name of the app.
- * @param bundleId - The bundle identifier for iOS.
- * @param androidPackageName - The package name for Android.
- * @param scheme - The URL scheme to link to the app.
- * @param easId - The EAS project ID.
- * @param androidIconColor - The background color for the adaptive icon on Android.
- */
-const setUpAppConfig = (appName, bundleId, androidPackageName, scheme, easId, androidIconColor) => {
- let contents = fs_1.default.readFileSync(constants_1.APP_CONFIG_PATH, 'utf8')
- const appConfig = `
-export const APP_CONFIG = {
- androidPackageName: '${androidPackageName}', // CONFIG: Add your android package name here
- appName: '${appName}', // CONFIG: Add your app name here
- easProjectId: '${easId}', // CONFIG: Add your eas project ID here
- iosBundleIdentifier: '${bundleId}', // CONFIG: Add your ios bundle identifier here
- scheme: '${scheme}', // CONFIG: Add your url scheme to link to your app
- adaptiveIconBackgroundColor: '${androidIconColor}', // CONFIG: Add your url scheme to link to your app
-} as const
-`
- contents = contents.replace(/(\/\/ APP_CONFIG_START)[\s\S]*?(\/\/ APP_CONFIG_END)/g, '$1$2')
- contents = (0, utils_1.addAfter)(contents, '// APP_CONFIG_START', `${appConfig}`)
- fs_1.default.writeFileSync(constants_1.APP_CONFIG_PATH, contents)
-}
-/**
- * Replaces the contents of the pull request template file with the contents of a new pull request template file.
- */
-const replacePullRequestTemplate = () => {
- const contents = fs_1.default.readFileSync(constants_1.NEW_PULL_REQUEST_TEMPLATE_PATH, 'utf8')
- fs_1.default.writeFileSync(constants_1.PULL_REQUEST_TEMPLATE_PATH, contents)
-}
-const changeAppJson = (appName, appSlug, organizationOwner) => {
- const newAppJson = JSON.parse(fs_1.default.readFileSync(constants_1.APP_JSON_PATH, 'utf8'))
- newAppJson.expo.slug = appSlug
- newAppJson.expo.name = appName
- newAppJson.expo.owner = organizationOwner
- newAppJson.version = '1.0.0'
- fs_1.default.writeFileSync(constants_1.APP_JSON_PATH, JSON.stringify(newAppJson, null, 2))
-}
-const changePackageJson = (appName, organizationOwner) => {
- const packageJson = JSON.parse(fs_1.default.readFileSync('./package.json', 'utf8'))
- packageJson.name = `@${organizationOwner}/${appName}`
- packageJson.description = `App created from expo-template powered by binarapps`
- packageJson.version = '1.0.0'
- delete packageJson.repository
- delete packageJson.bugs
- delete packageJson.keywords
- fs_1.default.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2))
-}
-const removeIssueTemplates = () => {
- fs_1.default.rm('./.github/ISSUE_TEMPLATE', { recursive: true, force: true }, () => {})
-}
-const removeDocsFolder = () => {
- fs_1.default.rm('./documentation', { recursive: true, force: true }, () => {})
-}
-const setUpProject = (
- appName,
- bundleId,
- androidPackageName,
- scheme,
- easId,
- organizationOwner,
- androidIconColor,
- appSlug
-) =>
- __awaiter(void 0, void 0, void 0, function* () {
- // START
- utils_1.logger.success('Start ...')
- // 1. Delete readme -> and create new, with new app name etc.
- utils_1.logger.info('Generating new readme file')
- replaceReadme(appName, organizationOwner)
- // 2. Replace appName, bundleId, androidPackageName,scheme and easProjectId in app.config.ts file
- utils_1.logger.info('Change project variables in app.config.ts file')
- setUpAppConfig(appName, bundleId, androidPackageName, scheme, easId, androidIconColor)
- // 3. Delete exist pull request template -> generate the new
- utils_1.logger.info('Generating new pull request template file')
- replacePullRequestTemplate()
- // 4. Change app.json file
- utils_1.logger.info('Change app.json file')
- changeAppJson(appName, appSlug, organizationOwner)
- // 5. Change package.json file
- utils_1.logger.info('Change package.json file')
- changePackageJson(appName, organizationOwner)
- // 6. Remove issue templates
- utils_1.logger.info('Remove issue templates')
- removeIssueTemplates()
- // 7. Remove docs folder
- utils_1.logger.info('Remove docs folder')
- removeDocsFolder()
- //Finish
- utils_1.logger.success(`Config your project has been success`)
- })
-const bootstrap = () => {
- utils_1.logger.info('Please give me this information to setup your project:')
- const appName = prompt('App name: ')
- if (!appName) {
- return utils_1.logger.error('Please write correct app name')
- }
- const appSlug = prompt('App slug (from expo dashboard): ')
- if (!appSlug) {
- return utils_1.logger.error('Please write app slug')
- }
- const organizationOwner = prompt('Organization owner (from expo dashboard): ')
- if (!organizationOwner) {
- return utils_1.logger.error('Please write organziation owner')
- }
- const easId = prompt('EAS project ID (from expo dashboard): ')
- if (!easId) {
- return utils_1.logger.error('Please write correct eas project ID')
- }
- const androidIconColor =
- prompt('Android adaptive icon color (you can leave it empty and fill it later): ') ||
- '#2E7AF0CC'
- const bundleId = prompt('Bundle ID (ios): ')
- if (!bundleId) {
- return utils_1.logger.error('Please write correct bundle ID')
- }
- const androidPackageName = prompt('Package name (android): ')
- if (!androidPackageName) {
- return utils_1.logger.error('Please write correct android package name')
- }
- const scheme = prompt('URL scheme (for deeplinking): ')
- if (!scheme) {
- return utils_1.logger.error('Please write correct scheme')
- }
- setUpProject(
- appName,
- bundleId,
- androidPackageName,
- scheme,
- easId,
- organizationOwner,
- androidIconColor,
- appSlug
- )
- utils_1.logger.info(
- '\nYou can also add images right now, go to assets folder and replace images to match your app \n'
- )
- utils_1.logger.info(
- '\nPlease verify the changes made by this script and commit it to your repository \n'
- )
-}
-exports.bootstrap = bootstrap
diff --git a/scripts/cli/build/actions/generate.js b/scripts/cli/build/actions/generate.js
deleted file mode 100644
index 12d8d7fa..00000000
--- a/scripts/cli/build/actions/generate.js
+++ /dev/null
@@ -1,75 +0,0 @@
-'use strict'
-var __awaiter =
- (this && this.__awaiter) ||
- function (thisArg, _arguments, P, generator) {
- function adopt(value) {
- return value instanceof P
- ? value
- : new P(function (resolve) {
- resolve(value)
- })
- }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) {
- try {
- step(generator.next(value))
- } catch (e) {
- reject(e)
- }
- }
- function rejected(value) {
- try {
- step(generator['throw'](value))
- } catch (e) {
- reject(e)
- }
- }
- function step(result) {
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
- }
- step((generator = generator.apply(thisArg, _arguments || [])).next())
- })
- }
-var __importDefault =
- (this && this.__importDefault) ||
- function (mod) {
- return mod && mod.__esModule ? mod : { default: mod }
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.generate = void 0
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-const select_prompt_1 = __importDefault(require('select-prompt'))
-const generateIconTypes_1 = require('../commands/generateIconTypes')
-const generateScreen_1 = require('../commands/generateScreen')
-const generatePrompts = [
- {
- title: 'Screen',
- value: 'screen',
- },
- {
- title: 'Component',
- value: 'component',
- },
- {
- title: 'Icon types',
- value: 'icon-types',
- },
-]
-const commands = {
- screen: generateScreen_1.generateScreen,
- component: () => {
- console.log('Generate Component')
- },
- 'icon-types': generateIconTypes_1.generateIconTypes,
-}
-const generate = () => {
- ;(0, select_prompt_1.default)('What do you want to generate?', generatePrompts).on(
- 'submit',
- (value) =>
- __awaiter(void 0, void 0, void 0, function* () {
- commands[value]()
- })
- )
-}
-exports.generate = generate
diff --git a/scripts/cli/build/actions/index.js b/scripts/cli/build/actions/index.js
deleted file mode 100644
index 8ee49f5c..00000000
--- a/scripts/cli/build/actions/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.executeAction = void 0
-const bootstrap_1 = require('./bootstrap')
-const generate_1 = require('./generate')
-const constants_1 = require('../constants')
-const utils_1 = require('../utils')
-const actions = {
- generate: generate_1.generate,
- g: generate_1.generate,
- bootstrap: bootstrap_1.bootstrap,
- b: bootstrap_1.bootstrap,
-}
-/**
- * Parses and executes the specified CLI action.
- *
- * @param action - The CLI action to parse and execute.
- */
-const executeAction = (action) => {
- if (!constants_1.CLI_ACTIONS.includes(action)) {
- utils_1.logger.error(`Action ${action} is not supported.`)
- return
- }
- actions[action]()
-}
-exports.executeAction = executeAction
diff --git a/scripts/cli/build/actions/parseAction.js b/scripts/cli/build/actions/parseAction.js
deleted file mode 100644
index b2439ccd..00000000
--- a/scripts/cli/build/actions/parseAction.js
+++ /dev/null
@@ -1,11 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.parseAction = void 0
-const constants_1 = require('../constants')
-const parseAction = (action) => {
- if (!constants_1.CLI_ACTIONS.includes(action)) {
- console.error('\x1b[31m%s\x1b[0m', `Invalid action ${action}`)
- return
- }
-}
-exports.parseAction = parseAction
diff --git a/scripts/cli/build/commands/generate.command.js b/scripts/cli/build/commands/generate.command.js
deleted file mode 100644
index ccacec30..00000000
--- a/scripts/cli/build/commands/generate.command.js
+++ /dev/null
@@ -1 +0,0 @@
-'use strict'
diff --git a/scripts/cli/build/commands/generateIconTypes.js b/scripts/cli/build/commands/generateIconTypes.js
deleted file mode 100644
index 9717bc93..00000000
--- a/scripts/cli/build/commands/generateIconTypes.js
+++ /dev/null
@@ -1,21 +0,0 @@
-'use strict'
-var __importDefault =
- (this && this.__importDefault) ||
- function (mod) {
- return mod && mod.__esModule ? mod : { default: mod }
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.generateIconTypes = void 0
-const fs_1 = __importDefault(require('fs'))
-const prefix = `export type IconNames =
- | `
-const generateIconTypes = () => {
- const json = fs_1.default.readFileSync('./assets/icomoon/selection.json')
- const types = JSON.parse(json.toString())
- .icons.map((icon) => `'${icon.properties.name}'`)
- .join('\n | ')
- .concat('\n')
- const content = prefix + types
- fs_1.default.writeFileSync('./src/types/icon.d.ts', content)
-}
-exports.generateIconTypes = generateIconTypes
diff --git a/scripts/cli/build/commands/generateScreen.js b/scripts/cli/build/commands/generateScreen.js
deleted file mode 100644
index f129abfd..00000000
--- a/scripts/cli/build/commands/generateScreen.js
+++ /dev/null
@@ -1,191 +0,0 @@
-'use strict'
-var __awaiter =
- (this && this.__awaiter) ||
- function (thisArg, _arguments, P, generator) {
- function adopt(value) {
- return value instanceof P
- ? value
- : new P(function (resolve) {
- resolve(value)
- })
- }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) {
- try {
- step(generator.next(value))
- } catch (e) {
- reject(e)
- }
- }
- function rejected(value) {
- try {
- step(generator['throw'](value))
- } catch (e) {
- reject(e)
- }
- }
- function step(result) {
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected)
- }
- step((generator = generator.apply(thisArg, _arguments || [])).next())
- })
- }
-var __importDefault =
- (this && this.__importDefault) ||
- function (mod) {
- return mod && mod.__esModule ? mod : { default: mod }
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.generateScreen = void 0
-const fs_1 = __importDefault(require('fs'))
-const prompt_sync_1 = __importDefault(require('prompt-sync'))
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-const select_prompt_1 = __importDefault(require('select-prompt'))
-const constants_1 = require('../constants')
-const utils_1 = require('../utils')
-const addAfter = (content, searchText, textToAdd) => {
- return content.replace(searchText, searchText + textToAdd)
-}
-/**
- * Recursively prompts the user to select a subdirectory and calls itself with the selected subdirectory path.
- *
- * @param basePath - The path of the current directory.
- */
-const selectPath = (basePath) =>
- new Promise((resolve) => {
- const subDirectories = (0, utils_1.getDirectoryNames)(basePath)
- const hasSubDirectories = subDirectories.length > 0
- // Return the result when there are no subdirectories
- if (!hasSubDirectories) {
- resolve(basePath)
- return
- }
- const subDirectoryPrompt = subDirectories.map((directoryName) => ({
- title: directoryName,
- value: directoryName,
- }))
- if (basePath.includes('tabs')) {
- subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
- }
- if (basePath !== constants_1.APP_ROUTER_DIRECTORY) {
- subDirectoryPrompt.unshift({ title: '.', value: '.' })
- }
- ;(0, select_prompt_1.default)(`Select a directory (${basePath})`, subDirectoryPrompt, {
- cursor: 0,
- }).on('submit', (subValue) => {
- // Return the result when user selects current directory
- if (subValue === '.') {
- resolve(basePath)
- return
- }
- // Recursively execute path selection when subValue is not the current directory
- selectPath(`${basePath}/${subValue}`).then((subResult) => {
- resolve(subResult)
- })
- })
- })
-/**
- * Validates if a route with the given name already exists in the specified path.
- * @param routeName - The name of the route.
- * @param routePath - The path where the route should be generated.
- * @throws Error if the route already exists in the specified path.
- */
-const validateRoute = (routeName, routePath) => {
- const filePath = `${routePath}/${routeName}.tsx`
- if (fs_1.default.existsSync(filePath)) {
- utils_1.logger.error(`Route ${routeName} already exists in ${routePath}`)
- }
-}
-/**
- * Creates a route file with the given route name and path.
- * @param {string} routeName - The name of the route.
- * @param {string} routePath - The path where the route file will be created.
- */
-const createRouteFile = (routeName, routePath) => {
- const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
- fs_1.default.writeFileSync(
- `${routePath}/${routeName.toLowerCase()}.tsx`,
- `import { ${screenName} } from '@baca/screens'
-
-export default ${screenName}
-`
- )
-}
-/**
- * Validates if a screen with the given name already exists.
- * @param screenName - The name of the screen.
- * @throws Error if the screen already exists.
- */
-const validateScreen = (screenName) => {
- const filePath = `${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`
- if (fs_1.default.existsSync(filePath)) {
- utils_1.logger.error(`Screen ${screenName} already exists`)
- }
-}
-/**
- * Creates a screen file with the given screen name.
- * @param {string} screenName - The name of the screen.
- */
-const createScreenFile = (screenName) => {
- const screenFromFile = fs_1.default.readFileSync('./templates/screen_template.tsx', 'utf8')
- const screenContent = screenFromFile
- .replaceAll('_NAME_', screenName)
- .replace("// @ts-expect-error: it's a template and will be removed", '')
- fs_1.default.writeFileSync(`${constants_1.SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent)
-}
-const addToScreensIndex = (screenName) => {
- const indexFilePath = `${constants_1.SCREENS_DIRECTORY}/index.ts`
- const indexFile = fs_1.default.readFileSync(indexFilePath, 'utf8')
- const newIndexFile = indexFile.padEnd(indexFile.length) + `export * from './${screenName}'\n`
- fs_1.default.writeFileSync(indexFilePath, newIndexFile)
-}
-const promptTabName = () => {
- const tabName = (0, prompt_sync_1.default)()('Enter tab name: ')
- if (!tabName) {
- throw new Error('Tab name is required')
- }
- return tabName
-}
-const createNewNavTab = (tabName) => {
- const navigationConfigFile = fs_1.default.readFileSync(
- './src/navigation/tabNavigator/navigation-config.ts',
- 'utf8'
- )
- const tabContent = `
- {
- displayedName: '${tabName.charAt(0).toUpperCase() + tabName.slice(1)}',
- icon: 'zzz-line', // CONFIG: Add your icon name here
- iconFocused: 'zzz-fill', // CONFIG: Add your icon name here
- id: '${tabName}',
- name: '${tabName}',
- },`
- const newContent = addAfter(navigationConfigFile, '// UPPER SIDE TABS', tabContent)
- fs_1.default.writeFileSync('./src/navigation/tabNavigator/navigation-config.ts', newContent)
-}
-/**
- * Generates a screen based on user input.
- * Prompts the user to enter a screen name and selects a screen path.
- * Validates the screen name and path.
- */
-const generateScreen = () =>
- __awaiter(void 0, void 0, void 0, function* () {
- const routeName = (0, prompt_sync_1.default)()('Enter screen name: ')
- let routePath = yield selectPath(constants_1.APP_ROUTER_DIRECTORY)
- const isNewTab = routePath.includes('(tabs)') && routePath.includes('new-tab')
- if (isNewTab) {
- const tabName = promptTabName()
- createNewNavTab(tabName)
- const newTabPath = routePath.replace('/new-tab', `/${tabName}`)
- routePath = newTabPath
- console.log({ newTabPath, routePath })
- fs_1.default.mkdirSync(newTabPath)
- }
- validateRoute(routeName, routePath)
- createRouteFile(routeName, routePath)
- const screenName = `${routeName.charAt(0).toUpperCase() + routeName.slice(1)}Screen`
- validateScreen(screenName)
- createScreenFile(screenName)
- addToScreensIndex(screenName)
- })
-exports.generateScreen = generateScreen
diff --git a/scripts/cli/build/commands/index.js b/scripts/cli/build/commands/index.js
deleted file mode 100644
index c38b9d85..00000000
--- a/scripts/cli/build/commands/index.js
+++ /dev/null
@@ -1,31 +0,0 @@
-'use strict'
-var __createBinding =
- (this && this.__createBinding) ||
- (Object.create
- ? function (o, m, k, k2) {
- if (k2 === undefined) k2 = k
- var desc = Object.getOwnPropertyDescriptor(m, k)
- if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = {
- enumerable: true,
- get: function () {
- return m[k]
- },
- }
- }
- Object.defineProperty(o, k2, desc)
- }
- : function (o, m, k, k2) {
- if (k2 === undefined) k2 = k
- o[k2] = m[k]
- })
-var __exportStar =
- (this && this.__exportStar) ||
- function (m, exports) {
- for (var p in m)
- if (p !== 'default' && !Object.prototype.hasOwnProperty.call(exports, p))
- __createBinding(exports, m, p)
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-__exportStar(require('./generateIconTypes'), exports)
-__exportStar(require('./generateScreen'), exports)
diff --git a/scripts/cli/build/constants.js b/scripts/cli/build/constants.js
deleted file mode 100644
index 8ded1cf5..00000000
--- a/scripts/cli/build/constants.js
+++ /dev/null
@@ -1,24 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.NEW_PULL_REQUEST_TEMPLATE_PATH =
- exports.PULL_REQUEST_TEMPLATE_PATH =
- exports.README_TEMPLATE_PATH =
- exports.README_PATH =
- exports.APP_CONFIG_PATH =
- exports.APP_JSON_PATH =
- exports.NAVIGATION_CONFIG_PATH =
- exports.SCREENS_DIRECTORY =
- exports.APP_ROUTER_DIRECTORY =
- exports.CLI_ACTIONS =
- void 0
-exports.CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
-exports.APP_ROUTER_DIRECTORY = 'app/(app)'
-exports.SCREENS_DIRECTORY = 'src/screens'
-// Paths
-exports.NAVIGATION_CONFIG_PATH = 'navigation/tabNavigator/navigation-config.ts'
-exports.APP_JSON_PATH = 'app.json'
-exports.APP_CONFIG_PATH = 'app.config.ts'
-exports.README_PATH = 'README.md'
-exports.README_TEMPLATE_PATH = 'templates/README.md'
-exports.PULL_REQUEST_TEMPLATE_PATH = '.github/pull_request_template.md'
-exports.NEW_PULL_REQUEST_TEMPLATE_PATH = 'templates/pull_request_template.md'
diff --git a/scripts/cli/build/constants/index.js b/scripts/cli/build/constants/index.js
deleted file mode 100644
index 3b00dc1b..00000000
--- a/scripts/cli/build/constants/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.NAVIGATION_CONFIG_PATH =
- exports.SCREENS_DIRECTORY =
- exports.APP_ROUTER_DIRECTORY =
- exports.CLI_ACTIONS =
- void 0
-exports.CLI_ACTIONS = ['generate', 'g', 'bootstrap', 'b']
-exports.APP_ROUTER_DIRECTORY = `${process.cwd()}/app/(app)`
-exports.SCREENS_DIRECTORY = `${process.cwd()}/src/screens`
-exports.NAVIGATION_CONFIG_PATH = `${process.cwd()}/navigation/tabNavigator/navigation-config.ts`
diff --git a/scripts/cli/build/index.js b/scripts/cli/build/index.js
deleted file mode 100644
index 26dba5af..00000000
--- a/scripts/cli/build/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
-const commander_1 = require('commander')
-const actions_1 = require('./actions')
-const program = new commander_1.Command()
-program.argument('').action((action) => {
- ;(0, actions_1.executeAction)(action)
-})
-program.parse()
diff --git a/scripts/cli/build/types.js b/scripts/cli/build/types.js
deleted file mode 100644
index 0a483a32..00000000
--- a/scripts/cli/build/types.js
+++ /dev/null
@@ -1,2 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
diff --git a/scripts/cli/build/types/index.js b/scripts/cli/build/types/index.js
deleted file mode 100644
index 0a483a32..00000000
--- a/scripts/cli/build/types/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
diff --git a/scripts/cli/build/utils/content.js b/scripts/cli/build/utils/content.js
deleted file mode 100644
index 88b6e409..00000000
--- a/scripts/cli/build/utils/content.js
+++ /dev/null
@@ -1,38 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.deleteText = exports.addBefore = exports.addAfter = void 0
-/**
- * Adds the specified text after the first occurrence of the search text in the content.
- *
- * @param content - The original content string.
- * @param searchText - The text to search for in the content.
- * @param textToAdd - The text to add after the first occurrence of the search text.
- * @returns The modified content string with the text added.
- */
-const addAfter = (content, searchText, textToAdd) => {
- return content.replace(searchText, searchText + textToAdd)
-}
-exports.addAfter = addAfter
-/**
- * Adds the specified text before the first occurrence of the search text in the content.
- *
- * @param content - The original content string.
- * @param searchText - The text to search for in the content.
- * @param textToAdd - The text to add before the first occurrence of the search text.
- * @returns The modified content string with the text added before the first occurrence of the search text.
- */
-const addBefore = (content, searchText, textToAdd) => {
- return content.replace(searchText, textToAdd + searchText)
-}
-exports.addBefore = addBefore
-/**
- * Deletes all occurrences of a specified search text from the given content.
- *
- * @param content - The content from which to delete the search text.
- * @param searchText - The text to be deleted from the content.
- * @returns The updated content with all occurrences of the search text removed.
- */
-const deleteText = (content, searchText) => {
- return content.replace(searchText, '')
-}
-exports.deleteText = deleteText
diff --git a/scripts/cli/build/utils/getDirectoryNames.js b/scripts/cli/build/utils/getDirectoryNames.js
deleted file mode 100644
index aa233144..00000000
--- a/scripts/cli/build/utils/getDirectoryNames.js
+++ /dev/null
@@ -1,33 +0,0 @@
-'use strict'
-var __importDefault =
- (this && this.__importDefault) ||
- function (mod) {
- return mod && mod.__esModule ? mod : { default: mod }
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.getDirectoryNames = void 0
-const fs_1 = __importDefault(require('fs'))
-const logger_1 = require('./logger')
-/**
- * Retrieves the names of all sub-directories in the specified directory.
- *
- * @param directoryPath - The path of the directory to retrieve directory names from.
- * @returns An array of directory names.
- */
-const getDirectoryNames = (directoryPath) => {
- try {
- if (directoryPath.includes('new-tab')) return []
- // Read the contents of the directory
- const contents = fs_1.default.readdirSync(directoryPath)
- // Filter out only directories
- const folderNames = contents.filter((item) => {
- const stat = fs_1.default.statSync(`${directoryPath}/${item}`)
- return stat.isDirectory()
- })
- return folderNames
- } catch (err) {
- logger_1.logger.error(`Error reading directory: ${err}`)
- return []
- }
-}
-exports.getDirectoryNames = getDirectoryNames
diff --git a/scripts/cli/build/utils/getFolderNames.js b/scripts/cli/build/utils/getFolderNames.js
deleted file mode 100644
index 78b9895b..00000000
--- a/scripts/cli/build/utils/getFolderNames.js
+++ /dev/null
@@ -1,31 +0,0 @@
-'use strict'
-var __importDefault =
- (this && this.__importDefault) ||
- function (mod) {
- return mod && mod.__esModule ? mod : { default: mod }
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.getFolderNames = void 0
-const fs_1 = __importDefault(require('fs'))
-/**
- * Retrieves the names of all folders in the specified directory.
- *
- * @param directoryPath - The path of the directory to retrieve folder names from.
- * @returns An array of folder names.
- */
-const getFolderNames = (directoryPath) => {
- try {
- // Read the contents of the directory
- const contents = fs_1.default.readdirSync(directoryPath)
- // Filter out only directories
- const folderNames = contents.filter((item) => {
- const stat = fs_1.default.statSync(`${directoryPath}/${item}`)
- return stat.isDirectory()
- })
- return folderNames
- } catch (err) {
- console.error(`Error reading directory: ${err}`)
- return []
- }
-}
-exports.getFolderNames = getFolderNames
diff --git a/scripts/cli/build/utils/index.js b/scripts/cli/build/utils/index.js
deleted file mode 100644
index 3b11ce9e..00000000
--- a/scripts/cli/build/utils/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-'use strict'
-var __createBinding =
- (this && this.__createBinding) ||
- (Object.create
- ? function (o, m, k, k2) {
- if (k2 === undefined) k2 = k
- var desc = Object.getOwnPropertyDescriptor(m, k)
- if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = {
- enumerable: true,
- get: function () {
- return m[k]
- },
- }
- }
- Object.defineProperty(o, k2, desc)
- }
- : function (o, m, k, k2) {
- if (k2 === undefined) k2 = k
- o[k2] = m[k]
- })
-var __exportStar =
- (this && this.__exportStar) ||
- function (m, exports) {
- for (var p in m)
- if (p !== 'default' && !Object.prototype.hasOwnProperty.call(exports, p))
- __createBinding(exports, m, p)
- }
-Object.defineProperty(exports, '__esModule', { value: true })
-__exportStar(require('./getDirectoryNames'), exports)
-__exportStar(require('./content'), exports)
-__exportStar(require('./logger'), exports)
diff --git a/scripts/cli/build/utils/logger.js b/scripts/cli/build/utils/logger.js
deleted file mode 100644
index e0100c0a..00000000
--- a/scripts/cli/build/utils/logger.js
+++ /dev/null
@@ -1,21 +0,0 @@
-'use strict'
-Object.defineProperty(exports, '__esModule', { value: true })
-exports.logger = void 0
-const LCERROR = '\x1b[31m%s\x1b[0m' //red
-const LCWARN = '\x1b[33m%s\x1b[0m' //yellow
-const LCINFO = '\x1b[36m%s\x1b[0m' //cyan
-const LCSUCCESS = '\x1b[32m%s\x1b[0m' //green
-exports.logger = {
- error: (message, ...optionalParams) => {
- console.error(LCERROR, message, ...optionalParams)
- },
- warn: (message, ...optionalParams) => {
- console.warn(LCWARN, message, ...optionalParams)
- },
- info: (message, ...optionalParams) => {
- console.info(LCINFO, message, ...optionalParams)
- },
- success: (message, ...optionalParams) => {
- console.info(LCSUCCESS, message, ...optionalParams)
- },
-}
diff --git a/scripts/cli/commands/generateScreen.ts b/scripts/cli/commands/generateScreen.ts
index b2d70637..0896464d 100644
--- a/scripts/cli/commands/generateScreen.ts
+++ b/scripts/cli/commands/generateScreen.ts
@@ -160,7 +160,7 @@ export const generateScreen = async () => {
const newTabPath = routePath.replace('/new-tab', `/${tabName}`)
routePath = newTabPath
- console.log({ newTabPath, routePath })
+
fs.mkdirSync(newTabPath)
}
From 500a695e4fcc464a0e9fbc9343c2ff526d7a67a3 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sun, 10 Mar 2024 18:10:06 +0100
Subject: [PATCH 07/47] chore: update scripts in package json
---
package.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index ce2ddaf2..e7d9f793 100644
--- a/package.json
+++ b/package.json
@@ -45,15 +45,15 @@
"deploy:staging:android": "yarn prepare:staging && eas build --platform android --profile staging --auto-submit --non-interactive",
"deploy:staging:ios": "yarn prepare:staging && eas build --platform ios --profile staging --auto-submit --non-interactive",
"deploy:staging": "yarn prepare:staging && eas build --platform all --profile staging --auto-submit --non-interactive",
- "generate:query": "yarn orval --config ./orval.config.ts",
+ "eas-build-pre-install": "base64 --help && echo $ANDROID_FIREBASE_CONFIG | base64 --decode > google-services.json && cat google-services.json && echo $IOS_FIREBASE_CONFIG | base64 --decode > GoogleService-Info.plist && cat GoogleService-Info.plist",
"generate:component": "node ./scripts/create_new_component.js && yarn eslint src --fix && yarn tsc",
"generate:env:production": "scripts/generate_dotenv.sh production",
"generate:env:qa": "scripts/generate_dotenv.sh qa",
"generate:env:staging": "scripts/generate_dotenv.sh staging",
- "lint": "eslint src && yarn tsc",
+ "generate:google-services-config": "./scripts/generate_firebase_config.sh",
+ "generate:query": "yarn orval --config ./orval.config.ts",
"lint:fix": "eslint src --fix",
- "login": "expo login",
- "logout": "expo logout",
+ "lint": "eslint src && yarn tsc",
"postinstall": "patch-package && yarn build:baca-cli",
"prebuild:android": "IS_DEV=1 npx expo prebuild --clean -p android",
"prebuild:ios": "IS_DEV=1 npx expo prebuild --clean -p ios",
From c3d5f39fd264067b6c4ba252f37738659b8cc199 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sun, 10 Mar 2024 18:15:17 +0100
Subject: [PATCH 08/47] chore: remove not needed ts-expect-error directive
---
scripts/cli/commands/generateScreen.ts | 4 +---
templates/screen_template.tsx | 2 +-
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/scripts/cli/commands/generateScreen.ts b/scripts/cli/commands/generateScreen.ts
index 0896464d..6925fd00 100644
--- a/scripts/cli/commands/generateScreen.ts
+++ b/scripts/cli/commands/generateScreen.ts
@@ -102,9 +102,7 @@ const validateScreen = (screenName: string) => {
*/
const createScreenFile = (screenName: string) => {
const screenFromFile = fs.readFileSync('./templates/screen_template.tsx', 'utf8')
- const screenContent = screenFromFile
- .replaceAll('_NAME_', screenName)
- .replace("// @ts-expect-error: it's a template and will be removed", '')
+ const screenContent = screenFromFile.replaceAll('_NAME_', screenName)
fs.writeFileSync(`${SCREENS_DIRECTORY}/${screenName}.tsx`, screenContent)
}
diff --git a/templates/screen_template.tsx b/templates/screen_template.tsx
index 113ac472..2ad19f16 100644
--- a/templates/screen_template.tsx
+++ b/templates/screen_template.tsx
@@ -1,6 +1,6 @@
import { Center, Text } from '@baca/design-system'
import { useTranslation } from '@baca/hooks'
-// @ts-expect-error: it's a template and will be removed
+
export const _NAME_ = (): JSX.Element => {
const { t } = useTranslation()
From aa5fefb38c817dc5404ea65520b2da1e70a81a51 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Mon, 1 Apr 2024 00:23:37 +0200
Subject: [PATCH 09/47] chore: move generate theme to scripts
---
scripts/cli/actions/generate.ts | 6 ++
.../commands/generateTheme.ts} | 81 +++++++++++--------
scripts/cli/commands/index.ts | 1 +
scripts/cli/tsconfig.cli.json | 2 +
4 files changed, 55 insertions(+), 35 deletions(-)
rename scripts/{generate_theme.js => cli/commands/generateTheme.ts} (56%)
diff --git a/scripts/cli/actions/generate.ts b/scripts/cli/actions/generate.ts
index 66ca715b..cf8798d7 100644
--- a/scripts/cli/actions/generate.ts
+++ b/scripts/cli/actions/generate.ts
@@ -4,6 +4,7 @@ import selectPrompt from 'select-prompt'
import { generateIconTypes } from '../commands/generateIconTypes'
import { generateScreen } from '../commands/generateScreen'
+import { generateTheme } from '../commands/generateTheme'
import { logger } from '../utils'
const generatePrompts = [
@@ -19,6 +20,10 @@ const generatePrompts = [
title: 'Icon types',
value: 'icon-types',
},
+ {
+ title: 'Generate theme',
+ value: 'generate-theme',
+ },
]
const commands = {
@@ -28,6 +33,7 @@ const commands = {
logger.info('Please use the `yarn generate:component` command.')
},
'icon-types': generateIconTypes,
+ 'generate-theme': generateTheme,
}
export const generate = () => {
diff --git a/scripts/generate_theme.js b/scripts/cli/commands/generateTheme.ts
similarity index 56%
rename from scripts/generate_theme.js
rename to scripts/cli/commands/generateTheme.ts
index a0162168..72367247 100644
--- a/scripts/generate_theme.js
+++ b/scripts/cli/commands/generateTheme.ts
@@ -1,41 +1,44 @@
#!/usr/bin/env node
+/* eslint-disable @typescript-eslint/no-explicit-any */
// eslint-disable-next-line @typescript-eslint/no-var-requires
-const fs = require('fs')
-const json = fs.readFileSync('./assets/figma/variables.json')
+import fs from 'fs'
+
+const json = fs.readFileSync('./assets/figma/variables.json') as unknown as string
const figmaVariables = JSON.parse(json)
-const collections = figmaVariables.collections
+const collections = figmaVariables.collections as any
-const primitivesCollection = collections.find((collection) => collection.name === '_Primitives')
-const colorsCollection = collections.find((collection) => collection.name === '1. Color modes')
+const primitivesCollection = collections.find(
+ (collection: any) => collection.name === '_Primitives'
+)
+const colorsCollection = collections.find((collection: any) => collection.name === '1. Color modes')
-const primitivesColors = primitivesCollection.modes
- .find((mode) => mode.name === 'Style')
- .variables.filter((variable) => variable.type === 'color')
- .map((color) => ({ name: color.name, value: color.value }))
+const primitivesColors = primitivesCollection?.modes
+ ?.find((mode: any) => mode.name === 'Style')
+ ?.variables.filter((variable: any) => variable.type === 'color')
+ ?.map((color: any) => ({ name: color.name, value: color.value }))
// colorMode could be either 'light' or 'dark'
-const getModeColors = (colorMode) => {
+const getModeColors = (colorMode: string) => {
const modeName = colorMode === 'light' ? 'Light mode' : 'Dark mode'
- const modeColors = colorsCollection.modes.find((mode) => mode.name === modeName)?.variables
+ const modeColors = colorsCollection?.modes.find((mode: any) => mode.name === modeName)?.variables
const colors = modeColors
- .map((variable) => {
+ ?.map((variable: any) => {
if (variable.isAlias) {
- if (variable.value.collection === '_Primitives') {
- const primitiveColor = primitivesColors.find(
- (color) => color.name === variable.value.name
- )
+ const valueName = variable.value.name
+ if (variable?.value?.collection === '_Primitives') {
+ const primitiveColor = primitivesColors?.find((color: any) => color.name === valueName)
if (primitiveColor) {
return { name: variable.name, value: primitiveColor.value }
}
return null
} else {
- const newColor = modeColors.find((color) => color.name === variable.value.name)
+ const newColor = modeColors.find((color: any) => color.name === valueName)
if (newColor) {
- const primitiveColor = primitivesColors.find(
- (color) => color.name === newColor.value.name
+ const primitiveColor = primitivesColors?.find(
+ (color: any) => color.name === newColor.value.name
)
if (primitiveColor) {
return { name: variable.name, value: primitiveColor.value }
@@ -49,11 +52,12 @@ const getModeColors = (colorMode) => {
})
.filter(Boolean)
- const colorsArray = colors.map((color) => {
- return { [color.name.split('/').pop().split(' ').shift() || '']: color.value }
+ const colorsArray = colors?.map((color: any) => {
+ const keyName = color?.name?.split?.('/')?.pop()?.split(' ').shift() || ''
+ return { [keyName]: color?.value }
})
- const colorsInMode = colorsArray.reduceRight((acc, color) => {
+ const colorsInMode = colorsArray?.reduceRight((acc: any, color: any) => {
const [entries] = Object.entries(color)
const nestedKeys = entries[0].split('-')
@@ -63,6 +67,10 @@ const getModeColors = (colorMode) => {
return mergeObjects(acc, newValue)
}, {})
+ if (!colorsInMode) {
+ return
+ }
+
const sortedColors = sortObject(colorsInMode)
return sortedColors
}
@@ -70,11 +78,11 @@ const getModeColors = (colorMode) => {
const light = getModeColors('light')
const dark = getModeColors('dark')
-const primitivesColorsArray = primitivesColors.map((color) => {
+const primitivesColorsArray = primitivesColors?.map((color: any) => {
return { [color.name.split('/').slice(1).join('-')]: color.value }
})
-const primitives = primitivesColorsArray.reduceRight((acc, color) => {
+const primitives = primitivesColorsArray?.reduceRight((acc: any, color: any) => {
const [entries] = Object.entries(color)
const colorName = entries[0].split('_')
@@ -94,18 +102,20 @@ const primitives = primitivesColorsArray.reduceRight((acc, color) => {
const theme = {
darkMode: dark,
lightMode: light,
- primitives: sortObject(primitives),
+ primitives: primitives ? sortObject(primitives) : undefined,
}
const objectString = `export const themeColors = ${JSON.stringify(theme, null, 2)}`
-// Specify the file path
-const filePath = './src/design-system/config/colors.ts'
+export const generateTheme = () => {
+ // Specify the file path
+ const filePath = './src/design-system/config/colors.ts'
-fs.writeFileSync(filePath, objectString, 'utf-8')
+ fs.writeFileSync(filePath, objectString, 'utf-8')
+}
// Utils
-function createNestedObject(keys, value) {
+function createNestedObject(keys: any[], value: any) {
if (keys.length === 0) {
return value
}
@@ -113,15 +123,15 @@ function createNestedObject(keys, value) {
const key = keys[0]
const remainingKeys = keys.slice(1)
- const nestedObject = {}
+ const nestedObject: any = {}
nestedObject[key] = createNestedObject(remainingKeys, value)
return nestedObject
}
-function mergeObjects(obj1, obj2) {
+function mergeObjects(obj1: any, obj2: any) {
// Initialize the result object
- const result = {}
+ const result: any = {}
// Loop through keys in obj1
for (const key in obj1) {
@@ -146,7 +156,7 @@ function mergeObjects(obj1, obj2) {
return result
}
-function sortObject(obj) {
+function sortObject(obj?: object): any {
if (typeof obj !== 'object' || obj === null) {
return obj
}
@@ -155,11 +165,12 @@ function sortObject(obj) {
return obj.map(sortObject)
}
- const sorted = {}
+ const sorted: any = {}
Object.keys(obj)
.sort()
.forEach((key) => {
- sorted[key] = sortObject(obj[key])
+ const objectToSort = (obj as any)[key]
+ sorted[key] = sortObject(objectToSort)
})
return sorted
}
diff --git a/scripts/cli/commands/index.ts b/scripts/cli/commands/index.ts
index a20c51e2..10afde15 100644
--- a/scripts/cli/commands/index.ts
+++ b/scripts/cli/commands/index.ts
@@ -1,2 +1,3 @@
export * from './generateIconTypes'
export * from './generateScreen'
+export * from './generateTheme'
diff --git a/scripts/cli/tsconfig.cli.json b/scripts/cli/tsconfig.cli.json
index 1382bc7a..9d54d044 100644
--- a/scripts/cli/tsconfig.cli.json
+++ b/scripts/cli/tsconfig.cli.json
@@ -1,6 +1,8 @@
{
+ "$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"rootDir": ".",
+ "noImplicitAny": false,
"outDir": "build",
"strict": true,
"lib": ["ESNext"],
From c91692c1e6716823cfdee4d323da98cc73b026e4 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Mon, 1 Apr 2024 00:42:57 +0200
Subject: [PATCH 10/47] chore: add script to generate component
---
scripts/cli/actions/generate.ts | 32 +++++-----
scripts/cli/commands/generateComponent.ts | 76 +++++++++++++++++++++++
scripts/cli/constants.ts | 3 +
3 files changed, 96 insertions(+), 15 deletions(-)
create mode 100644 scripts/cli/commands/generateComponent.ts
diff --git a/scripts/cli/actions/generate.ts b/scripts/cli/actions/generate.ts
index cf8798d7..845692d9 100644
--- a/scripts/cli/actions/generate.ts
+++ b/scripts/cli/actions/generate.ts
@@ -2,45 +2,47 @@
// @ts-ignore
import selectPrompt from 'select-prompt'
+import { generateComponent } from '../commands/generateComponent'
import { generateIconTypes } from '../commands/generateIconTypes'
import { generateScreen } from '../commands/generateScreen'
import { generateTheme } from '../commands/generateTheme'
-import { logger } from '../utils'
-const generatePrompts = [
+const data = [
{
title: 'Screen',
value: 'screen',
+ command: generateScreen,
},
{
- title: 'Component TBD',
+ title: 'Component',
value: 'component',
+ command: generateComponent,
},
{
title: 'Icon types',
value: 'icon-types',
+ command: generateIconTypes,
},
{
title: 'Generate theme',
value: 'generate-theme',
+ command: generateTheme,
},
-]
+] as const
-const commands = {
- screen: generateScreen,
- component: () => {
- logger.info('Not implemented yet.')
- logger.info('Please use the `yarn generate:component` command.')
- },
- 'icon-types': generateIconTypes,
- 'generate-theme': generateTheme,
-}
+const generatePrompts = data.map(({ title, value }) => ({ title, value }))
export const generate = () => {
selectPrompt('What do you want to generate?', generatePrompts).on(
'submit',
- async (value: keyof typeof commands) => {
- commands[value]()
+ async (value: string) => {
+ const command = data.find((item) => item.value === value)?.command
+
+ if (command) {
+ command()
+ } else {
+ console.log('There was some issue while running the script ', value)
+ }
}
)
}
diff --git a/scripts/cli/commands/generateComponent.ts b/scripts/cli/commands/generateComponent.ts
new file mode 100644
index 00000000..d0bc2d4d
--- /dev/null
+++ b/scripts/cli/commands/generateComponent.ts
@@ -0,0 +1,76 @@
+import promptSync from 'prompt-sync'
+
+import { COMPONENT_TEMPLATE_PATH, COMPONENTS_PATH } from '../constants'
+import { logger } from '../utils'
+
+const prompt = promptSync()
+
+/* eslint-disable @typescript-eslint/no-var-requires */
+const fs = require('fs')
+const selectPrompt = require('select-prompt')
+
+const paths = {
+ template: COMPONENT_TEMPLATE_PATH,
+ componentsIndex: COMPONENTS_PATH,
+}
+
+const createComponentFile = (name: string, type: string) => {
+ const newCommonComponentPath = `./src/components/${name}.tsx`
+ const newAtomicComponentPath = `./src/components/${type}s/${name}.tsx`
+ const componentFromFile = fs.readFileSync(paths.template, 'utf8')
+ const componentContent = componentFromFile.replaceAll('_NAME_', name)
+
+ if (type === 'common') {
+ fs.writeFileSync(newCommonComponentPath, componentContent)
+ return
+ }
+ fs.writeFileSync(newAtomicComponentPath, componentContent)
+}
+
+const addToIndex = (name: string, type: string) => {
+ const atomicComponentIndexPath = `./src/components/${type}s/index.ts`
+ const newExport = `
+export * from './${name}'`
+ if (type === 'common') {
+ const contents = fs.readFileSync(paths.componentsIndex, 'utf8')
+ fs.writeFileSync(paths.componentsIndex, contents + newExport)
+
+ return
+ }
+
+ const contents = fs.readFileSync(atomicComponentIndexPath, 'utf8')
+ fs.writeFileSync(atomicComponentIndexPath, contents + newExport)
+}
+
+const generateNewComponent = async (name: string, type: string) => {
+ // Generate Component file
+ logger.info('Generating component files')
+ createComponentFile(name, type)
+
+ // Add Component to index
+ addToIndex(name, type)
+
+ // Finish
+ logger.success(`Component ${name} created successfully`)
+}
+
+export const generateComponent = async () => {
+ const componentTypes = [
+ { title: 'Molecule', value: 'molecule' },
+ { title: 'Organism', value: 'organism' },
+ { title: 'Common', value: 'common' },
+ ]
+
+ selectPrompt('Select type for new component', componentTypes, {
+ cursor: 0,
+ }).on('submit', async (type: string) => {
+ const name = prompt('What is component name? ')
+
+ if (!name) {
+ return logger.error('No component name passed')
+ }
+
+ // 1. New component -> component_name + component_type (atom | molecule | organism | common)
+ await generateNewComponent(name, type)
+ })
+}
diff --git a/scripts/cli/constants.ts b/scripts/cli/constants.ts
index d856b514..7b35d2f6 100644
--- a/scripts/cli/constants.ts
+++ b/scripts/cli/constants.ts
@@ -8,6 +8,9 @@ export const NAVIGATION_CONFIG_PATH = 'navigation/tabNavigator/navigation-config
export const APP_JSON_PATH = 'app.json'
export const APP_CONFIG_PATH = 'app.config.ts'
export const README_PATH = 'README.md'
+
+export const COMPONENTS_PATH = 'src/components/index.ts'
+export const COMPONENT_TEMPLATE_PATH = 'templates/component_template.tsx'
export const README_TEMPLATE_PATH = 'templates/README.md'
export const PULL_REQUEST_TEMPLATE_PATH = '.github/pull_request_template.md'
export const NEW_PULL_REQUEST_TEMPLATE_PATH = 'templates/pull_request_template.md'
From 32c544f8e18531d9f9c515a3321bdd5c055d41c3 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Mon, 1 Apr 2024 18:11:39 +0200
Subject: [PATCH 11/47] chore: add scripts to package json
---
package.json | 2 ++
1 file changed, 2 insertions(+)
diff --git a/package.json b/package.json
index 003034dc..56cbb445 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,8 @@
"android:dev-client": "IS_DEV=1 npx expo run:android",
"baca:bootstrap": "node ./scripts/cli/build bootstrap",
"baca:generate": "node ./scripts/cli/build generate",
+ "generate": "yarn build:baca-cli && node ./scripts/cli/build generate",
+ "g": "node ./scripts/cli/build g && yarn eslint src --fix && yarn tsc",
"build:baca-cli": "npx tsc -p ./scripts/cli/tsconfig.cli.json",
"build:production:android": "yarn prepare:production && eas build --platform android --profile production",
"build:production:ios": "yarn prepare:production && eas build --platform ios --profile production",
From 0fa07e46dcfb17a67d55895fed22c16f79bc1f96 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Fri, 12 Apr 2024 10:37:59 +0200
Subject: [PATCH 12/47] chore: add scripts documentation
---
docs/docs/tutorials/SCRIPTS.md | 68 ++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 docs/docs/tutorials/SCRIPTS.md
diff --git a/docs/docs/tutorials/SCRIPTS.md b/docs/docs/tutorials/SCRIPTS.md
new file mode 100644
index 00000000..07915de4
--- /dev/null
+++ b/docs/docs/tutorials/SCRIPTS.md
@@ -0,0 +1,68 @@
+---
+id: scripts
+slug: /scripts
+title: Scripts
+sidebar_position: 8
+tags:
+ - Scripts
+ - Expo
+ - React
+ - React Native
+description: BACA - scripts
+---
+
+
+
+# Scripts
+
+Here is a list of useful scripts in this starter:
+
+- [yarn g](#generators)
+- [yarn b](#bootstrap-new-app)
+- [yarn generate:last:publish](#generate-last-update-info)
+
+## Generators
+
+Run this command to see magic:
+
+```
+yarn g
+```
+
+OR
+
+```bash
+yarn baca:generate
+```
+
+This will show you list of generators, run this to test it :)
+
+## Boostrap new app
+
+Check [boostrap docs](/docs/bootstrap/testing) to see more details.
+
+```
+yarn b
+```
+
+OR
+
+```bash
+yarn baca:boostrap
+```
+
+## Envrionment variables
+
+Check [doppler documentantion](/docs/doppler-config) to see more details
+
+## Generate last update info
+
+This script is automatically executed after running `yarn update:production`, this will return ids of last udpate:
+
+```
+BACA - 2.1.0:
+- android: 8f6577b8-f1a6-46de-9471-8a0ff072ccc9
+- ios: a8bdc3aa-239a-48da-b76e-c259af5567b0
+```
+
+You can easily share this with testers or clients, thanks to that users will be sure what version is currently in the app.
From d92adec83643ad4fd0dabaacf90a4ade9331022e Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Fri, 12 Apr 2024 10:38:17 +0200
Subject: [PATCH 13/47] chore: update package json scripts
---
package.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 1383c3b0..cb6d12a6 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"android:dev-client": "IS_DEV=1 npx expo run:android",
"baca:bootstrap": "node ./scripts/cli/build bootstrap",
"baca:generate": "node ./scripts/cli/build generate",
- "generate": "yarn build:baca-cli && node ./scripts/cli/build generate",
+ "b": "node ./scripts/cli/build b && yarn eslint src --fix && yarn tsc",
"g": "node ./scripts/cli/build g && yarn eslint src --fix && yarn tsc",
"build:baca-cli": "npx tsc -p ./scripts/cli/tsconfig.cli.json",
"build:production:android": "yarn prepare:production && eas build --platform android --profile production",
@@ -49,7 +49,6 @@
"deploy:staging:ios": "yarn prepare:staging && eas build --platform ios --profile staging --auto-submit --non-interactive",
"deploy:staging": "yarn prepare:staging && eas build --platform all --profile staging --auto-submit --non-interactive",
"eas-build-pre-install": "base64 --help && echo $ANDROID_FIREBASE_CONFIG | base64 --decode > google-services.json && cat google-services.json && echo $IOS_FIREBASE_CONFIG | base64 --decode > GoogleService-Info.plist && cat GoogleService-Info.plist",
- "generate:component": "node ./scripts/create_new_component.js && yarn eslint src --fix && yarn tsc",
"generate:env:production": "scripts/generate_dotenv.sh production",
"generate:env:qa": "scripts/generate_dotenv.sh qa",
"generate:env:staging": "scripts/generate_dotenv.sh staging",
From 1ab70802149ffa21bf0cd64214f26e940d4d7c48 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Fri, 12 Apr 2024 10:38:40 +0200
Subject: [PATCH 14/47] chore: update bootstrap docs
---
docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx | 2 +-
docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx b/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
index 226de4bf..e6d7ff1e 100644
--- a/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
+++ b/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
@@ -16,7 +16,7 @@ import Details from '@site/src/components/Details'
Bootstrap project structure, that is needed to start development
-## **What you need to do to start development?**
+## **What you need todo, to start development?**
---
diff --git a/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx b/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
index 9d0fe62c..74743cd2 100644
--- a/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
+++ b/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
@@ -127,7 +127,7 @@ You can generate this data and save it in some notepad or somewhere else.
### **After you will collect all necessary data run this command:**
```sh
-yarn bootstrap:new_app
+yarn baca:bootstrap
```
## Potential issues
From 1cf6869f2f0242ef40899bfbf60143185fd0dc0e Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sat, 13 Apr 2024 11:58:50 +0200
Subject: [PATCH 15/47] chore: improve bootstrap script
---
.gitignore | 1 +
package.json | 9 +-
scripts/cli/actions/bootstrap.ts | 220 +++++++++++++++++++++----------
3 files changed, 154 insertions(+), 76 deletions(-)
diff --git a/.gitignore b/.gitignore
index ba2e3697..6fdbfa9d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -47,3 +47,4 @@ env.json
# baca-cli build
scripts/cli/build/
+scripts/cli/temp/
diff --git a/package.json b/package.json
index cb6d12a6..bde74f24 100644
--- a/package.json
+++ b/package.json
@@ -27,10 +27,10 @@
"android:dev-client": "IS_DEV=1 npx expo run:android",
"baca:bootstrap": "node ./scripts/cli/build bootstrap",
"baca:generate": "node ./scripts/cli/build generate",
- "b": "node ./scripts/cli/build b && yarn eslint src --fix && yarn tsc",
- "g": "node ./scripts/cli/build g && yarn eslint src --fix && yarn tsc",
- "build:baca-cli": "npx tsc -p ./scripts/cli/tsconfig.cli.json",
- "build:production:android": "yarn prepare:production && eas build --platform android --profile production",
+ "b": "yarn build:baca-cli && node ./scripts/cli/build b && yarn eslint src --fix && yarn tsc",
+ "g": "yarn build:baca-cli && node ./scripts/cli/build g && yarn eslint src --fix && yarn tsc",
+ "build:baca-cli": "mkdir -p scripts/cli/temp && cp app.config.ts scripts/cli/temp/app.config.ts && npx tsc -p ./scripts/cli/tsconfig.cli.json",
+ "build:production:android": "yarnx prepare:production && eas build --platform android --profile production",
"build:production:ios": "yarn prepare:production && eas build --platform ios --profile production",
"build:production": "yarn prepare:production && eas build --platform all --profile production",
"build:qa:android": "yarn prepare:qa && eas build --platform android --profile qa",
@@ -183,6 +183,7 @@
"commander": "^12.0.0",
"cross-env": "^7.0.3",
"dotenv": "^16.4.1",
+ "enquirer": "^2.4.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-universe": "^11.2.0",
diff --git a/scripts/cli/actions/bootstrap.ts b/scripts/cli/actions/bootstrap.ts
index 64a3b09f..a5e3b11b 100644
--- a/scripts/cli/actions/bootstrap.ts
+++ b/scripts/cli/actions/bootstrap.ts
@@ -1,5 +1,5 @@
+import { prompt } from 'enquirer'
import fs from 'fs'
-import promptSync from 'prompt-sync'
import {
README_PATH,
@@ -8,9 +8,114 @@ import {
PULL_REQUEST_TEMPLATE_PATH,
APP_JSON_PATH,
} from '../constants'
+import { APP_CONFIG } from '../temp/app.config'
import { logger, addAfter } from '../utils'
-const prompt = promptSync()
+const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'))
+const newAppJson = JSON.parse(fs.readFileSync(APP_JSON_PATH, 'utf8'))
+
+type SetupProjectProps = {
+ appName: string
+ bundleId: string
+ androidPackageName: string
+ scheme: string
+ easId: string
+ organizationOwner: string
+ androidIconColor: string
+ appSlug: string
+}
+
+// Check types of questions here:
+// - https://github.com/enquirer/enquirer/blob/master/examples/enquirer/questions.js
+type Questions = keyof SetupProjectProps
+
+type QuestionsObject = {
+ [k in Questions]: {
+ type: string
+ message: string
+ initial: string
+ order: number
+ }
+}
+
+const questionsObject: QuestionsObject = {
+ appName: {
+ type: 'text',
+ message: 'What is your app name?',
+ initial: APP_CONFIG.appName,
+ order: 1,
+ },
+ bundleId: {
+ type: 'text',
+ message: 'What is your bundle Id?',
+ initial: APP_CONFIG.iosBundleIdentifier,
+ order: 2,
+ },
+ androidPackageName: {
+ type: 'text',
+ message: 'What is your android package name?',
+ initial: APP_CONFIG.androidPackageName,
+ order: 3,
+ },
+ scheme: {
+ type: 'text',
+ message: 'What is your scheme name?',
+ initial: APP_CONFIG.scheme,
+ order: 4,
+ },
+ easId: {
+ type: 'text',
+ message: 'What is your eas id?',
+ initial: APP_CONFIG.easProjectId,
+ order: 5,
+ },
+ organizationOwner: {
+ type: 'text',
+ message: 'What is your expo organization owner?',
+ initial: newAppJson.expo.owner,
+ order: 6,
+ },
+ androidIconColor: {
+ type: 'text',
+ message: 'What is your android icon color?',
+ initial: APP_CONFIG.adaptiveIconBackgroundColor,
+ order: 7,
+ },
+ appSlug: {
+ type: 'text',
+ message: 'What is your expo app slug?',
+ initial: newAppJson.expo.slug,
+ order: 8,
+ },
+}
+
+/**
+ * Creates temp files
+ * - app.config.ts
+ *
+ */
+const createTempFiles = () => {
+ return new Promise((resolve, reject) => {
+ try {
+ const exist = fs.existsSync('scripts/cli/temp/')
+
+ if (!exist) {
+ fs.mkdirSync('scripts/cli/temp/')
+ }
+
+ fs.copyFile('app.config.ts', 'scripts/cli/temp/app.config.ts', (err) => {
+ if (err) {
+ logger.error('ERROR WHEN CREATING TEMP FILES, please run this script again \n', err)
+ reject(new Error('ERROR SEE MESSAGE ABOVE'))
+ } else {
+ resolve(true)
+ }
+ })
+ } catch (e) {
+ reject(e)
+ }
+ })
+}
/**
* Replaces placeholders in the README file with the provided app name and organization owner.
@@ -54,7 +159,7 @@ export const APP_CONFIG = {
easProjectId: '${easId}', // CONFIG: Add your eas project ID here
iosBundleIdentifier: '${bundleId}', // CONFIG: Add your ios bundle identifier here
scheme: '${scheme}', // CONFIG: Add your url scheme to link to your app
- adaptiveIconBackgroundColor: '${androidIconColor}', // CONFIG: Add your url scheme to link to your app
+ adaptiveIconBackgroundColor: '${androidIconColor}', // CONFIG: Add your android adaptive icon background color here
} as const
`
@@ -74,16 +179,15 @@ const replacePullRequestTemplate = () => {
}
const changeAppJson = (appName: string, appSlug: string, organizationOwner: string) => {
- const newAppJson = JSON.parse(fs.readFileSync(APP_JSON_PATH, 'utf8'))
newAppJson.expo.slug = appSlug
newAppJson.expo.name = appName
newAppJson.expo.owner = organizationOwner
- newAppJson.version = '1.0.0'
+ newAppJson.expo.version = '1.0.0'
+
fs.writeFileSync(APP_JSON_PATH, JSON.stringify(newAppJson, null, 2))
}
const changePackageJson = (appName: string, organizationOwner: string) => {
- const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'))
packageJson.name = `@${organizationOwner}/${appName}`
packageJson.description = `App created from expo-template powered by binarapps`
packageJson.version = '1.0.0'
@@ -103,18 +207,18 @@ const removeDocsFolder = () => {
fs.rm('./documentation', { recursive: true, force: true }, () => {})
}
-const setUpProject = async (
- appName: string,
- bundleId: string,
- androidPackageName: string,
- scheme: string,
- easId: string,
- organizationOwner: string,
- androidIconColor: string,
- appSlug: string
-) => {
+const setUpProject = async ({
+ appName,
+ bundleId,
+ androidPackageName,
+ scheme,
+ easId,
+ organizationOwner,
+ androidIconColor,
+ appSlug,
+}: SetupProjectProps) => {
// START
- logger.success('Start ...')
+ logger.success('Start bootstrapping ...')
// 1. Delete readme -> and create new, with new app name etc.
logger.info('Generating new readme file')
@@ -148,60 +252,32 @@ const setUpProject = async (
logger.success(`Config your project has been success`)
}
-export const bootstrap = () => {
- logger.info('Please give me this information to setup your project:')
- const appName = prompt('App name: ')
- if (!appName) {
- return logger.error('Please write correct app name')
- }
-
- const appSlug = prompt('App slug (from expo dashboard): ')
- if (!appSlug) {
- return logger.error('Please write app slug')
- }
-
- const organizationOwner = prompt('Organization owner (from expo dashboard): ')
- if (!organizationOwner) {
- return logger.error('Please write organziation owner')
- }
-
- const easId = prompt('EAS project ID (from expo dashboard): ')
- if (!easId) {
- return logger.error('Please write correct eas project ID')
+const questions = Object.entries(questionsObject)
+ .map((value) => ({
+ name: value[0],
+ ...value[1],
+ }))
+ .sort((a, b) => a.order - b.order)
+
+export const bootstrap = async () => {
+ try {
+ logger.info('Please give me this information to setup your project:')
+
+ // 0. Create temp files
+ await createTempFiles()
+
+ const answers = (await prompt(questions)) as unknown as SetupProjectProps
+
+ await setUpProject(answers)
+
+ logger.info(
+ '\nYou can also add images (splash screen, app icon, logos) right now, \nGo to `assets` folder and replace images to match your app.\n'
+ )
+ logger.info('\nPlease verify the changes made by this script and commit it to your repository.')
+ } catch (e) {
+ logger.error(
+ '\nError while bootstraping project \nERROR:',
+ e ? e : "Couldn't find what's happened"
+ )
}
-
- const androidIconColor =
- prompt('Android adaptive icon color (you can leave it empty and fill it later): ') ||
- '#2E7AF0CC'
-
- const bundleId = prompt('Bundle ID (ios): ')
- if (!bundleId) {
- return logger.error('Please write correct bundle ID')
- }
-
- const androidPackageName = prompt('Package name (android): ')
- if (!androidPackageName) {
- return logger.error('Please write correct android package name')
- }
-
- const scheme = prompt('URL scheme (for deeplinking): ')
- if (!scheme) {
- return logger.error('Please write correct scheme')
- }
-
- setUpProject(
- appName,
- bundleId,
- androidPackageName,
- scheme,
- easId,
- organizationOwner,
- androidIconColor,
- appSlug
- )
-
- logger.info(
- '\nYou can also add images right now, go to assets folder and replace images to match your app \n'
- )
- logger.info('\nPlease verify the changes made by this script and commit it to your repository \n')
}
From 085c74fe8585158aea065ded19627eea23067951 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sat, 13 Apr 2024 12:39:52 +0200
Subject: [PATCH 16/47] chore: update package json scripts
---
package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index bde74f24..f84c7e34 100644
--- a/package.json
+++ b/package.json
@@ -25,8 +25,8 @@
"license": "MIT",
"scripts": {
"android:dev-client": "IS_DEV=1 npx expo run:android",
- "baca:bootstrap": "node ./scripts/cli/build bootstrap",
- "baca:generate": "node ./scripts/cli/build generate",
+ "baca:bootstrap": "yarn build:baca-cli && node ./scripts/cli/build bootstrap",
+ "baca:generate": "yarn build:baca-cli && node ./scripts/cli/build generate",
"b": "yarn build:baca-cli && node ./scripts/cli/build b && yarn eslint src --fix && yarn tsc",
"g": "yarn build:baca-cli && node ./scripts/cli/build g && yarn eslint src --fix && yarn tsc",
"build:baca-cli": "mkdir -p scripts/cli/temp && cp app.config.ts scripts/cli/temp/app.config.ts && npx tsc -p ./scripts/cli/tsconfig.cli.json",
From c0bc5af22a2f3d6e6c9505b54cd5368c3326d842 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sun, 14 Apr 2024 11:57:51 +0200
Subject: [PATCH 17/47] chore: update readme template
---
templates/readme_template.md | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/templates/readme_template.md b/templates/readme_template.md
index aaf2a759..468767a0 100644
--- a/templates/readme_template.md
+++ b/templates/readme_template.md
@@ -9,26 +9,21 @@ Version in the `package.json` is one to one the latest expo on which the templat
#### 1. Bootstrap - At start you should trigger script
```
-node ./scripts/bootstrap.js
+yarn b
```
The script gives you opportunity to setup the essentialest variables for your project like app name, bundle ID or android package name
-#### 2. Generate new screen
+#### 2. Generators
```
-node ./scripts/create_new_screen.js
+yarn g
```
-You can use this script for generate new common screen, tabs screen or new bottom tab, from screen template. You have possiblity to change screen template for your own.
+Usage:
-#### 3. Generate new component
-
-```
-node ./scripts/create_new_component.js
-```
-
-You can use this script for generate new common component (atom, molecule, organism, common) from component template. You have possiblity to change component template for your own.
+- You can use this script to generate new common screen, tabs screen or new bottom tab, from screen template. You have possiblity to change screen template for your own.
+- You can use this script for generate new common component (atom, molecule, organism, common) from component template. You have possiblity to change component template for your own.
## Run Locally
@@ -89,7 +84,9 @@ It is added to the app as a font generated by [icomoon app](https://icomoon.io/a
9. Generate new types for icons
-- run script generating icon types `yarn generate:icon:types`
+- run script generating icon types `yarn g` and pick icon types
+
+
## Sync up with template:
From 6094d50e45560f836b350fe8f3110c6acc0b136d Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sun, 14 Apr 2024 12:04:45 +0200
Subject: [PATCH 18/47] chore: update bootstrap testing docs
---
docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx b/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
index 74743cd2..45b08e75 100644
--- a/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
+++ b/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
@@ -103,6 +103,14 @@ If you have some domain, for example: example.com, your bundle id could be: `com
open your app when tapped. It is only available in standalone apps.
+
+> **Optional step** - You can run the bootstrap script later
+This can be found in developer apple console.
+
+> Image will be added in future
+
+
+
You can generate this data and save it in some notepad or somewhere else.
@@ -115,7 +123,8 @@ You can generate this data and save it in some notepad or somewhere else.
"slug": "expo_app_slug",
"easProjectId": "xxx-xxx-xxx-xx",
"scheme": "yourUrlScheme",
- "adaptiveIconBackgroundColor": "#2E7AF0CC"
+ "adaptiveIconBackgroundColor": "#2E7AF0CC",
+ "appleTeamId": "1234XXXYYX"
}
```
@@ -126,7 +135,14 @@ You can generate this data and save it in some notepad or somewhere else.
### **After you will collect all necessary data run this command:**
+> If you don't have some value you can use default value, bootstrap script is collecting current data from code, so you can run this script multiple times
+> **REMEBER** to have empty git repo because this script will do changes in your codebase
+
```sh
+yarn b
+
+## OR
+
yarn baca:bootstrap
```
From 33a46d9c8d20e5199a8295f105338494a8e090c5 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sun, 14 Apr 2024 12:04:59 +0200
Subject: [PATCH 19/47] chore: update bootstrap script
---
scripts/cli/actions/bootstrap.ts | 61 ++++++++++++++++++--------------
1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/scripts/cli/actions/bootstrap.ts b/scripts/cli/actions/bootstrap.ts
index a5e3b11b..b0b4d205 100644
--- a/scripts/cli/actions/bootstrap.ts
+++ b/scripts/cli/actions/bootstrap.ts
@@ -23,6 +23,7 @@ type SetupProjectProps = {
organizationOwner: string
androidIconColor: string
appSlug: string
+ appleTeamId: string
}
// Check types of questions here:
@@ -87,6 +88,12 @@ const questionsObject: QuestionsObject = {
initial: newAppJson.expo.slug,
order: 8,
},
+ appleTeamId: {
+ type: 'text',
+ message: 'What is your apple team id? (Optional)',
+ initial: newAppJson.expo.slug,
+ order: 8,
+ },
}
/**
@@ -123,7 +130,7 @@ const createTempFiles = () => {
* @param appName - The name of the app.
* @param organizationOwner - The owner of the organization.
*/
-const replaceReadme = (appName: string, organizationOwner: string) => {
+const replaceReadme = ({ appName, organizationOwner }: SetupProjectProps) => {
let contents = fs.readFileSync(README_PATH, 'utf-8')
contents = contents.replaceAll('_NAME_', appName)
@@ -142,14 +149,14 @@ const replaceReadme = (appName: string, organizationOwner: string) => {
* @param easId - The EAS project ID.
* @param androidIconColor - The background color for the adaptive icon on Android.
*/
-const setUpAppConfig = (
- appName: string,
- bundleId: string,
- androidPackageName: string,
- scheme: string,
- easId: string,
- androidIconColor: string
-) => {
+const setUpAppConfig = ({
+ appName,
+ bundleId,
+ androidPackageName,
+ scheme,
+ easId,
+ androidIconColor,
+}: SetupProjectProps) => {
let contents = fs.readFileSync(APP_CONFIG_PATH, 'utf8')
const appConfig = `
@@ -178,7 +185,7 @@ const replacePullRequestTemplate = () => {
fs.writeFileSync(PULL_REQUEST_TEMPLATE_PATH, contents)
}
-const changeAppJson = (appName: string, appSlug: string, organizationOwner: string) => {
+const changeAppJson = ({ appName, appSlug, organizationOwner }: SetupProjectProps) => {
newAppJson.expo.slug = appSlug
newAppJson.expo.name = appName
newAppJson.expo.owner = organizationOwner
@@ -187,7 +194,7 @@ const changeAppJson = (appName: string, appSlug: string, organizationOwner: stri
fs.writeFileSync(APP_JSON_PATH, JSON.stringify(newAppJson, null, 2))
}
-const changePackageJson = (appName: string, organizationOwner: string) => {
+const changePackageJson = ({ appName, organizationOwner }: SetupProjectProps) => {
packageJson.name = `@${organizationOwner}/${appName}`
packageJson.description = `App created from expo-template powered by binarapps`
packageJson.version = '1.0.0'
@@ -204,29 +211,24 @@ const removeIssueTemplates = () => {
}
const removeDocsFolder = () => {
- fs.rm('./documentation', { recursive: true, force: true }, () => {})
+ fs.rm('./docs', { recursive: true, force: true }, () => {})
}
-const setUpProject = async ({
- appName,
- bundleId,
- androidPackageName,
- scheme,
- easId,
- organizationOwner,
- androidIconColor,
- appSlug,
-}: SetupProjectProps) => {
+// TODO: Implement changeEasJson and changeDeeplinkFiles functions
+const changeEasJson = (config: SetupProjectProps) => {}
+const changeDeeplinkFiles = (config: SetupProjectProps) => {}
+
+const setUpProject = async (config: SetupProjectProps) => {
// START
logger.success('Start bootstrapping ...')
// 1. Delete readme -> and create new, with new app name etc.
logger.info('Generating new readme file')
- replaceReadme(appName, organizationOwner)
+ replaceReadme(config)
// 2. Replace appName, bundleId, androidPackageName,scheme and easProjectId in app.config.ts file
logger.info('Change project variables in app.config.ts file')
- setUpAppConfig(appName, bundleId, androidPackageName, scheme, easId, androidIconColor)
+ setUpAppConfig(config)
// 3. Delete exist pull request template -> generate the new
logger.info('Generating new pull request template file')
@@ -234,11 +236,11 @@ const setUpProject = async ({
// 4. Change app.json file
logger.info('Change app.json file')
- changeAppJson(appName, appSlug, organizationOwner)
+ changeAppJson(config)
// 5. Change package.json file
logger.info('Change package.json file')
- changePackageJson(appName, organizationOwner)
+ changePackageJson(config)
// 6. Remove issue templates
logger.info('Remove issue templates')
@@ -248,6 +250,13 @@ const setUpProject = async ({
logger.info('Remove docs folder')
removeDocsFolder()
+ // 8. Change eas.json
+ logger.info('Remove docs folder')
+ changeEasJson(config)
+
+ // 8. Change deeplink files
+ changeDeeplinkFiles(config)
+
//Finish
logger.success(`Config your project has been success`)
}
From 39fdfc973e79f0dd28166c0fe516c02f8ee74a3c Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Mon, 15 Apr 2024 18:27:28 +0200
Subject: [PATCH 20/47] chore: revert removing generateIconTypes function - p1
---
scripts/generate_icon_types.js | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 scripts/generate_icon_types.js
diff --git a/scripts/generate_icon_types.js b/scripts/generate_icon_types.js
new file mode 100644
index 00000000..e0c23a56
--- /dev/null
+++ b/scripts/generate_icon_types.js
@@ -0,0 +1,17 @@
+import fs from 'fs'
+
+const prefix = `export type IconNames =
+ | `
+
+export const generateIconTypes = () => {
+ const json = fs.readFileSync('./assets/icomoon/selection.json')
+
+ const types = JSON.parse(json.toString())
+ .icons.map((icon: { properties: { name: string } }) => `'${icon.properties.name}'`)
+ .join('\n | ')
+ .concat('\n')
+
+ const content = prefix + types
+
+ fs.writeFileSync('./src/types/icon.d.ts', content)
+}
From dcf3d09047d467f995078a7f2fe44c756149d89a Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Mon, 15 Apr 2024 18:27:43 +0200
Subject: [PATCH 21/47] chore: revert removing generateIconTypes function - p2
---
scripts/cli/commands/generateIconTypes.ts | 17 -----------------
1 file changed, 17 deletions(-)
delete mode 100644 scripts/cli/commands/generateIconTypes.ts
diff --git a/scripts/cli/commands/generateIconTypes.ts b/scripts/cli/commands/generateIconTypes.ts
deleted file mode 100644
index e0c23a56..00000000
--- a/scripts/cli/commands/generateIconTypes.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import fs from 'fs'
-
-const prefix = `export type IconNames =
- | `
-
-export const generateIconTypes = () => {
- const json = fs.readFileSync('./assets/icomoon/selection.json')
-
- const types = JSON.parse(json.toString())
- .icons.map((icon: { properties: { name: string } }) => `'${icon.properties.name}'`)
- .join('\n | ')
- .concat('\n')
-
- const content = prefix + types
-
- fs.writeFileSync('./src/types/icon.d.ts', content)
-}
From 482902c58c05459cfd50f7c73daedd91365600ea Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Mon, 15 Apr 2024 18:28:26 +0200
Subject: [PATCH 22/47] chore: properly move generateIconTypes file
---
.../{generate_icon_types.js => cli/commands/generateIconTypes.ts} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename scripts/{generate_icon_types.js => cli/commands/generateIconTypes.ts} (100%)
diff --git a/scripts/generate_icon_types.js b/scripts/cli/commands/generateIconTypes.ts
similarity index 100%
rename from scripts/generate_icon_types.js
rename to scripts/cli/commands/generateIconTypes.ts
From 3b5a5dbf95e1abc5c280b771910967b12d22f2f2 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Tue, 16 Apr 2024 20:10:47 +0200
Subject: [PATCH 23/47] chore: update package json
---
package.json | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index f84c7e34..980634dc 100644
--- a/package.json
+++ b/package.json
@@ -25,10 +25,11 @@
"license": "MIT",
"scripts": {
"android:dev-client": "IS_DEV=1 npx expo run:android",
+ "baca": "yarn build:baca-cli && node ./scripts/cli/build --help ",
"baca:bootstrap": "yarn build:baca-cli && node ./scripts/cli/build bootstrap",
"baca:generate": "yarn build:baca-cli && node ./scripts/cli/build generate",
- "b": "yarn build:baca-cli && node ./scripts/cli/build b && yarn eslint src --fix && yarn tsc",
- "g": "yarn build:baca-cli && node ./scripts/cli/build g && yarn eslint src --fix && yarn tsc",
+ "b": "yarn build:baca-cli && node ./scripts/cli/build b",
+ "g": "yarn build:baca-cli && node ./scripts/cli/build g",
"build:baca-cli": "mkdir -p scripts/cli/temp && cp app.config.ts scripts/cli/temp/app.config.ts && npx tsc -p ./scripts/cli/tsconfig.cli.json",
"build:production:android": "yarnx prepare:production && eas build --platform android --profile production",
"build:production:ios": "yarn prepare:production && eas build --platform ios --profile production",
From 2a8fadc8c8f139c1ffe8c284c8dfb92c0b3c4c9c Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Tue, 16 Apr 2024 20:11:06 +0200
Subject: [PATCH 24/47] chore: remove not used script
---
scripts/create_new_component.js | 73 ---------------------------------
1 file changed, 73 deletions(-)
delete mode 100644 scripts/create_new_component.js
diff --git a/scripts/create_new_component.js b/scripts/create_new_component.js
deleted file mode 100644
index a650cad8..00000000
--- a/scripts/create_new_component.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* eslint-disable @typescript-eslint/no-var-requires */
-const fs = require('fs')
-const prompt = require('prompt-sync')()
-const selectPrompt = require('select-prompt')
-
-const { logger } = require('./utils')
-
-const paths = {
- template: './templates/component_template.tsx',
- componentsIndex: './src/components/index.ts',
-}
-
-const createComponentFile = (name, type) => {
- const newCommonComponentPath = `./src/components/${name}.tsx`
- const newAtomicComponentPath = `./src/components/${type}s/${name}.tsx`
- const componentFromFile = fs.readFileSync(paths.template, 'utf8')
- const componentContent = componentFromFile.replaceAll('_NAME_', name)
-
- if (type === 'common') {
- fs.writeFileSync(newCommonComponentPath, componentContent)
- return
- }
- fs.writeFileSync(newAtomicComponentPath, componentContent)
-}
-
-const addToIndex = (name, type) => {
- const atomicComponentIndexPath = `./src/components/${type}s/index.ts`
- const newExport = `
-export * from './${name}'`
- if (type === 'common') {
- const contents = fs.readFileSync(paths.componentsIndex, 'utf8')
- fs.writeFileSync(paths.componentsIndex, contents + newExport)
-
- return
- }
-
- const contents = fs.readFileSync(atomicComponentIndexPath, 'utf8')
- fs.writeFileSync(atomicComponentIndexPath, contents + newExport)
-}
-
-const generateComponent = async (name, type) => {
- // Generate Component file
- logger.info('Generating component files')
- createComponentFile(name, type)
-
- // Add Component to index
- addToIndex(name, type)
-
- // Finish
- logger.success(`Component ${name} created successfully`)
-}
-
-const generateNewComponent = async () => {
- const componentTypes = [
- { title: 'Atom', value: 'atom' },
- { title: 'Molecule', value: 'molecule' },
- { title: 'Organism', value: 'organism' },
- { title: 'Common', value: 'common' },
- ]
-
- selectPrompt('Select type for new component', componentTypes, {
- cursor: 0,
- }).on('submit', async (type) => {
- const name = prompt('What is component name? ')
- if (!name) {
- return logger.error('No component name passed')
- }
- // 1. New component -> component_name + component_type (atom | molecule | organism | common)
- await generateComponent(name, type)
- })
-}
-
-generateNewComponent()
From a3afde498f14d2920d183af7f83fe8952e4f1e6b Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:24:48 +0200
Subject: [PATCH 25/47] chore: update readme
---
README.md | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index fcc08060..4ef639de 100644
--- a/README.md
+++ b/README.md
@@ -70,13 +70,16 @@ It's great for production project, but if you want to just test it, you can foll
### Implemented custom features
+- custom cli
+ - run `yarn baca` to see available options
- generators:
- - create screen - `yarn generate:screen`
- - create component - `yarn generate:component`
+ - `yarn baca generate` | `yarn g`
- support of multiple environments
- production, staging, qa
- eas configuration
- update, build, submit
+- deployment docs
+ - https://baca-docs.vercel.app/docs/bootstrap/intro
- verifying code on pull request - pipelines
- when creating pull request on github, there are tests, linters and types checks. If there will be some error you will be notified that something is wrong.
- custom fonts
@@ -117,11 +120,11 @@ It's great for production project, but if you want to just test it, you can foll
- [Reanimated v2](https://github.com/software-mansion/react-native-reanimated)
- Axios + React query
- Fetching data from backend
+- Jotai
+ - State management
## What is planned in the future?
-- add some state management tool - in progress
-- write docs (app deployment, app setup and more) - in progress
- tutorial on how to use features
- navigation
- deepLinking
@@ -136,7 +139,6 @@ It's great for production project, but if you want to just test it, you can foll
- Create sample app and document the process of deployment
- Improve mock server logic
- add commit lint
-- add script that display last update information (eas update)
### Implementations to add
From cae7e7c7d223e7d4a5ae92eb8760a93516c13887 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:25:08 +0200
Subject: [PATCH 26/47] chore: update scripts in package.json
---
package.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 980634dc..b6700165 100644
--- a/package.json
+++ b/package.json
@@ -25,12 +25,12 @@
"license": "MIT",
"scripts": {
"android:dev-client": "IS_DEV=1 npx expo run:android",
- "baca": "yarn build:baca-cli && node ./scripts/cli/build --help ",
- "baca:bootstrap": "yarn build:baca-cli && node ./scripts/cli/build bootstrap",
- "baca:generate": "yarn build:baca-cli && node ./scripts/cli/build generate",
- "b": "yarn build:baca-cli && node ./scripts/cli/build b",
- "g": "yarn build:baca-cli && node ./scripts/cli/build g",
- "build:baca-cli": "mkdir -p scripts/cli/temp && cp app.config.ts scripts/cli/temp/app.config.ts && npx tsc -p ./scripts/cli/tsconfig.cli.json",
+ "baca": "yarn build:baca-cli && node ./scripts/cli/build/scripts/cli",
+ "baca:bootstrap": "yarn build:baca-cli && yarn baca bootstrap",
+ "baca:generate": "yarn build:baca-cli && yarn baca generate",
+ "b": "yarn build:baca-cli && yarn baca b",
+ "g": "yarn build:baca-cli && yarn baca g",
+ "build:baca-cli": "npx tsc -p ./scripts/cli/tsconfig.cli.json",
"build:production:android": "yarnx prepare:production && eas build --platform android --profile production",
"build:production:ios": "yarn prepare:production && eas build --platform ios --profile production",
"build:production": "yarn prepare:production && eas build --platform all --profile production",
From 9c6a0215d72148c0abca8bf01c18d7328505294b Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:25:37 +0200
Subject: [PATCH 27/47] chore: update docs
---
docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx | 2 +-
docs/docs/tutorials/SCRIPTS.md | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx b/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
index e6d7ff1e..cb2402d2 100644
--- a/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
+++ b/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
@@ -16,7 +16,7 @@ import Details from '@site/src/components/Details'
Bootstrap project structure, that is needed to start development
-## **What you need todo, to start development?**
+## **What you need to do, to start development**
---
diff --git a/docs/docs/tutorials/SCRIPTS.md b/docs/docs/tutorials/SCRIPTS.md
index 07915de4..fe794dde 100644
--- a/docs/docs/tutorials/SCRIPTS.md
+++ b/docs/docs/tutorials/SCRIPTS.md
@@ -66,3 +66,9 @@ BACA - 2.1.0:
```
You can easily share this with testers or clients, thanks to that users will be sure what version is currently in the app.
+
+## Generate icon types
+
+This script has to be executed when new icons where added to the icomoon.ttf icons set in case to provide proper types for components which use icons.
+
+If script won't be executed typescript will throw an error when trying to use newly added icon.
From c1922da25e0765b0a2e62ff60f5e202ab9bf1649 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:27:53 +0200
Subject: [PATCH 28/47] chore: update readme scripts
---
scripts/README.md | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/scripts/README.md b/scripts/README.md
index 46544518..b835ebfb 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -44,15 +44,23 @@ yarn prepare:qa
yarn prepare:staging
```
-## 4. generators
+## 3. generators
+
+Run this command to see all available commands
```bash
-## Create new component
-yarn generate:component
+yarn baca
+```
-## Create new screen
-yarn baca:generate
+Our custom cli for now contain this screens:
-## Bootstrap the app
-yarn baca:bootstrap
-```
+1. Generators
+
+- create new screen - `yarn baca generate screen`
+- create new component - `yarn baca generate component`
+- create icon types - `yarn baca generate icon-types`
+- create theme - `yarn baca generate theme`
+
+2. Bootstrap the app
+
+- `yarn baca bootstrap`
From f6d0ac5b77b6af1d807fb179ae452e7d6239684c Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:32:03 +0200
Subject: [PATCH 29/47] chore: refactor generate screen script to use enquirer
instead of promt-sync and select-prompt
---
scripts/cli/commands/generateScreen.ts | 107 ++++++++++++++-----------
1 file changed, 62 insertions(+), 45 deletions(-)
diff --git a/scripts/cli/commands/generateScreen.ts b/scripts/cli/commands/generateScreen.ts
index 6925fd00..4595d8b9 100644
--- a/scripts/cli/commands/generateScreen.ts
+++ b/scripts/cli/commands/generateScreen.ts
@@ -1,8 +1,6 @@
+import { prompt } from 'enquirer'
+// eslint-disable-next-line import/order
import fs from 'fs'
-import prompt from 'prompt-sync'
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-import selectPrompt from 'select-prompt'
import { APP_ROUTER_DIRECTORY, SCREENS_DIRECTORY } from '../constants'
import { getDirectoryNames, logger } from '../utils'
@@ -16,45 +14,48 @@ const addAfter = (content: string, searchText: string, textToAdd: string) => {
*
* @param basePath - The path of the current directory.
*/
-const selectPath = (basePath: string) =>
- new Promise((resolve) => {
- const subDirectories = getDirectoryNames(basePath)
- const hasSubDirectories = subDirectories.length > 0
-
- // Return the result when there are no subdirectories
- if (!hasSubDirectories) {
- resolve(basePath)
- return
- }
-
- const subDirectoryPrompt = subDirectories.map((directoryName) => ({
- title: directoryName,
- value: directoryName,
- }))
-
- if (basePath.includes('tabs')) {
- subDirectoryPrompt.unshift({ title: '_New Tab_', value: 'new-tab' })
- }
-
- if (basePath !== APP_ROUTER_DIRECTORY) {
- subDirectoryPrompt.unshift({ title: '.', value: '.' })
- }
-
- selectPrompt(`Select a directory (${basePath})`, subDirectoryPrompt, {
- cursor: 0,
- }).on('submit', (subValue: string) => {
- // Return the result when user selects current directory
- if (subValue === '.') {
- resolve(basePath)
- return
- }
- // Recursively execute path selection when subValue is not the current directory
- selectPath(`${basePath}/${subValue}`).then((subResult) => {
- resolve(subResult)
- })
- })
+const selectPath = async (basePath: string): Promise => {
+ const subDirectories = getDirectoryNames(basePath)
+ const hasSubDirectories = subDirectories.length > 0
+
+ // Return the result when there are no subdirectories
+ if (!hasSubDirectories) {
+ return basePath
+ }
+
+ const subDirectoryPrompt = subDirectories.map((directoryName) => ({
+ name: directoryName,
+ value: directoryName,
+ }))
+
+ if (basePath.includes('tabs')) {
+ subDirectoryPrompt.unshift({ name: '_New Tab_', value: 'new-tab' })
+ }
+
+ if (basePath !== APP_ROUTER_DIRECTORY) {
+ subDirectoryPrompt.unshift({ name: '.', value: '.' })
+ }
+
+ const promptAnswer = await prompt({
+ name: 'subValue',
+ message: 'What do you want to generate?',
+ type: 'select',
+ choices: subDirectoryPrompt,
})
+ // @ts-expect-error: subValue not found on promptAnswer
+ const subValue = promptAnswer.subValue
+
+ // Return the result when user selects current directory
+ if (subValue === '.') {
+ return basePath
+ }
+ // Recursively execute path selection when subValue is not the current directory
+ const subResult = await selectPath(`${basePath}/${subValue}`)
+
+ return subResult
+}
+
/**
* Validates if a route with the given name already exists in the specified path.
* @param routeName - The name of the route.
@@ -115,8 +116,16 @@ const addToScreensIndex = (screenName: string) => {
fs.writeFileSync(indexFilePath, newIndexFile)
}
-const promptTabName = () => {
- const tabName = prompt()('Enter tab name: ')
+const promptTabName = async () => {
+ const promptAnswer = await prompt({
+ message: 'What is your screen name?',
+ name: 'tabName',
+ type: 'input',
+ })
+
+ // @ts-expect-error: generator not found on promptAnswer
+ const tabName = promptAnswer.tabName as string
+
if (!tabName) {
throw new Error('Tab name is required')
}
@@ -148,13 +157,21 @@ const createNewNavTab = (tabName: string) => {
* Validates the screen name and path.
*/
export const generateScreen = async () => {
- const routeName = prompt()('Enter screen name: ')
+ const promptAnswer = await prompt({
+ message: 'What is your screen name?',
+ name: 'screenName',
+ type: 'input',
+ })
+
+ // @ts-expect-error: generator not found on promptAnswer
+ const routeName = promptAnswer.screenName as string
+
let routePath = await selectPath(APP_ROUTER_DIRECTORY)
const isNewTab = routePath.includes('(tabs)') && routePath.includes('new-tab')
if (isNewTab) {
const tabName = promptTabName()
- createNewNavTab(tabName)
+ createNewNavTab(routeName)
const newTabPath = routePath.replace('/new-tab', `/${tabName}`)
routePath = newTabPath
From 35c121c15469b182452866cfe6b0dbbf8fc181ec Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:33:11 +0200
Subject: [PATCH 30/47] chore: refactor generate component script to use
enquirer instead of pr omt-sync
---
scripts/cli/commands/generateComponent.ts | 42 +++++++++++++----------
1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/scripts/cli/commands/generateComponent.ts b/scripts/cli/commands/generateComponent.ts
index d0bc2d4d..882a95a2 100644
--- a/scripts/cli/commands/generateComponent.ts
+++ b/scripts/cli/commands/generateComponent.ts
@@ -1,13 +1,10 @@
-import promptSync from 'prompt-sync'
+import { prompt } from 'enquirer'
import { COMPONENT_TEMPLATE_PATH, COMPONENTS_PATH } from '../constants'
import { logger } from '../utils'
-const prompt = promptSync()
-
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
-const selectPrompt = require('select-prompt')
const paths = {
template: COMPONENT_TEMPLATE_PATH,
@@ -56,21 +53,28 @@ const generateNewComponent = async (name: string, type: string) => {
export const generateComponent = async () => {
const componentTypes = [
- { title: 'Molecule', value: 'molecule' },
- { title: 'Organism', value: 'organism' },
- { title: 'Common', value: 'common' },
+ { name: 'Molecule', value: 'molecule' },
+ { name: 'Organism', value: 'organism' },
+ { name: 'Common', value: 'common' },
]
- selectPrompt('Select type for new component', componentTypes, {
- cursor: 0,
- }).on('submit', async (type: string) => {
- const name = prompt('What is component name? ')
-
- if (!name) {
- return logger.error('No component name passed')
- }
-
- // 1. New component -> component_name + component_type (atom | molecule | organism | common)
- await generateNewComponent(name, type)
- })
+ const promptAnswer = await prompt([
+ {
+ message: 'What is your component type?',
+ name: 'componentType',
+ type: 'select',
+ choices: componentTypes,
+ },
+ {
+ message: 'What is your component name?',
+ name: 'componentName',
+ type: 'input',
+ },
+ ])
+ // @ts-expect-error: componentType not found on promptAnswer
+ const componentType = promptAnswer.componentType as string
+ // @ts-expect-error: componentName not found on promptAnswer
+ const componentName = promptAnswer.componentName as string
+
+ await generateNewComponent(componentName, componentType)
}
From fc5eb90ca5b9e10032b0f05c82242dc4400bc820 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:33:34 +0200
Subject: [PATCH 31/47] chore: update readme_template
---
templates/readme_template.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/templates/readme_template.md b/templates/readme_template.md
index 468767a0..93837346 100644
--- a/templates/readme_template.md
+++ b/templates/readme_template.md
@@ -84,7 +84,7 @@ It is added to the app as a font generated by [icomoon app](https://icomoon.io/a
9. Generate new types for icons
-- run script generating icon types `yarn g` and pick icon types
+- run script generating icon types `yarn g icon-types` and pick icon types
From 686360d0d2148cdc504788657a5e21e5608b7430 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Wed, 17 Apr 2024 14:34:08 +0200
Subject: [PATCH 32/47] chore: improve baca cli to work as proffesional cli
---
scripts/cli/actions/bootstrap.ts | 35 ++---------------------
scripts/cli/actions/generate.ts | 47 ++++++++++++++++--------------
scripts/cli/actions/index.ts | 19 +------------
scripts/cli/commands/index.ts | 1 +
scripts/cli/index.ts | 49 +++++++++++++++++++++++++++++---
scripts/cli/tsconfig.cli.json | 7 +++--
6 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/scripts/cli/actions/bootstrap.ts b/scripts/cli/actions/bootstrap.ts
index b0b4d205..3d6bebf8 100644
--- a/scripts/cli/actions/bootstrap.ts
+++ b/scripts/cli/actions/bootstrap.ts
@@ -1,6 +1,7 @@
import { prompt } from 'enquirer'
import fs from 'fs'
+import { APP_CONFIG } from '../../../app.config'
import {
README_PATH,
APP_CONFIG_PATH,
@@ -8,7 +9,6 @@ import {
PULL_REQUEST_TEMPLATE_PATH,
APP_JSON_PATH,
} from '../constants'
-import { APP_CONFIG } from '../temp/app.config'
import { logger, addAfter } from '../utils'
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'))
@@ -96,34 +96,6 @@ const questionsObject: QuestionsObject = {
},
}
-/**
- * Creates temp files
- * - app.config.ts
- *
- */
-const createTempFiles = () => {
- return new Promise((resolve, reject) => {
- try {
- const exist = fs.existsSync('scripts/cli/temp/')
-
- if (!exist) {
- fs.mkdirSync('scripts/cli/temp/')
- }
-
- fs.copyFile('app.config.ts', 'scripts/cli/temp/app.config.ts', (err) => {
- if (err) {
- logger.error('ERROR WHEN CREATING TEMP FILES, please run this script again \n', err)
- reject(new Error('ERROR SEE MESSAGE ABOVE'))
- } else {
- resolve(true)
- }
- })
- } catch (e) {
- reject(e)
- }
- })
-}
-
/**
* Replaces placeholders in the README file with the provided app name and organization owner.
*
@@ -268,13 +240,10 @@ const questions = Object.entries(questionsObject)
}))
.sort((a, b) => a.order - b.order)
-export const bootstrap = async () => {
+export const bootstrap = async (params?: string) => {
try {
logger.info('Please give me this information to setup your project:')
- // 0. Create temp files
- await createTempFiles()
-
const answers = (await prompt(questions)) as unknown as SetupProjectProps
await setUpProject(answers)
diff --git a/scripts/cli/actions/generate.ts b/scripts/cli/actions/generate.ts
index 845692d9..8ef67d07 100644
--- a/scripts/cli/actions/generate.ts
+++ b/scripts/cli/actions/generate.ts
@@ -1,48 +1,53 @@
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-import selectPrompt from 'select-prompt'
+import { prompt } from 'enquirer'
-import { generateComponent } from '../commands/generateComponent'
-import { generateIconTypes } from '../commands/generateIconTypes'
-import { generateScreen } from '../commands/generateScreen'
-import { generateTheme } from '../commands/generateTheme'
+import { generateIconTypes, generateScreen, generateTheme, generateComponent } from '../commands'
-const data = [
+export const generators = [
{
title: 'Screen',
+ description: 'Generate new screen',
value: 'screen',
command: generateScreen,
},
{
title: 'Component',
+ description: 'Generate new component',
value: 'component',
command: generateComponent,
},
{
title: 'Icon types',
+ description: 'Generate new icon types - based on icon - `selection.json`',
value: 'icon-types',
command: generateIconTypes,
},
{
title: 'Generate theme',
+ description: 'Generate new theme - based on figma variables',
value: 'generate-theme',
command: generateTheme,
},
] as const
-const generatePrompts = data.map(({ title, value }) => ({ title, value }))
+export const generate = async () => {
+ const promptAnswer = await prompt({
+ name: 'generator',
+ message: 'What do you want to generate?',
+ type: 'select',
+ choices: generators.map((generator) => ({
+ name: generator.title,
+ value: generator.value,
+ })),
+ })
-export const generate = () => {
- selectPrompt('What do you want to generate?', generatePrompts).on(
- 'submit',
- async (value: string) => {
- const command = data.find((item) => item.value === value)?.command
+ // @ts-expect-error: generator not found on promptAnswer
+ const answerValue = promptAnswer?.generator as string
- if (command) {
- command()
- } else {
- console.log('There was some issue while running the script ', value)
- }
- }
- )
+ const command = generators.find((item) => item.title === answerValue)?.command
+
+ if (command) {
+ command()
+ } else {
+ console.log('There was some issue while running the script ', answerValue)
+ }
}
diff --git a/scripts/cli/actions/index.ts b/scripts/cli/actions/index.ts
index 1fe5edeb..cb6fe6ad 100644
--- a/scripts/cli/actions/index.ts
+++ b/scripts/cli/actions/index.ts
@@ -1,24 +1,7 @@
import { bootstrap } from './bootstrap'
import { generate } from './generate'
-import { CLI_ACTIONS } from '../constants'
-import { logger } from '../utils'
-const actions = {
+export const actions = {
generate,
- g: generate,
bootstrap,
- b: bootstrap,
-}
-
-/**
- * Parses and executes the specified CLI action.
- *
- * @param action - The CLI action to parse and execute.
- */
-export const executeAction = (action: keyof typeof actions) => {
- if (!CLI_ACTIONS.includes(action)) {
- logger.error(`Action ${action} is not supported.`)
- return
- }
- actions[action]()
}
diff --git a/scripts/cli/commands/index.ts b/scripts/cli/commands/index.ts
index 10afde15..e738d13e 100644
--- a/scripts/cli/commands/index.ts
+++ b/scripts/cli/commands/index.ts
@@ -1,3 +1,4 @@
+export * from './generateComponent'
export * from './generateIconTypes'
export * from './generateScreen'
export * from './generateTheme'
diff --git a/scripts/cli/index.ts b/scripts/cli/index.ts
index d4d712d2..6e1a21e6 100644
--- a/scripts/cli/index.ts
+++ b/scripts/cli/index.ts
@@ -1,11 +1,52 @@
+// #!/usr/bin/env node
import { Command } from 'commander'
-import { executeAction } from './actions'
+import { actions } from './actions'
+import { generators } from './actions/generate'
-const program = new Command()
+class CommandWithTrace extends Command {
+ createCommand(name: string) {
+ const cmd = new CommandWithTrace(name)
+ // Add an option to subcommands created using `.command()`
+ cmd.option('-t, --trace', 'display extra information when run command')
+ return cmd
+ }
+}
-program.argument('').action((action) => {
- executeAction(action)
+function inpectCommand(command: Command) {
+ // The option value is stored as property on command because we called .storeOptionsAsProperties()
+
+ console.log(command.helpInformation())
+ // console.log(`
+ // Please run this script with -h argument, to see what options you have
+ // `)
+}
+
+const program = new CommandWithTrace('baca').action((options, command) => {
+ inpectCommand(command)
+})
+
+const generateGroup = program
+ .command('generate [params...]')
+ .description('Run generators, please check `g -h` to check available generators')
+ .alias('g')
+ .action(() => {
+ actions.generate()
+ })
+
+generators.forEach((generator) => {
+ generateGroup
+ .command(generator.value)
+ .description(generator.description)
+ .action(() => generator.command())
})
+program
+ .command('bootstrap')
+ .description('Bootstrap of new project')
+ .alias('b')
+ .action((buildTarget, options, command) => {
+ actions.bootstrap()
+ })
+
program.parse()
diff --git a/scripts/cli/tsconfig.cli.json b/scripts/cli/tsconfig.cli.json
index 9d54d044..0aa0ebac 100644
--- a/scripts/cli/tsconfig.cli.json
+++ b/scripts/cli/tsconfig.cli.json
@@ -1,7 +1,6 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
- "rootDir": ".",
"noImplicitAny": false,
"outDir": "build",
"strict": true,
@@ -11,6 +10,8 @@
"sourceMap": false,
"esModuleInterop": true,
"moduleResolution": "node",
- "skipLibCheck": true
- }
+ "skipLibCheck": true,
+ "allowJs": false
+ },
+ "include": ["../../app.config.ts", "**/*"]
}
From 89acea5749edb061726b3520224f8af161e9422c Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Thu, 18 Apr 2024 10:29:30 +0200
Subject: [PATCH 33/47] chore: update tutorials docs
---
docs/docs/tutorials/ICONS.md | 2 +-
docs/docs/tutorials/SCRIPTS.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/docs/tutorials/ICONS.md b/docs/docs/tutorials/ICONS.md
index 1b1e326f..5ee9b766 100644
--- a/docs/docs/tutorials/ICONS.md
+++ b/docs/docs/tutorials/ICONS.md
@@ -40,4 +40,4 @@ It is added to the app as a font generated by [icomoon app](https://icomoon.io/a
9. Generate new types for icons
- - run script generating icon types `yarn generate:icon:types`
+ - run script generating icon types `yarn baca generate icon-types`
diff --git a/docs/docs/tutorials/SCRIPTS.md b/docs/docs/tutorials/SCRIPTS.md
index fe794dde..d628819d 100644
--- a/docs/docs/tutorials/SCRIPTS.md
+++ b/docs/docs/tutorials/SCRIPTS.md
@@ -57,7 +57,7 @@ Check [doppler documentantion](/docs/doppler-config) to see more details
## Generate last update info
-This script is automatically executed after running `yarn update:production`, this will return ids of last udpate:
+This script is automatically executed after running `yarn update:production` (or staging|qa), this will return ids of last udpate:
```
BACA - 2.1.0:
From cc438a80f9eb80e7b201850194846e1e590ba72c Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Thu, 18 Apr 2024 10:30:20 +0200
Subject: [PATCH 34/47] chore: remove not needed script from package json
---
package.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/package.json b/package.json
index b6700165..5cc7522a 100644
--- a/package.json
+++ b/package.json
@@ -54,7 +54,6 @@
"generate:env:qa": "scripts/generate_dotenv.sh qa",
"generate:env:staging": "scripts/generate_dotenv.sh staging",
"generate:google-services-config": "./scripts/generate_firebase_config.sh",
- "generate:icon:types": "node ./scripts/generate_icon_types.js",
"generate:last:publish": "node ./scripts/generate_last_update_id.js",
"generate:query": "yarn orval --config ./orval.config.ts",
"ios:dev-client": "IS_DEV=1 npx expo run:ios",
From edec8cb27772a0375fccb1883d85b1528cbeddf5 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Fri, 19 Apr 2024 12:41:41 +0200
Subject: [PATCH 35/47] chore: update bootstrap script
---
scripts/cli/actions/bootstrap.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/scripts/cli/actions/bootstrap.ts b/scripts/cli/actions/bootstrap.ts
index 3d6bebf8..cb6cd09a 100644
--- a/scripts/cli/actions/bootstrap.ts
+++ b/scripts/cli/actions/bootstrap.ts
@@ -223,10 +223,9 @@ const setUpProject = async (config: SetupProjectProps) => {
removeDocsFolder()
// 8. Change eas.json
- logger.info('Remove docs folder')
changeEasJson(config)
- // 8. Change deeplink files
+ // 9. Change deeplink files
changeDeeplinkFiles(config)
//Finish
From b1d8b29fcd89946caf32ae8c8e8a1ee018a861a1 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sat, 20 Apr 2024 16:06:30 +0200
Subject: [PATCH 36/47] chore: change name of the create new app docs
---
...BOOTSTRAP_INTRO.mdx => CREATE_NEW_APP.mdx} | 40 ++++++++++++-------
1 file changed, 26 insertions(+), 14 deletions(-)
rename docs/docs/bootstrap/{BOOTSTRAP_INTRO.mdx => CREATE_NEW_APP.mdx} (80%)
diff --git a/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx b/docs/docs/bootstrap/CREATE_NEW_APP.mdx
similarity index 80%
rename from docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
rename to docs/docs/bootstrap/CREATE_NEW_APP.mdx
index cb2402d2..056755fb 100644
--- a/docs/docs/bootstrap/BOOTSTRAP_INTRO.mdx
+++ b/docs/docs/bootstrap/CREATE_NEW_APP.mdx
@@ -1,10 +1,11 @@
---
id: bootstrap
-slug: /bootstrap/intro
-title: Bootstrap - start development
+slug: /bootstrap/create-new-app
+title: Create new app
sidebar_position: 1
tags:
- Bootstrap
+ - Create new app
- Getting started
- Project structure
description: Bootstrap project structure, that is needed to start development your new project
@@ -62,7 +63,12 @@ If you do not have expo account → register on your company email. In terminal
eas register
```
-You will be redirected to expo registration page. If something is not right please make sure you have eas cli installed - `npm install -g eas-cli`
+You will be redirected to expo registration page. If something is not right please make sure you have eas cli installed
+
+```bash
+npm install -g eas-cli
+
+```
Login to expo account on your local machine.
@@ -112,22 +118,28 @@ eas whoami
### Step 4.Sync project with code.
-Synchronize the newly created Expo Project to your app.
+Please gather this data:
+
+1. **app name** - you can add **display name** from previous step, or add anything you want here, this name will be displayed for users later
+2. **slug name** - created in 1-st point.
+3. **owner** - organization picked from the list in 1-st point
-In `app.json` file please insert the following:
+:::note
-1. **slug name** - created in 1-st point.
-2. **owner** - organization picked from the list in 1-st point
+If you will have issues with finding this values, please check [bootstrap testing docs](/docs/bootstrap/testing)
-```json
-{
- "expo": {
- "owner": "your_organization_name",
- "slug": "your_app_name"
- }
-}
+:::
+
+If you gather all this data please run this command:
+
+```bash
+yarn baca bootstrap --simple
```
+:::warning
+Please verify all changes made with the script
+:::
+
---
### Step 5. Make environment variables setup - [tutorial](/docs/doppler-config)
From cfca17ff40ae0a7de12bfb8a9e971a19280acbba Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sat, 20 Apr 2024 16:08:15 +0200
Subject: [PATCH 37/47] chore: add overview to docs
---
docs/docs/OVERVIEW.md | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 docs/docs/OVERVIEW.md
diff --git a/docs/docs/OVERVIEW.md b/docs/docs/OVERVIEW.md
new file mode 100644
index 00000000..d87bff3e
--- /dev/null
+++ b/docs/docs/OVERVIEW.md
@@ -0,0 +1,36 @@
+---
+id: overview
+slug: /overview
+title: Overview
+sidebar_position: 1
+tags:
+ - Bootstrap
+ - Getting started
+ - Project structure
+description: Bootstrap project structure, that is needed to start development your new project
+---
+
+# Overview
+
+**Welcome in BACA starter!**
+
+It is specialy designed to make react native apps development much easier and much faster.
+
+## How to start?
+
+1. Create new app - follow [this docs](/docs/bootstrap/create-new-app)
+
+ - At this point you can start development
+ - When you will need to show app to testers or client go to next step
+
+2. Fill needed data to start deployment - follow [this docs](/docs/bootstrap/testing)
+
+ - This will make all required changes to the code base
+
+3. Prepare deployment - follow [this docs](/docs/deploy/intro)
+
+ - Thanks to this docs you will have possibility to automatically deploy app to testers and
+
+4. Send app to review and publish it on app stores
+
+ - We don't plan to make docs about that, but maybe in the future we will do that!
From b28d44c7b781f3120db0dfaeb74cc4fe586a1a1f Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sat, 20 Apr 2024 16:09:31 +0200
Subject: [PATCH 38/47] chore: update navigation in docs pages
---
README.md | 6 +++---
docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx | 6 ++++--
docs/docs/bootstrap/_category_.json | 2 +-
docs/docs/deploy/_category_.json | 2 +-
docs/docs/tutorials/NOTIFICATIONS_SETUP.md | 2 +-
docs/docs/tutorials/_category_.json | 2 +-
docs/docusaurus.config.ts | 7 ++++++-
docs/src/pages/index.tsx | 2 +-
8 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 4ef639de..a9e3b7ce 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ This is a template to be used with react native and expo. It includes all the ne
## Documentation
-Check out our [documentation page](https://baca-docs.vercel.app/docs/bootstrap/intro), it contains:
+Check out our [documentation page](https://baca-docs.vercel.app/docs/overview), it contains:
- Bootstrapping project - tutorial how to easy setup from scratch
- Deploying app
@@ -52,7 +52,7 @@ We know there are a lot of project starters for react native, but we have some g
## How to use?
-We have prepared a detailed documentation for how to run project with this template - **[Bootstrap docs](https://baca-docs.vercel.app/docs/bootstrap/intro)**
+We have prepared a detailed documentation for how to run project with this template - **[Bootstrap docs](https://baca-docs.vercel.app/docs/overview)**
It's great for production project, but if you want to just test it, you can follow the quick steps (on the bottom).
@@ -79,7 +79,7 @@ It's great for production project, but if you want to just test it, you can foll
- eas configuration
- update, build, submit
- deployment docs
- - https://baca-docs.vercel.app/docs/bootstrap/intro
+ - https://baca-docs.vercel.app/docs/overview
- verifying code on pull request - pipelines
- when creating pull request on github, there are tests, linters and types checks. If there will be some error you will be notified that something is wrong.
- custom fonts
diff --git a/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx b/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
index 45b08e75..95cd4b0e 100644
--- a/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
+++ b/docs/docs/bootstrap/BOOTSTRAP_TESTING.mdx
@@ -1,7 +1,7 @@
---
id: bootstrap-testing
slug: /bootstrap/testing
-title: Bootstrap - testing
+title: Prepare for testing
sidebar_position: 2
tags:
- Bootstrap
@@ -104,7 +104,9 @@ If you have some domain, for example: example.com, your bundle id could be: `com
+
> **Optional step** - You can run the bootstrap script later
+
This can be found in developer apple console.
> Image will be added in future
@@ -143,7 +145,7 @@ yarn b
## OR
-yarn baca:bootstrap
+yarn baca bootstrap
```
## Potential issues
diff --git a/docs/docs/bootstrap/_category_.json b/docs/docs/bootstrap/_category_.json
index 9be6a2fc..db02be29 100644
--- a/docs/docs/bootstrap/_category_.json
+++ b/docs/docs/bootstrap/_category_.json
@@ -1,6 +1,6 @@
{
"label": "Start development",
- "position": 1,
+ "position": 2,
"collapsible": true,
"collapsed": false,
"link": {
diff --git a/docs/docs/deploy/_category_.json b/docs/docs/deploy/_category_.json
index 7f821806..1c146b5f 100644
--- a/docs/docs/deploy/_category_.json
+++ b/docs/docs/deploy/_category_.json
@@ -1,6 +1,6 @@
{
"label": "Deployment",
- "position": 2,
+ "position": 3,
"collapsible": true,
"collapsed": false,
"link": {
diff --git a/docs/docs/tutorials/NOTIFICATIONS_SETUP.md b/docs/docs/tutorials/NOTIFICATIONS_SETUP.md
index a4dfe463..785ec5f5 100644
--- a/docs/docs/tutorials/NOTIFICATIONS_SETUP.md
+++ b/docs/docs/tutorials/NOTIFICATIONS_SETUP.md
@@ -21,7 +21,7 @@ Expo notifications are already preconfigured in this template. However, you stil
## Usage in expo dev client (expo run:\[android:ios\])
1. Make sure you have created your account in [expo.dev](http://expo.dev).
-2. Follow [bootstrap](/docs/bootstrap/intro) docs
+2. Follow [bootstrap](/docs/bootstrap/create-new-app) docs
3. Follow platform specific configuration.
### Android
diff --git a/docs/docs/tutorials/_category_.json b/docs/docs/tutorials/_category_.json
index 95985d9e..4ec1db4c 100644
--- a/docs/docs/tutorials/_category_.json
+++ b/docs/docs/tutorials/_category_.json
@@ -1,6 +1,6 @@
{
"label": "Tutorials",
- "position": 3,
+ "position": 4,
"collapsible": true,
"collapsed": false,
"link": {
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index 95c575b1..4e7a919b 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -72,9 +72,13 @@ const config: Config = {
{
title: 'Docs',
items: [
+ {
+ label: 'Overview',
+ to: '/docs/overview',
+ },
{
label: 'Intro',
- to: '/docs/bootstrap/intro',
+ to: '/docs/bootstrap/create-new-app',
},
],
},
@@ -106,6 +110,7 @@ const config: Config = {
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
+ additionalLanguages: ['bash'],
},
} satisfies Preset.ThemeConfig,
}
diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx
index b54f693f..066b1fc0 100644
--- a/docs/src/pages/index.tsx
+++ b/docs/src/pages/index.tsx
@@ -18,7 +18,7 @@ function HomepageHeader() {
{siteConfig.tagline}
-
+
See docs
From 358a790fda67386dd5f542e71c2c90206f0f3821 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sat, 20 Apr 2024 16:10:00 +0200
Subject: [PATCH 39/47] chore: support short version in bootstrap script
---
scripts/cli/actions/bootstrap.ts | 71 +++++++++++++++++++++-----------
scripts/cli/index.ts | 6 ++-
2 files changed, 52 insertions(+), 25 deletions(-)
diff --git a/scripts/cli/actions/bootstrap.ts b/scripts/cli/actions/bootstrap.ts
index cb6cd09a..38548722 100644
--- a/scripts/cli/actions/bootstrap.ts
+++ b/scripts/cli/actions/bootstrap.ts
@@ -35,64 +35,77 @@ type QuestionsObject = {
type: string
message: string
initial: string
+ simple?: boolean
order: number
}
}
+type Question = {
+ type: string
+ message: string
+ initial: string
+ order: number
+ name: string
+}
+
const questionsObject: QuestionsObject = {
appName: {
type: 'text',
message: 'What is your app name?',
initial: APP_CONFIG.appName,
+ simple: true,
order: 1,
},
+ appSlug: {
+ type: 'text',
+ message: 'What is your expo app slug?',
+ initial: newAppJson.expo.slug,
+ simple: true,
+ order: 2,
+ },
+ organizationOwner: {
+ type: 'text',
+ message: 'What is your expo organization owner?',
+ initial: newAppJson.expo.owner,
+ simple: true,
+ order: 3,
+ },
bundleId: {
type: 'text',
message: 'What is your bundle Id?',
initial: APP_CONFIG.iosBundleIdentifier,
- order: 2,
+ order: 4,
},
androidPackageName: {
type: 'text',
message: 'What is your android package name?',
initial: APP_CONFIG.androidPackageName,
- order: 3,
+ order: 5,
},
scheme: {
type: 'text',
message: 'What is your scheme name?',
initial: APP_CONFIG.scheme,
- order: 4,
+ order: 6,
},
easId: {
type: 'text',
message: 'What is your eas id?',
initial: APP_CONFIG.easProjectId,
- order: 5,
- },
- organizationOwner: {
- type: 'text',
- message: 'What is your expo organization owner?',
- initial: newAppJson.expo.owner,
- order: 6,
+ order: 7,
},
androidIconColor: {
type: 'text',
message: 'What is your android icon color?',
initial: APP_CONFIG.adaptiveIconBackgroundColor,
- order: 7,
- },
- appSlug: {
- type: 'text',
- message: 'What is your expo app slug?',
- initial: newAppJson.expo.slug,
order: 8,
},
appleTeamId: {
type: 'text',
message: 'What is your apple team id? (Optional)',
- initial: newAppJson.expo.slug,
- order: 8,
+ // FIXME: GET IT FROM EAS.JSON
+ initial: '5764GC687R',
+ order: 9,
},
}
@@ -232,18 +245,30 @@ const setUpProject = async (config: SetupProjectProps) => {
logger.success(`Config your project has been success`)
}
-const questions = Object.entries(questionsObject)
- .map((value) => ({
+type BootstrapConfig = { isSimple: boolean }
+
+const sortQuestions = (questions: Question[]) => {
+ return questions.sort((a, b) => a.order - b.order)
+}
+
+const getQuesstions = ({ isSimple }: BootstrapConfig) => {
+ const questions = Object.entries(questionsObject).map((value) => ({
name: value[0],
...value[1],
}))
- .sort((a, b) => a.order - b.order)
-export const bootstrap = async (params?: string) => {
+ if (isSimple) {
+ return sortQuestions(questions.filter((question) => question.simple))
+ }
+
+ return sortQuestions(questions)
+}
+
+export const bootstrap = async (config: BootstrapConfig) => {
try {
logger.info('Please give me this information to setup your project:')
- const answers = (await prompt(questions)) as unknown as SetupProjectProps
+ const answers = (await prompt(getQuesstions(config))) as unknown as SetupProjectProps
await setUpProject(answers)
diff --git a/scripts/cli/index.ts b/scripts/cli/index.ts
index 6e1a21e6..25a024c7 100644
--- a/scripts/cli/index.ts
+++ b/scripts/cli/index.ts
@@ -43,10 +43,12 @@ generators.forEach((generator) => {
program
.command('bootstrap')
+ .option('-s, --simple', 'Run bootstrap simple with needed values')
.description('Bootstrap of new project')
.alias('b')
- .action((buildTarget, options, command) => {
- actions.bootstrap()
+ .action((buildTarget) => {
+ const isSimple = buildTarget.simple ?? false
+ actions.bootstrap({ isSimple })
})
program.parse()
From e3e541ad78e917a93df11464e26183b4c506afd4 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sun, 21 Apr 2024 12:02:17 +0200
Subject: [PATCH 40/47] chore: update readme
---
README.md | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index a9e3b7ce..09df6941 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,10 @@
-[](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs)
-[](https://img.shields.io/npm/v/@binarapps/expo-ts-template?style=flat-square)
-[](https://img.shields.io/npm/dt/@binarapps/expo-ts-template?style=flat-square)
-[](https://img.shields.io/github/stars/binarapps/expo-ts-template?style=flat-square)
+[](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs)
+[](https://img.shields.io/npm/v/@binarapps/baca-react-native-template?style=flat-square)
+[](https://img.shields.io/npm/dt/@binarapps/baca-react-native-template?style=flat-square)
+[](https://img.shields.io/github/stars/binarapps/baca-react-native-template?style=flat-square)
[](https://expo.dev/client)
# @binarapps/baca-react-native-template
@@ -48,7 +48,7 @@ We know there are a lot of project starters for react native, but we have some g
-[](https://www.youtube.com/watch?v=NmTd5nXXTLI)
+[](https://www.youtube.com/watch?v=NmTd5nXXTLI)
## How to use?
@@ -58,15 +58,15 @@ It's great for production project, but if you want to just test it, you can foll
### Quick steps:
-- `npx create-expo-app --template=@binarapps/expo-ts-template name_of_your_app`
+- `npx create-expo-app --template=@binarapps/baca-react-native-template name_of_your_app`
- `cd name_of_your_app`
- `yarn bootstrap` - the cli will ask you some questions about your app (you can fill all this data later)
## What's inside?
-[](https://img.shields.io/npm/types/@binarapps/expo-ts-template?style=flat-square)
-[](https://img.shields.io/github/package-json/dependency-version/binarapps/expo-ts-template/expo?style=flat-square)
-[](https://img.shields.io/github/package-json/dependency-version/binarapps/expo-ts-template/@react-navigation/native?style=flat-square)
+[](https://img.shields.io/npm/types/@binarapps/baca-react-native-template?style=flat-square)
+[](https://img.shields.io/github/package-json/dependency-version/binarapps/baca-react-native-template/expo?style=flat-square)
+[](https://img.shields.io/github/package-json/dependency-version/binarapps/baca-react-native-template/@react-navigation/native?style=flat-square)
### Implemented custom features
@@ -159,13 +159,13 @@ Please adhere to this project's `code of conduct`.
Clone the project
```bash
- git clone https://github.com/binarapps/expo-ts-template.git
+ git clone https://github.com/binarapps/baca-react-native-template.git
```
Go to the project directory
```bash
- cd expo-ts-template
+ cd baca-react-native-template
```
Install dependencies
From 765d6794edf7f312baee41c14fff8b5302ea2539 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Sun, 21 Apr 2024 12:02:25 +0200
Subject: [PATCH 41/47] chore: update scripts readme
---
src/components/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/README.md b/src/components/README.md
index 3a7d493b..e2f39956 100644
--- a/src/components/README.md
+++ b/src/components/README.md
@@ -1,6 +1,6 @@
# Components
-Components in [expo-ts-template](https://github.com/binarapps/expo-ts-template) follows [atomic design methodology](https://atomicdesign.bradfrost.com/).
+Components in [baca-react-native-template](https://github.com/binarapps/baca-react-native-template) follows [atomic design methodology](https://atomicdesign.bradfrost.com/).
For more information on such a design methodology, visit the page above.
On the other hand, below you can find documentation of the implemented components
From f9185779b728ab72869498087e36227c50e59863 Mon Sep 17 00:00:00 2001
From: Mateusz Rostkowski
Date: Mon, 22 Apr 2024 08:31:39 +0200
Subject: [PATCH 42/47] chore: update readme template
---
templates/readme_template.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/templates/readme_template.md b/templates/readme_template.md
index 93837346..2e779565 100644
--- a/templates/readme_template.md
+++ b/templates/readme_template.md
@@ -93,7 +93,7 @@ It is added to the app as a font generated by [icomoon app](https://icomoon.io/a
1. Add template remote
```bash
-git remote add template git@github.com:binarapps/expo-ts-template.git
+git remote add template git@github.com:binarapps/baca-react-native-template.git
```
2. Go to new branch (for safety reason)
@@ -125,7 +125,7 @@ git commit -m "chore: sync up with template code"
```