create-catalyst-app-internal 0.0.3-canary.9 → 0.1.0
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/Readme.md +2 -2
- package/package.json +1 -1
- package/scripts/cli.cjs +108 -8
- package/templates/common/config/config.json +5 -3
- package/templates/common/public/offline.html +56 -0
- package/templates/common/webpackConfig.js +1 -0
- package/templates/mcp-root/mcp/mcp.js +55 -0
- package/templates/none-js/package.json +4 -4
- package/templates/none-ts/client/index.js +23 -0
- package/templates/none-ts/package.json +40 -0
- package/templates/none-ts/src/js/containers/App/index.js +16 -0
- package/templates/none-ts/src/js/routes/utils.js +42 -0
- package/templates/none-ts/tsconfig.json +13 -0
- package/templates/none-ts/types.d.ts +4 -0
- package/templates/redux-js/package.json +4 -4
- package/templates/redux-ts/client/index.js +28 -0
- package/templates/redux-ts/package.json +43 -0
- package/templates/redux-ts/src/js/containers/App/actions.js +17 -0
- package/templates/redux-ts/src/js/containers/App/index.js +16 -0
- package/templates/redux-ts/src/js/containers/App/reducer.js +19 -0
- package/templates/redux-ts/src/js/routes/utils.js +42 -0
- package/templates/redux-ts/src/js/store/index.js +28 -0
- package/templates/redux-ts/tsconfig.json +13 -0
- package/templates/redux-ts/types.d.ts +4 -0
- package/templates/rtk-js/package.json +4 -4
- package/templates/rtk-ts/client/index.js +28 -0
- package/templates/rtk-ts/package.json +43 -0
- package/templates/rtk-ts/src/js/containers/App/index.js +16 -0
- package/templates/rtk-ts/src/js/containers/App/reducer.js +18 -0
- package/templates/rtk-ts/src/js/routes/utils.js +42 -0
- package/templates/rtk-ts/src/js/store/index.js +28 -0
- package/templates/rtk-ts/tsconfig.json +13 -0
- package/templates/rtk-ts/types.d.ts +4 -0
- package/templates/tailwind/postcss.config.js +5 -0
- package/templates/tailwind/src/static/css/base/index.scss +2 -0
package/Readme.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Creating a Catalyst App
|
|
2
2
|
|
|
3
|
-
Scaffold your Catalyst app swiftly with `create-catalyst-app
|
|
3
|
+
Scaffold your Catalyst app swiftly with `create-catalyst-app`. This tool expedites the process by initializing your project with predefined configurations. To kickstart your project, execute the following command:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npx create-catalyst-app
|
|
6
|
+
npx create-catalyst-app@latest
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Upon execution, you'll be prompted to name your project. Once named, a template will be cloned into the specified directory.
|
package/package.json
CHANGED
package/scripts/cli.cjs
CHANGED
|
@@ -17,6 +17,7 @@ const program = new Commander.Command()
|
|
|
17
17
|
.arguments("[folderName]")
|
|
18
18
|
.usage(`${green("[folderName]")} [options]`)
|
|
19
19
|
.action((name) => (projectName = name))
|
|
20
|
+
.addOption(new Option("-y, --yes [yes]", "Use default configuration"))
|
|
20
21
|
.addOption(
|
|
21
22
|
new Option(
|
|
22
23
|
"-s, --state-management [stateManagement]",
|
|
@@ -27,15 +28,39 @@ const program = new Commander.Command()
|
|
|
27
28
|
)
|
|
28
29
|
.action(async (folderName = null, cmd) => {
|
|
29
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
|
+
|
|
30
40
|
if (process.argv.includes("new-route")) {
|
|
31
41
|
const createRoutePath = path.join(__dirname, "../codemod/new-route/index.js")
|
|
32
42
|
execSync(`node ${createRoutePath}`, { stdio: "inherit" })
|
|
33
43
|
return
|
|
34
44
|
}
|
|
35
45
|
|
|
46
|
+
console.log(cyan(`Using create-catalyst-app version ${bold(packageJson.version)}`))
|
|
47
|
+
|
|
36
48
|
// Use options provided through commander or prompt the user
|
|
37
49
|
validateOptions(cmd)
|
|
38
|
-
|
|
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())
|
|
39
64
|
let isNameValid = validate(projectName)
|
|
40
65
|
if (!isNameValid.validForNewPackages) {
|
|
41
66
|
isNameValid?.warnings?.forEach?.((item) => console.log(red(item)))
|
|
@@ -47,9 +72,11 @@ const program = new Commander.Command()
|
|
|
47
72
|
console.log(red(`${projectName} already exists, try again.`))
|
|
48
73
|
process.exit(1)
|
|
49
74
|
}
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
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())
|
|
53
80
|
|
|
54
81
|
// Define mapping of options to repository suffixes
|
|
55
82
|
const repositorySuffixes = {
|
|
@@ -65,7 +92,13 @@ const program = new Commander.Command()
|
|
|
65
92
|
|
|
66
93
|
const commonCodeDirectory = "package/templates/common"
|
|
67
94
|
const selectedTemplateCode = `package/templates/${repositorySuffixes[stateManagement]}-${repositorySuffixes[language]}`
|
|
95
|
+
const tailwindCodeDirectory = "package/templates/tailwind"
|
|
96
|
+
const mcpCodeDirectory = "package/templates/mcp-root"
|
|
97
|
+
|
|
68
98
|
const subDirectoriesToExtract = [commonCodeDirectory, selectedTemplateCode]
|
|
99
|
+
if (tailWindSupport) subDirectoriesToExtract.push(tailwindCodeDirectory)
|
|
100
|
+
if (mcpSupport) subDirectoriesToExtract.push(mcpCodeDirectory)
|
|
101
|
+
|
|
69
102
|
const extractionDestination = `/${projectName}/`
|
|
70
103
|
let tempDir
|
|
71
104
|
;(() => {
|
|
@@ -78,10 +111,27 @@ const program = new Commander.Command()
|
|
|
78
111
|
createGitignore(projectName)
|
|
79
112
|
|
|
80
113
|
execSync(
|
|
81
|
-
`cd ${projectName} && npm i && npm pkg set name=${projectName} ${projectDescription ? `description="${projectDescription}"` : ""} && git init --quiet
|
|
114
|
+
`cd ${projectName} && npm i && npm pkg set name=${projectName} ${projectDescription ? `description="${projectDescription}"` : ""} && git init --quiet`,
|
|
82
115
|
{ stdio: "inherit" }
|
|
83
116
|
)
|
|
84
117
|
|
|
118
|
+
if (tailWindSupport) {
|
|
119
|
+
execSync(`cd ${projectName} && npm i tailwindcss@4.1.4 @tailwindcss/postcss@4.1.4`, {
|
|
120
|
+
stdio: "inherit",
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (mcpSupport) {
|
|
125
|
+
execSync(`cd ${projectName} && npm i @modelcontextprotocol/sdk`, { stdio: "inherit" })
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
execSync(
|
|
129
|
+
`cd ${projectName} && git add . && git commit -m "initial commit from Create Catalyst App"`,
|
|
130
|
+
{
|
|
131
|
+
stdio: "inherit",
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
|
|
85
135
|
console.log(`\n${green(bold("Success!"))} created ${projectName} at ${projectPath}`)
|
|
86
136
|
console.log("Inside this directory, you can run the following commands.")
|
|
87
137
|
|
|
@@ -114,8 +164,8 @@ const program = new Commander.Command()
|
|
|
114
164
|
|
|
115
165
|
// to test locally, comment the upper execSync and uncomment this one.
|
|
116
166
|
// execSync(`npm pack --pack-destination=${tempDir} --silent`, {
|
|
117
|
-
//
|
|
118
|
-
// })
|
|
167
|
+
// cwd: process.cwd(),
|
|
168
|
+
// })
|
|
119
169
|
|
|
120
170
|
return tarballFilePath
|
|
121
171
|
} catch (error) {
|
|
@@ -150,13 +200,19 @@ const program = new Commander.Command()
|
|
|
150
200
|
if (entry.path.startsWith(selectedTemplateCode)) {
|
|
151
201
|
entry.path = entry.path.replace(selectedTemplateCode, extractionDestination)
|
|
152
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
|
+
}
|
|
153
209
|
},
|
|
154
210
|
})
|
|
155
211
|
} catch (e) {
|
|
156
212
|
console.log("An error occurred", e)
|
|
157
213
|
}
|
|
158
214
|
|
|
159
|
-
cyan(`Run cd ${projectName} && npm start to get started.`)
|
|
215
|
+
console.log(cyan(`Run cd ${projectName} && npm start to get started.`))
|
|
160
216
|
}
|
|
161
217
|
} catch (error) {
|
|
162
218
|
console.error(red("An error occurred:"), error.message)
|
|
@@ -218,6 +274,46 @@ async function promptDescription() {
|
|
|
218
274
|
} else return null
|
|
219
275
|
}
|
|
220
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
|
+
|
|
221
317
|
function validateOptions(cmd) {
|
|
222
318
|
// Validate language option
|
|
223
319
|
if (cmd.lang && !["js", "ts"].includes(cmd.lang.toLowerCase())) {
|
|
@@ -228,6 +324,10 @@ function validateOptions(cmd) {
|
|
|
228
324
|
if (cmd.stateManagement && !["rtk", "redux", "none"].includes(cmd.stateManagement.toLowerCase())) {
|
|
229
325
|
throw new Error('Invalid state management option. Use "rtk", "redux", or "none".')
|
|
230
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
|
+
}
|
|
231
331
|
}
|
|
232
332
|
|
|
233
333
|
function deleteDirectory(dirPath) {
|
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
"ANALYZE_BUNDLE": false,
|
|
11
11
|
"CLIENT_ENV_VARIABLES": ["API_URL"],
|
|
12
12
|
"WEBVIEW_CONFIG": {
|
|
13
|
+
"LOCAL_IP": "localhost",
|
|
13
14
|
"port": "3005",
|
|
15
|
+
"appInfo": "",
|
|
14
16
|
"android": {
|
|
15
|
-
|
|
17
|
+
"buildType": "debug"
|
|
16
18
|
},
|
|
17
19
|
"ios": {
|
|
18
|
-
|
|
20
|
+
"buildType": "debug"
|
|
19
21
|
}
|
|
20
|
-
|
|
22
|
+
}
|
|
21
23
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Offline</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
margin: 0;
|
|
10
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
11
|
+
background: #282c34;
|
|
12
|
+
color: #ffffff;
|
|
13
|
+
min-height: 100vh;
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
text-align: center;
|
|
18
|
+
font-size: calc(10px + 2vmin);
|
|
19
|
+
}
|
|
20
|
+
.card {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
align-items: center;
|
|
24
|
+
gap: 12px;
|
|
25
|
+
padding: 0 24px;
|
|
26
|
+
max-width: 440px;
|
|
27
|
+
}
|
|
28
|
+
h1 {
|
|
29
|
+
margin: 0;
|
|
30
|
+
font-size: 2rem;
|
|
31
|
+
font-weight: 700;
|
|
32
|
+
}
|
|
33
|
+
p {
|
|
34
|
+
margin: 0;
|
|
35
|
+
color: #d8e0f7;
|
|
36
|
+
line-height: 1.4;
|
|
37
|
+
}
|
|
38
|
+
a.retry {
|
|
39
|
+
color: #61dafb;
|
|
40
|
+
font-weight: 600;
|
|
41
|
+
text-decoration: none;
|
|
42
|
+
transition: color 0.2s ease;
|
|
43
|
+
}
|
|
44
|
+
a.retry:hover {
|
|
45
|
+
color: #9ae3fb;
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
48
|
+
</head>
|
|
49
|
+
<body>
|
|
50
|
+
<div class="card">
|
|
51
|
+
<h1>You're Offline</h1>
|
|
52
|
+
<p>Please check your connection and try again.</p>
|
|
53
|
+
<a class="retry" href="catalyst://retry">Try Again</a>
|
|
54
|
+
</div>
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js")
|
|
2
|
+
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js")
|
|
3
|
+
|
|
4
|
+
const fetchContextFromGitHub = async () => {
|
|
5
|
+
const url = "https://raw.githubusercontent.com/tata1mg/catalyst-core-internal/main/context.md"
|
|
6
|
+
const response = await fetch(url)
|
|
7
|
+
|
|
8
|
+
if (!response.ok) {
|
|
9
|
+
throw new Error(`HTTP ${response.status}: Failed to fetch context from GitHub`)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return await response.text()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const server = new McpServer({
|
|
16
|
+
name: "catalyst",
|
|
17
|
+
version: "1.0.0",
|
|
18
|
+
capabilities: {
|
|
19
|
+
tools: {},
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
server.tool("get_context", "Complete context of catalyst framework", {}, async () => {
|
|
24
|
+
try {
|
|
25
|
+
const context = await fetchContextFromGitHub()
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: context,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: `Error fetching context: ${error.message}`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const init = async () => {
|
|
47
|
+
try {
|
|
48
|
+
const transport = new StdioServerTransport()
|
|
49
|
+
await server.connect(transport)
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error("Error starting MCP server:", error)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
init()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "create-catalyst-app-
|
|
2
|
+
"name": "create-catalyst-app-starter",
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"start": "catalyst start",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"buildApp": "catalyst buildApp",
|
|
12
12
|
"buildApp:ios": "catalyst buildApp:ios",
|
|
13
13
|
"buildApp:android": "catalyst buildApp:android",
|
|
14
|
-
"setupEmulator"
|
|
14
|
+
"setupEmulator": "catalyst setupEmulator",
|
|
15
15
|
"setupEmulator:ios": "catalyst setupEmulator:ios",
|
|
16
16
|
"setupEmulator:android": "catalyst setupEmulator:android"
|
|
17
17
|
},
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@loadable/component": "^5.16.3",
|
|
28
|
-
"@tata1mg/router": "
|
|
29
|
-
"catalyst-core-internal": "
|
|
28
|
+
"@tata1mg/router": "0.0.1-beta.7",
|
|
29
|
+
"catalyst-core-internal": "0.1.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"eslint": "^8.26.0",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import "./styles"
|
|
3
|
+
import { hydrateRoot } from "react-dom/client"
|
|
4
|
+
import { loadableReady } from "@loadable/component"
|
|
5
|
+
import { RouterProvider } from "@tata1mg/router"
|
|
6
|
+
import clientRouter from "catalyst-core-internal/router/ClientRouter"
|
|
7
|
+
|
|
8
|
+
window.addEventListener("load", () => {
|
|
9
|
+
loadableReady(() => {
|
|
10
|
+
const { __ROUTER_INITIAL_DATA__: routerInitialData } = window
|
|
11
|
+
|
|
12
|
+
const router = clientRouter({ routerInitialState: routerInitialData })
|
|
13
|
+
|
|
14
|
+
const Application = (
|
|
15
|
+
<React.StrictMode>
|
|
16
|
+
<RouterProvider router={router} />
|
|
17
|
+
</React.StrictMode>
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const container = document.getElementById("app")
|
|
21
|
+
hydrateRoot(container, Application)
|
|
22
|
+
})
|
|
23
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-catalyst-app-starter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"start": "catalyst start",
|
|
6
|
+
"build": "npm run typecheck && catalyst build",
|
|
7
|
+
"serve": "catalyst serve",
|
|
8
|
+
"lint": "eslint .",
|
|
9
|
+
"devBuild": "catalyst devBuild",
|
|
10
|
+
"devServe": "catalyst devServe",
|
|
11
|
+
"buildApp": "catalyst buildApp",
|
|
12
|
+
"buildApp:ios": "catalyst buildApp:ios",
|
|
13
|
+
"buildApp:android": "catalyst buildApp:android",
|
|
14
|
+
"setupEmulator": "catalyst setupEmulator",
|
|
15
|
+
"setupEmulator:ios": "catalyst setupEmulator:ios",
|
|
16
|
+
"setupEmulator:android": "catalyst setupEmulator:android",
|
|
17
|
+
"typecheck": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"_moduleAliases": {
|
|
20
|
+
"@api": "api.js",
|
|
21
|
+
"@containers": "src/js/containers",
|
|
22
|
+
"@server": "server",
|
|
23
|
+
"@config": "config",
|
|
24
|
+
"@css": "src/static/css",
|
|
25
|
+
"@routes": "src/js/routes/"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@loadable/component": "^5.16.3",
|
|
29
|
+
"@tata1mg/router": "0.0.1-beta.7",
|
|
30
|
+
"catalyst-core-internal": "0.1.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"eslint": "^8.26.0",
|
|
34
|
+
"typescript": "^5.8.3",
|
|
35
|
+
"@types/react": "^18.2.0",
|
|
36
|
+
"@types/react-dom": "^18.2.0",
|
|
37
|
+
"eslint-plugin-react": "^7.34.1",
|
|
38
|
+
"eslint-plugin-react-hooks": "^4.6.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { Outlet } from "@tata1mg/router"
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
return (
|
|
6
|
+
<>
|
|
7
|
+
<Outlet />
|
|
8
|
+
</>
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
App.serverSideFunction = () => {
|
|
13
|
+
return new Promise((resolve) => resolve())
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default App
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { RouterDataProvider, MetaTag } from "@tata1mg/router"
|
|
3
|
+
import App from "@containers/App"
|
|
4
|
+
import routes from "./index.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Making the routes array compatible with the format accepted by createBrowserRouter
|
|
8
|
+
* API on the client side
|
|
9
|
+
* https://reactrouter.com/en/main/routers/create-browser-router
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const preparedRoutes = ({ routerInitialState }) => {
|
|
13
|
+
const getPreparedRoutes = (routes) => {
|
|
14
|
+
return routes.map((route, index) => {
|
|
15
|
+
const Component = route.component
|
|
16
|
+
const routeToRender = {
|
|
17
|
+
...route,
|
|
18
|
+
element: <Component key={index} />,
|
|
19
|
+
}
|
|
20
|
+
if (route.children) {
|
|
21
|
+
routeToRender.children = getPreparedRoutes(route.children)
|
|
22
|
+
}
|
|
23
|
+
return routeToRender
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
element: (
|
|
30
|
+
<RouterDataProvider config={{}} initialState={routerInitialState}>
|
|
31
|
+
<MetaTag />
|
|
32
|
+
<App />
|
|
33
|
+
</RouterDataProvider>
|
|
34
|
+
),
|
|
35
|
+
children: getPreparedRoutes(routes),
|
|
36
|
+
},
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const getRoutes = () => {
|
|
41
|
+
return routes
|
|
42
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "create-catalyst-app-
|
|
2
|
+
"name": "create-catalyst-app-starter",
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"start": "catalyst start",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"buildApp": "catalyst buildApp",
|
|
12
12
|
"buildApp:ios": "catalyst buildApp:ios",
|
|
13
13
|
"buildApp:android": "catalyst buildApp:android",
|
|
14
|
-
"setupEmulator"
|
|
14
|
+
"setupEmulator": "catalyst setupEmulator",
|
|
15
15
|
"setupEmulator:ios": "catalyst setupEmulator:ios",
|
|
16
16
|
"setupEmulator:android": "catalyst setupEmulator:android"
|
|
17
17
|
},
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@loadable/component": "^5.16.3",
|
|
29
|
-
"@tata1mg/router": "
|
|
30
|
-
"catalyst-core-internal": "
|
|
29
|
+
"@tata1mg/router": "0.0.1-beta.7",
|
|
30
|
+
"catalyst-core-internal": "0.1.0",
|
|
31
31
|
"@reduxjs/toolkit": "1.9.3",
|
|
32
32
|
"react-redux": "^8.1.3"
|
|
33
33
|
},
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import "./styles"
|
|
3
|
+
import { hydrateRoot } from "react-dom/client"
|
|
4
|
+
import { loadableReady } from "@loadable/component"
|
|
5
|
+
import { Provider } from "react-redux"
|
|
6
|
+
import { RouterProvider } from "@tata1mg/router"
|
|
7
|
+
import clientRouter from "catalyst-core-internal/router/ClientRouter"
|
|
8
|
+
import configureStore from "@store"
|
|
9
|
+
|
|
10
|
+
window.addEventListener("load", () => {
|
|
11
|
+
loadableReady(() => {
|
|
12
|
+
const { __ROUTER_INITIAL_DATA__: routerInitialData, __INITIAL_STATE__ } = window
|
|
13
|
+
const store = configureStore(__INITIAL_STATE__ || {})
|
|
14
|
+
|
|
15
|
+
const router = clientRouter({ store, routerInitialState: routerInitialData })
|
|
16
|
+
|
|
17
|
+
const Application = (
|
|
18
|
+
<Provider store={store} serverState={__INITIAL_STATE__}>
|
|
19
|
+
<React.StrictMode>
|
|
20
|
+
<RouterProvider router={router} />
|
|
21
|
+
</React.StrictMode>
|
|
22
|
+
</Provider>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const container = document.getElementById("app")
|
|
26
|
+
hydrateRoot(container, Application)
|
|
27
|
+
})
|
|
28
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-catalyst-app-starter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"start": "catalyst start",
|
|
6
|
+
"build": "npm run typecheck && catalyst build",
|
|
7
|
+
"serve": "catalyst serve",
|
|
8
|
+
"lint": "eslint .",
|
|
9
|
+
"devBuild": "catalyst devBuild",
|
|
10
|
+
"devServe": "catalyst devServe",
|
|
11
|
+
"buildApp": "catalyst buildApp",
|
|
12
|
+
"buildApp:ios": "catalyst buildApp:ios",
|
|
13
|
+
"buildApp:android": "catalyst buildApp:android",
|
|
14
|
+
"setupEmulator": "catalyst setupEmulator",
|
|
15
|
+
"setupEmulator:ios": "catalyst setupEmulator:ios",
|
|
16
|
+
"setupEmulator:android": "catalyst setupEmulator:android",
|
|
17
|
+
"typecheck": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"_moduleAliases": {
|
|
20
|
+
"@api": "api.js",
|
|
21
|
+
"@containers": "src/js/containers",
|
|
22
|
+
"@server": "server",
|
|
23
|
+
"@config": "config",
|
|
24
|
+
"@css": "src/static/css",
|
|
25
|
+
"@routes": "src/js/routes/",
|
|
26
|
+
"@store": "src/js/store/index.js"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@loadable/component": "^5.16.3",
|
|
30
|
+
"@tata1mg/router": "0.0.1-beta.7",
|
|
31
|
+
"catalyst-core-internal": "0.1.0",
|
|
32
|
+
"@reduxjs/toolkit": "1.9.3",
|
|
33
|
+
"react-redux": "^8.1.3"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"eslint": "^8.26.0",
|
|
37
|
+
"typescript": "^5.8.3",
|
|
38
|
+
"@types/react": "^18.2.0",
|
|
39
|
+
"@types/react-dom": "^18.2.0",
|
|
40
|
+
"eslint-plugin-react": "^7.34.1",
|
|
41
|
+
"eslint-plugin-react-hooks": "^4.6.0"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const createActionTypes = (prefix, actionTypeList = []) => {
|
|
2
|
+
const actionTypesObject = {}
|
|
3
|
+
actionTypeList.forEach((item) => {
|
|
4
|
+
actionTypesObject[item] = `${prefix}/${item}`
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
return actionTypesObject
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default createActionTypes
|
|
11
|
+
|
|
12
|
+
export const ShellActions = createActionTypes("shellActions", ["REDUX_TEST"])
|
|
13
|
+
export const reduxTest = () => {
|
|
14
|
+
return {
|
|
15
|
+
type: ShellActions.REDUX_TEST,
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { Outlet } from "@tata1mg/router"
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
return (
|
|
6
|
+
<>
|
|
7
|
+
<Outlet />
|
|
8
|
+
</>
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
App.serverSideFunction = () => {
|
|
13
|
+
return new Promise((resolve) => resolve())
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default App
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ShellActions } from "./actions"
|
|
2
|
+
|
|
3
|
+
export const defaultState = {
|
|
4
|
+
testActionDispatched: false,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const shellReducer = (state = defaultState, action) => {
|
|
8
|
+
switch (action.type) {
|
|
9
|
+
case ShellActions.REDUX_TEST: {
|
|
10
|
+
return {
|
|
11
|
+
...state,
|
|
12
|
+
testActionDispatched: true,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
default:
|
|
17
|
+
return state
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { RouterDataProvider, MetaTag } from "@tata1mg/router"
|
|
3
|
+
import App from "@containers/App"
|
|
4
|
+
import routes from "./index.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Making the routes array compatible with the format accepted by createBrowserRouter
|
|
8
|
+
* API on the client side
|
|
9
|
+
* https://reactrouter.com/en/main/routers/create-browser-router
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const preparedRoutes = ({ store, routerInitialState }) => {
|
|
13
|
+
const getPreparedRoutes = (routes) => {
|
|
14
|
+
return routes.map((route, index) => {
|
|
15
|
+
const Component = route.component
|
|
16
|
+
const routeToRender = {
|
|
17
|
+
...route,
|
|
18
|
+
element: <Component key={index} />,
|
|
19
|
+
}
|
|
20
|
+
if (route.children) {
|
|
21
|
+
routeToRender.children = getPreparedRoutes(route.children)
|
|
22
|
+
}
|
|
23
|
+
return routeToRender
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
element: (
|
|
30
|
+
<RouterDataProvider config={{}} initialState={routerInitialState} fetcherArgs={{ store }}>
|
|
31
|
+
<MetaTag />
|
|
32
|
+
<App />
|
|
33
|
+
</RouterDataProvider>
|
|
34
|
+
),
|
|
35
|
+
children: getPreparedRoutes(routes),
|
|
36
|
+
},
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const getRoutes = () => {
|
|
41
|
+
return routes
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { configureStore as createStore } from "@reduxjs/toolkit"
|
|
2
|
+
import { combineReducers } from "redux"
|
|
3
|
+
import { shellReducer } from "@containers/App/reducer.js"
|
|
4
|
+
import fetchInstance from "@api"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Function that initializes the store with the initialstate and adds middlewares that can be used during action dispatch
|
|
8
|
+
* @param {object} initialState Default state
|
|
9
|
+
* @param {object} request Request object that we recieve on server, this is only recieved when store is initialized on the server.
|
|
10
|
+
* @return {object} The store itself
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const configureStore = (initialState) => {
|
|
14
|
+
const api = fetchInstance
|
|
15
|
+
const store = createStore({
|
|
16
|
+
reducer: combineReducers({ shellReducer }),
|
|
17
|
+
middleware: (getDefaultMiddleware) =>
|
|
18
|
+
getDefaultMiddleware({
|
|
19
|
+
thunk: {
|
|
20
|
+
extraArgument: { api },
|
|
21
|
+
},
|
|
22
|
+
}),
|
|
23
|
+
preloadedState: initialState,
|
|
24
|
+
})
|
|
25
|
+
return store
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default configureStore
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "create-catalyst-app-
|
|
2
|
+
"name": "create-catalyst-app-starter",
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"start": "catalyst start",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"buildApp": "catalyst buildApp",
|
|
12
12
|
"buildApp:ios": "catalyst buildApp:ios",
|
|
13
13
|
"buildApp:android": "catalyst buildApp:android",
|
|
14
|
-
"setupEmulator"
|
|
14
|
+
"setupEmulator": "catalyst setupEmulator",
|
|
15
15
|
"setupEmulator:ios": "catalyst setupEmulator:ios",
|
|
16
16
|
"setupEmulator:android": "catalyst setupEmulator:android"
|
|
17
17
|
},
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@loadable/component": "^5.16.3",
|
|
29
|
-
"@tata1mg/router": "
|
|
30
|
-
"catalyst-core-internal": "
|
|
29
|
+
"@tata1mg/router": "0.0.1-beta.7",
|
|
30
|
+
"catalyst-core-internal": "0.1.0",
|
|
31
31
|
"@reduxjs/toolkit": "1.9.3",
|
|
32
32
|
"react-redux": "^8.1.3"
|
|
33
33
|
},
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import "./styles"
|
|
3
|
+
import { hydrateRoot } from "react-dom/client"
|
|
4
|
+
import { loadableReady } from "@loadable/component"
|
|
5
|
+
import { Provider } from "react-redux"
|
|
6
|
+
import { RouterProvider } from "@tata1mg/router"
|
|
7
|
+
import clientRouter from "catalyst-core-internal/router/ClientRouter"
|
|
8
|
+
import configureStore from "@store"
|
|
9
|
+
|
|
10
|
+
window.addEventListener("load", () => {
|
|
11
|
+
loadableReady(() => {
|
|
12
|
+
const { __ROUTER_INITIAL_DATA__: routerInitialData, __INITIAL_STATE__ } = window
|
|
13
|
+
const store = configureStore(__INITIAL_STATE__ || {})
|
|
14
|
+
|
|
15
|
+
const router = clientRouter({ store, routerInitialState: routerInitialData })
|
|
16
|
+
|
|
17
|
+
const Application = (
|
|
18
|
+
<Provider store={store} serverState={__INITIAL_STATE__}>
|
|
19
|
+
<React.StrictMode>
|
|
20
|
+
<RouterProvider router={router} />
|
|
21
|
+
</React.StrictMode>
|
|
22
|
+
</Provider>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const container = document.getElementById("app")
|
|
26
|
+
hydrateRoot(container, Application)
|
|
27
|
+
})
|
|
28
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-catalyst-app-starter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"start": "catalyst start",
|
|
6
|
+
"build": "npm run typecheck && catalyst build",
|
|
7
|
+
"serve": "catalyst serve",
|
|
8
|
+
"lint": "eslint .",
|
|
9
|
+
"devBuild": "catalyst devBuild",
|
|
10
|
+
"devServe": "catalyst devServe",
|
|
11
|
+
"buildApp": "catalyst buildApp",
|
|
12
|
+
"buildApp:ios": "catalyst buildApp:ios",
|
|
13
|
+
"buildApp:android": "catalyst buildApp:android",
|
|
14
|
+
"setupEmulator": "catalyst setupEmulator",
|
|
15
|
+
"setupEmulator:ios": "catalyst setupEmulator:ios",
|
|
16
|
+
"setupEmulator:android": "catalyst setupEmulator:android",
|
|
17
|
+
"typecheck": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"_moduleAliases": {
|
|
20
|
+
"@api": "api.js",
|
|
21
|
+
"@containers": "src/js/containers",
|
|
22
|
+
"@server": "server",
|
|
23
|
+
"@config": "config",
|
|
24
|
+
"@css": "src/static/css",
|
|
25
|
+
"@routes": "src/js/routes/",
|
|
26
|
+
"@store": "src/js/store/index.js"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@loadable/component": "^5.16.3",
|
|
30
|
+
"@tata1mg/router": "0.0.1-beta.7",
|
|
31
|
+
"catalyst-core-internal": "0.1.0",
|
|
32
|
+
"@reduxjs/toolkit": "1.9.3",
|
|
33
|
+
"react-redux": "^8.1.3"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"eslint": "^8.26.0",
|
|
37
|
+
"typescript": "^5.8.3",
|
|
38
|
+
"@types/react": "^18.2.0",
|
|
39
|
+
"@types/react-dom": "^18.2.0",
|
|
40
|
+
"eslint-plugin-react": "^7.34.1",
|
|
41
|
+
"eslint-plugin-react-hooks": "^4.6.0"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { Outlet } from "@tata1mg/router"
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
return (
|
|
6
|
+
<>
|
|
7
|
+
<Outlet />
|
|
8
|
+
</>
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
App.serverSideFunction = () => {
|
|
13
|
+
return new Promise((resolve) => resolve())
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default App
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createSlice } from "@reduxjs/toolkit"
|
|
2
|
+
|
|
3
|
+
const initialState = {
|
|
4
|
+
testActionDispatched: false,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const appSlice = createSlice({
|
|
8
|
+
name: "shellReducer",
|
|
9
|
+
initialState: initialState,
|
|
10
|
+
reducers: {
|
|
11
|
+
reduxTest: (state) => {
|
|
12
|
+
state.testActionDispatched = true
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
export const { reduxTest } = appSlice.actions
|
|
18
|
+
export const shellReducer = appSlice.reducer
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { RouterDataProvider, MetaTag } from "@tata1mg/router"
|
|
3
|
+
import App from "@containers/App"
|
|
4
|
+
import routes from "./index.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Making the routes array compatible with the format accepted by createBrowserRouter
|
|
8
|
+
* API on the client side
|
|
9
|
+
* https://reactrouter.com/en/main/routers/create-browser-router
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const preparedRoutes = ({ store, routerInitialState }) => {
|
|
13
|
+
const getPreparedRoutes = (routes) => {
|
|
14
|
+
return routes.map((route, index) => {
|
|
15
|
+
const Component = route.component
|
|
16
|
+
const routeToRender = {
|
|
17
|
+
...route,
|
|
18
|
+
element: <Component key={index} />,
|
|
19
|
+
}
|
|
20
|
+
if (route.children) {
|
|
21
|
+
routeToRender.children = getPreparedRoutes(route.children)
|
|
22
|
+
}
|
|
23
|
+
return routeToRender
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
element: (
|
|
30
|
+
<RouterDataProvider config={{}} initialState={routerInitialState} fetcherArgs={{ store }}>
|
|
31
|
+
<MetaTag />
|
|
32
|
+
<App />
|
|
33
|
+
</RouterDataProvider>
|
|
34
|
+
),
|
|
35
|
+
children: getPreparedRoutes(routes),
|
|
36
|
+
},
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const getRoutes = () => {
|
|
41
|
+
return routes
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { configureStore as createStore } from "@reduxjs/toolkit"
|
|
2
|
+
import { combineReducers } from "redux"
|
|
3
|
+
import { shellReducer } from "@containers/App/reducer.js"
|
|
4
|
+
import fetchInstance from "@api"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Function that initializes the store with the initialstate and adds middlewares that can be used during action dispatch
|
|
8
|
+
* @param {object} initialState Default state
|
|
9
|
+
* @param {object} request Request object that we recieve on server, this is only recieved when store is initialized on the server.
|
|
10
|
+
* @return {object} The store itself
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const configureStore = (initialState) => {
|
|
14
|
+
const api = fetchInstance
|
|
15
|
+
const store = createStore({
|
|
16
|
+
reducer: combineReducers({ shellReducer }),
|
|
17
|
+
middleware: (getDefaultMiddleware) =>
|
|
18
|
+
getDefaultMiddleware({
|
|
19
|
+
thunk: {
|
|
20
|
+
extraArgument: { api },
|
|
21
|
+
},
|
|
22
|
+
}),
|
|
23
|
+
preloadedState: initialState,
|
|
24
|
+
})
|
|
25
|
+
return store
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default configureStore
|