create-catalyst-app-internal 0.0.1-beta.7 → 0.0.1-beta.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/Readme.md +56 -0
  2. package/codemod/new-route/index.js +98 -0
  3. package/codemod/new-route/template.js +119 -0
  4. package/codemod/new-route/transformers/createReducer.js +38 -0
  5. package/codemod/new-route/transformers/createRoute.js +33 -0
  6. package/codemod/new-route/utils.js +90 -0
  7. package/license +10 -0
  8. package/package.json +6 -7
  9. package/scripts/cli.cjs +163 -42
  10. package/templates/common/.eslintignore +1 -0
  11. package/templates/common/.eslintrc +28 -0
  12. package/templates/common/README.md +2 -2
  13. package/templates/common/api.js +12 -23
  14. package/templates/common/client/styles.js +1 -12
  15. package/templates/common/config/config.json +2 -23
  16. package/templates/common/public/favicon.ico +0 -0
  17. package/templates/common/server/document.js +3 -5
  18. package/templates/common/server/index.js +1 -0
  19. package/templates/common/server/server.js +8 -1
  20. package/templates/common/src/js/routes/index.js +0 -6
  21. package/templates/common/webpackConfig.js +1 -0
  22. package/templates/mcp-root/mcp/context.md +674 -0
  23. package/templates/mcp-root/mcp/mcp.js +36 -0
  24. package/templates/none-js/client/index.js +5 -7
  25. package/templates/none-js/package.json +12 -5
  26. package/templates/none-js/src/js/containers/App/index.js +1 -1
  27. package/templates/none-js/src/js/routes/utils.js +42 -0
  28. package/templates/none-ts/client/index.js +23 -0
  29. package/templates/none-ts/package.json +34 -0
  30. package/templates/none-ts/src/js/containers/App/index.js +16 -0
  31. package/templates/none-ts/src/js/routes/utils.js +42 -0
  32. package/templates/none-ts/tsconfig.json +13 -0
  33. package/templates/none-ts/types.d.ts +4 -0
  34. package/templates/redux-js/client/index.js +1 -1
  35. package/templates/redux-js/package.json +11 -3
  36. package/templates/redux-js/src/js/containers/App/index.js +1 -1
  37. package/templates/redux-js/src/js/containers/App/reducer.js +0 -1
  38. package/templates/redux-js/src/js/routes/utils.js +42 -0
  39. package/templates/redux-js/src/js/store/index.js +2 -2
  40. package/templates/redux-ts/client/index.js +28 -0
  41. package/templates/redux-ts/package.json +37 -0
  42. package/templates/redux-ts/src/js/containers/App/actions.js +17 -0
  43. package/templates/redux-ts/src/js/containers/App/index.js +16 -0
  44. package/templates/redux-ts/src/js/containers/App/reducer.js +19 -0
  45. package/templates/redux-ts/src/js/routes/utils.js +42 -0
  46. package/templates/redux-ts/src/js/store/index.js +28 -0
  47. package/templates/redux-ts/tsconfig.json +13 -0
  48. package/templates/redux-ts/types.d.ts +4 -0
  49. package/templates/rtk-js/client/index.js +1 -1
  50. package/templates/rtk-js/package.json +11 -3
  51. package/templates/rtk-js/src/js/containers/App/index.js +1 -1
  52. package/templates/rtk-js/src/js/containers/App/reducer.js +1 -1
  53. package/templates/rtk-js/src/js/routes/utils.js +42 -0
  54. package/templates/rtk-js/src/js/store/index.js +2 -2
  55. package/templates/rtk-ts/client/index.js +28 -0
  56. package/templates/rtk-ts/package.json +37 -0
  57. package/templates/rtk-ts/src/js/containers/App/index.js +16 -0
  58. package/templates/rtk-ts/src/js/containers/App/reducer.js +18 -0
  59. package/templates/rtk-ts/src/js/routes/utils.js +42 -0
  60. package/templates/rtk-ts/src/js/store/index.js +28 -0
  61. package/templates/rtk-ts/tsconfig.json +13 -0
  62. package/templates/rtk-ts/types.d.ts +4 -0
  63. package/templates/tailwind/postcss.config.js +5 -0
  64. package/templates/tailwind/src/static/css/base/index.scss +2 -0
  65. package/templates/common/.babelrc +0 -26
  66. package/templates/common/src/js/routes/utils.js +0 -29
package/scripts/cli.cjs CHANGED
@@ -3,14 +3,13 @@ const { execSync } = require("child_process")
3
3
  const Commander = require("commander")
4
4
  const { Option } = require("commander")
5
5
  const prompts = require("prompts")
6
- const { red, green, cyan } = require("picocolors")
7
-
8
- const packageJson = require("../package.json")
6
+ const { red, green, cyan, bold } = require("picocolors")
9
7
  const tar = require("tar")
10
8
  const path = require("path")
11
9
  const fs = require("fs")
10
+ var validate = require("validate-npm-package-name")
11
+ const packageJson = require("../package.json")
12
12
 
13
- // Hardcoded branch
14
13
  let projectName = null
15
14
  const program = new Commander.Command()
16
15
  .version(packageJson.version)
@@ -18,6 +17,7 @@ const program = new Commander.Command()
18
17
  .arguments("[folderName]")
19
18
  .usage(`${green("[folderName]")} [options]`)
20
19
  .action((name) => (projectName = name))
20
+ .addOption(new Option("-y, --yes [yes]", "Use default configuration"))
21
21
  .addOption(
22
22
  new Option(
23
23
  "-s, --state-management [stateManagement]",
@@ -28,13 +28,55 @@ const program = new Commander.Command()
28
28
  )
29
29
  .action(async (folderName = null, cmd) => {
30
30
  try {
31
+ let config = {
32
+ folderName,
33
+ language: null,
34
+ tailWindSupport: null,
35
+ description: null,
36
+ stateManagement: cmd.stateManagement,
37
+ mcpSupport: null,
38
+ }
39
+
40
+ if (process.argv.includes("new-route")) {
41
+ const createRoutePath = path.join(__dirname, "../codemod/new-route/index.js")
42
+ execSync(`node ${createRoutePath}`, { stdio: "inherit" })
43
+ return
44
+ }
45
+
46
+ console.log(cyan(`Using create-catalyst-app version ${bold(packageJson.version)}`))
47
+
31
48
  // Use options provided through commander or prompt the user
32
49
  validateOptions(cmd)
33
- const projectName = folderName || (await promptProjectName())
34
- const language = "js"
35
- const projectDescription = await promptDescription()
36
- const stateManagement = cmd.stateManagement || (await promptStateManagement())
37
50
 
51
+ if (cmd.yes) {
52
+ console.log("Using default configuration.")
53
+ config = {
54
+ folderName: "my-app",
55
+ language: "js",
56
+ tailWindSupport: false,
57
+ description: "Default catalyst app",
58
+ stateManagement: "none",
59
+ mcpSupport: true,
60
+ }
61
+ }
62
+
63
+ const projectName = config.folderName || (await promptProjectName())
64
+ let isNameValid = validate(projectName)
65
+ if (!isNameValid.validForNewPackages) {
66
+ isNameValid?.warnings?.forEach?.((item) => console.log(red(item)))
67
+ isNameValid?.errors?.forEach?.((item) => console.log(red(item)))
68
+ process.exit(1)
69
+ }
70
+ let projectPath = path.join(process.cwd(), projectName)
71
+ if (fs.existsSync(projectPath)) {
72
+ console.log(red(`${projectName} already exists, try again.`))
73
+ process.exit(1)
74
+ }
75
+ const projectDescription = config.description || (await promptDescription())
76
+ const language = config.language || (await promptTypescript())
77
+ const tailWindSupport = config.tailWindSupport !== null || (await promptTailwind())
78
+ const stateManagement = config.stateManagement || (await promptStateManagement())
79
+ const mcpSupport = config.mcpSupport !== null || (await promptMcp())
38
80
 
39
81
  // Define mapping of options to repository suffixes
40
82
  const repositorySuffixes = {
@@ -50,32 +92,67 @@ const program = new Commander.Command()
50
92
 
51
93
  const commonCodeDirectory = "package/templates/common"
52
94
  const selectedTemplateCode = `package/templates/${repositorySuffixes[stateManagement]}-${repositorySuffixes[language]}`
95
+ const tailwindCodeDirectory = "package/templates/tailwind"
96
+ const mcpCodeDirectory = "package/templates/mcp-root"
97
+
53
98
  const subDirectoriesToExtract = [commonCodeDirectory, selectedTemplateCode]
99
+ if (tailWindSupport) subDirectoriesToExtract.push(tailwindCodeDirectory)
100
+ if (mcpSupport) subDirectoriesToExtract.push(mcpCodeDirectory)
101
+
54
102
  const extractionDestination = `/${projectName}/`
55
103
  let tempDir
56
- ; (() => {
57
- try {
58
- tempDir = createTempDir()
104
+ ;(() => {
105
+ try {
106
+ tempDir = createTempDir()
59
107
 
60
- const packageFilePath = packNpmPackage(packageName, packageVersion, tempDir)
108
+ const packageFilePath = packNpmPackage(packageName, packageVersion, tempDir)
61
109
 
62
- extractSubdirectory(packageFilePath)
63
- createGitignore(projectName)
110
+ extractSubdirectory(packageFilePath)
111
+ createGitignore(projectName)
64
112
 
65
- execSync(
66
- `cd ${projectName} && npm i && npm pkg set name=${projectName} ${projectDescription ? `description=${projectDescription}` : ""} && git init --quiet`,
67
- { stdio: "inherit" }
68
- )
113
+ execSync(
114
+ `cd ${projectName} && npm i && npm pkg set name=${projectName} ${projectDescription ? `description="${projectDescription}"` : ""} && git init --quiet`,
115
+ { stdio: "inherit" }
116
+ )
69
117
 
118
+ if (tailWindSupport) {
119
+ execSync(`cd ${projectName} && npm i tailwindcss@4.1.4 @tailwindcss/postcss@4.1.4`, {
120
+ stdio: "inherit",
121
+ })
122
+ }
70
123
 
71
- deleteDirectory(tempDir)
72
- } catch (error) {
73
- deleteDirectory(tempDir)
74
- console.error(`Error: ${error.message}`)
75
- process.exit(1)
124
+ if (mcpSupport) {
125
+ execSync(`cd ${projectName} && npm i @modelcontextprotocol/sdk`, { stdio: "inherit" })
76
126
  }
77
- })()
78
127
 
128
+ execSync(
129
+ `cd ${projectName} && git add . && git commit -m "initial commit from Create Catalyst App"`,
130
+ {
131
+ stdio: "inherit",
132
+ }
133
+ )
134
+
135
+ console.log(`\n${green(bold("Success!"))} created ${projectName} at ${projectPath}`)
136
+ console.log("Inside this directory, you can run the following commands.")
137
+
138
+ console.log(cyan(bold(" \n npm run start")))
139
+ console.log(" Starts the development server ")
140
+
141
+ console.log(cyan(bold("\n npm run build")))
142
+ console.log(" Bundles the app for production ")
143
+
144
+ console.log(cyan(bold("\n npm run serve")))
145
+ console.log(" Serves the production build ")
146
+
147
+ console.log("\nWe suggest you to begin, by running")
148
+ console.log(` ${cyan("cd")} ${projectName} && ${cyan("npm start")} \n\n`)
149
+ } catch (error) {
150
+ console.error(`Error: ${error.message}`)
151
+ process.exit(1)
152
+ } finally {
153
+ deleteDirectory(tempDir)
154
+ }
155
+ })()
79
156
  function packNpmPackage(packageName, packageVersion, tempDir) {
80
157
  const tarballFileName = `${packageName}-${packageVersion}.tgz`
81
158
  const tarballFilePath = path.join(tempDir, tarballFileName)
@@ -87,8 +164,8 @@ const program = new Commander.Command()
87
164
 
88
165
  // to test locally, comment the upper execSync and uncomment this one.
89
166
  // execSync(`npm pack --pack-destination=${tempDir} --silent`, {
90
- // cwd: process.cwd(),
91
- // });
167
+ // cwd: process.cwd(),
168
+ // })
92
169
 
93
170
  return tarballFilePath
94
171
  } catch (error) {
@@ -123,13 +200,19 @@ const program = new Commander.Command()
123
200
  if (entry.path.startsWith(selectedTemplateCode)) {
124
201
  entry.path = entry.path.replace(selectedTemplateCode, extractionDestination)
125
202
  }
203
+ if (entry.path.startsWith(tailwindCodeDirectory)) {
204
+ entry.path = entry.path.replace(tailwindCodeDirectory, extractionDestination)
205
+ }
206
+ if (entry.path.startsWith(mcpCodeDirectory)) {
207
+ entry.path = entry.path.replace(mcpCodeDirectory, extractionDestination)
208
+ }
126
209
  },
127
210
  })
128
211
  } catch (e) {
129
212
  console.log("An error occurred", e)
130
213
  }
131
214
 
132
- cyan(`Run cd ${projectName} && npm start to get started.`)
215
+ console.log(cyan(`Run cd ${projectName} && npm start to get started.`))
133
216
  }
134
217
  } catch (error) {
135
218
  console.error(red("An error occurred:"), error.message)
@@ -170,10 +253,10 @@ async function promptProjectName() {
170
253
  if (!res.path || projectName === "") {
171
254
  console.log(
172
255
  "\nPlease specify the project directory:\n" +
173
- ` ${cyan(program.name())} ${green("<project-directory>")}\n` +
174
- "For example:\n" +
175
- ` ${cyan(program.name())} ${green("my-next-app")}\n\n` +
176
- `Run ${cyan(`${program.name()} --help`)} to see all options.`
256
+ ` ${cyan(program.name())} ${green("<project-directory>")}\n` +
257
+ "For example:\n" +
258
+ ` ${cyan(program.name())} ${green("my-next-app")}\n\n` +
259
+ `Run ${cyan(`${program.name()} --help`)} to see all options.`
177
260
  )
178
261
  process.exit(1)
179
262
  }
@@ -191,6 +274,46 @@ async function promptDescription() {
191
274
  } else return null
192
275
  }
193
276
 
277
+ async function promptTypescript() {
278
+ const response = await prompts({
279
+ type: "select",
280
+ name: "typescript",
281
+ message: "Would you like to use TypeScript?",
282
+ choices: [
283
+ { title: "Yes", value: "ts" },
284
+ { title: "No", value: "js" },
285
+ ],
286
+ })
287
+
288
+ return response.typescript
289
+ }
290
+
291
+ async function promptTailwind() {
292
+ const response = await prompts({
293
+ type: "select",
294
+ name: "tailwind",
295
+ message: "Would you like to use Tailwind CSS?",
296
+ choices: [
297
+ { title: "Yes", value: true },
298
+ { title: "No", value: false },
299
+ ],
300
+ })
301
+ return response.tailwind
302
+ }
303
+
304
+ async function promptMcp() {
305
+ const response = await prompts({
306
+ type: "select",
307
+ name: "mcp",
308
+ message: "Would you like to setup an MCP server?",
309
+ choices: [
310
+ { title: "Yes", value: true },
311
+ { title: "No", value: false },
312
+ ],
313
+ })
314
+ return response.mcp
315
+ }
316
+
194
317
  function validateOptions(cmd) {
195
318
  // Validate language option
196
319
  if (cmd.lang && !["js", "ts"].includes(cmd.lang.toLowerCase())) {
@@ -201,6 +324,10 @@ function validateOptions(cmd) {
201
324
  if (cmd.stateManagement && !["rtk", "redux", "none"].includes(cmd.stateManagement.toLowerCase())) {
202
325
  throw new Error('Invalid state management option. Use "rtk", "redux", or "none".')
203
326
  }
327
+
328
+ if (cmd.yes && typeof cmd.yes !== "boolean") {
329
+ throw new Error('Invalid option for "yes". Use "-y" or "--yes" to accept defaults.')
330
+ }
204
331
  }
205
332
 
206
333
  function deleteDirectory(dirPath) {
@@ -219,20 +346,14 @@ function deleteDirectory(dirPath) {
219
346
 
220
347
  // Function to create a .gitignore file with the hardcoded patterns
221
348
  function createGitignore(projectName) {
349
+ const gitiIgnorePatterns = ["node_modules", "build", "logs"]
222
350
 
223
- const gitiIgnorePatterns = [
224
- 'node_modules/*',
225
- 'build/*',
226
- 'logs/*'
227
- ];
228
-
229
- const gitignorePath = path.join(process.cwd(), projectName, '.gitignore');
351
+ const gitignorePath = path.join(process.cwd(), projectName, ".gitignore")
230
352
 
231
353
  if (fs.existsSync(gitignorePath)) {
232
- console.log('.gitignore already exists. Please rename or remove it before running the script.');
233
- return;
354
+ console.log(".gitignore already exists. Please rename or remove it before running the script.")
355
+ return
234
356
  }
235
357
 
236
- fs.writeFileSync(gitignorePath, gitiIgnorePatterns.join('\n'));
358
+ fs.writeFileSync(gitignorePath, gitiIgnorePatterns.join("\n"))
237
359
  }
238
-
@@ -0,0 +1 @@
1
+ **/build/*
@@ -0,0 +1,28 @@
1
+ {
2
+ "rules": {
3
+ "react-hooks/exhaustive-deps": "error" // Checks effect dependencies
4
+ },
5
+ "env": {
6
+ "browser": true,
7
+ "es6": true,
8
+ "node": true
9
+ },
10
+ "extends": [
11
+ "eslint:recommended",
12
+ "plugin:react/recommended",
13
+ ],
14
+ "parserOptions": {
15
+ "sourceType": "module",
16
+ "ecmaVersion": "latest"
17
+ },
18
+ "plugins": [
19
+ "react",
20
+ "react-hooks"
21
+ ],
22
+ "settings": {
23
+ "react": {
24
+ "pragma": "React",
25
+ "version": "detect"
26
+ }
27
+ }
28
+ }
@@ -1,6 +1,6 @@
1
1
  ## Getting Started
2
2
 
3
- Commence development by initiating the application in development mode with the following commands:
3
+ Commence development by initiating the the following commands:
4
4
 
5
5
  For running the application in development mode, run:
6
6
 
@@ -8,7 +8,7 @@ For running the application in development mode, run:
8
8
  npm run start
9
9
  ```
10
10
 
11
- For a production build, utilize:
11
+ For a production build, change NODE_ENV to "production" in config/config.json, then run :
12
12
 
13
13
  ```bash
14
14
  npm run build
@@ -1,27 +1,16 @@
1
- const apiInstance = () => {
2
- const fetchFunction = async (url, options) => {
3
- let baseURL = process.env.API_URL
4
- let finalUrl = baseURL + url
1
+ const fetchFunction = (url, options) => {
2
+ let baseURL = process.env.API_URL
3
+ let finalUrl = baseURL + url
5
4
 
6
- // Request Interceptor - you can modify request here
5
+ // Request Interceptor - modify request here
7
6
 
8
- // Add query params if exist
9
- if (Object.keys(options?.params).length > 0) {
10
- finalUrl = url + "?" + new URLSearchParams(options.params)
11
- }
12
-
13
- return fetch(finalUrl, options).then(async (response) => {
14
- const parsedResponse = await response.json()
15
- // Response Interceptor - you can modify response here
16
- return parsedResponse
7
+ return fetch(finalUrl, options)
8
+ .then(response => {
9
+ return response.json().then(parsedResponse => {
10
+ // Response Interceptor - modify response here
11
+ return parsedResponse
12
+ })
17
13
  })
18
- }
19
- return {
20
- get: fetchFunction,
21
- post: fetchFunction,
22
- delete: fetchFunction,
23
- patch: fetchFunction,
24
- put: fetchFunction,
25
- }
26
14
  }
27
- export default { apiInstance }
15
+
16
+ export default fetchFunction
@@ -1,14 +1,3 @@
1
- /* Style Loader
2
- *
3
- * Anything imported in here will either be added to the vendor CSS chunk, or
4
- * the main app CSS chunk. Where they will go depends on its location or its
5
- * extension.
6
- *
7
- * Files will be added to the vendor.css chunk if:
8
- * - they are located inside `node_modules`, or
9
- * - they are plain .css files.
10
- * Otherwise, files will be added to the main app.css chunk.
11
- */
1
+ // Include initial base styles. Global styles will come here.
12
2
 
13
- // Include initial base styles.
14
3
  import "@css/base/index.scss"
@@ -5,29 +5,8 @@
5
5
  "WEBPACK_DEV_SERVER_PORT": 3006,
6
6
  "BUILD_OUTPUT_PATH": "build",
7
7
  "PUBLIC_STATIC_ASSET_PATH": "/assets/",
8
- "PUBLIC_STATIC_ASSET_URL": "http://localhost:3006",
9
- "NODE_ENV": "development",
10
- "BUILD_ENV": "localBuild",
8
+ "PUBLIC_STATIC_ASSET_URL": "http://localhost:3005",
11
9
  "API_URL": "",
12
10
  "ANALYZE_BUNDLE": false,
13
- "CLIENT_ENV_VARIABLES": [
14
- "NODE_SERVER_HOSTNAME",
15
- "NODE_SERVER_PORT",
16
- "WEBPACK_DEV_SERVER_HOSTNAME",
17
- "WEBPACK_DEV_SERVER_PORT",
18
- "BUILD_OUTPUT_PATH",
19
- "PUBLIC_STATIC_ASSET_PATH",
20
- "PUBLIC_STATIC_ASSET_URL",
21
- "NODE_ENV",
22
- "BUILD_ENV",
23
- "API_URL",
24
- "ANALYZE_BUNDLE",
25
- "ENABLE_DEBUG_LOGS",
26
- "ENABLE_FILE_LOGGING",
27
- "ENABLE_CONSOLE_LOGGING",
28
- "ANALYZE_BUNDLE",
29
- "ENABLE_DEBUG_LOGS",
30
- "ENABLE_FILE_LOGGING",
31
- "ENABLE_CONSOLE_LOGGING"
32
- ]
11
+ "CLIENT_ENV_VARIABLES": ["API_URL"]
33
12
  }
@@ -1,12 +1,10 @@
1
1
  import React from "react"
2
- import { Head, Body } from "catalyst-core-internal"
2
+ import { Head, Body } from "catalyst-core"
3
3
 
4
4
  function Document(props) {
5
5
  return (
6
- <html lang={props.lang}>
7
- <Head {...props}>
8
- <meta charset="final-order" />
9
- </Head>
6
+ <html lang="en">
7
+ <Head {...props}></Head>
10
8
  <Body {...props} />
11
9
  </html>
12
10
  )
@@ -1 +1,2 @@
1
+ // This function is executed before server starts.
1
2
  export const preServerInit = () => {}
@@ -1 +1,8 @@
1
- export function addMiddlewares(app) {}
1
+ const express = require("express")
2
+ const path = require("path")
3
+
4
+ // Server middlewares are added here.
5
+
6
+ export function addMiddlewares(app) {
7
+ app.use("/favicon.ico", express.static(path.join(__dirname, "../public/favicon.ico")))
8
+ }
@@ -8,10 +8,4 @@ const routes = [
8
8
  },
9
9
  ]
10
10
 
11
- /**
12
- * Making the routes array compatible with the format accepted by createBrowserRouter
13
- * API on the client side
14
- * https://reactrouter.com/en/main/routers/create-browser-router
15
- */
16
-
17
11
  export default routes
@@ -2,4 +2,5 @@ module.exports = {
2
2
  developmentPlugins: [],
3
3
  ssrPlugins: [],
4
4
  clientPlugins: [],
5
+ transpileModules: [],
5
6
  }