create-catalyst-app 0.1.0-canary.8 → 0.2.0-beta.1

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.
@@ -1,21 +1,34 @@
1
1
  const fs = require("fs")
2
2
  const path = require("path")
3
3
  const pc = require("picocolors")
4
- const prompts = require('prompts');
5
- const { program } = require('commander');
6
-
7
- const { createNewComponent, createRTKReducerFile, createReduxActionFile, createReduxReducerFile } = require("./template")
8
- const { validateComponentName, validatePath, discardChanges, createDirectory, createReducerEntryInStore, createNewRoute, toCamelCase, checkIfRoutePathExist } = require("./utils")
4
+ const prompts = require("prompts")
5
+ const { program } = require("commander")
6
+
7
+ const {
8
+ createNewComponent,
9
+ createRTKReducerFile,
10
+ createReduxActionFile,
11
+ createReduxReducerFile,
12
+ } = require("./template")
13
+ const {
14
+ validateComponentName,
15
+ validatePath,
16
+ discardChanges,
17
+ createDirectory,
18
+ createReducerEntryInStore,
19
+ createNewRoute,
20
+ toCamelCase,
21
+ checkIfRoutePathExist,
22
+ } = require("./utils")
9
23
 
10
24
  // Configure commander to accept CLI options
11
25
  program
12
- .option('-p, --path <path>', 'Path for the new route')
13
- .option('-c, --component <component>', 'Component name for the new route')
14
- .parse(process.argv);
15
-
26
+ .option("-p, --path <path>", "Path for the new route")
27
+ .option("-c, --component <component>", "Component name for the new route")
28
+ .parse(process.argv)
16
29
 
17
30
  async function main() {
18
- let { routePath, templateType, componentName } = program;
31
+ let { routePath, templateType, componentName } = program
19
32
 
20
33
  // If all options are not provided, prompt the user for input
21
34
  if (!routePath || !componentName || !templateType) {
@@ -31,40 +44,44 @@ async function main() {
31
44
  ],
32
45
  },
33
46
  {
34
- type: routePath ? null : 'text',
35
- name: 'routePath',
47
+ type: routePath ? null : "text",
48
+ name: "routePath",
36
49
  message: "Enter the route path",
37
- validate: validatePath
50
+ validate: validatePath,
38
51
  },
39
52
  {
40
- type: componentName ? null : 'text',
41
- name: 'componentName',
42
- message: 'Enter the component name for new route',
43
- validate: validateComponentName
44
- }
45
- ]);
53
+ type: componentName ? null : "text",
54
+ name: "componentName",
55
+ message: "Enter the component name for new route",
56
+ validate: validateComponentName,
57
+ },
58
+ ])
46
59
 
47
- routePath = routePath || response.routePath;
60
+ routePath = routePath || response.routePath
48
61
  templateType = templateType || response.templateType
49
- componentName = componentName || response.componentName;
62
+ componentName = componentName || response.componentName
50
63
  }
51
64
 
52
-
53
65
  // Code transformations
54
66
  if (componentName && routePath && templateType) {
55
-
56
67
  const reducerName = toCamelCase(componentName)
57
- const containersDir = 'src/js/containers';
58
- const routeTransformerPath = path.join(__dirname, "./", 'transformers/createRoute.js')
59
- const reducerTransformerPath = path.join(__dirname, "./", 'transformers/createReducer.js');
60
-
61
- const funcArgs = { containersDir, componentName, routePath, reducerName, templateType, reducerTransformerPath, routeTransformerPath }
68
+ const containersDir = "src/js/containers"
69
+ const routeTransformerPath = path.join(__dirname, "./", "transformers/createRoute.js")
70
+ const reducerTransformerPath = path.join(__dirname, "./", "transformers/createReducer.js")
71
+
72
+ const funcArgs = {
73
+ containersDir,
74
+ componentName,
75
+ routePath,
76
+ reducerName,
77
+ templateType,
78
+ reducerTransformerPath,
79
+ routeTransformerPath,
80
+ }
62
81
 
63
- // create directory
82
+ // create directory
64
83
  if (createDirectory(funcArgs)) {
65
-
66
84
  try {
67
-
68
85
  checkIfRoutePathExist(funcArgs)
69
86
 
70
87
  if (templateType === "none") {
@@ -84,15 +101,13 @@ async function main() {
84
101
  createReducerEntryInStore(funcArgs)
85
102
  }
86
103
 
87
- createNewRoute(funcArgs);
88
-
104
+ createNewRoute(funcArgs)
89
105
  } catch (e) {
90
106
  discardChanges(funcArgs)
91
107
  console.log(pc.red(`\n${e}`))
92
108
  }
93
109
  }
94
-
95
110
  }
96
111
  }
97
112
 
98
- main();
113
+ main()
@@ -4,8 +4,7 @@ const pc = require("picocolors")
4
4
 
5
5
  // Function to create component using given input
6
6
  function createNewComponent({ componentName, containersDir }) {
7
-
8
- const componentPath = path.join(containersDir, `${componentName}/${componentName}.js`);
7
+ const componentPath = `${containersDir}${path.sep}${componentName}${path.sep}${componentName}.js`
9
8
 
10
9
  // Component template
11
10
  const componentTemplate = `import React from 'react';
@@ -20,16 +19,15 @@ function createNewComponent({ componentName, containersDir }) {
20
19
  };
21
20
 
22
21
  export default ${componentName};
23
- `;
22
+ `
24
23
 
25
- fs.writeFileSync(componentPath, componentTemplate, 'utf8');
26
- console.log(`\n${pc.cyan(componentName)} component created at ${pc.gray(componentPath)}`);
24
+ fs.writeFileSync(componentPath, componentTemplate, "utf8")
25
+ console.log(`\n${pc.cyan(componentName)} component created at ${pc.gray(componentPath)}`)
27
26
  }
28
27
 
29
-
30
28
  // Function to create rtk reducer file using given input
31
29
  function createRTKReducerFile({ componentName, containersDir, reducerName }) {
32
- const reducerPath = path.join(containersDir, `${componentName}/reducer.js`);
30
+ const reducerPath = `${containersDir}${path.sep}${componentName}${path.sep}reducer.js`
33
31
 
34
32
  // rtk reducer template
35
33
  const reducerTemplate = `import { createSlice } from "@reduxjs/toolkit"
@@ -50,16 +48,15 @@ export const appSlice = createSlice({
50
48
 
51
49
  export const { reduxTest } = appSlice.actions
52
50
  export const ${reducerName}Reducer = appSlice.reducer
53
- `;
51
+ `
54
52
 
55
- fs.writeFileSync(reducerPath, reducerTemplate, 'utf8');
56
- console.log(`\n${pc.cyan("reducer.js")} file created at ${pc.gray(reducerPath)} `);
53
+ fs.writeFileSync(reducerPath, reducerTemplate, "utf8")
54
+ console.log(`\n${pc.cyan("reducer.js")} file created at ${pc.gray(reducerPath)} `)
57
55
  }
58
56
 
59
-
60
57
  // Function to create redux action file using given input
61
58
  function createReduxActionFile({ componentName, containersDir, reducerName }) {
62
- const actionsPath = path.join(containersDir, `${componentName}/actions.js`);
59
+ const actionsPath = `${containersDir}${path.sep}${componentName}${path.sep}actions.js`
63
60
 
64
61
  // redux action template
65
62
  const actionTemplate = `const createActionTypes = (prefix, actionTypeList = []) => {
@@ -79,16 +76,15 @@ export const reduxTest = () => {
79
76
  type: ${reducerName}Actions.REDUX_TEST,
80
77
  }
81
78
  }
82
- `;
83
-
84
- fs.writeFileSync(actionsPath, actionTemplate, 'utf8');
85
- console.log(`\n${pc.cyan("action.js")} file created at ${pc.gray(actionsPath)} `);
79
+ `
86
80
 
81
+ fs.writeFileSync(actionsPath, actionTemplate, "utf8")
82
+ console.log(`\n${pc.cyan("action.js")} file created at ${pc.gray(actionsPath)} `)
87
83
  }
88
84
 
89
85
  // Function to create redux reducer file using given input
90
86
  function createReduxReducerFile({ componentName, containersDir, reducerName }) {
91
- const reducerPath = path.join(containersDir, `${componentName}/reducer.js`);
87
+ const reducerPath = `${containersDir}${path.sep}${componentName}${path.sep}reducer.js`
92
88
 
93
89
  // redux reducer template
94
90
  const reducerTemplate = `import { ${reducerName}Actions } from "./actions"
@@ -110,10 +106,10 @@ export const ${reducerName}Reducer = (state = defaultState, action) => {
110
106
  return state
111
107
  }
112
108
  }
113
- `;
109
+ `
114
110
 
115
- fs.writeFileSync(reducerPath, reducerTemplate, 'utf8');
116
- console.log(`\n${pc.cyan("reducer.js")} file created at ${pc.gray(reducerPath)} `);
111
+ fs.writeFileSync(reducerPath, reducerTemplate, "utf8")
112
+ console.log(`\n${pc.cyan("reducer.js")} file created at ${pc.gray(reducerPath)} `)
117
113
  }
118
114
 
119
- module.exports = { createNewComponent, createRTKReducerFile, createReduxActionFile, createReduxReducerFile }
115
+ module.exports = { createNewComponent, createRTKReducerFile, createReduxActionFile, createReduxReducerFile }
@@ -1,38 +1,38 @@
1
1
  const pc = require("picocolors")
2
2
 
3
3
  module.exports = function (fileInfo, api, options) {
4
- const jscodeshift = api.jscodeshift;
5
- const root = jscodeshift(fileInfo.source);
4
+ const jscodeshift = api.jscodeshift
5
+ const root = jscodeshift(fileInfo.source)
6
6
 
7
- const { componentName, reducerName } = options;
7
+ const { componentName, reducerName } = options
8
8
 
9
9
  // Insert the node at the top of the file
10
- root.find(jscodeshift.Program).get('body', 0).insertBefore(`import { ${reducerName}Reducer } from '@containers/${componentName}/reducer.js'`);
10
+ root.find(jscodeshift.Program)
11
+ .get("body", 0)
12
+ .insertBefore(`import { ${reducerName}Reducer } from '@containers/${componentName}/reducer.js'`)
11
13
 
12
14
  root.find(jscodeshift.CallExpression, {
13
15
  callee: {
14
- name: 'combineReducers'
15
- }
16
- }).forEach(path => {
17
- const args = path.value.arguments;
18
- if (args.length > 0 && args[0].type === 'ObjectExpression') {
16
+ name: "combineReducers",
17
+ },
18
+ }).forEach((path) => {
19
+ const args = path.value.arguments
20
+ if (args.length > 0 && args[0].type === "ObjectExpression") {
19
21
  args[0].properties.push(
20
22
  jscodeshift.property(
21
- 'init',
23
+ "init",
22
24
  jscodeshift.identifier(`${reducerName}Reducer`),
23
25
  jscodeshift.identifier(`${reducerName}Reducer`)
24
26
  )
25
- );
26
- args[0].properties.forEach(property => {
27
+ )
28
+ args[0].properties.forEach((property) => {
27
29
  if (property.key.name === property.value.name) {
28
- property.shorthand = true;
30
+ property.shorthand = true
29
31
  }
30
- });
32
+ })
31
33
  }
32
34
  })
33
35
 
34
- console.log(`\nReducer added in ${pc.gray("src/js/store/index.js")}`);
35
- return root.toSource();
36
-
37
- };
38
-
36
+ console.log(`\nReducer added in ${pc.gray("src/js/store/index.js")}`)
37
+ return root.toSource()
38
+ }
@@ -1,10 +1,10 @@
1
1
  const pc = require("picocolors")
2
2
 
3
3
  module.exports = function (fileInfo, api, options) {
4
- const jscodeshift = api.jscodeshift;
5
- const root = jscodeshift(fileInfo.source);
4
+ const jscodeshift = api.jscodeshift
5
+ const root = jscodeshift(fileInfo.source)
6
6
 
7
- const { routePath, componentName } = options;
7
+ const { routePath, componentName } = options
8
8
 
9
9
  // Create a new route object using a template expression
10
10
  const newObject = jscodeshift.template.expression`
@@ -13,21 +13,20 @@ module.exports = function (fileInfo, api, options) {
13
13
  end: true,
14
14
  component: ${componentName}
15
15
  }
16
- `;
16
+ `
17
17
 
18
18
  // Insert the node at the top of the file
19
- root.find(jscodeshift.Program).get('body', 0).insertBefore(`import ${componentName} from '@containers/${componentName}/${componentName}'`);
20
-
21
- root.find(jscodeshift.VariableDeclarator, { id: { name: 'routes' } })
22
- .forEach(path => {
23
- // Ensure we are modifying the top-level array expression
24
- if (path.value.init.type === 'ArrayExpression') {
25
- path.value.init.elements.push(newObject);
26
- }
27
- });
28
-
29
- console.log(pc.green('\nNew route added successfully.'));
30
- return root.toSource();
31
-
32
- };
33
-
19
+ root.find(jscodeshift.Program)
20
+ .get("body", 0)
21
+ .insertBefore(`import ${componentName} from '@containers/${componentName}/${componentName}'`)
22
+
23
+ root.find(jscodeshift.VariableDeclarator, { id: { name: "routes" } }).forEach((path) => {
24
+ // Ensure we are modifying the top-level array expression
25
+ if (path.value.init.type === "ArrayExpression") {
26
+ path.value.init.elements.push(newObject)
27
+ }
28
+ })
29
+
30
+ console.log(pc.green("\nNew route added successfully."))
31
+ return root.toSource()
32
+ }
@@ -1,41 +1,45 @@
1
1
  const fs = require("fs")
2
2
  const path = require("path")
3
3
  const pc = require("picocolors")
4
- const { execSync } = require('child_process');
4
+ const { execFileSync } = require("child_process")
5
+
6
+ const executable = (command) => (process.platform === "win32" ? `${command}.cmd` : command)
5
7
 
6
8
  // validates router path
7
9
  function validatePath(path) {
8
- const pathPattern = /^\/[a-zA-Z0-9-_]+(?:\/:[a-zA-Z0-9-_]+)?(?:\?[a-zA-Z0-9-_=]*)?$/;
10
+ const pathPattern = /^\/[a-zA-Z0-9-_]+(?:\/:[a-zA-Z0-9-_]+)?(?:\?[a-zA-Z0-9-_=]*)?$/
9
11
 
10
- if (!path.startsWith('/')) {
11
- return "The path must start with a forward slash (`/`).";
12
+ if (!path.startsWith("/")) {
13
+ return "The path must start with a forward slash (`/`)."
12
14
  }
13
15
  if (!pathPattern.test(path)) {
14
16
  if (!/^[\/a-zA-Z0-9-_]+/.test(path)) {
15
17
  s
16
- return "Only letters, digits, hyphens, and underscores are allowed after the initial slash.";
18
+ return "Only letters, digits, hyphens, and underscores are allowed after the initial slash."
17
19
  }
18
20
  if (/\/[^:][a-zA-Z0-9-_]+/.test(path)) {
19
- return "Parameters must start with a slash and a colon, followed by valid characters.";
21
+ return "Parameters must start with a slash and a colon, followed by valid characters."
20
22
  }
21
23
  if (/\?[^a-zA-Z0-9-_=]*$/.test(path)) {
22
- return "Query strings must start with a question mark and contain valid characters.";
24
+ return "Query strings must start with a question mark and contain valid characters."
23
25
  }
24
- return "The path is incorrectly formatted.";
26
+ return "The path is incorrectly formatted."
25
27
  }
26
- return true;
28
+ return true
27
29
  }
28
30
 
29
31
  // validates component name
30
32
  function validateComponentName(name) {
31
- return /^[A-Z][a-zA-Z0-9]*$/.test(name) || "Component name should start with an uppercase letter and may contain alphanumeric characters";
33
+ return (
34
+ /^[A-Z][a-zA-Z0-9]*$/.test(name) ||
35
+ "Component name should start with an uppercase letter and may contain alphanumeric characters"
36
+ )
32
37
  }
33
38
 
34
-
35
39
  // discard changes if anything breaks
36
40
  function discardChanges({ componentName, containersDir }) {
37
41
  if (fs.existsSync(`${containersDir}/${componentName}`)) {
38
- fs.rmSync(`${containersDir}/${componentName}`, { recursive: true, force: true });
42
+ fs.rmSync(`${containersDir}/${componentName}`, { recursive: true, force: true })
39
43
  }
40
44
  }
41
45
 
@@ -44,14 +48,13 @@ function createDirectory({ componentName, containersDir }) {
44
48
  try {
45
49
  // directory check
46
50
  if (fs.existsSync(`${containersDir}/${componentName}`)) {
47
- throw new Error("directory with similar name already exist");
51
+ throw new Error("directory with similar name already exist")
48
52
  }
49
53
 
50
54
  fs.mkdirSync(`${containersDir}/${componentName}`)
51
- console.log(`\n${pc.cyan(componentName)} directory created at ${pc.gray(containersDir)}`);
55
+ console.log(`\n${pc.cyan(componentName)} directory created at ${pc.gray(containersDir)}`)
52
56
 
53
57
  return true
54
-
55
58
  } catch (e) {
56
59
  console.log(pc.red(`\nError: ${e}`))
57
60
  }
@@ -59,24 +62,50 @@ function createDirectory({ componentName, containersDir }) {
59
62
 
60
63
  // adds route object inside src/js/route/index.js file
61
64
  function createNewRoute({ componentName, routePath, routeTransformerPath }) {
62
- const command = `jscodeshift --silent -t ${routeTransformerPath} --routePath ${routePath} --componentName ${componentName} src/js/routes/index.js`;
63
- execSync(command, { stdio: 'inherit' });
65
+ execFileSync(
66
+ executable("jscodeshift"),
67
+ [
68
+ "--silent",
69
+ "-t",
70
+ routeTransformerPath,
71
+ "--routePath",
72
+ routePath,
73
+ "--componentName",
74
+ componentName,
75
+ "src/js/routes/index.js",
76
+ ],
77
+ { stdio: "inherit" }
78
+ )
64
79
  }
65
80
 
66
81
  // adds newly created reducer into src/js/store/index.js file
67
82
  function createReducerEntryInStore({ componentName, routePath, reducerTransformerPath, reducerName }) {
68
- const command = `jscodeshift --silent -t ${reducerTransformerPath} --reducerName ${reducerName} --routePath ${routePath} --componentName ${componentName} src/js/store/index.js`;
69
- execSync(command, { stdio: 'inherit' });
83
+ execFileSync(
84
+ executable("jscodeshift"),
85
+ [
86
+ "--silent",
87
+ "-t",
88
+ reducerTransformerPath,
89
+ "--reducerName",
90
+ reducerName,
91
+ "--routePath",
92
+ routePath,
93
+ "--componentName",
94
+ componentName,
95
+ "src/js/store/index.js",
96
+ ],
97
+ { stdio: "inherit" }
98
+ )
70
99
  }
71
100
 
72
101
  // converts string to camel case
73
102
  function toCamelCase(str) {
74
- return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (match, chr) => chr.toUpperCase());
103
+ return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (match, chr) => chr.toUpperCase())
75
104
  }
76
105
 
77
- function checkIfRoutePathExist({routePath, componentName}) {
78
- const routeIndexPath = "src/js/routes/index.js";
79
- const data = fs.readFileSync(routeIndexPath, 'utf8')
106
+ function checkIfRoutePathExist({ routePath, componentName }) {
107
+ const routeIndexPath = "src/js/routes/index.js"
108
+ const data = fs.readFileSync(routeIndexPath, "utf8")
80
109
  // Check if the file content includes routePath
81
110
  if (data.includes(routePath)) {
82
111
  throw new Error(`${routePath} path already exist in src/js/routes/index.js`)
@@ -87,4 +116,13 @@ function checkIfRoutePathExist({routePath, componentName}) {
87
116
  }
88
117
  }
89
118
 
90
- module.exports = { validatePath, validateComponentName, discardChanges, createReducerEntryInStore, createNewRoute, createDirectory, toCamelCase, checkIfRoutePathExist }
119
+ module.exports = {
120
+ validatePath,
121
+ validateComponentName,
122
+ discardChanges,
123
+ createReducerEntryInStore,
124
+ createNewRoute,
125
+ createDirectory,
126
+ toCamelCase,
127
+ checkIfRoutePathExist,
128
+ }
package/package.json CHANGED
@@ -1,17 +1,25 @@
1
1
  {
2
2
  "name": "create-catalyst-app",
3
3
  "bin": "scripts/cli.cjs",
4
- "version": "0.1.0-canary.8",
4
+ "version": "0.2.0-beta.1",
5
5
  "description": "cli package to scaffold Catalyst application",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/tata1mg/catalyst-core.git",
9
+ "directory": "packages/create-catalyst-app"
10
+ },
11
+ "scripts": {
12
+ "prettify": "prettier . --write"
13
+ },
6
14
  "dependencies": {
7
15
  "commander": "^8.2.0",
8
16
  "fs": "^0.0.1-security",
9
17
  "https": "^1.0.0",
18
+ "jscodeshift": "^0.16.0",
10
19
  "picocolors": "^0.1.0",
11
20
  "prompts": "^2.4.0",
12
- "tar": "^6.2.1",
13
- "validate-npm-package-name": "^5.0.0",
14
- "jscodeshift": "^0.16.0"
21
+ "tar": "^7.5.19",
22
+ "validate-npm-package-name": "^5.0.0"
15
23
  },
16
24
  "devDependencies": {
17
25
  "prettier": "^3.2.5"
package/scripts/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const { execSync } = require("child_process")
2
+ const { execFileSync, execSync } = require("child_process")
3
3
  const Commander = require("commander")
4
4
  const { Option } = require("commander")
5
5
  const prompts = require("prompts")
@@ -9,6 +9,8 @@ const path = require("path")
9
9
  const fs = require("fs")
10
10
  var validate = require("validate-npm-package-name")
11
11
  const packageJson = require("../package.json")
12
+ const packageRoot = path.join(__dirname, "..")
13
+ const executable = (command) => (process.platform === "win32" ? `${command}.cmd` : command)
12
14
 
13
15
  let projectName = null
14
16
  const program = new Commander.Command()
@@ -43,11 +45,6 @@ const program = new Commander.Command()
43
45
  return
44
46
  }
45
47
 
46
- if (process.argv.includes("mcp-setup")) {
47
- execSync(` cd ${projectName} && node node_modules/catalyst-core/mcp_v2/setup.js`, { stdio: "inherit" })
48
- return
49
- }
50
-
51
48
  console.log(cyan(`Using create-catalyst-app version ${bold(packageJson.version)}`))
52
49
 
53
50
  // Use options provided through commander or prompt the user
@@ -123,10 +120,6 @@ const program = new Commander.Command()
123
120
  })
124
121
  }
125
122
 
126
- if (mcpSupport) {
127
- execSync(` cd ${projectName} && node node_modules/catalyst-core/mcp_v2/setup.js`, { stdio: "inherit" })
128
- }
129
-
130
123
  execSync(
131
124
  `cd ${projectName} && git add . && git commit -m "initial commit from Create Catalyst App"`,
132
125
  {
@@ -148,6 +141,17 @@ const program = new Commander.Command()
148
141
 
149
142
  console.log("\nWe suggest you to begin, by running")
150
143
  console.log(` ${cyan("cd")} ${projectName} && ${cyan("npm start")} \n\n`)
144
+
145
+ if (mcpSupport) {
146
+ const newMcpDir = path.join(
147
+ process.cwd(),
148
+ projectName,
149
+ "node_modules",
150
+ "catalyst-core",
151
+ "mcp_v2"
152
+ )
153
+ runMcpSetup(newMcpDir, path.join(process.cwd(), projectName))
154
+ }
151
155
  } catch (error) {
152
156
  console.error(`Error: ${error.message}`)
153
157
  process.exit(1)
@@ -157,17 +161,26 @@ const program = new Commander.Command()
157
161
  })()
158
162
  function packNpmPackage(packageName, packageVersion, tempDir) {
159
163
  const tarballFileName = `${packageName}-${packageVersion}.tgz`
160
- const tarballFilePath = path.join(tempDir, tarballFileName)
164
+ const tarballFilePath = `${tempDir}${path.sep}${tarballFileName}`
161
165
 
162
166
  try {
163
- execSync(`npm pack ${packageName}@${packageVersion} --silent`, {
164
- cwd: tempDir,
165
- })
166
-
167
- // to test locally, comment the upper execSync and uncomment this one.
168
- // execSync(`npm pack --pack-destination=${tempDir} --silent`, {
169
- // cwd: process.cwd(),
170
- // })
167
+ if (process.env.CREATE_CATALYST_APP_PACK_SOURCE === "local") {
168
+ execFileSync(
169
+ executable("npm"),
170
+ ["pack", `--pack-destination=${tempDir}`, "--silent"],
171
+ {
172
+ cwd: packageRoot,
173
+ }
174
+ )
175
+ } else {
176
+ execFileSync(
177
+ executable("npm"),
178
+ ["pack", `${packageName}@${packageVersion}`, "--silent"],
179
+ {
180
+ cwd: tempDir,
181
+ }
182
+ )
183
+ }
171
184
 
172
185
  return tarballFilePath
173
186
  } catch (error) {
@@ -189,22 +202,20 @@ const program = new Commander.Command()
189
202
  tar.extract({
190
203
  file: packageFilePath,
191
204
  sync: true,
192
- filter: (path, entry) => {
193
- return subDirectoriesToExtract.reduce((acc, item) => {
194
- return acc || path.startsWith(item)
195
- }, false)
196
- },
197
205
  cwd: path.join(process.cwd()),
198
- onentry: (entry) => {
206
+ filter: (entryPath, entry) => {
207
+ const shouldExtract = subDirectoriesToExtract.reduce((acc, item) => {
208
+ return acc || entryPath.startsWith(item)
209
+ }, false)
210
+ if (!shouldExtract) return false
199
211
  if (entry.path.startsWith(commonCodeDirectory)) {
200
212
  entry.path = entry.path.replace(commonCodeDirectory, extractionDestination)
201
- }
202
- if (entry.path.startsWith(selectedTemplateCode)) {
213
+ } else if (entry.path.startsWith(selectedTemplateCode)) {
203
214
  entry.path = entry.path.replace(selectedTemplateCode, extractionDestination)
204
- }
205
- if (entry.path.startsWith(tailwindCodeDirectory)) {
215
+ } else if (entry.path.startsWith(tailwindCodeDirectory)) {
206
216
  entry.path = entry.path.replace(tailwindCodeDirectory, extractionDestination)
207
217
  }
218
+ return true
208
219
  },
209
220
  })
210
221
  } catch (e) {
@@ -220,8 +231,69 @@ const program = new Commander.Command()
220
231
  })
221
232
  .allowUnknownOption()
222
233
 
234
+ program
235
+ .command("catalyst-mcp")
236
+ .description("Set up MCP server in an existing catalyst project")
237
+ .action(() => {
238
+ try {
239
+ const mcpDir = path.join(process.cwd(), "node_modules", "catalyst-core", "mcp_v2")
240
+ const setupPath = path.join(mcpDir, "setup.js")
241
+
242
+ if (!fs.existsSync(setupPath)) {
243
+ console.log(cyan("mcp_v2 not found in catalyst-core. Downloading from GitHub..."))
244
+ const catalystCoreDir = path.join(process.cwd(), "node_modules", "catalyst-core")
245
+ const tarballUrl = "https://github.com/tata1mg/catalyst-core/archive/refs/heads/main.tar.gz"
246
+ const tarballPath = path.join(catalystCoreDir, "_mcp_v2_tarball.tar.gz")
247
+ const repoMcpDir = "catalyst-core-main/packages/catalyst-core/mcp_v2"
248
+ execSync(`curl -fsSL "${tarballUrl}" -o "${tarballPath}"`, { stdio: "inherit" })
249
+ fs.mkdirSync(mcpDir, { recursive: true })
250
+ tar.extract({
251
+ file: tarballPath,
252
+ cwd: mcpDir,
253
+ sync: true,
254
+ strip: 4,
255
+ filter: (entryPath) => entryPath === repoMcpDir || entryPath.startsWith(`${repoMcpDir}/`),
256
+ })
257
+ fs.unlinkSync(tarballPath)
258
+ console.log(cyan("mcp_v2 downloaded successfully."))
259
+ }
260
+
261
+ runMcpSetup(mcpDir)
262
+ } catch (error) {
263
+ console.error(red("An error occurred:"), error.message)
264
+ process.exit(1)
265
+ }
266
+ })
267
+
223
268
  program.parse(process.argv)
224
269
 
270
+ function runMcpSetup(mcpDir, cwd = process.cwd()) {
271
+ const pkgPath = `${mcpDir}${path.sep}package.json`
272
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"))
273
+ pkg.dependencies["better-sqlite3"] = "^12.8.0"
274
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2))
275
+
276
+ const mcpNodeModules = `${mcpDir}${path.sep}node_modules`
277
+ let needsInstall = !fs.existsSync(mcpNodeModules)
278
+
279
+ if (!needsInstall) {
280
+ try {
281
+ execSync(`node -e "require('better-sqlite3')"`, { cwd: mcpDir, stdio: "pipe" })
282
+ } catch {
283
+ console.log(cyan("Detected incompatible better-sqlite3 build. Reinstalling..."))
284
+ fs.rmSync(mcpNodeModules, { recursive: true, force: true })
285
+ needsInstall = true
286
+ }
287
+ }
288
+
289
+ if (needsInstall) {
290
+ console.log(cyan("Installing mcp_v2 dependencies..."))
291
+ execSync("npm install", { cwd: mcpDir, stdio: "inherit" })
292
+ }
293
+
294
+ execFileSync(process.execPath, [`${mcpDir}${path.sep}setup.js`], { cwd, stdio: "inherit" })
295
+ }
296
+
225
297
  async function promptStateManagement() {
226
298
  const response = await prompts({
227
299
  type: "select",
@@ -332,7 +404,7 @@ function validateOptions(cmd) {
332
404
  function deleteDirectory(dirPath) {
333
405
  if (dirPath && fs.existsSync(dirPath)) {
334
406
  fs.readdirSync(dirPath).forEach((file) => {
335
- const currentPath = path.join(dirPath, file)
407
+ const currentPath = `${dirPath}${path.sep}${file}`
336
408
  if (fs.lstatSync(currentPath).isDirectory()) {
337
409
  deleteDirectory(currentPath)
338
410
  } else {
@@ -347,7 +419,7 @@ function deleteDirectory(dirPath) {
347
419
  function createGitignore(projectName) {
348
420
  const gitiIgnorePatterns = ["node_modules", "build", "logs"]
349
421
 
350
- const gitignorePath = path.join(process.cwd(), projectName, ".gitignore")
422
+ const gitignorePath = `${process.cwd()}${path.sep}${projectName}${path.sep}.gitignore`
351
423
 
352
424
  if (fs.existsSync(gitignorePath)) {
353
425
  console.log(".gitignore already exists. Please rename or remove it before running the script.")
@@ -4,13 +4,12 @@ const fetchFunction = (url, options) => {
4
4
 
5
5
  // Request Interceptor - modify request here
6
6
 
7
- return fetch(finalUrl, options)
8
- .then(response => {
9
- return response.json().then(parsedResponse => {
10
- // Response Interceptor - modify response here
11
- return parsedResponse
12
- })
7
+ return fetch(finalUrl, options).then((response) => {
8
+ return response.json().then((parsedResponse) => {
9
+ // Response Interceptor - modify response here
10
+ return parsedResponse
13
11
  })
12
+ })
14
13
  }
15
14
 
16
15
  export default fetchFunction
@@ -25,12 +25,28 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@loadable/component": "^5.16.3",
28
- "@tata1mg/router": "0.0.1-beta.7",
29
- "catalyst-core": "0.1.0-canary.7"
28
+ "@tata1mg/router": "0.1.0-beta",
29
+ "catalyst-core": "0.2.0-beta.1",
30
+ "react": "19.0.0",
31
+ "react-dom": "19.0.0"
30
32
  },
31
33
  "devDependencies": {
32
34
  "eslint": "^8.26.0",
33
35
  "eslint-plugin-react": "^7.34.1",
34
36
  "eslint-plugin-react-hooks": "^4.6.0"
37
+ },
38
+ "overrides": {
39
+ "react-helmet-async": {
40
+ "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
41
+ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
42
+ },
43
+ "@loadable/component": {
44
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
45
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
46
+ },
47
+ "@loadable/server": {
48
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
49
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
50
+ }
35
51
  }
36
52
  }
@@ -26,15 +26,31 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@loadable/component": "^5.16.3",
29
- "@tata1mg/router": "0.0.1-beta.7",
30
- "catalyst-core": "0.1.0-canary.7"
29
+ "@tata1mg/router": "0.1.0-beta",
30
+ "catalyst-core": "0.2.0-beta.1",
31
+ "react": "19.0.0",
32
+ "react-dom": "19.0.0"
31
33
  },
32
34
  "devDependencies": {
33
35
  "eslint": "^8.26.0",
34
36
  "typescript": "^5.8.3",
35
- "@types/react": "^18.2.0",
36
- "@types/react-dom": "^18.2.0",
37
+ "@types/react": "^19.0.0",
38
+ "@types/react-dom": "^19.0.0",
37
39
  "eslint-plugin-react": "^7.34.1",
38
40
  "eslint-plugin-react-hooks": "^4.6.0"
41
+ },
42
+ "overrides": {
43
+ "react-helmet-async": {
44
+ "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
45
+ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
46
+ },
47
+ "@loadable/component": {
48
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
49
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
50
+ },
51
+ "@loadable/server": {
52
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
53
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
54
+ }
39
55
  }
40
56
  }
@@ -26,14 +26,31 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@loadable/component": "^5.16.3",
29
- "@tata1mg/router": "0.0.1-beta.7",
30
- "catalyst-core": "0.1.0-canary.7",
31
- "@reduxjs/toolkit": "1.9.3",
32
- "react-redux": "^8.1.3"
29
+ "@tata1mg/router": "0.1.0-beta",
30
+ "@reduxjs/toolkit": "^2.9.0",
31
+ "react-redux": "^9.2.0",
32
+ "catalyst-core": "0.2.0-beta.1",
33
+ "react": "19.0.0",
34
+ "react-dom": "19.0.0",
35
+ "redux": "^5.0.1"
33
36
  },
34
37
  "devDependencies": {
35
38
  "eslint": "^8.26.0",
36
39
  "eslint-plugin-react": "^7.34.1",
37
40
  "eslint-plugin-react-hooks": "^4.6.0"
41
+ },
42
+ "overrides": {
43
+ "react-helmet-async": {
44
+ "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
45
+ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
46
+ },
47
+ "@loadable/component": {
48
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
49
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
50
+ },
51
+ "@loadable/server": {
52
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
53
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
54
+ }
38
55
  }
39
56
  }
@@ -27,17 +27,34 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@loadable/component": "^5.16.3",
30
- "@tata1mg/router": "0.0.1-beta.7",
31
- "catalyst-core": "0.1.0-canary.7",
32
- "@reduxjs/toolkit": "1.9.3",
33
- "react-redux": "^8.1.3"
30
+ "@tata1mg/router": "0.1.0-beta",
31
+ "@reduxjs/toolkit": "^2.9.0",
32
+ "react-redux": "^9.2.0",
33
+ "catalyst-core": "0.2.0-beta.1",
34
+ "react": "19.0.0",
35
+ "react-dom": "19.0.0",
36
+ "redux": "^5.0.1"
34
37
  },
35
38
  "devDependencies": {
36
39
  "eslint": "^8.26.0",
37
40
  "typescript": "^5.8.3",
38
- "@types/react": "^18.2.0",
39
- "@types/react-dom": "^18.2.0",
41
+ "@types/react": "^19.0.0",
42
+ "@types/react-dom": "^19.0.0",
40
43
  "eslint-plugin-react": "^7.34.1",
41
44
  "eslint-plugin-react-hooks": "^4.6.0"
45
+ },
46
+ "overrides": {
47
+ "react-helmet-async": {
48
+ "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
49
+ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
50
+ },
51
+ "@loadable/component": {
52
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
53
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
54
+ },
55
+ "@loadable/server": {
56
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
57
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
58
+ }
42
59
  }
43
60
  }
@@ -26,14 +26,31 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@loadable/component": "^5.16.3",
29
- "@tata1mg/router": "0.0.1-beta.7",
30
- "catalyst-core": "0.1.0-canary.7",
31
- "@reduxjs/toolkit": "1.9.3",
32
- "react-redux": "^8.1.3"
29
+ "@tata1mg/router": "0.1.0-beta",
30
+ "@reduxjs/toolkit": "^2.9.0",
31
+ "react-redux": "^9.2.0",
32
+ "catalyst-core": "0.2.0-beta.1",
33
+ "react": "19.0.0",
34
+ "react-dom": "19.0.0",
35
+ "redux": "^5.0.1"
33
36
  },
34
37
  "devDependencies": {
35
38
  "eslint": "^8.26.0",
36
39
  "eslint-plugin-react": "^7.34.1",
37
40
  "eslint-plugin-react-hooks": "^4.6.0"
41
+ },
42
+ "overrides": {
43
+ "react-helmet-async": {
44
+ "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
45
+ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
46
+ },
47
+ "@loadable/component": {
48
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
49
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
50
+ },
51
+ "@loadable/server": {
52
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
53
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
54
+ }
38
55
  }
39
56
  }
@@ -27,17 +27,34 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@loadable/component": "^5.16.3",
30
- "@tata1mg/router": "0.0.1-beta.7",
31
- "catalyst-core": "0.1.0-canary.7",
32
- "@reduxjs/toolkit": "1.9.3",
33
- "react-redux": "^8.1.3"
30
+ "@tata1mg/router": "0.1.0-beta",
31
+ "@reduxjs/toolkit": "^2.9.0",
32
+ "react-redux": "^9.2.0",
33
+ "catalyst-core": "0.2.0-beta.1",
34
+ "react": "19.0.0",
35
+ "react-dom": "19.0.0",
36
+ "redux": "^5.0.1"
34
37
  },
35
38
  "devDependencies": {
36
39
  "eslint": "^8.26.0",
37
40
  "typescript": "^5.8.3",
38
- "@types/react": "^18.2.0",
39
- "@types/react-dom": "^18.2.0",
41
+ "@types/react": "^19.0.0",
42
+ "@types/react-dom": "^19.0.0",
40
43
  "eslint-plugin-react": "^7.34.1",
41
44
  "eslint-plugin-react-hooks": "^4.6.0"
45
+ },
46
+ "overrides": {
47
+ "react-helmet-async": {
48
+ "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
49
+ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
50
+ },
51
+ "@loadable/component": {
52
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
53
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
54
+ },
55
+ "@loadable/server": {
56
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
57
+ "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
58
+ }
42
59
  }
43
60
  }