@nathapp/na-cli 1.0.8 → 1.0.10
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/dist/templates/db-schema/.gitlab-ci.yml +139 -0
- package/dist/templates/db-schema/Makefile +885 -0
- package/dist/templates/k8s-deployment/.gitlab-ci.yml +158 -0
- package/dist/templates/k8s-deployment/Makefile +233 -0
- package/dist/templates/k8s-deployment/resources/charts/mysql/charts/mysql-install/script/Makefile +12 -0
- package/dist/templates/k8s-deployment/resources/charts/redis/charts/redis-install/script/Makefile +8 -0
- package/dist/templates/k8s-deployment/services/charts/hooks/charts/pre-delete-rsc/script/Makefile +56 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-cypress/Makefile +9 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/script/Makefile +14 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/_t-0100-readiness-liveness.ts +84 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/hub.ts +372 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/individual-contact.ts +158 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/individual-contract.ts +328 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/individual-kyc.ts +304 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/individual-onboard-app.ts +823 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/individual-onboard-web.ts +493 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/individual-profile.ts +277 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/individual-whitelist.ts +133 -0
- package/dist/templates/k8s-deployment/services/charts/tests/charts/e2e-test-js/tests/t-0200-start.ts +172 -0
- package/dist/templates/nestjs-api/.dockerignore +9 -0
- package/dist/templates/nestjs-api/.env +35 -0
- package/dist/templates/nestjs-api/.env.local +5 -29
- package/dist/templates/nestjs-api/.gitlab-ci.yml +180 -0
- package/dist/templates/nestjs-api/.nvmrc +1 -0
- package/dist/templates/nestjs-api/.prettierrc +4 -0
- package/dist/templates/nestjs-api/Makefile +95 -0
- package/dist/templates/nestjs-api/README.md +15 -0
- package/dist/templates/nestjs-api/nest-cli.json +10 -0
- package/dist/templates/nestjs-api/ormconfig.ts +16 -0
- package/dist/templates/nestjs-api/package.json +9 -9
- package/dist/templates/nestjs-api/src/app.controller.spec.ts +24 -0
- package/dist/templates/nestjs-api/src/app.controller.ts +27 -0
- package/dist/templates/nestjs-api/src/app.module.ts +33 -0
- package/dist/templates/nestjs-api/src/app.service.ts +27 -0
- package/dist/templates/nestjs-api/src/main.ts +31 -0
- package/dist/templates/nestjs-api/test/app.e2e-spec.ts +47 -0
- package/dist/templates/nestjs-api/tsconfig.build.json +5 -0
- package/dist/templates/nestjs-api/tsconfig.json +28 -0
- package/dist/templates/nestjs-api/tsconfig.spec.json +9 -0
- package/dist/templates/nestjs-library/.gitlab-ci.yml +134 -0
- package/dist/templates/nestjs-library/.nvmrc +1 -0
- package/dist/templates/nestjs-library/.prettierrc +6 -0
- package/dist/templates/nestjs-library/Makefile +60 -0
- package/dist/templates/nestjs-library/lib/index.ts +2 -0
- package/dist/templates/nestjs-library/test/app/controller/hello.controller.spec.ts +20 -0
- package/dist/templates/nestjs-library/test/app/controller/hello.controller.ts +7 -0
- package/dist/templates/nestjs-library/tsconfig.build.json +8 -0
- package/dist/templates/nestjs-library/tsconfig.json +21 -0
- package/dist/templates/nestjs-library/tsconfig.spec.json +9 -0
- package/dist/templates/ts-library/.dockerignore +2 -0
- package/dist/templates/ts-library/.eslintrc.js +24 -0
- package/dist/templates/ts-library/.gitlab-ci.yml +136 -0
- package/dist/templates/ts-library/.prettierrc +6 -0
- package/dist/templates/ts-library/Makefile +58 -0
- package/dist/templates/ts-library/index.ts +1 -0
- package/dist/templates/ts-library/lib/index.ts +1 -0
- package/dist/templates/ts-library/lib/samples/index.ts +5 -0
- package/dist/templates/ts-library/lib/samples/samples-function.ts +3 -0
- package/dist/templates/ts-library/test/sample.e2e-spec.ts +10 -0
- package/dist/templates/ts-library/tsconfig.build.json +4 -0
- package/dist/templates/ts-library/tsconfig.json +18 -0
- package/dist/templates/turbo-nestjs-vuexy/.dockerignore +2 -0
- package/dist/templates/turbo-nestjs-vuexy/.gitignore-rename +40 -0
- package/dist/templates/turbo-nestjs-vuexy/.npmrc-rename +0 -0
- package/dist/templates/turbo-nestjs-vuexy/Makefile +48 -0
- package/dist/templates/vuexy-portal/.dockerignore +2 -0
- package/dist/templates/vuexy-portal/.env +1 -0
- package/dist/templates/vuexy-portal/.gitlab-ci.yml +233 -0
- package/dist/templates/vuexy-portal/.npmrc-rename +2 -0
- package/dist/templates/vuexy-portal/.nvmrc +1 -0
- package/dist/templates/vuexy-portal/Makefile +55 -0
- package/dist/templates/vuexy-portal/src/@core/composable/createUrl.ts +20 -0
- package/dist/templates/vuexy-portal/src/@core/composable/useCookie.ts +43 -0
- package/dist/templates/vuexy-portal/src/@core/composable/useGenerateImageVariant.ts +25 -0
- package/dist/templates/vuexy-portal/src/@core/composable/useResponsiveSidebar.ts +29 -0
- package/dist/templates/vuexy-portal/src/@core/composable/useSkins.ts +42 -0
- package/dist/templates/vuexy-portal/src/@core/enums.ts +21 -0
- package/dist/templates/vuexy-portal/src/@core/index.ts +43 -0
- package/dist/templates/vuexy-portal/src/@core/initCore.ts +93 -0
- package/dist/templates/vuexy-portal/src/@core/libs/apex-chart/apexCharConfig.ts +701 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/chartjsConfig.ts +372 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/components/BarChart.ts +58 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/components/BubbleChart.ts +58 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/components/DoughnutChart.ts +58 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/components/LineChart.ts +58 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/components/PolarAreaChart.ts +58 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/components/RadarChart.ts +58 -0
- package/dist/templates/vuexy-portal/src/@core/libs/chartjs/components/ScatterChart.ts +58 -0
- package/dist/templates/vuexy-portal/src/@core/stores/config.ts +80 -0
- package/dist/templates/vuexy-portal/src/@core/types.ts +49 -0
- package/dist/templates/vuexy-portal/src/@core/utils/formatters.ts +48 -0
- package/dist/templates/vuexy-portal/src/@core/utils/helpers.ts +32 -0
- package/dist/templates/vuexy-portal/src/@core/utils/plugins.ts +53 -0
- package/dist/templates/vuexy-portal/src/@core/utils/validators.ts +105 -0
- package/dist/templates/vuexy-portal/src/@core/utils/vuetify.ts +13 -0
- package/dist/templates/vuexy-portal/src/@custom/composables/toasts.ts +45 -0
- package/dist/templates/vuexy-portal/src/@custom/composables/validator.ts +160 -0
- package/dist/templates/vuexy-portal/src/@custom/enums/index.ts +0 -0
- package/dist/templates/vuexy-portal/src/@custom/types/common.ts +17 -0
- package/dist/templates/vuexy-portal/src/@custom/types/index.ts +0 -0
- package/dist/templates/vuexy-portal/src/@custom/types/pagination.ts +19 -0
- package/dist/templates/vuexy-portal/src/@custom/types/user.ts +5 -0
- package/dist/templates/vuexy-portal/src/@custom/utils/formatters.ts +83 -0
- package/dist/templates/vuexy-portal/src/@custom/utils/index.ts +0 -0
- package/dist/templates/vuexy-portal/src/@custom/utils/validators.ts +51 -0
- package/dist/templates/vuexy-portal/src/@layouts/components.ts +11 -0
- package/dist/templates/vuexy-portal/src/@layouts/config.ts +43 -0
- package/dist/templates/vuexy-portal/src/@layouts/enums.ts +27 -0
- package/dist/templates/vuexy-portal/src/@layouts/index.ts +49 -0
- package/dist/templates/vuexy-portal/src/@layouts/plugins/casl.ts +48 -0
- package/dist/templates/vuexy-portal/src/@layouts/stores/config.ts +115 -0
- package/dist/templates/vuexy-portal/src/@layouts/symbols.ts +1 -0
- package/dist/templates/vuexy-portal/src/@layouts/types.ts +126 -0
- package/dist/templates/vuexy-portal/src/@layouts/utils.ts +180 -0
- package/dist/templates/vuexy-portal/src/api/api.ts +1 -0
- package/dist/templates/vuexy-portal/src/api/commonApi.ts +25 -0
- package/dist/templates/vuexy-portal/src/api/index.ts +58 -0
- package/dist/templates/vuexy-portal/src/api/requestInterceptor.ts +21 -0
- package/dist/templates/vuexy-portal/src/api/responseInterceptor.ts +52 -0
- package/dist/templates/vuexy-portal/src/api/types.ts +14 -0
- package/dist/templates/vuexy-portal/src/api/useApi.ts +68 -0
- package/dist/templates/vuexy-portal/src/api/useFetchApi.ts +41 -0
- package/dist/templates/vuexy-portal/src/api/userApi.ts +11 -0
- package/dist/templates/vuexy-portal/src/composables/useApiFetch.ts +48 -0
- package/dist/templates/vuexy-portal/src/composables/useJwt.ts +108 -0
- package/dist/templates/vuexy-portal/src/main.ts +17 -0
- package/dist/templates/vuexy-portal/src/navigation/horizontal/index.ts +5 -0
- package/dist/templates/vuexy-portal/src/navigation/index.ts +7 -0
- package/dist/templates/vuexy-portal/src/navigation/vertical/index.ts +5 -0
- package/dist/templates/vuexy-portal/src/plugins/1.router/additional-routes.ts +23 -0
- package/dist/templates/vuexy-portal/src/plugins/1.router/guards.ts +50 -0
- package/dist/templates/vuexy-portal/src/plugins/1.router/index.ts +45 -0
- package/dist/templates/vuexy-portal/src/plugins/2.pinia.ts +8 -0
- package/dist/templates/vuexy-portal/src/plugins/casl/ability.ts +10 -0
- package/dist/templates/vuexy-portal/src/plugins/casl/composables/useAbility.ts +4 -0
- package/dist/templates/vuexy-portal/src/plugins/casl/index.ts +14 -0
- package/dist/templates/vuexy-portal/src/plugins/i18n/index.ts +29 -0
- package/dist/templates/vuexy-portal/src/plugins/iconify/build-icons.ts +299 -0
- package/dist/templates/vuexy-portal/src/plugins/iconify/index.ts +5 -0
- package/dist/templates/vuexy-portal/src/plugins/layouts.ts +13 -0
- package/dist/templates/vuexy-portal/src/plugins/toast/index.ts +9 -0
- package/dist/templates/vuexy-portal/src/plugins/vuetify/defaults.ts +192 -0
- package/dist/templates/vuexy-portal/src/plugins/vuetify/icons.ts +84 -0
- package/dist/templates/vuexy-portal/src/plugins/vuetify/index.ts +47 -0
- package/dist/templates/vuexy-portal/src/plugins/vuetify/theme.ts +155 -0
- package/dist/templates/vuexy-portal/src/plugins/webfontloader.ts +19 -0
- package/dist/templates/vuexy-portal/src/stores/auth.ts +22 -0
- package/dist/templates/vuexy-portal/src/stores/common.ts +41 -0
- package/dist/templates/vuexy-portal/src/stores/index.ts +0 -0
- package/dist/templates/vuexy-portal/src/utils/constants.ts +3 -0
- package/dist/templates/vuexy-portal/src/utils/paginationMeta.ts +10 -0
- package/dist/templates/vuexy-portal/themeConfig.ts +66 -0
- package/dist/templates/vuexy-portal/tsconfig.json +86 -0
- package/dist/templates/vuexy-portal/vite.config.ts +111 -0
- package/dist/utils/jwt-keys.js +26 -0
- package/dist/utils/jwt-keys.js.map +1 -0
- package/dist/utils/template.js +4 -1
- package/dist/utils/template.js.map +1 -1
- package/package.json +4 -1
- package/alias-script.sh +0 -30
- package/bunfig.toml +0 -3
- package/nax/config.json +0 -23
- package/nax/features/enhancements/prd.json +0 -61
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RouteRecordRaw } from 'vue-router/auto'
|
|
2
|
+
|
|
3
|
+
// const emailRouteComponent = () => import('@/pages/apps/email/index.vue')
|
|
4
|
+
|
|
5
|
+
// 👉 Redirects
|
|
6
|
+
export const redirects: RouteRecordRaw[] = [
|
|
7
|
+
// ℹ️ We are redirecting to different pages based on role.
|
|
8
|
+
// NOTE: Role is just for UI purposes. ACL is based on abilities.
|
|
9
|
+
// {
|
|
10
|
+
// path: '/pages/user-profile',
|
|
11
|
+
// name: 'pages-user-profile',
|
|
12
|
+
// redirect: () => ({ name: 'pages-user-profile-tab', params: { tab: 'profile' } }),
|
|
13
|
+
// },
|
|
14
|
+
{
|
|
15
|
+
path: '/account-settings',
|
|
16
|
+
name: 'account-settings',
|
|
17
|
+
redirect: () => ({ name: 'account-settings-tab', params: { tab: 'security' } }),
|
|
18
|
+
},
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
export const routes: RouteRecordRaw[] = [
|
|
22
|
+
|
|
23
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Router } from 'vue-router'
|
|
2
|
+
import { canNavigate } from '@layouts/plugins/casl'
|
|
3
|
+
|
|
4
|
+
export const setupGuards = (router: Router) => {
|
|
5
|
+
// 👉 router.beforeEach
|
|
6
|
+
// Docs: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards
|
|
7
|
+
router.beforeEach(to => {
|
|
8
|
+
/*
|
|
9
|
+
* If it's a public route, continue navigation. This kind of pages are allowed to visited by login & non-login users. Basically, without any restrictions.
|
|
10
|
+
* Examples of public routes are, 404, under maintenance, etc.
|
|
11
|
+
*/
|
|
12
|
+
if (to.meta.public)
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if user is logged in by checking if token & user data exists in local storage
|
|
17
|
+
* Feel free to update this logic to suit your needs
|
|
18
|
+
*/
|
|
19
|
+
const isLoggedIn = !!(useCookie('userData').value && useCookie('accessToken').value)
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
If user is logged in and is trying to access login like page, redirect to home
|
|
23
|
+
else allow visiting the page
|
|
24
|
+
(WARN: Don't allow executing further by return statement because next code will check for permissions)
|
|
25
|
+
*/
|
|
26
|
+
if (to.meta.unauthenticatedOnly) {
|
|
27
|
+
if (isLoggedIn)
|
|
28
|
+
return '/'
|
|
29
|
+
else
|
|
30
|
+
return undefined
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (to.meta.authenticatedOnly && isLoggedIn)
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
if (!canNavigate(to) && to.matched.length) {
|
|
37
|
+
/* eslint-disable indent */
|
|
38
|
+
return isLoggedIn
|
|
39
|
+
? { name: 'not-authorized' }
|
|
40
|
+
: {
|
|
41
|
+
name: 'login',
|
|
42
|
+
query: {
|
|
43
|
+
...to.query,
|
|
44
|
+
to: to.fullPath !== '/' ? to.path : undefined,
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
/* eslint-enable indent */
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
|
|
3
|
+
import { setupLayouts } from 'virtual:generated-layouts'
|
|
4
|
+
import type { RouteRecordRaw } from 'vue-router/auto'
|
|
5
|
+
|
|
6
|
+
import { createRouter, createWebHistory } from 'vue-router/auto'
|
|
7
|
+
|
|
8
|
+
import { redirects, routes } from './additional-routes'
|
|
9
|
+
import { setupGuards } from './guards'
|
|
10
|
+
|
|
11
|
+
function recursiveLayouts(route: RouteRecordRaw): RouteRecordRaw {
|
|
12
|
+
if (route.children) {
|
|
13
|
+
for (let i = 0; i < route.children.length; i++)
|
|
14
|
+
route.children[i] = recursiveLayouts(route.children[i])
|
|
15
|
+
|
|
16
|
+
return route
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return setupLayouts([route])[0]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const router = createRouter({
|
|
23
|
+
history: createWebHistory(import.meta.env.BASE_URL),
|
|
24
|
+
scrollBehavior(to) {
|
|
25
|
+
if (to.hash)
|
|
26
|
+
return { el: to.hash, behavior: 'smooth', top: 60 }
|
|
27
|
+
|
|
28
|
+
return { top: 0 }
|
|
29
|
+
},
|
|
30
|
+
extendRoutes: pages => [
|
|
31
|
+
...redirects,
|
|
32
|
+
...[
|
|
33
|
+
...pages,
|
|
34
|
+
...routes,
|
|
35
|
+
].map(route => recursiveLayouts(route)),
|
|
36
|
+
],
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
setupGuards(router)
|
|
40
|
+
|
|
41
|
+
export { router }
|
|
42
|
+
|
|
43
|
+
export default function (app: App) {
|
|
44
|
+
app.use(router)
|
|
45
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createMongoAbility } from '@casl/ability'
|
|
2
|
+
|
|
3
|
+
export type Actions = 'create' | 'read' | 'update' | 'delete' | 'manage'
|
|
4
|
+
|
|
5
|
+
// ex: Post, Comment, User, etc. We haven't used any of these in our demo though.
|
|
6
|
+
export type Subjects = 'Post' | 'Comment' | 'all'
|
|
7
|
+
|
|
8
|
+
export interface Rule { action: Actions; subject: Subjects }
|
|
9
|
+
|
|
10
|
+
export const ability = createMongoAbility<[Actions, Subjects]>()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
|
|
3
|
+
import { createMongoAbility } from '@casl/ability'
|
|
4
|
+
import { abilitiesPlugin } from '@casl/vue'
|
|
5
|
+
import type { Rule } from './ability'
|
|
6
|
+
|
|
7
|
+
export default function (app: App) {
|
|
8
|
+
const userAbilityRules = useCookie<Rule[]>('userAbilityRules')
|
|
9
|
+
const initialAbility = createMongoAbility(userAbilityRules.value ?? [])
|
|
10
|
+
|
|
11
|
+
app.use(abilitiesPlugin, initialAbility, {
|
|
12
|
+
useGlobalProperties: true,
|
|
13
|
+
})
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { cookieRef } from '@layouts/stores/config'
|
|
2
|
+
import { themeConfig } from '@themeConfig'
|
|
3
|
+
import type { App } from 'vue'
|
|
4
|
+
import { createI18n } from 'vue-i18n'
|
|
5
|
+
|
|
6
|
+
const messages = Object.fromEntries(
|
|
7
|
+
Object.entries(
|
|
8
|
+
import.meta.glob<{ default: any }>('./locales/*.json', { eager: true }))
|
|
9
|
+
.map(([key, value]) => [key.slice(10, -5), value.default]),
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
let _i18n: any = null
|
|
13
|
+
|
|
14
|
+
export const getI18n = () => {
|
|
15
|
+
if (_i18n === null) {
|
|
16
|
+
_i18n = createI18n({
|
|
17
|
+
legacy: false,
|
|
18
|
+
locale: cookieRef('language', themeConfig.app.i18n.defaultLocale).value,
|
|
19
|
+
fallbackLocale: 'en_US',
|
|
20
|
+
messages,
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return _i18n
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default function (app: App) {
|
|
28
|
+
app.use(getI18n())
|
|
29
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is an advanced example for creating icon bundles for Iconify SVG Framework.
|
|
3
|
+
*
|
|
4
|
+
* It creates a bundle from:
|
|
5
|
+
* - All SVG files in a directory.
|
|
6
|
+
* - Custom JSON files.
|
|
7
|
+
* - Iconify icon sets.
|
|
8
|
+
* - SVG framework.
|
|
9
|
+
*
|
|
10
|
+
* This example uses Iconify Tools to import and clean up icons.
|
|
11
|
+
* For Iconify Tools documentation visit https://docs.iconify.design/tools/tools2/
|
|
12
|
+
*/
|
|
13
|
+
import { promises as fs } from 'node:fs'
|
|
14
|
+
import { dirname, join } from 'node:path'
|
|
15
|
+
|
|
16
|
+
// Installation: npm install --save-dev @iconify/tools @iconify/utils @iconify/json @iconify/iconify
|
|
17
|
+
import { cleanupSVG, importDirectory, isEmptyColor, parseColors, runSVGO } from '@iconify/tools'
|
|
18
|
+
import type { IconifyJSON } from '@iconify/types'
|
|
19
|
+
import { getIcons, getIconsCSS, stringToIcon } from '@iconify/utils'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Script configuration
|
|
23
|
+
*/
|
|
24
|
+
interface BundleScriptCustomSVGConfig {
|
|
25
|
+
|
|
26
|
+
// Path to SVG files
|
|
27
|
+
dir: string
|
|
28
|
+
|
|
29
|
+
// True if icons should be treated as monotone: colors replaced with currentColor
|
|
30
|
+
monotone: boolean
|
|
31
|
+
|
|
32
|
+
// Icon set prefix
|
|
33
|
+
prefix: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface BundleScriptCustomJSONConfig {
|
|
37
|
+
|
|
38
|
+
// Path to JSON file
|
|
39
|
+
filename: string
|
|
40
|
+
|
|
41
|
+
// List of icons to import. If missing, all icons will be imported
|
|
42
|
+
icons?: string[]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface BundleScriptConfig {
|
|
46
|
+
|
|
47
|
+
// Custom SVG to import and bundle
|
|
48
|
+
svg?: BundleScriptCustomSVGConfig[]
|
|
49
|
+
|
|
50
|
+
// Icons to bundled from @iconify/json packages
|
|
51
|
+
icons?: string[]
|
|
52
|
+
|
|
53
|
+
// List of JSON files to bundled
|
|
54
|
+
// Entry can be a string, pointing to filename or a BundleScriptCustomJSONConfig object (see type above)
|
|
55
|
+
// If entry is a string or object without 'icons' property, an entire JSON file will be bundled
|
|
56
|
+
json?: (string | BundleScriptCustomJSONConfig)[]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const sources: BundleScriptConfig = {
|
|
60
|
+
|
|
61
|
+
svg: [
|
|
62
|
+
// {
|
|
63
|
+
// dir: 'src/assets/images/iconify-svg',
|
|
64
|
+
// monotone: true,
|
|
65
|
+
// prefix: 'custom',
|
|
66
|
+
// },
|
|
67
|
+
|
|
68
|
+
// {
|
|
69
|
+
// dir: 'emojis',
|
|
70
|
+
// monotone: false,
|
|
71
|
+
// prefix: 'emoji',
|
|
72
|
+
// },
|
|
73
|
+
],
|
|
74
|
+
|
|
75
|
+
icons: [
|
|
76
|
+
// 'mdi:home',
|
|
77
|
+
// 'mdi:account',
|
|
78
|
+
// 'mdi:login',
|
|
79
|
+
// 'mdi:logout',
|
|
80
|
+
// 'octicon:book-24',
|
|
81
|
+
// 'octicon:code-square-24',
|
|
82
|
+
],
|
|
83
|
+
|
|
84
|
+
json: [
|
|
85
|
+
// Custom JSON file
|
|
86
|
+
// 'json/gg.json',
|
|
87
|
+
|
|
88
|
+
// Iconify JSON file (@iconify/json is a package name, /json/ is directory where files are, then filename)
|
|
89
|
+
require.resolve('@iconify-json/tabler/icons.json'),
|
|
90
|
+
{
|
|
91
|
+
filename: require.resolve('@iconify-json/mdi/icons.json'),
|
|
92
|
+
icons: [
|
|
93
|
+
'close-circle',
|
|
94
|
+
'language-javascript',
|
|
95
|
+
'language-typescript',
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
filename: require.resolve('@iconify-json/fa/icons.json'),
|
|
100
|
+
icons: [
|
|
101
|
+
'circle',
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// Custom file with only few icons
|
|
106
|
+
// {
|
|
107
|
+
// filename: require.resolve('@iconify-json/line-md/icons.json'),
|
|
108
|
+
// icons: [
|
|
109
|
+
// 'home-twotone-alt',
|
|
110
|
+
// 'github',
|
|
111
|
+
// 'document-list',
|
|
112
|
+
// 'document-code',
|
|
113
|
+
// 'image-twotone',
|
|
114
|
+
// ],
|
|
115
|
+
// },
|
|
116
|
+
],
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// File to save bundle to
|
|
120
|
+
const target = join(__dirname, 'icons.css')
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Do stuff!
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
;(async function () {
|
|
127
|
+
// Create directory for output if missing
|
|
128
|
+
const dir = dirname(target)
|
|
129
|
+
try {
|
|
130
|
+
await fs.mkdir(dir, {
|
|
131
|
+
recursive: true,
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
//
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const allIcons: IconifyJSON[] = []
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Convert sources.icons to sources.json
|
|
142
|
+
*/
|
|
143
|
+
if (sources.icons) {
|
|
144
|
+
const sourcesJSON = sources.json ? sources.json : (sources.json = [])
|
|
145
|
+
|
|
146
|
+
// Sort icons by prefix
|
|
147
|
+
const organizedList = organizeIconsList(sources.icons)
|
|
148
|
+
|
|
149
|
+
for (const prefix in organizedList) {
|
|
150
|
+
const filename = require.resolve(`@iconify/json/json/${prefix}.json`)
|
|
151
|
+
|
|
152
|
+
sourcesJSON.push({
|
|
153
|
+
filename,
|
|
154
|
+
icons: organizedList[prefix],
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Bundle JSON files and collect icons
|
|
161
|
+
*/
|
|
162
|
+
if (sources.json) {
|
|
163
|
+
for (let i = 0; i < sources.json.length; i++) {
|
|
164
|
+
const item = sources.json[i]
|
|
165
|
+
|
|
166
|
+
// Load icon set
|
|
167
|
+
const filename = typeof item === 'string' ? item : item.filename
|
|
168
|
+
const content = JSON.parse(await fs.readFile(filename, 'utf8')) as IconifyJSON
|
|
169
|
+
|
|
170
|
+
for (const key in content) {
|
|
171
|
+
if (key === 'prefix' && content.prefix === 'tabler') {
|
|
172
|
+
for (const k in content.icons)
|
|
173
|
+
content.icons[k].body = content.icons[k].body.replace(/stroke-width="2"/g, 'stroke-width="1.5"')
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Filter icons
|
|
178
|
+
if (typeof item !== 'string' && item.icons?.length) {
|
|
179
|
+
const filteredContent = getIcons(content, item.icons)
|
|
180
|
+
|
|
181
|
+
if (!filteredContent)
|
|
182
|
+
throw new Error(`Cannot find required icons in ${filename}`)
|
|
183
|
+
|
|
184
|
+
// Collect filtered icons
|
|
185
|
+
allIcons.push(filteredContent)
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
// Collect all icons from the JSON file
|
|
189
|
+
allIcons.push(content)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Bundle custom SVG icons and collect icons
|
|
196
|
+
*/
|
|
197
|
+
if (sources.svg) {
|
|
198
|
+
for (let i = 0; i < sources.svg.length; i++) {
|
|
199
|
+
const source = sources.svg[i]
|
|
200
|
+
|
|
201
|
+
// Import icons
|
|
202
|
+
const iconSet = await importDirectory(source.dir, {
|
|
203
|
+
prefix: source.prefix,
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
// Validate, clean up, fix palette, etc.
|
|
207
|
+
await iconSet.forEach(async (name, type) => {
|
|
208
|
+
if (type !== 'icon')
|
|
209
|
+
return
|
|
210
|
+
|
|
211
|
+
// Get SVG instance for parsing
|
|
212
|
+
const svg = iconSet.toSVG(name)
|
|
213
|
+
|
|
214
|
+
if (!svg) {
|
|
215
|
+
// Invalid icon
|
|
216
|
+
iconSet.remove(name)
|
|
217
|
+
|
|
218
|
+
return
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Clean up and optimise icons
|
|
222
|
+
try {
|
|
223
|
+
// Clean up icon code
|
|
224
|
+
await cleanupSVG(svg)
|
|
225
|
+
|
|
226
|
+
if (source.monotone) {
|
|
227
|
+
// Replace color with currentColor, add if missing
|
|
228
|
+
// If icon is not monotone, remove this code
|
|
229
|
+
await parseColors(svg, {
|
|
230
|
+
defaultColor: 'currentColor',
|
|
231
|
+
callback: (attr, colorStr, color) => {
|
|
232
|
+
return !color || isEmptyColor(color) ? colorStr : 'currentColor'
|
|
233
|
+
},
|
|
234
|
+
})
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Optimise
|
|
238
|
+
await runSVGO(svg)
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
// Invalid icon
|
|
242
|
+
console.error(`Error parsing ${name} from ${source.dir}:`, err)
|
|
243
|
+
iconSet.remove(name)
|
|
244
|
+
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Update icon from SVG instance
|
|
249
|
+
iconSet.fromSVG(name, svg)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
// Collect the SVG icon
|
|
253
|
+
allIcons.push(iconSet.export())
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Generate CSS from collected icons
|
|
258
|
+
const cssContent = allIcons
|
|
259
|
+
.map(iconSet => getIconsCSS(
|
|
260
|
+
iconSet,
|
|
261
|
+
Object.keys(iconSet.icons),
|
|
262
|
+
{
|
|
263
|
+
iconSelector: '.{prefix}-{name}',
|
|
264
|
+
mode: 'mask',
|
|
265
|
+
},
|
|
266
|
+
))
|
|
267
|
+
.join('\n')
|
|
268
|
+
|
|
269
|
+
// Save the CSS to a file
|
|
270
|
+
await fs.writeFile(target, cssContent, 'utf8')
|
|
271
|
+
|
|
272
|
+
console.log(`Saved CSS to ${target}!`)
|
|
273
|
+
})().catch(err => {
|
|
274
|
+
console.error(err)
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Sort icon names by prefix
|
|
279
|
+
*/
|
|
280
|
+
function organizeIconsList(icons: string[]): Record<string, string[]> {
|
|
281
|
+
const sorted: Record<string, string[]> = Object.create(null)
|
|
282
|
+
|
|
283
|
+
icons.forEach(icon => {
|
|
284
|
+
const item = stringToIcon(icon)
|
|
285
|
+
|
|
286
|
+
if (!item)
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
const prefix = item.prefix
|
|
290
|
+
const prefixList = sorted[prefix] ? sorted[prefix] : (sorted[prefix] = [])
|
|
291
|
+
|
|
292
|
+
const name = item.name
|
|
293
|
+
|
|
294
|
+
if (!prefixList.includes(name))
|
|
295
|
+
prefixList.push(name)
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
return sorted
|
|
299
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
|
|
3
|
+
import { createLayouts } from '@layouts'
|
|
4
|
+
|
|
5
|
+
import { layoutConfig } from '@themeConfig'
|
|
6
|
+
|
|
7
|
+
// Styles
|
|
8
|
+
import '@layouts/styles/index.scss'
|
|
9
|
+
|
|
10
|
+
export default function (app: App) {
|
|
11
|
+
// ℹ️ We generate layout config from our themeConfig so you don't have to write config twice
|
|
12
|
+
app.use(createLayouts(layoutConfig))
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
import ToastPlugin from 'vue-toast-notification'
|
|
3
|
+
import 'vue-toast-notification/dist/theme-default.css'
|
|
4
|
+
|
|
5
|
+
// import 'vue-toast-notification/dist/theme-bootstrap.css';
|
|
6
|
+
|
|
7
|
+
export default function (app: App) {
|
|
8
|
+
app.use(ToastPlugin)
|
|
9
|
+
}
|