create-catalyst-app-internal 0.0.1-beta.67 → 0.0.1-beta.69
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.
- package/package.json +1 -1
- package/scripts/cli.cjs +37 -0
- package/templates/common/server/document.js +1 -1
- package/templates/mcp-root/mcp/context.md +509 -0
- package/templates/mcp-root/mcp/mcp.js +36 -0
- package/templates/none-js/client/index.js +1 -1
- package/templates/none-js/package.json +1 -1
- package/templates/none-ts/client/index.js +1 -1
- package/templates/none-ts/package.json +1 -1
- package/templates/redux-js/client/index.js +1 -1
- package/templates/redux-js/package.json +1 -1
- package/templates/redux-ts/client/index.js +1 -1
- package/templates/redux-ts/package.json +1 -1
- package/templates/rtk-js/client/index.js +1 -1
- package/templates/rtk-js/package.json +1 -1
- package/templates/rtk-ts/client/index.js +1 -1
- package/templates/rtk-ts/package.json +1 -1
package/package.json
CHANGED
package/scripts/cli.cjs
CHANGED
|
@@ -34,6 +34,7 @@ const program = new Commander.Command()
|
|
|
34
34
|
tailWindSupport: null,
|
|
35
35
|
description: null,
|
|
36
36
|
stateManagement: cmd.stateManagement,
|
|
37
|
+
mcpSupport: null,
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
if (process.argv.includes("new-route")) {
|
|
@@ -55,6 +56,7 @@ const program = new Commander.Command()
|
|
|
55
56
|
tailWindSupport: false,
|
|
56
57
|
description: "Default catalyst app",
|
|
57
58
|
stateManagement: "none",
|
|
59
|
+
mcpSupport: true,
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -74,6 +76,7 @@ const program = new Commander.Command()
|
|
|
74
76
|
const language = config.language || (await promptTypescript())
|
|
75
77
|
const tailWindSupport = config.tailWindSupport !== null || (await promptTailwind())
|
|
76
78
|
const stateManagement = config.stateManagement || (await promptStateManagement())
|
|
79
|
+
const mcpSupport = config.mcpSupport !== null || (await promptMcp())
|
|
77
80
|
|
|
78
81
|
// Define mapping of options to repository suffixes
|
|
79
82
|
const repositorySuffixes = {
|
|
@@ -90,9 +93,11 @@ const program = new Commander.Command()
|
|
|
90
93
|
const commonCodeDirectory = "package/templates/common"
|
|
91
94
|
const selectedTemplateCode = `package/templates/${repositorySuffixes[stateManagement]}-${repositorySuffixes[language]}`
|
|
92
95
|
const tailwindCodeDirectory = "package/templates/tailwind"
|
|
96
|
+
const mcpCodeDirectory = "package/templates/mcp-root"
|
|
93
97
|
|
|
94
98
|
const subDirectoriesToExtract = [commonCodeDirectory, selectedTemplateCode]
|
|
95
99
|
if (tailWindSupport) subDirectoriesToExtract.push(tailwindCodeDirectory)
|
|
100
|
+
if (mcpSupport) subDirectoriesToExtract.push(mcpCodeDirectory)
|
|
96
101
|
|
|
97
102
|
const extractionDestination = `/${projectName}/`
|
|
98
103
|
let tempDir
|
|
@@ -106,6 +111,7 @@ const program = new Commander.Command()
|
|
|
106
111
|
createGitignore(projectName)
|
|
107
112
|
|
|
108
113
|
if (tailWindSupport) setupTailwind(projectName)
|
|
114
|
+
if (mcpSupport) setupMcp(projectName)
|
|
109
115
|
|
|
110
116
|
execSync(
|
|
111
117
|
`cd ${projectName} && npm i && npm pkg set name=${projectName} ${projectDescription ? `description="${projectDescription}"` : ""} && git init --quiet && git add . && git commit -m "initial commit from Create Catalyst App"`,
|
|
@@ -183,6 +189,9 @@ const program = new Commander.Command()
|
|
|
183
189
|
if (entry.path.startsWith(tailwindCodeDirectory)) {
|
|
184
190
|
entry.path = entry.path.replace(tailwindCodeDirectory, extractionDestination)
|
|
185
191
|
}
|
|
192
|
+
if (entry.path.startsWith(mcpCodeDirectory)) {
|
|
193
|
+
entry.path = entry.path.replace(mcpCodeDirectory, extractionDestination)
|
|
194
|
+
}
|
|
186
195
|
},
|
|
187
196
|
})
|
|
188
197
|
} catch (e) {
|
|
@@ -278,6 +287,19 @@ async function promptTailwind() {
|
|
|
278
287
|
return response.tailwind
|
|
279
288
|
}
|
|
280
289
|
|
|
290
|
+
async function promptMcp() {
|
|
291
|
+
const response = await prompts({
|
|
292
|
+
type: "select",
|
|
293
|
+
name: "mcp",
|
|
294
|
+
message: "Would you like to setup an MCP server?",
|
|
295
|
+
choices: [
|
|
296
|
+
{ title: "Yes", value: true },
|
|
297
|
+
{ title: "No", value: false },
|
|
298
|
+
],
|
|
299
|
+
})
|
|
300
|
+
return response.mcp
|
|
301
|
+
}
|
|
302
|
+
|
|
281
303
|
async function setupTailwind(projectName) {
|
|
282
304
|
try {
|
|
283
305
|
const packageJsonPath = path.join(process.cwd(), projectName, "package.json")
|
|
@@ -294,6 +316,21 @@ async function setupTailwind(projectName) {
|
|
|
294
316
|
}
|
|
295
317
|
}
|
|
296
318
|
|
|
319
|
+
async function setupMcp(projectName) {
|
|
320
|
+
try {
|
|
321
|
+
const packageJsonPath = path.join(process.cwd(), projectName, "package.json")
|
|
322
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"))
|
|
323
|
+
packageJson.dependencies = {
|
|
324
|
+
...(packageJson.dependencies || {}),
|
|
325
|
+
"@modelcontextprotocol/sdk": "^1.12.3",
|
|
326
|
+
}
|
|
327
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
|
|
328
|
+
} catch (error) {
|
|
329
|
+
console.log("Error while setting up MCP:", error)
|
|
330
|
+
process.exit(1)
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
297
334
|
function validateOptions(cmd) {
|
|
298
335
|
// Validate language option
|
|
299
336
|
if (cmd.lang && !["js", "ts"].includes(cmd.lang.toLowerCase())) {
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
Catalyst Context
|
|
2
|
+
|
|
3
|
+
- Catalyst is a framework over react to build UIs
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
TITLE: Creating a new catalyst application
|
|
8
|
+
|
|
9
|
+
DESCRIPTION: A new catalyst app can be created using the create-catalyst-app CLI command
|
|
10
|
+
|
|
11
|
+
SOURCE: https://catalyst.1mg.com/public_docs/content/installation
|
|
12
|
+
|
|
13
|
+
LANGUAGE: bash
|
|
14
|
+
CODE:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
npx create-catalyst-app@latest -y
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
TITLE: Starting the catalyst application
|
|
25
|
+
|
|
26
|
+
DESCRIPTION: This snippet starts the catalyst development application, The application supports hot reloading
|
|
27
|
+
the application is typically served on `http://localhost:3005`
|
|
28
|
+
|
|
29
|
+
SOURCE: https://catalyst.1mg.com/public_docs/content/installation
|
|
30
|
+
|
|
31
|
+
LANGUAGE: bash
|
|
32
|
+
CODE:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
npm run start
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
TITLE: Adding routes in catalyst
|
|
43
|
+
|
|
44
|
+
DESCRIPTION:
|
|
45
|
+
|
|
46
|
+
- Catalyst uses @tata1mg/router package for routing, which is a wrapper around react-router
|
|
47
|
+
- Catalyst uses react-router-v6 based routing
|
|
48
|
+
- Routes are defined in "src/js/routes/index.js" file
|
|
49
|
+
- Pages are imported at top of this file
|
|
50
|
+
- A new entry in the routes array is added like this
|
|
51
|
+
|
|
52
|
+
SOURCE: https://catalyst.1mg.com/public_docs/content/Core%20Concepts/Routing/routing/index
|
|
53
|
+
|
|
54
|
+
LANGUAGE: js
|
|
55
|
+
CODE:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
{
|
|
59
|
+
path: "", // path of the page
|
|
60
|
+
end: false,
|
|
61
|
+
component: Page, // name of the page
|
|
62
|
+
},
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
TITLE: Navigation in catalyst
|
|
70
|
+
|
|
71
|
+
DESCRIPTION:
|
|
72
|
+
|
|
73
|
+
- Navigation in @tata1mg/router is based on react-router-v6, and client side navigation can be achieved through components like <Navigate> or <Link> or through hooks like useNavigate
|
|
74
|
+
|
|
75
|
+
LANGUAGE: js
|
|
76
|
+
CODE:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
import { useNavigate } from "@tata1mg/router"
|
|
80
|
+
const Page = () => {
|
|
81
|
+
const navigate = useNavigate()
|
|
82
|
+
return (
|
|
83
|
+
<div onClick={() => navigate("/about")}>Click to navigate</div>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
LANGUAGE: js
|
|
89
|
+
CODE:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
import { Link } from "@tata1mg/router"
|
|
93
|
+
const Page = () => {
|
|
94
|
+
const navigate = useNavigate()
|
|
95
|
+
return (
|
|
96
|
+
<Link to="/about">Click to navigate</Link>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- Navigation inside clientFetcher function can be achieved through the navigate property which is available as an argument in clientFetcher.
|
|
102
|
+
|
|
103
|
+
LANGUAGE: js
|
|
104
|
+
CODE:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Page.clientFetcher = async ({ navigate }) => {
|
|
108
|
+
navigate("/about")
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- Navigation inside serverFetcher function can also be achieved through the navigate property which is available as an argument in serverFetcher.
|
|
113
|
+
navigate available inside server fetcher is a wrapper around response.send() so it would result it server side navigation.
|
|
114
|
+
|
|
115
|
+
LANGUAGE: js
|
|
116
|
+
CODE:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
Page.serverFetcher = async ({ navigate }) => {
|
|
120
|
+
navigate("/about") // will be navigated to /about on the server
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
TITLE: Data fetching in catalyst
|
|
129
|
+
|
|
130
|
+
DESCRIPTION:
|
|
131
|
+
|
|
132
|
+
- Routes can fetch data using two primary functions:
|
|
133
|
+
|
|
134
|
+
1. **Client Fetcher**: Executes during client-side navigation or absence of **_server fetcher_**.
|
|
135
|
+
2. **Server Fetcher**: Executes during server-side rendering (SSR)
|
|
136
|
+
|
|
137
|
+
LANGUAGE: js
|
|
138
|
+
CODE:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
const Page = ()=> <div>Some Page</div>
|
|
142
|
+
|
|
143
|
+
// Client-side data fetching
|
|
144
|
+
Page.clientFetcher = (routerProps,fetcherArgs) => { return new Promise()}
|
|
145
|
+
|
|
146
|
+
// Server-side data fetching
|
|
147
|
+
Page.serverFetcher = (serverRouterProps,fetcherArgs) => { return new Promise()}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
clientFetcher will be called during client side navigation, when navigating through <Link/> or <Navigate> components or by using hooks like useNavigate provided by router.
|
|
151
|
+
|
|
152
|
+
LANGUAGE: js
|
|
153
|
+
CODE:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
Page.clientFetcher = async ({ route, location, params, searchParams, navigate }, { store }) => {
|
|
157
|
+
const res = await await fetch('<https://api.example.com/data>');
|
|
158
|
+
const json = await res.json();
|
|
159
|
+
return json;
|
|
160
|
+
};
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
serverFetcher will be called during the first fold request or when navigation is done by window.location.href or similar methods. It will only be called on the server and will not be included in the client bundle, so it is safe to use server only secrets in this function
|
|
164
|
+
|
|
165
|
+
LANGUAGE: js
|
|
166
|
+
CODE:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
Page.serverFunction = async ({ route, location, params, searchParams, navigate },{ store }) => {
|
|
170
|
+
const res = await fetch('<https://api.example.com/data>');
|
|
171
|
+
const json = await res.json();
|
|
172
|
+
return json;
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
useCurrentRouteData hook from @tata1mg/router returns the current router context object with data, error, isFetching, isFetched, refetch and clear properties.
|
|
177
|
+
|
|
178
|
+
LANGUAGE: js
|
|
179
|
+
CODE:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
import { useCurrentRouteData } from "@tata1mg/router"
|
|
183
|
+
const Home = () => {
|
|
184
|
+
const { isFetching, isFetched, error, data, refetch, clear } = useCurrentRouteData()
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
Home.clientFetcher = async () => {
|
|
188
|
+
return {status:200}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The useRouterData hook returns a router context object with data of all the fetchers in the current route tree.
|
|
193
|
+
|
|
194
|
+
refetch executes the client loader. A custom argument can be passed while calling it through refetch in client loader to handle use cases where the fetch function needs to access the application state like for pagination, infinite scroll, etc.
|
|
195
|
+
|
|
196
|
+
LANGUAGE: js
|
|
197
|
+
CODE:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
const Home = () => {
|
|
201
|
+
...
|
|
202
|
+
useEffect(()=>{
|
|
203
|
+
refetch({pageNo})
|
|
204
|
+
},[pageNo])
|
|
205
|
+
}
|
|
206
|
+
Home.clientFetcher = async ({},{},{pageNo}) => {
|
|
207
|
+
const res = await fetch(`some_url/${pageNo}`)
|
|
208
|
+
const json = await res.json()
|
|
209
|
+
return json
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The clear function clears the data for the particular route from where it is called.
|
|
214
|
+
|
|
215
|
+
LANGUAGE: js
|
|
216
|
+
CODE:
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
const Home = () => {
|
|
220
|
+
...
|
|
221
|
+
useEffect(()=>{
|
|
222
|
+
clear()
|
|
223
|
+
},[pathname])
|
|
224
|
+
|
|
225
|
+
//will clear data for this particular route on navigation
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
TITLE: Environment variables in catalyst
|
|
234
|
+
|
|
235
|
+
DESCRIPTION:
|
|
236
|
+
|
|
237
|
+
- Catalyst can be configured through a config/config.json file in the root of your project directory. You can define your keys to access them inside the project.
|
|
238
|
+
- These variables will be accessible through process.env[variable_name].
|
|
239
|
+
- Out of the complete contents of config/config.json, keys listed in CLIENT_ENV_KEYS are filtered and made available for the client side code.
|
|
240
|
+
- Any key that is listed in CLIENT_ENV_KEYS will be exposed on the client and can become a security issue. Be careful while adding keys
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
TITLE: App shell in catalyst
|
|
247
|
+
|
|
248
|
+
DESCRIPTION:
|
|
249
|
+
|
|
250
|
+
- Catalyst offers an app shell, which serves as a wrapper around your page code, enabling you to perform common operations required for all pages. You can access the app shell inside the src/js/containers/App directory under the src folder.
|
|
251
|
+
- All your pages will be rendered in this app shell. It will be the parent component for all your apps.
|
|
252
|
+
- The app shell provides you with a function called serverSideFunction, which you can use to perform any operations while rendering your page on the server. This function is similar to serverFetcher, which we define in the page component. The key distinction lies in the fact that serverSideFunction runs on each page request, whereas serverFetcher runs only when that specific page is requested.
|
|
253
|
+
|
|
254
|
+
LANGUAGE: js
|
|
255
|
+
CODE:
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
import React from "react"
|
|
259
|
+
import { Outlet } from "@tata1mg/router"
|
|
260
|
+
|
|
261
|
+
const App = () => {
|
|
262
|
+
return (
|
|
263
|
+
<>
|
|
264
|
+
<Outlet />
|
|
265
|
+
</>
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
App.serverSideFunction = ({store, req, res}) => {
|
|
270
|
+
return new Promise((resolve) => resolve())
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export default App
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
TITLE: Lifecycle methods in catalyst
|
|
281
|
+
|
|
282
|
+
DESCRIPTION:
|
|
283
|
+
|
|
284
|
+
- Catalyst provides several methods to handle different stages of the SSR lifecycle, allowing for more fine grain control over the flow
|
|
285
|
+
- Functions
|
|
286
|
+
1. preServerInit - Triggers before starting the server.
|
|
287
|
+
2. onServerError - Triggered if the SSR server fails to start or encounters a critical error. Useful for handling server initialization issues.
|
|
288
|
+
3. onRouteMatch - Called after route matching attempts, regardless of whether a match was found or not. This method enables you to handle both successful and failed route matches
|
|
289
|
+
4. onFetcherSuccess - Triggered after running a container's serverFetcher (currently running for both success and failure case)
|
|
290
|
+
5. onRenderError - Executes when the rendering process encounters an error. This allows you to handle any failures during component rendering.
|
|
291
|
+
6. onRequestError - Executes if any error occurs while handling the document request (think of it like the outer most catch block)
|
|
292
|
+
- All these functions can be defined in and exported from server/index.js
|
|
293
|
+
|
|
294
|
+
LANGUAGE: js
|
|
295
|
+
CODE:
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
export const preServerInit = () => {}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
TITLE: Adding middlewares on the server
|
|
306
|
+
|
|
307
|
+
DESCRIPTION:
|
|
308
|
+
|
|
309
|
+
- Catalyst offers a flexible approach to defining server-side code, granting you greater control and customization over server operations.
|
|
310
|
+
- To modify the server behavior, create a file named server.js within the server directory of your app.
|
|
311
|
+
- Define a function named addMiddlewares, which receives the app server instance as a parameter. Catalyst - provides this instance when executing the function on the server.
|
|
312
|
+
- Use the app parameter to configure middleware for your application.
|
|
313
|
+
|
|
314
|
+
LANGUAGE: js
|
|
315
|
+
File: server/server.js
|
|
316
|
+
CODE:
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
export function addMiddlewares(app) {
|
|
320
|
+
// server code
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
TITLE: Styling in catalyst
|
|
329
|
+
|
|
330
|
+
DESCRIPTION:
|
|
331
|
+
|
|
332
|
+
- Catalyst offers a variety of methods for styling your application
|
|
333
|
+
|
|
334
|
+
Global CSS
|
|
335
|
+
|
|
336
|
+
- Global styles can be imported into any layout, page, or component.
|
|
337
|
+
- Place all your global css in "/src/static/css/base"
|
|
338
|
+
- Placing css in "/src/static/css/base" would prevent it from being modularized as css-module is enabled by default in Catalyst
|
|
339
|
+
- Import these global css file in client/styles.js so that it can be available globally.
|
|
340
|
+
|
|
341
|
+
LANGUAGE: js
|
|
342
|
+
File: Home.js
|
|
343
|
+
CODE:
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
const Home = () => {
|
|
347
|
+
return <section className="marginTop-4">Home</section>
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
LANGUAGE: js
|
|
352
|
+
File: client/styles.js
|
|
353
|
+
CODE:
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
import "src/static/css/base/layout.css"
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
LANGUAGE: css
|
|
360
|
+
File: src/static/css/base/layout.css
|
|
361
|
+
CODE:
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
.marginTop-4 {
|
|
365
|
+
margin-top: 4px;
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
CSS modules
|
|
370
|
+
|
|
371
|
+
- Catalyst enables support for css-module out-of-the-box. CSS-modules locally scope CSS by creating unique names. This allows you to use same classnames in different files without worrying about naming conflicts.
|
|
372
|
+
|
|
373
|
+
LANGUAGE: js
|
|
374
|
+
CODE:
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
import css from "./styles.css"
|
|
378
|
+
|
|
379
|
+
const Home = () => {
|
|
380
|
+
return <section className={css.layout}>Home</section>
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Sass
|
|
385
|
+
|
|
386
|
+
- Catalyst includes out-of-the-box support for Sass. Utilize Sass in Catalyst with the .scss file extension.
|
|
387
|
+
- Place all mixins, variables, and other Sass resources in /src/static/css/resources. These will be automatically imported into your .scss files, allowing you to use these resources without manual imports.
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
TITLE: Code splitting in catalyst
|
|
394
|
+
|
|
395
|
+
DESCRIPTION:
|
|
396
|
+
|
|
397
|
+
- Catalyst utilizes loadable-components for efficient code splitting on both the client and server. It offers built-in support for code splitting, making it easy to split your code into smaller chunks.
|
|
398
|
+
|
|
399
|
+
LANGUAGE: js
|
|
400
|
+
CODE:
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
const Component = loadable(()=> import("@components/Component.js"),{
|
|
404
|
+
fallback: <div>Fallback</div>,
|
|
405
|
+
ssr:false
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
const App = () => {
|
|
409
|
+
return (
|
|
410
|
+
<Component />
|
|
411
|
+
);
|
|
412
|
+
};
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
TITLE: Module aliases in catalyst
|
|
420
|
+
|
|
421
|
+
DESCRIPTION:
|
|
422
|
+
|
|
423
|
+
- Catalyst supports module aliases to create shorter and more descriptive import paths for modules. This practice can make the codebase cleaner and more maintainable. Some module aliases come pre-configured when setting up Catalyst, making imports cleaner.
|
|
424
|
+
- To create module aliases, add \_moduleAliases key to package.json
|
|
425
|
+
|
|
426
|
+
LANGUAGE: JSON
|
|
427
|
+
CODE:
|
|
428
|
+
|
|
429
|
+
```
|
|
430
|
+
{
|
|
431
|
+
"_moduleAliases": {
|
|
432
|
+
"@api": "api.js",
|
|
433
|
+
"@containers": "src/js/containers",
|
|
434
|
+
"@server": "server",
|
|
435
|
+
"@config": "config",
|
|
436
|
+
"@css": "src/static/css",
|
|
437
|
+
"@routes": "src/js/routes/",
|
|
438
|
+
"@store": "src/js/store/index.js"
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
TITLE: Custom document
|
|
448
|
+
|
|
449
|
+
DESCRIPTION:
|
|
450
|
+
|
|
451
|
+
- The document is an HTML file served by the Node server whenever a page request is made. It contains the head, body, and all HTML tags.
|
|
452
|
+
- Custom Document enables ability to update these tags and render the data according to the needs.
|
|
453
|
+
- Head and Body tags are required and the application won't work without it. It is mandatory to pass props because they are used in Head and Body tags.
|
|
454
|
+
- Custom tags should be added between the Head and Body tags.
|
|
455
|
+
|
|
456
|
+
LANGUAGE: js
|
|
457
|
+
FILE: server/document.js
|
|
458
|
+
CODE:
|
|
459
|
+
|
|
460
|
+
```
|
|
461
|
+
import { Head, Body } from "catalyst"
|
|
462
|
+
|
|
463
|
+
function Document(props) {
|
|
464
|
+
return (
|
|
465
|
+
<html lang={props.lang}>
|
|
466
|
+
<Head {...props} />
|
|
467
|
+
<Body {...props} />
|
|
468
|
+
</html>
|
|
469
|
+
)
|
|
470
|
+
}
|
|
471
|
+
export default Document
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
TITLE: Webpack customization
|
|
479
|
+
|
|
480
|
+
DESCRIPTION:
|
|
481
|
+
|
|
482
|
+
- Catalyst provides ways to customize webpack configuration for specific needs through the webpackConfig.js file.
|
|
483
|
+
|
|
484
|
+
Catalyst allows customizing webpack's chunk splitting behavior through the splitChunksConfig option
|
|
485
|
+
LANGUAGE: js
|
|
486
|
+
CODE:
|
|
487
|
+
|
|
488
|
+
```
|
|
489
|
+
module.exports = {
|
|
490
|
+
splitChunksConfig: {
|
|
491
|
+
chunks: 'all',
|
|
492
|
+
minSize: 20000,
|
|
493
|
+
minChunks: 1,
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Some packages are distributed as ESM-only (ECMAScript Modules) and cannot be directly imported in Catalyst's CommonJS environment. To handle these packages, you can use the transpileModules option:
|
|
499
|
+
|
|
500
|
+
```
|
|
501
|
+
module.exports = {
|
|
502
|
+
transpileModules: [
|
|
503
|
+
'esm-only-package',
|
|
504
|
+
/@scope/another-esm-package/
|
|
505
|
+
]
|
|
506
|
+
};
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
---
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const fs = require("fs")
|
|
2
|
+
const path = require("path")
|
|
3
|
+
const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js")
|
|
4
|
+
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js")
|
|
5
|
+
|
|
6
|
+
const server = new McpServer({
|
|
7
|
+
name: "catalyst",
|
|
8
|
+
version: "1.0.0",
|
|
9
|
+
capabilities: {
|
|
10
|
+
tools: {},
|
|
11
|
+
},
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
server.tool("get_context", "Complete context of catalyst framework", {}, () => {
|
|
15
|
+
const context = fs.readFileSync(path.join(__dirname, "context.md"), "utf-8")
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: "text",
|
|
20
|
+
text: context,
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const init = async () => {
|
|
27
|
+
try {
|
|
28
|
+
const transport = new StdioServerTransport()
|
|
29
|
+
await server.connect(transport)
|
|
30
|
+
console.log("MCP Server Running!")
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error("Error starting MCP server:", error)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
init()
|
|
@@ -3,7 +3,7 @@ import "./styles"
|
|
|
3
3
|
import { hydrateRoot } from "react-dom/client"
|
|
4
4
|
import { loadableReady } from "@loadable/component"
|
|
5
5
|
import { RouterProvider } from "@tata1mg/router"
|
|
6
|
-
import clientRouter from "catalyst-core
|
|
6
|
+
import clientRouter from "catalyst-core/router/ClientRouter"
|
|
7
7
|
|
|
8
8
|
window.addEventListener("load", () => {
|
|
9
9
|
loadableReady(() => {
|
|
@@ -3,7 +3,7 @@ import "./styles"
|
|
|
3
3
|
import { hydrateRoot } from "react-dom/client"
|
|
4
4
|
import { loadableReady } from "@loadable/component"
|
|
5
5
|
import { RouterProvider } from "@tata1mg/router"
|
|
6
|
-
import clientRouter from "catalyst-core
|
|
6
|
+
import clientRouter from "catalyst-core/router/ClientRouter"
|
|
7
7
|
|
|
8
8
|
window.addEventListener("load", () => {
|
|
9
9
|
loadableReady(() => {
|
|
@@ -4,7 +4,7 @@ import { hydrateRoot } from "react-dom/client"
|
|
|
4
4
|
import { loadableReady } from "@loadable/component"
|
|
5
5
|
import { Provider } from "react-redux"
|
|
6
6
|
import { RouterProvider } from "@tata1mg/router"
|
|
7
|
-
import clientRouter from "catalyst-core
|
|
7
|
+
import clientRouter from "catalyst-core/router/ClientRouter"
|
|
8
8
|
import configureStore from "@store"
|
|
9
9
|
|
|
10
10
|
window.addEventListener("load", () => {
|
|
@@ -4,7 +4,7 @@ import { hydrateRoot } from "react-dom/client"
|
|
|
4
4
|
import { loadableReady } from "@loadable/component"
|
|
5
5
|
import { Provider } from "react-redux"
|
|
6
6
|
import { RouterProvider } from "@tata1mg/router"
|
|
7
|
-
import clientRouter from "catalyst-core
|
|
7
|
+
import clientRouter from "catalyst-core/router/ClientRouter"
|
|
8
8
|
import configureStore from "@store"
|
|
9
9
|
|
|
10
10
|
window.addEventListener("load", () => {
|
|
@@ -4,7 +4,7 @@ import { hydrateRoot } from "react-dom/client"
|
|
|
4
4
|
import { loadableReady } from "@loadable/component"
|
|
5
5
|
import { Provider } from "react-redux"
|
|
6
6
|
import { RouterProvider } from "@tata1mg/router"
|
|
7
|
-
import clientRouter from "catalyst-core
|
|
7
|
+
import clientRouter from "catalyst-core/router/ClientRouter"
|
|
8
8
|
import configureStore from "@store"
|
|
9
9
|
|
|
10
10
|
window.addEventListener("load", () => {
|
|
@@ -4,7 +4,7 @@ import { hydrateRoot } from "react-dom/client"
|
|
|
4
4
|
import { loadableReady } from "@loadable/component"
|
|
5
5
|
import { Provider } from "react-redux"
|
|
6
6
|
import { RouterProvider } from "@tata1mg/router"
|
|
7
|
-
import clientRouter from "catalyst-core
|
|
7
|
+
import clientRouter from "catalyst-core/router/ClientRouter"
|
|
8
8
|
import configureStore from "@store"
|
|
9
9
|
|
|
10
10
|
window.addEventListener("load", () => {
|