@gnar-engine/cli 1.0.3 → 1.0.5
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/bootstrap/deploy.localdev.yml +44 -30
- package/bootstrap/secrets.localdev.yml +20 -14
- package/bootstrap/services/control/src/config.js +4 -0
- package/bootstrap/services/{agent → page}/Dockerfile +3 -3
- package/bootstrap/services/page/package.json +16 -0
- package/bootstrap/services/page/src/app.js +50 -0
- package/bootstrap/services/page/src/commands/block.handler.js +94 -0
- package/bootstrap/services/page/src/commands/page.handler.js +167 -0
- package/bootstrap/services/page/src/config.js +62 -0
- package/bootstrap/services/page/src/controllers/block.http.controller.js +87 -0
- package/bootstrap/services/page/src/controllers/message.controller.js +51 -0
- package/bootstrap/services/page/src/controllers/page.http.controller.js +89 -0
- package/bootstrap/services/page/src/policies/block.policy.js +50 -0
- package/bootstrap/services/page/src/policies/page.policy.js +49 -0
- package/bootstrap/services/page/src/schema/page.schema.js +139 -0
- package/bootstrap/services/page/src/services/block.service.js +83 -0
- package/bootstrap/services/page/src/services/page.service.js +83 -0
- package/bootstrap/services/portal/Dockerfile +7 -10
- package/bootstrap/services/portal/README.md +66 -15
- package/bootstrap/services/portal/index.html +13 -0
- package/bootstrap/services/portal/nginx.conf +5 -12
- package/bootstrap/services/portal/package.json +27 -53
- package/bootstrap/services/portal/public/vite.svg +1 -0
- package/bootstrap/services/portal/react-router.config.js +7 -0
- package/bootstrap/services/portal/src/App.jsx +16 -0
- package/bootstrap/services/portal/src/assets/gnar-engine-white-logo.svg +9 -0
- package/bootstrap/services/portal/src/assets/icon-agent.svg +6 -0
- package/bootstrap/services/portal/src/assets/icon-cog.svg +4 -0
- package/bootstrap/services/portal/src/assets/icon-delete.svg +3 -0
- package/bootstrap/services/portal/src/assets/icon-home.svg +3 -0
- package/bootstrap/services/portal/src/assets/icon-padlock.svg +3 -0
- package/bootstrap/services/portal/src/assets/icon-page.svg +6 -0
- package/bootstrap/services/portal/src/assets/icon-reports.svg +3 -0
- package/bootstrap/services/portal/src/assets/icon-user.svg +3 -0
- package/bootstrap/services/portal/src/assets/icon-users.svg +3 -0
- package/bootstrap/services/portal/src/assets/login-green-rad-back-1.jpg +0 -0
- package/bootstrap/services/portal/src/assets/react.svg +1 -0
- package/bootstrap/services/portal/src/components/CrudList/CrudList.jsx +85 -0
- package/bootstrap/services/portal/src/components/CrudList/CrudList.less +59 -0
- package/bootstrap/services/portal/src/{ui/customSelect → components/CustomSelect}/CustomSelect.jsx +21 -3
- package/bootstrap/services/portal/src/components/LoginForm/LoginForm.jsx +58 -0
- package/bootstrap/services/portal/src/components/PageBlockSwitch/PageBlockSwitch.jsx +129 -0
- package/bootstrap/services/portal/src/components/Sidebar/Sidebar.jsx +33 -0
- package/bootstrap/services/portal/src/components/Sidebar/Sidebar.less +37 -0
- package/bootstrap/services/portal/src/components/Topbar/Topbar.jsx +19 -0
- package/bootstrap/services/portal/src/components/Topbar/Topbar.less +22 -0
- package/bootstrap/services/portal/src/components/UserInfo/UserInfo.jsx +33 -0
- package/bootstrap/services/portal/src/components/UserInfo/UserInfo.less +21 -0
- package/bootstrap/services/portal/src/css/style.css +446 -742
- package/bootstrap/services/portal/src/data/pages.data.js +10 -0
- package/bootstrap/services/portal/src/elements/CustomSelect/CustomSelect.jsx +65 -0
- package/bootstrap/services/portal/src/{ui/customSelect/customSelect.less → elements/CustomSelect/CustomSelect.less} +17 -7
- package/bootstrap/services/portal/src/elements/ImageInput/ImageInput.jsx +115 -0
- package/bootstrap/services/portal/src/elements/ImageInput/ImageInput.less +43 -0
- package/bootstrap/services/portal/src/elements/ImageMultiInput/ImageMultiInput.jsx +124 -0
- package/bootstrap/services/portal/src/elements/ImageMultiInput/ImageMultiInput.less +0 -0
- package/bootstrap/services/portal/src/elements/Repeater/Repeater.jsx +52 -0
- package/bootstrap/services/portal/src/elements/Repeater/Repeater.less +70 -0
- package/bootstrap/services/portal/src/elements/RichTextInput/RichTextInput.jsx +18 -0
- package/bootstrap/services/portal/src/elements/RichTextInput/RichTextInput.less +37 -0
- package/bootstrap/services/portal/src/elements/SaveButton/SaveButton.jsx +45 -0
- package/bootstrap/services/portal/src/elements/SelectRepeater/SelectRepeater.jsx +63 -0
- package/bootstrap/services/portal/src/elements/SelectRepeater/SelectRepeater.less +23 -0
- package/bootstrap/services/portal/src/elements/TextInput/TextInput.jsx +17 -0
- package/bootstrap/services/portal/src/layouts/Card/Card.jsx +15 -0
- package/bootstrap/services/portal/src/layouts/PortalLayout/PortalLayout.jsx +29 -0
- package/bootstrap/services/portal/src/layouts/PortalLayout/PortalLayout.less +49 -0
- package/bootstrap/services/portal/src/main.jsx +51 -0
- package/bootstrap/services/portal/src/pages/BlockSinglePage/BlockSinglePage.jsx +277 -0
- package/bootstrap/services/portal/src/pages/BlocksPage/BlocksPage.jsx +23 -0
- package/bootstrap/services/portal/src/pages/DashboardPage/DashboardPage.jsx +11 -0
- package/bootstrap/services/portal/src/pages/DashboardPage/DashboardPage.less +0 -0
- package/bootstrap/services/portal/src/pages/LoginPage/LoginPage.jsx +21 -0
- package/bootstrap/services/portal/src/pages/LoginPage/LoginPage.less +51 -0
- package/bootstrap/services/portal/src/pages/PageSinglePage/PageSinglePage.jsx +338 -0
- package/bootstrap/services/portal/src/pages/PagesPage/PagesPage.jsx +23 -0
- package/bootstrap/services/portal/src/pages/UserSinglePage/UserSinglePage.jsx +9 -0
- package/bootstrap/services/portal/src/pages/UserSinglePage/UserSinglePage.less +0 -0
- package/bootstrap/services/portal/src/pages/UsersPage/UsersPage.jsx +25 -0
- package/bootstrap/services/portal/src/pages/UsersPage/UsersPage.less +0 -0
- package/bootstrap/services/portal/src/services/block.js +28 -0
- package/bootstrap/services/portal/src/services/client.js +67 -0
- package/bootstrap/services/portal/src/services/gravatar.js +14 -0
- package/bootstrap/services/portal/src/services/page.js +28 -0
- package/bootstrap/services/portal/src/services/storage.js +62 -0
- package/bootstrap/services/portal/src/services/user.js +41 -0
- package/bootstrap/services/portal/src/slices/authSlice.js +44 -14
- package/bootstrap/services/portal/src/store/configureStore.js +1 -3
- package/bootstrap/services/portal/src/style/cards.less +57 -0
- package/bootstrap/services/portal/src/{styles → style}/global.less +90 -45
- package/bootstrap/services/portal/src/style/icons.less +21 -0
- package/bootstrap/services/portal/src/style/inputs.less +52 -0
- package/bootstrap/services/portal/src/style/main.less +28 -0
- package/bootstrap/services/portal/src/utils/utils.js +9 -0
- package/bootstrap/services/portal/vite.config.js +12 -0
- package/bootstrap/services/user/Dockerfile +1 -1
- package/bootstrap/services/user/src/app.js +6 -1
- package/bootstrap/services/user/src/commands/user.handler.js +0 -3
- package/bootstrap/services/user/src/config.js +5 -1
- package/bootstrap/services/user/src/policies/user.policy.js +3 -1
- package/bootstrap/services/user/src/tests/commands/user.test.js +22 -0
- package/install-from-clone.sh +30 -0
- package/package.json +1 -1
- package/src/cli.js +8 -0
- package/src/config.js +2 -1
- package/src/dev/commands.js +10 -2
- package/src/dev/dev.service.js +167 -52
- package/src/provisioner/Dockerfile +27 -0
- package/src/provisioner/package.json +19 -0
- package/src/provisioner/src/app.js +56 -0
- package/src/provisioner/src/services/mongodb.js +58 -0
- package/src/provisioner/src/services/mysql.js +51 -0
- package/src/provisioner/src/services/secrets.js +84 -0
- package/src/scaffolder/commands.js +12 -5
- package/src/scaffolder/scaffolder.handler.js +256 -58
- package/templates/service/Dockerfile.hbs +4 -1
- package/templates/service/package.json.hbs +14 -16
- package/templates/service/src/app.js.hbs +53 -0
- package/templates/service/{commands → src/commands}/{{serviceName}}.handler.js.hbs +2 -3
- package/templates/service/src/mongodb.config.js.hbs +49 -0
- package/templates/service/{config.js.hbs → src/mysql.config.js.hbs} +10 -0
- package/{bootstrap/services/agent/src/schema/Agent.schema.js → templates/service/src/schema/{{serviceName}}.schema.js.hbs} +3 -3
- package/templates/service/src/services/mongodb.{{serviceName}}.service.js.hbs +70 -0
- package/bootstrap/services/agent/notes.md +0 -28
- package/bootstrap/services/agent/package.json +0 -16
- package/bootstrap/services/agent/src/app.js +0 -52
- package/bootstrap/services/agent/src/commands/agent.handler.js +0 -104
- package/bootstrap/services/agent/src/config.js +0 -52
- package/bootstrap/services/agent/src/controllers/http.controller.js +0 -44
- package/bootstrap/services/agent/src/controllers/message.controller.js +0 -51
- package/bootstrap/services/agent/src/db/migrations/01-init.js +0 -50
- package/bootstrap/services/agent/src/db/migrations/02-agent-service-init.js +0 -36
- package/bootstrap/services/agent/src/policies/agent.policy.js +0 -13
- package/bootstrap/services/agent/src/services/agent.service.js +0 -259
- package/bootstrap/services/agent/src/services/chatgpt.service.js +0 -46
- package/bootstrap/services/agent/src/services/manifest.service.js +0 -21
- package/bootstrap/services/portal/Dockerfile.remote +0 -40
- package/bootstrap/services/portal/public/favicon.ico +0 -0
- package/bootstrap/services/portal/public/gnar-white.png +0 -0
- package/bootstrap/services/portal/public/gnarengine-logo-black.png +0 -0
- package/bootstrap/services/portal/public/index.html +0 -43
- package/bootstrap/services/portal/public/logo192.png +0 -0
- package/bootstrap/services/portal/public/logo512.png +0 -0
- package/bootstrap/services/portal/public/manifest.json +0 -25
- package/bootstrap/services/portal/public/robots.txt +0 -3
- package/bootstrap/services/portal/src/App.js +0 -56
- package/bootstrap/services/portal/src/assets/Logo_Anchord_Black.svg +0 -1
- package/bootstrap/services/portal/src/assets/Logo_Anchord_Black_Green.svg +0 -1
- package/bootstrap/services/portal/src/assets/Logo_Anchord_White_Green.svg +0 -1
- package/bootstrap/services/portal/src/assets/activity.svg +0 -3
- package/bootstrap/services/portal/src/assets/arrow.svg +0 -3
- package/bootstrap/services/portal/src/assets/bin-white.svg +0 -3
- package/bootstrap/services/portal/src/assets/bin.svg +0 -3
- package/bootstrap/services/portal/src/assets/check.svg +0 -3
- package/bootstrap/services/portal/src/assets/chevron.svg +0 -3
- package/bootstrap/services/portal/src/assets/contact.svg +0 -3
- package/bootstrap/services/portal/src/assets/dots-vertical.svg +0 -5
- package/bootstrap/services/portal/src/assets/eye-off.svg +0 -3
- package/bootstrap/services/portal/src/assets/eye.svg +0 -4
- package/bootstrap/services/portal/src/assets/gnar-engine-black.svg +0 -47
- package/bootstrap/services/portal/src/assets/gnar-engine-white.svg +0 -47
- package/bootstrap/services/portal/src/assets/gnar_engine.svg +0 -3
- package/bootstrap/services/portal/src/assets/gnarengine-logo-black.png +0 -0
- package/bootstrap/services/portal/src/assets/home.svg +0 -3
- package/bootstrap/services/portal/src/assets/link.svg +0 -3
- package/bootstrap/services/portal/src/assets/lock.svg +0 -3
- package/bootstrap/services/portal/src/assets/package.svg +0 -4
- package/bootstrap/services/portal/src/assets/raffle.svg +0 -3
- package/bootstrap/services/portal/src/assets/settings.svg +0 -4
- package/bootstrap/services/portal/src/assets/shopping-bag.svg +0 -3
- package/bootstrap/services/portal/src/assets/user-black.svg +0 -3
- package/bootstrap/services/portal/src/assets/user.svg +0 -3
- package/bootstrap/services/portal/src/assets/users.svg +0 -3
- package/bootstrap/services/portal/src/assets/wallet.svg +0 -3
- package/bootstrap/services/portal/src/data/data.js +0 -70
- package/bootstrap/services/portal/src/features/attributeFormRow/AttributeFormRow.jsx +0 -32
- package/bootstrap/services/portal/src/features/billingShipping/BillingShipping.jsx +0 -160
- package/bootstrap/services/portal/src/features/crud/crudEdit.less +0 -230
- package/bootstrap/services/portal/src/features/crud/crudList.less +0 -134
- package/bootstrap/services/portal/src/features/crud/crudPage.less +0 -31
- package/bootstrap/services/portal/src/features/crudContact/CrudContactList.jsx +0 -108
- package/bootstrap/services/portal/src/features/crudContact/CrudContactSingle.jsx +0 -243
- package/bootstrap/services/portal/src/features/crudOrder/CrudOrderList.jsx +0 -109
- package/bootstrap/services/portal/src/features/crudOrder/CrudOrderSingle.jsx +0 -315
- package/bootstrap/services/portal/src/features/crudProducts/CrudProductList.jsx +0 -104
- package/bootstrap/services/portal/src/features/crudProducts/CrudProductSingle.jsx +0 -388
- package/bootstrap/services/portal/src/features/crudRaffles/CrudRafflesList.jsx +0 -104
- package/bootstrap/services/portal/src/features/crudRaffles/CrudRafflesSingle.jsx +0 -208
- package/bootstrap/services/portal/src/features/crudSubscription/CrudSubscriptionList.jsx +0 -110
- package/bootstrap/services/portal/src/features/crudSubscription/CrudSubscriptionSingle.jsx +0 -261
- package/bootstrap/services/portal/src/features/crudUser/CrudUserList.jsx +0 -107
- package/bootstrap/services/portal/src/features/crudUser/CrudUserSingle.jsx +0 -402
- package/bootstrap/services/portal/src/features/inventoryFormRow/InventoryFormRow.jsx +0 -30
- package/bootstrap/services/portal/src/features/lineItems/LineItems.jsx +0 -113
- package/bootstrap/services/portal/src/features/loginForm/LoginForm.jsx +0 -56
- package/bootstrap/services/portal/src/features/loginForm/loginForm.less +0 -56
- package/bootstrap/services/portal/src/features/notes/Notes.jsx +0 -18
- package/bootstrap/services/portal/src/features/passwordReset/PasswordResetForm.jsx +0 -96
- package/bootstrap/services/portal/src/features/passwordReset/PasswordResetRequestForm.jsx +0 -74
- package/bootstrap/services/portal/src/features/priceFormRow/PriceFormRow.jsx +0 -102
- package/bootstrap/services/portal/src/features/priceFormRow/priceFormRow.less +0 -24
- package/bootstrap/services/portal/src/features/raffleEntriesList/RaffleEntriesList.jsx +0 -99
- package/bootstrap/services/portal/src/features/raffleProductFormRow/RaffleProductFormRow.jsx +0 -46
- package/bootstrap/services/portal/src/features/sidebar/Sidebar.jsx +0 -64
- package/bootstrap/services/portal/src/features/sidebar/sidebar.less +0 -49
- package/bootstrap/services/portal/src/features/skus/Skus.jsx +0 -109
- package/bootstrap/services/portal/src/features/subscriptionSchedule/SubscriptionSchedule.jsx +0 -44
- package/bootstrap/services/portal/src/features/taxonomyFormRow/TaxonomyFormRow.jsx +0 -32
- package/bootstrap/services/portal/src/features/user/User.jsx +0 -54
- package/bootstrap/services/portal/src/features/user/user.less +0 -57
- package/bootstrap/services/portal/src/includes/utilities.js +0 -259
- package/bootstrap/services/portal/src/index.js +0 -14
- package/bootstrap/services/portal/src/layouts/CrudLayout.jsx +0 -50
- package/bootstrap/services/portal/src/layouts/LoginLayout.jsx +0 -17
- package/bootstrap/services/portal/src/layouts/PortalLayout.jsx +0 -48
- package/bootstrap/services/portal/src/layouts/loginLayout.less +0 -33
- package/bootstrap/services/portal/src/layouts/portalLayout.less +0 -67
- package/bootstrap/services/portal/src/pages/contacts/Contacts.jsx +0 -199
- package/bootstrap/services/portal/src/pages/dashboard/Dashboard.jsx +0 -17
- package/bootstrap/services/portal/src/pages/integrations/Integrations.jsx +0 -10
- package/bootstrap/services/portal/src/pages/login/Login.jsx +0 -15
- package/bootstrap/services/portal/src/pages/login/login.less +0 -10
- package/bootstrap/services/portal/src/pages/orders/Orders.jsx +0 -199
- package/bootstrap/services/portal/src/pages/passwordReset/PasswordResetPage.jsx +0 -15
- package/bootstrap/services/portal/src/pages/passwordResetRequest/PasswordResetRequestPage.jsx +0 -15
- package/bootstrap/services/portal/src/pages/payments/Payments.jsx +0 -10
- package/bootstrap/services/portal/src/pages/portal/Portal.jsx +0 -43
- package/bootstrap/services/portal/src/pages/products/Products.jsx +0 -212
- package/bootstrap/services/portal/src/pages/raffleEntries/RaffleEntries.jsx +0 -124
- package/bootstrap/services/portal/src/pages/raffles/Raffles.jsx +0 -186
- package/bootstrap/services/portal/src/pages/reports/Reports.jsx +0 -10
- package/bootstrap/services/portal/src/pages/settings/Settings.jsx +0 -10
- package/bootstrap/services/portal/src/pages/subscriptions/Subscriptions.jsx +0 -199
- package/bootstrap/services/portal/src/pages/users/Users.jsx +0 -193
- package/bootstrap/services/portal/src/pages/users/users.less +0 -25
- package/bootstrap/services/portal/src/styles/inputs.less +0 -157
- package/bootstrap/services/portal/src/styles/main.less +0 -26
- package/bootstrap/services/portal/src/ui/collapsible/Collapsible.jsx +0 -97
- package/bootstrap/services/portal/src/ui/collapsible/collapsible.less +0 -23
- package/bootstrap/services/portal/src/ui/customCheckbox/CustomCheckbox.jsx +0 -17
- package/bootstrap/services/portal/src/ui/customCheckbox/customCheckbox.less +0 -42
- package/bootstrap/services/portal/src/ui/customMultiSelect/CustomMultiSelect.jsx +0 -63
- package/bootstrap/services/portal/src/ui/customMultiSelect/CustomMultiSelectPeriod.jsx +0 -63
- package/bootstrap/services/portal/src/ui/goBack/GoBack.jsx +0 -19
- package/bootstrap/services/portal/src/ui/loader/Loader.jsx +0 -12
- package/bootstrap/services/portal/src/ui/pagination/Pagination.jsx +0 -23
- package/bootstrap/services/portal/src/ui/repeater/Repeater.jsx +0 -29
- package/bootstrap/services/portal/src/ui/saveButton/SaveButton.jsx +0 -69
- package/bootstrap/services/user/src/db/seeders/development/02-portal-admin-user.js +0 -27
- package/bootstrap/services/user/src/tests/user.test.js +0 -126
- package/templates/service/app.js.hbs +0 -38
- package/templates/service/schema/{{serviceName}}.schema.js.hbs +0 -14
- /package/bootstrap/services/portal/src/{ui/saveButton/saveButton.less → components/CustomSelect/CustomSelect.less} +0 -0
- /package/templates/service/{controllers → src/controllers}/http.controller.js.hbs +0 -0
- /package/templates/service/{controllers → src/controllers}/message.controller.js.hbs +0 -0
- /package/templates/service/{db → src/mysql.db}/migrations/01-init.js.hbs +0 -0
- /package/templates/service/{db → src/mysql.db}/migrations/02-{{lowerCase serviceName}}-service-init.js.hbs +0 -0
- /package/templates/service/{policies → src/policies}/{{serviceName}}.policy.js.hbs +0 -0
- /package/templates/service/{services/{{serviceName}}.service.js.hbs → src/services/mysql.{{serviceName}}.service.js.hbs} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { commands } from '@gnar-engine/core';
|
|
2
|
+
|
|
3
|
+
export const messageHandlers = {
|
|
4
|
+
|
|
5
|
+
getPage: async (payload) => {
|
|
6
|
+
let result;
|
|
7
|
+
if (payload.data?.id) {
|
|
8
|
+
result = await commands.execute('getSinglePage', {
|
|
9
|
+
id: payload.data.id
|
|
10
|
+
});
|
|
11
|
+
} else if (payload.data?.email) {
|
|
12
|
+
result = await commands.execute('getSinglePage', {
|
|
13
|
+
email: payload.data.email
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
throw new Error('No page ID or email provided');
|
|
17
|
+
}
|
|
18
|
+
if (!result) {
|
|
19
|
+
throw new Error('Page not found');
|
|
20
|
+
}
|
|
21
|
+
return { page: result };
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
getManyPages: async (payload) => {
|
|
25
|
+
const results = await commands.execute('getManyPages', {});
|
|
26
|
+
return { pages: results };
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
createPage: async (payload) => {
|
|
30
|
+
const results = await commands.execute('createPages', {
|
|
31
|
+
pages: [payload.data.page]
|
|
32
|
+
});
|
|
33
|
+
return { pages: results };
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
updatePage: async (payload) => {
|
|
37
|
+
const result = await commands.execute('updatePage', {
|
|
38
|
+
id: payload.data.id,
|
|
39
|
+
newPageData: payload.data
|
|
40
|
+
});
|
|
41
|
+
return { page: result };
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
deletePage: async (payload) => {
|
|
45
|
+
await commands.execute('deletePage', {
|
|
46
|
+
id: payload.data.id
|
|
47
|
+
});
|
|
48
|
+
return { message: 'Page deleted' };
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { commands } from '@gnar-engine/core';
|
|
2
|
+
import { authorise } from '../policies/page.policy.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HTTP controller
|
|
6
|
+
*/
|
|
7
|
+
export const httpController = {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get single page
|
|
11
|
+
*/
|
|
12
|
+
getSingle: {
|
|
13
|
+
method: 'GET',
|
|
14
|
+
url: '/pages/:id',
|
|
15
|
+
preHandler: async (request, reply) => authorise.getSingle(request, reply),
|
|
16
|
+
handler: async (request, reply) => {
|
|
17
|
+
const params = {
|
|
18
|
+
id: request.params.id
|
|
19
|
+
};
|
|
20
|
+
const result = await commands.execute('getSinglePage', params);
|
|
21
|
+
reply.code(200).send({ page: result });
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get multiple pages
|
|
27
|
+
*/
|
|
28
|
+
getMany: {
|
|
29
|
+
method: 'GET',
|
|
30
|
+
url: '/pages/',
|
|
31
|
+
preHandler: async (request, reply) => authorise.getMany(request, reply),
|
|
32
|
+
handler: async (request, reply) => {
|
|
33
|
+
const params = {};
|
|
34
|
+
const results = await commands.execute('getManyPages', params);
|
|
35
|
+
reply.code(200).send({ pages: results });
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create new page
|
|
41
|
+
*/
|
|
42
|
+
create: {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
url: '/pages/',
|
|
45
|
+
preHandler: async (request, reply) => authorise.create(request, reply),
|
|
46
|
+
handler: async (request, reply) => {
|
|
47
|
+
const params = {
|
|
48
|
+
pages: [request.body.page],
|
|
49
|
+
requestUser: request.user
|
|
50
|
+
};
|
|
51
|
+
const results = await commands.execute('createPages', params);
|
|
52
|
+
reply.code(200).send({ pages: results });
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Update page
|
|
58
|
+
*/
|
|
59
|
+
update: {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
url: '/pages/:id',
|
|
62
|
+
preHandler: async (request, reply) => authorise.update(request, reply),
|
|
63
|
+
handler: async (request, reply) => {
|
|
64
|
+
const params = {
|
|
65
|
+
id: request.params.id,
|
|
66
|
+
newPageData: request.body.page,
|
|
67
|
+
requestUser: request.user
|
|
68
|
+
};
|
|
69
|
+
const result = await commands.execute('updatePage', params);
|
|
70
|
+
reply.code(200).send({ page: result });
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Delete page
|
|
76
|
+
*/
|
|
77
|
+
delete: {
|
|
78
|
+
method: 'DELETE',
|
|
79
|
+
url: '/pages/:id',
|
|
80
|
+
preHandler: async (request, reply) => authorise.delete(request, reply),
|
|
81
|
+
handler: async (request, reply) => {
|
|
82
|
+
const params = {
|
|
83
|
+
id: request.params.id
|
|
84
|
+
};
|
|
85
|
+
await commands.execute('deletePage', params);
|
|
86
|
+
reply.code(200).send({ message: 'Page deleted' });
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { config } from '../config.js';
|
|
2
|
+
|
|
3
|
+
export const authorise = {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Authorise get single block
|
|
7
|
+
*/
|
|
8
|
+
getSingle: async (request, reply) => {
|
|
9
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
10
|
+
reply.code(403).send({error: 'not authorised'});
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Authorise get many blocks
|
|
16
|
+
*/
|
|
17
|
+
getMany: async (request, reply) => {
|
|
18
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
19
|
+
reply.code(403).send({error: 'not authorised'});
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Authorise create blocks
|
|
25
|
+
*/
|
|
26
|
+
create: async (request, reply) => {
|
|
27
|
+
console.log('request user', request.user);
|
|
28
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
29
|
+
reply.code(403).send({error: 'not authorised'});
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Authorise update block
|
|
35
|
+
*/
|
|
36
|
+
update: async (request, reply) => {
|
|
37
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
38
|
+
reply.code(403).send({error: 'not authorised'});
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Authorise delete block
|
|
44
|
+
*/
|
|
45
|
+
delete: async (request, reply) => {
|
|
46
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
47
|
+
reply.code(403).send({error: 'not authorised'});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { config } from '../config.js';
|
|
2
|
+
|
|
3
|
+
export const authorise = {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Authorise get single page
|
|
7
|
+
*/
|
|
8
|
+
getSingle: async (request, reply) => {
|
|
9
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
10
|
+
reply.code(403).send({error: 'not authorised'});
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Authorise get many pages
|
|
16
|
+
*/
|
|
17
|
+
getMany: async (request, reply) => {
|
|
18
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
19
|
+
reply.code(403).send({error: 'not authorised'});
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Authorise create pages
|
|
25
|
+
*/
|
|
26
|
+
create: async (request, reply) => {
|
|
27
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
28
|
+
reply.code(403).send({error: 'not authorised'});
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Authorise update page
|
|
34
|
+
*/
|
|
35
|
+
update: async (request, reply) => {
|
|
36
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
37
|
+
reply.code(403).send({error: 'not authorised'});
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Authorise delete page
|
|
43
|
+
*/
|
|
44
|
+
delete: async (request, reply) => {
|
|
45
|
+
if (!request.user || request.user.role !== 'service_admin') {
|
|
46
|
+
reply.code(403).send({error: 'not authorised'});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { schema } from '@gnar-engine/core';
|
|
2
|
+
import { config } from '../config.js';
|
|
3
|
+
|
|
4
|
+
export const pageSchema = {
|
|
5
|
+
schemaName: 'pageService.pageSchema',
|
|
6
|
+
schema: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
name: { type: 'string' },
|
|
10
|
+
key: { type: 'string' },
|
|
11
|
+
blocks: {
|
|
12
|
+
type: 'array',
|
|
13
|
+
items: { $ref: 'pageService.blockSchema' }
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
required: ['name', 'key'],
|
|
17
|
+
additionalProperties: false
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const blockSchema = {
|
|
22
|
+
$id: 'pageService.blockSchema',
|
|
23
|
+
schemaName: 'pageService.blockSchema',
|
|
24
|
+
schema: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
properties: {
|
|
27
|
+
name: { type: 'string' },
|
|
28
|
+
key: { type: 'string' },
|
|
29
|
+
blocks: {
|
|
30
|
+
type: 'array',
|
|
31
|
+
items: { $ref: 'pageService.blockSchema' }
|
|
32
|
+
},
|
|
33
|
+
fields: {
|
|
34
|
+
type: 'array',
|
|
35
|
+
items: {
|
|
36
|
+
oneOf: [
|
|
37
|
+
{ $ref: 'pageService.textInputSchema' },
|
|
38
|
+
{ $ref: 'pageService.richTextSchema' },
|
|
39
|
+
{ $ref: 'pageService.imageSchema' },
|
|
40
|
+
{ $ref: 'pageService.blockSchema' },
|
|
41
|
+
{ $ref: 'pageService.repeaterSchema' }
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
type: { type: 'string', enum: ['block'] },
|
|
46
|
+
instanceId: { type: 'string' }
|
|
47
|
+
},
|
|
48
|
+
required: ['name', 'key'],
|
|
49
|
+
additionalProperties: false
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const textInputSchema = {
|
|
54
|
+
$id: 'pageService.textInputSchema',
|
|
55
|
+
schemaName: 'pageService.textInputSchema',
|
|
56
|
+
schema: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
key: { type: 'string' },
|
|
60
|
+
name: { type: 'string' },
|
|
61
|
+
type: { type: 'string', enum: ['text'] },
|
|
62
|
+
value: { type: 'string' }
|
|
63
|
+
},
|
|
64
|
+
required: ['key', 'type'],
|
|
65
|
+
additionalProperties: false
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const richTextSchema = {
|
|
70
|
+
$id: 'pageService.richTextSchema',
|
|
71
|
+
schemaName: 'pageService.richTextSchema',
|
|
72
|
+
schema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
key: { type: 'string' },
|
|
76
|
+
name: { type: 'string' },
|
|
77
|
+
type: { type: 'string', enum: ['richtext'] },
|
|
78
|
+
value: { type: 'string' }
|
|
79
|
+
},
|
|
80
|
+
required: ['key', 'type'],
|
|
81
|
+
additionalProperties: false
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const imageSchema = {
|
|
86
|
+
$id: 'pageService.imageSchema',
|
|
87
|
+
schemaName: 'pageService.imageSchema',
|
|
88
|
+
schema: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
key: { type: 'string' },
|
|
92
|
+
name: { type: 'string' },
|
|
93
|
+
type: { type: 'string', enum: ['image'] },
|
|
94
|
+
value: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
properties: {
|
|
97
|
+
file: { type: 'string' },
|
|
98
|
+
mimeType: { type: 'string' },
|
|
99
|
+
fileName: { type: 'string' },
|
|
100
|
+
url: { type: 'string' }
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
altText: { type: 'string' }
|
|
104
|
+
},
|
|
105
|
+
required: ['key', 'type'],
|
|
106
|
+
additionalProperties: false
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const repeaterSchema = {
|
|
111
|
+
$id: 'pageService.repeaterSchema',
|
|
112
|
+
schemaName: 'pageService.repeaterSchema',
|
|
113
|
+
schema: {
|
|
114
|
+
type: 'object',
|
|
115
|
+
properties: {
|
|
116
|
+
key: { type: 'string' },
|
|
117
|
+
name: { type: 'string' },
|
|
118
|
+
type: { type: 'string', enum: ['repeater'] },
|
|
119
|
+
repeaterType: { type: 'string' },
|
|
120
|
+
value: {
|
|
121
|
+
type: 'array',
|
|
122
|
+
items: {
|
|
123
|
+
$ref: 'pageService.blockSchema'
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
required: ['key', 'type', 'repeaterType'],
|
|
128
|
+
additionalProperties: false
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
schema.addSchema(blockSchema);
|
|
133
|
+
schema.addSchema(textInputSchema);
|
|
134
|
+
schema.addSchema(richTextSchema);
|
|
135
|
+
schema.addSchema(imageSchema);
|
|
136
|
+
schema.addSchema(repeaterSchema);
|
|
137
|
+
|
|
138
|
+
export const validatePage = schema.compile(pageSchema);
|
|
139
|
+
export const validateBlock = schema.compile(blockSchema);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { db, logger } from '@gnar-engine/core';
|
|
2
|
+
import { ObjectId } from 'mongodb';
|
|
3
|
+
|
|
4
|
+
export const block = {
|
|
5
|
+
|
|
6
|
+
// Get all blocks
|
|
7
|
+
getAll: async () => {
|
|
8
|
+
try {
|
|
9
|
+
const items = await db.collection('blocks').find().toArray();
|
|
10
|
+
return items.map(mappings);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
logger.error("Error fetching blocks:", error);
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
// Create a block
|
|
18
|
+
create: async (data) => {
|
|
19
|
+
try {
|
|
20
|
+
const collection = db.collection('blocks');
|
|
21
|
+
const result = await collection.insertOne(data);
|
|
22
|
+
const insterted = await collection.findOne({ _id: result.insertedId });
|
|
23
|
+
return mappings(insterted);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
logger.error("Error creating block:", error);
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
// Get a block by ID
|
|
31
|
+
getById: async ({ id }) => {
|
|
32
|
+
try {
|
|
33
|
+
const collection = db.collection('blocks');
|
|
34
|
+
const objectId = new ObjectId(id);
|
|
35
|
+
const item = await collection.findOne({ _id: objectId });
|
|
36
|
+
return mappings(item);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error("Error fetching block:", error);
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// Update a block
|
|
44
|
+
update: async ({ id, updatedData }) => {
|
|
45
|
+
try {
|
|
46
|
+
const collection = db.collection('blocks');
|
|
47
|
+
const objectId = new ObjectId(id);
|
|
48
|
+
const result = await collection.updateOne(
|
|
49
|
+
{ _id: objectId },
|
|
50
|
+
{ $set: updatedData }
|
|
51
|
+
);
|
|
52
|
+
return result.modifiedCount > 0;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
logger.error("Error updating block:", error);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// Delete a block
|
|
60
|
+
delete: async ({ id }) => {
|
|
61
|
+
try {
|
|
62
|
+
const collection = db.collection('blocks');
|
|
63
|
+
const objectId = new ObjectId(id);
|
|
64
|
+
const result = await collection.deleteOne({ _id: objectId });
|
|
65
|
+
return result.deletedCount > 0;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
logger.error("Error deleting block:", error);
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const mappings = (item) => {
|
|
74
|
+
if (!item) {
|
|
75
|
+
return item;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// _id -> id
|
|
79
|
+
const { _id, ...rest } = item;
|
|
80
|
+
item = { id: _id.toString(), ...rest };
|
|
81
|
+
|
|
82
|
+
return item;
|
|
83
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { db, logger } from '@gnar-engine/core';
|
|
2
|
+
import { ObjectId } from 'mongodb';
|
|
3
|
+
|
|
4
|
+
export const page = {
|
|
5
|
+
|
|
6
|
+
// Get all pages
|
|
7
|
+
getAll: async () => {
|
|
8
|
+
try {
|
|
9
|
+
const items = await db.collection('pages').find().toArray();
|
|
10
|
+
return items.map(mappings);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
logger.error("Error fetching pages:", error);
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
// Create a page
|
|
18
|
+
create: async (data) => {
|
|
19
|
+
try {
|
|
20
|
+
const collection = db.collection('pages');
|
|
21
|
+
const result = await collection.insertOne(data);
|
|
22
|
+
const insterted = await collection.findOne({ _id: result.insertedId });
|
|
23
|
+
return mappings(insterted);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
logger.error("Error creating page:", error);
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
// Get a page by ID
|
|
31
|
+
getById: async ({ id }) => {
|
|
32
|
+
try {
|
|
33
|
+
const collection = db.collection('pages');
|
|
34
|
+
const objectId = new ObjectId(id);
|
|
35
|
+
const item = await collection.findOne({ _id: objectId });
|
|
36
|
+
return mappings(item);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error("Error fetching page:", error);
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// Update a page
|
|
44
|
+
update: async ({ id, updatedData }) => {
|
|
45
|
+
try {
|
|
46
|
+
const collection = db.collection('pages');
|
|
47
|
+
const objectId = new ObjectId(id);
|
|
48
|
+
const result = await collection.updateOne(
|
|
49
|
+
{ _id: objectId },
|
|
50
|
+
{ $set: updatedData }
|
|
51
|
+
);
|
|
52
|
+
return result.modifiedCount > 0;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
logger.error("Error updating page:", error);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// Delete a page
|
|
60
|
+
delete: async ({ id }) => {
|
|
61
|
+
try {
|
|
62
|
+
const collection = db.collection('pages');
|
|
63
|
+
const objectId = new ObjectId(id);
|
|
64
|
+
const result = await collection.deleteOne({ _id: objectId });
|
|
65
|
+
return result.deletedCount > 0;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
logger.error("Error deleting page:", error);
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const mappings = (item) => {
|
|
74
|
+
if (!item) {
|
|
75
|
+
return item;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// _id -> id
|
|
79
|
+
const { _id, ...rest } = item;
|
|
80
|
+
item = { id: _id.toString(), ...rest };
|
|
81
|
+
|
|
82
|
+
return item;
|
|
83
|
+
}
|
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
# Dockerfile for
|
|
1
|
+
# Dockerfile for Control Service
|
|
2
2
|
FROM node:20-alpine
|
|
3
3
|
|
|
4
4
|
# Set the working directory
|
|
5
5
|
WORKDIR /usr/gnar_engine/app
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# Copy public directory
|
|
11
|
-
COPY ./services/portal/public ./public
|
|
7
|
+
# Define a global env var
|
|
8
|
+
ENV GLOBAL_SERVICE_BASE_DIR=/usr/gnar_engine/app/src/
|
|
12
9
|
|
|
13
|
-
# Copy
|
|
14
|
-
COPY ./
|
|
10
|
+
# Copy package.json and package-lock.json
|
|
11
|
+
COPY ./services/portal/ ./
|
|
15
12
|
|
|
16
13
|
# Install app dependencies
|
|
17
14
|
RUN npm install
|
|
18
15
|
|
|
19
16
|
# Expose the port the service will run on
|
|
20
|
-
EXPOSE
|
|
17
|
+
EXPOSE 5173
|
|
21
18
|
|
|
22
19
|
# Start the application
|
|
23
|
-
CMD ["npm", "run", "start"]
|
|
20
|
+
CMD ["npm", "run", "start:dev"]
|
|
@@ -1,22 +1,73 @@
|
|
|
1
|
-
#
|
|
1
|
+
# React + TypeScript + Vite
|
|
2
2
|
|
|
3
|
-
React
|
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Currently, two official plugins are available:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
# Checkout local production branch
|
|
11
|
-
git branch checkout production
|
|
10
|
+
## React Compiler
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
npm run build-style
|
|
15
|
-
npm run build
|
|
12
|
+
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
npm run deploy
|
|
14
|
+
## Expanding the ESLint configuration
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
```
|
|
16
|
+
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
export default defineConfig([
|
|
20
|
+
globalIgnores(['dist']),
|
|
21
|
+
{
|
|
22
|
+
files: ['**/*.{ts,tsx}'],
|
|
23
|
+
extends: [
|
|
24
|
+
// Other configs...
|
|
25
|
+
|
|
26
|
+
// Remove tseslint.configs.recommended and replace with this
|
|
27
|
+
tseslint.configs.recommendedTypeChecked,
|
|
28
|
+
// Alternatively, use this for stricter rules
|
|
29
|
+
tseslint.configs.strictTypeChecked,
|
|
30
|
+
// Optionally, add this for stylistic rules
|
|
31
|
+
tseslint.configs.stylisticTypeChecked,
|
|
32
|
+
|
|
33
|
+
// Other configs...
|
|
34
|
+
],
|
|
35
|
+
languageOptions: {
|
|
36
|
+
parserOptions: {
|
|
37
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
38
|
+
tsconfigRootDir: import.meta.dirname,
|
|
39
|
+
},
|
|
40
|
+
// other options...
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
])
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
// eslint.config.js
|
|
50
|
+
import reactX from 'eslint-plugin-react-x'
|
|
51
|
+
import reactDom from 'eslint-plugin-react-dom'
|
|
52
|
+
|
|
53
|
+
export default defineConfig([
|
|
54
|
+
globalIgnores(['dist']),
|
|
55
|
+
{
|
|
56
|
+
files: ['**/*.{ts,tsx}'],
|
|
57
|
+
extends: [
|
|
58
|
+
// Other configs...
|
|
59
|
+
// Enable lint rules for React
|
|
60
|
+
reactX.configs['recommended-typescript'],
|
|
61
|
+
// Enable lint rules for React DOM
|
|
62
|
+
reactDom.configs.recommended,
|
|
63
|
+
],
|
|
64
|
+
languageOptions: {
|
|
65
|
+
parserOptions: {
|
|
66
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
67
|
+
tsconfigRootDir: import.meta.dirname,
|
|
68
|
+
},
|
|
69
|
+
// other options...
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
])
|
|
73
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>portal</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|