create-jwn-js 1.0.2 → 1.0.3

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.
Files changed (41) hide show
  1. package/index.js +11 -0
  2. package/package.json +1 -1
  3. package/template-vite-vue3-ts/.gitignore +5 -0
  4. package/template-vite-vue3-ts/connect-template.json +36 -0
  5. package/template-vite-vue3-ts/cron.js +90 -0
  6. package/template-vite-vue3-ts/docs/index.md +27 -0
  7. package/template-vite-vue3-ts/index.html +18 -0
  8. package/template-vite-vue3-ts/jest.config.ts +38 -0
  9. package/template-vite-vue3-ts/package.json +57 -0
  10. package/template-vite-vue3-ts/postcss.config.js +28 -0
  11. package/template-vite-vue3-ts/src/backend/server/helpers/createConfigServer.ts +16 -0
  12. package/template-vite-vue3-ts/src/backend/server/helpers/createMariadb.ts +16 -0
  13. package/template-vite-vue3-ts/src/backend/server/helpers/createMemcached.ts +15 -0
  14. package/template-vite-vue3-ts/src/backend/server/helpers/readManifest.ts +16 -0
  15. package/template-vite-vue3-ts/src/backend/server/index.ts +51 -0
  16. package/template-vite-vue3-ts/src/backend/server/site-schema.ts +21 -0
  17. package/template-vite-vue3-ts/src/backend/server/web-routes/index.ts +9 -0
  18. package/template-vite-vue3-ts/src/backend/views/Index/IndexController.ts +16 -0
  19. package/template-vite-vue3-ts/src/frontend/App.vue +30 -0
  20. package/template-vite-vue3-ts/src/frontend/entry-client.ts +2 -0
  21. package/template-vite-vue3-ts/src/frontend/entry-server.ts +4 -0
  22. package/template-vite-vue3-ts/src/frontend/helpers/customerPrefetch.ts +46 -0
  23. package/template-vite-vue3-ts/src/frontend/main.ts +68 -0
  24. package/template-vite-vue3-ts/src/frontend/routes/index.ts +42 -0
  25. package/template-vite-vue3-ts/src/frontend/shims-plugins.d.ts +18 -0
  26. package/template-vite-vue3-ts/src/frontend/shims-vue.d.ts +5 -0
  27. package/template-vite-vue3-ts/src/frontend/shims-vuex.d.ts +10 -0
  28. package/template-vite-vue3-ts/src/frontend/store/fetch.ts +174 -0
  29. package/template-vite-vue3-ts/src/frontend/store/index.ts +131 -0
  30. package/template-vite-vue3-ts/src/frontend/store/types.d.ts +83 -0
  31. package/template-vite-vue3-ts/src/frontend/views/Error/Error.vue +62 -0
  32. package/template-vite-vue3-ts/src/frontend/views/Index/Index.vue +27 -0
  33. package/template-vite-vue3-ts/src/frontend/views/Index/__tests__/Index.spec.ts +31 -0
  34. package/template-vite-vue3-ts/src/frontend/vite-env.d.ts +1 -0
  35. package/template-vite-vue3-ts/src/helpers/langLink.ts +17 -0
  36. package/template-vite-vue3-ts/src/helpers/parseLang.ts +10 -0
  37. package/template-vite-vue3-ts/src/scripts/jest.global.setup.ts +23 -0
  38. package/template-vite-vue3-ts/src/scripts/jest.global.teardown.ts +10 -0
  39. package/template-vite-vue3-ts/src/scripts/jest.setup.ts +16 -0
  40. package/template-vite-vue3-ts/tsconfig.json +47 -0
  41. package/template-vite-vue3-ts/vite.config.ts +87 -0
package/index.js CHANGED
@@ -23,6 +23,17 @@ const FRAMEWORKS = [
23
23
  color: blue
24
24
  }
25
25
  ]
26
+ },
27
+ {
28
+ name: 'vite-vue3',
29
+ color: yellow,
30
+ variants: [
31
+ {
32
+ name: 'vite-vue3-ts',
33
+ display: 'TypeScript',
34
+ color: blue
35
+ }
36
+ ]
26
37
  }
27
38
  ]
28
39
  const TEMPLATES = FRAMEWORKS.map(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jwn-js",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "license": "PRIVATE",
5
5
  "author": "Webigorkiev",
6
6
  "bin": {
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ .DS_Store
3
+ *.local
4
+ connect.json
5
+ .idea
@@ -0,0 +1,36 @@
1
+ {
2
+ "server": {
3
+ "development": {
4
+ "mode": "development",
5
+ "vite": {
6
+ "port": 3000
7
+ },
8
+ "port": 3001,
9
+ "host": "localhost"
10
+ },
11
+ "production": {
12
+ "mode": "production",
13
+ "port": 3000,
14
+ "host": "127.0.0.1",
15
+ "url": "http://127.0.0.1"
16
+ }
17
+ },
18
+ "db": {
19
+ "home": {
20
+ "engine": "mysql",
21
+ "host": "localhost",
22
+ "user": "",
23
+ "password": "",
24
+ "database": "",
25
+ "connectTimeout": 10000,
26
+ "acquireTimeout": 10000,
27
+ "connectionLimit": 2,
28
+ "charset": "utf8",
29
+ "compress": true,
30
+ "port": 3306,
31
+ "multipleStatements": true,
32
+ "namedPlaceholders": true,
33
+ "dateStrings": true
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,90 @@
1
+ const {appendFileSync} = require("fs");
2
+ const {performance} = require("perf_hooks");
3
+ const margv = require("margv");
4
+ const fetch = require("cross-fetch");
5
+ const chalk = require("chalk");
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+
9
+ const logFile = "/var/www/tehnoskarb/logs/cron/skarb.works.log";
10
+ const two = (value) => ("0" + value).slice(-2);
11
+ const toMysqlDatetime = (date) => `${date.getFullYear()}-${two(date.getMonth()+1)}-${two(date.getDate())} ${two(date.getHours())}:${two(date.getMinutes())}:${two(date.getSeconds())}`;
12
+
13
+ (async() => {
14
+ const start = performance.now();
15
+ const args = margv();
16
+
17
+ if(args.help) {
18
+ console.log(`// $ cron.js -c=<controller> -s=<subaction> -p={} -m=<method> -h={} --development`);
19
+
20
+ return;
21
+ }
22
+
23
+ const connect = path.resolve(__dirname, './connect.json');
24
+ const config = JSON.parse(fs.readFileSync(connect, 'utf8'));
25
+ const host = args.development || args.d
26
+ ? `http://${config.server.development.host}:${config.server.development.port}/web`
27
+ : `http://${config.server.production.host}:${config.server.production.port}/web`;
28
+ const controller = args.controller || args.c;
29
+ const subaction = args.subaction || args.s;
30
+ const params = args.params || args.p || {};
31
+ const method = args.method || args.m || "get";
32
+ const headers = args.headers || args.h || {};
33
+ const adminToken = config.cron["admin-token"];
34
+ const apiToken = config.cron["api-token"];
35
+
36
+ console.log(chalk.green(host));
37
+
38
+ if(!controller) {
39
+ console.log(chalk.red("required --controller=<controller>"));
40
+
41
+ return;
42
+ }
43
+
44
+ if(!subaction) {
45
+ console.log(chalk.red("required --subaction=<subaction>"));
46
+
47
+ return;
48
+ }
49
+
50
+ const url = new URL(host);
51
+ const options = {
52
+ compress: true,
53
+ method,
54
+ headers: {
55
+ "content-type": "application/json",
56
+ "cookie":`admin-token=${adminToken}`,
57
+ ...headers
58
+ }
59
+ }
60
+
61
+ if(method.toLowerCase() === "get") {
62
+ url.search = new URLSearchParams(Object.assign(params, {controller, subaction, token: apiToken})).toString();
63
+ } else {
64
+ options.body = JSON.stringify(Object.assign(params, {controller, subaction, token: apiToken}));
65
+ }
66
+
67
+ console.log(chalk.green(`send params to ${controller} ${subaction}`));
68
+ const response = await fetch(url.toString(), options);
69
+ const text = decodeURIComponent(await response.text());
70
+ const time = Math.round(performance.now() - start)/1000;
71
+ const logParams = (JSON.stringify(Object.assign(params, {subaction}))
72
+ .substring(0, 512));
73
+
74
+ try {
75
+ appendFileSync(
76
+ logFile,
77
+ `${toMysqlDatetime(new Date())}\t${time}\t${text}\t${host}\t${logParams}\n`
78
+ );
79
+ } catch(e) {
80
+ console.log(chalk.red( `No log file ${logFile}`));
81
+ }
82
+
83
+ if(response.ok) {
84
+ console.log(chalk.green("response ok."));
85
+ console.log(chalk.green(text));
86
+ } else {
87
+ console.log(chalk.red("Error during request!"));
88
+ console.log(chalk.red(text));
89
+ }
90
+ })();
@@ -0,0 +1,27 @@
1
+ # Template template-vite-vue3-ts
2
+
3
+ ```typescript
4
+ yarn
5
+ ```
6
+
7
+ ### Develop
8
+
9
+ ```bash
10
+ yarn dev
11
+ ```
12
+
13
+ ### Test
14
+
15
+ ```bash
16
+ yarn test
17
+ ```
18
+
19
+ ### Docs
20
+
21
+ ```bash
22
+ yarn docs:dev
23
+ ```
24
+
25
+ ```bash
26
+ yarn docs:build
27
+ ```
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="msapplication-TileColor" content="#da532c">
6
+ <meta name="theme-color" content="#ffffff">
7
+ <meta name='viewport' content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0">
8
+ <style>
9
+ .iconing {
10
+ width: 20px;
11
+ }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <div id="app"></div>
16
+ <script type="module" src="/src/frontend/entry-client.ts"></script>
17
+ </body>
18
+ </html>
@@ -0,0 +1,38 @@
1
+ export default {
2
+ moduleFileExtensions: [
3
+ "js",
4
+ "ts",
5
+ "json",
6
+ "vue",
7
+ "node"
8
+ ],
9
+ transform: {
10
+ "^.+\\.ts$": "ts-jest",
11
+ "^.+\\.vue$": "@vue/vue3-jest"
12
+ },
13
+ moduleNameMapper: {
14
+ "@/(.*)$": "<rootDir>/src/$1"
15
+ },
16
+ setupFiles: ["./src/scripts/jest.setup.ts"],
17
+ globalSetup: "./src/scripts/jest.global.setup.ts",
18
+ globalTeardown: "./src/scripts/jest.global.teardown.ts",
19
+ testTimeout: 35000,
20
+ globals: {
21
+ 'ts-jest': {
22
+ tsconfig: './tsconfig.json',
23
+ diagnostics: false
24
+ }
25
+ },
26
+ testEnvironment: "jsdom",
27
+ maxWorkers: 2,
28
+ testMatch: [ "**/__its__/**/*.[jt]s?(x)", "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ],
29
+ testPathIgnorePatterns: ["<rootDir>/src/scripts",],
30
+ collectCoverageFrom: [
31
+ "**/src/**/*.{ts}",
32
+ "!**/src/**/*.d.ts",
33
+ "!**/src/**/index.ts",
34
+ "!**/src/scripts/**",
35
+ "!**/src/sql/**",
36
+ "!**/src/backend/server/web-routes/**",
37
+ ]
38
+ };
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "template-vite-vue3-ts",
3
+ "private": true,
4
+ "author": "webigorkiev",
5
+ "license": "PRIVATE",
6
+ "version": "1.0.1",
7
+ "scripts": {
8
+ "dev": "vite",
9
+ "build": "vite build",
10
+ "test": "jest src -c jest.config.ts --silent true",
11
+ "docs:dev": "vitepress dev docs",
12
+ "docs:build": "vitepress build docs",
13
+ "docs:serve": "vitepress serve docs"
14
+ },
15
+ "devDependencies": {
16
+ "@types/jest": "^27.0.3",
17
+ "@types/memjs": "^1.2.4",
18
+ "@types/node": "^17.0.4",
19
+ "@vue/compiler-sfc": "^3.2.26",
20
+ "@vue/test-utils": "^2.0.0-rc.18",
21
+ "@vue/vue3-jest": "^27.0.0-alpha.4",
22
+ "autoprefixer": "^10.4.1",
23
+ "jest": "^27.4.5",
24
+ "ts-jest": "^27.1.2",
25
+ "ts-node": "^10.4.0",
26
+ "typescript": "^4.4.4",
27
+ "vite": "^2.7.10",
28
+ "vite-svg-loader": "^3.1.1",
29
+ "vitepress": "^0.20.10"
30
+ },
31
+ "dependencies": {
32
+ "@jwn-js/common": "^2.0.7",
33
+ "@jwn-js/plugins": "^1.0.13",
34
+ "@vue/server-renderer": "^3.2.26",
35
+ "@vuemod/prefetch": "^1.0.10",
36
+ "amitt": "^1.0.5",
37
+ "buildmsql": "^1.3.2",
38
+ "chalk": "4",
39
+ "cross-fetch": "^3.1.4",
40
+ "easy-ash": "^1.1.5",
41
+ "margv": "^1.1.2",
42
+ "memjs": "^1.3.0",
43
+ "postcss": "^8.3.5",
44
+ "postcss-custom-media": "^8.0.0",
45
+ "postcss-each": "^1.1.0",
46
+ "postcss-load-config": "^3.1.0",
47
+ "postcss-nested": "^5.0.5",
48
+ "postcss-nesting": "^8.0.1",
49
+ "postcss-plugin": "^1.0.0",
50
+ "postcss-scss": "^4.0.0",
51
+ "primevue": "^3.10.0",
52
+ "vue": "^3.2.26",
53
+ "vue-router": "^4.0.12",
54
+ "vuex": "^4.0.2",
55
+ "vuex-router-sync": "^6.0.0-rc.1"
56
+ }
57
+ }
@@ -0,0 +1,28 @@
1
+ module.exports = (ctx) => {
2
+
3
+ return {
4
+ parser: 'postcss-scss',
5
+ map: {
6
+ inline: true
7
+ },
8
+ plugins: {
9
+ 'postcss-nested': {},
10
+ 'postcss-custom-media': {
11
+ importFrom: [
12
+ {
13
+ customMedia: {
14
+ '--xxl': '(max-width: 1920px)',
15
+ '--xl': '(min-width: 1200px)',
16
+ '--lg': '(min-width: 992px)',
17
+ '--md': '(min-width: 768px)',
18
+ '--sm': '(min-width: 576px)',
19
+ '--mm': '(max-width: 375px)',
20
+ }
21
+ },
22
+ ]
23
+ },
24
+ 'postcss-each': {},
25
+ 'autoprefixer': {}
26
+ }
27
+ }
28
+ };
@@ -0,0 +1,16 @@
1
+ import margv from "margv";
2
+ const args = margv();
3
+
4
+ /**
5
+ * Config for server
6
+ * @param config
7
+ */
8
+ export const createConfigServer = (config: Record<string, any>) => {
9
+ const configServer = process.env.NODE_ENV === "production" ? config.server.production : config.server.development;
10
+ configServer.port = +args.port + 1 || configServer.port;
11
+ configServer.host = args.host || configServer.host;
12
+ configServer.proxy = `http://${configServer.host}:${configServer.port}`;
13
+ configServer.vitePort = config.server.development.vite.port;
14
+
15
+ return configServer;
16
+ }
@@ -0,0 +1,16 @@
1
+ import {Query} from "buildmsql";
2
+
3
+ /**
4
+ * Create mariadb pool
5
+ * @param config
6
+ */
7
+ export const createMariadb = (config: Record<string, any>) => {
8
+ if(config.db.home) {
9
+ const home = new Query({debug: process.env.NODE_ENV === "production" ? 0 : 1});
10
+ const homePool = home.createPool(config.db.home);
11
+
12
+ return {homePool, home};
13
+ }
14
+
15
+ return {};
16
+ }
@@ -0,0 +1,15 @@
1
+ import memjs from "memjs";
2
+ import {Memcached} from "@jwn-js/common";
3
+
4
+ export const createMemcached = () => {
5
+ const memcachedClient = memjs.Client.create("127.0.0.1:11211", {
6
+ timeout: 1,
7
+ conntimeout: 1,
8
+ logger: {
9
+ log: () => {}
10
+ }
11
+ });
12
+ const memcached = new Memcached(memcachedClient);
13
+
14
+ return {memcachedClient, memcached};
15
+ }
@@ -0,0 +1,16 @@
1
+ import {helpers} from "@jwn-js/common";
2
+
3
+ /**
4
+ * Read ssr manifest
5
+ */
6
+ export const readManifest = () => {
7
+ let manifest = {};
8
+
9
+ try {
10
+ manifest = helpers.readConfigSync("./dist/client/ssr-manifest.json");
11
+ } catch(e: any) {
12
+ // console.log(e.message);
13
+ }
14
+
15
+ return manifest;
16
+ }
@@ -0,0 +1,51 @@
1
+ import {Server, helpers, Web, Ssr, OptionsWeb, OptionsSsr} from "@jwn-js/common";
2
+ import {createConfigServer} from "./helpers/createConfigServer";
3
+ import {schema} from "./site-schema";
4
+ import {webRoutes} from "./web-routes";
5
+ import {createMariadb} from "./helpers/createMariadb";
6
+ import {createMemcached} from "./helpers/createMemcached";
7
+ import {readManifest} from "@/backend/server/helpers/readManifest";
8
+ import entry from "@/frontend/main";
9
+ declare var process: any;
10
+
11
+ const {readConfigSync} = helpers;
12
+ process.server = process.server || {};
13
+ let memcachedClient, memcached, home;
14
+ const config = readConfigSync("./connect.json");
15
+ const configServer = createConfigServer(config);
16
+
17
+ if(process.env.NODE_ENV === "production") {
18
+ ({home} = createMariadb(config));
19
+ ({memcachedClient, memcached} = createMemcached());
20
+ }
21
+ const webOptions: OptionsWeb = {
22
+ routes: webRoutes,
23
+ config,
24
+ db: process.server.db || {
25
+ home
26
+ },
27
+ memcached: process.server.memcached || memcached,
28
+ schema
29
+ }
30
+ const ssrOptions:OptionsSsr = {
31
+ manifest: readManifest(),
32
+ memcached: process.server.memcached || memcached
33
+ }
34
+
35
+ process.server.app = new Server({
36
+ ...configServer,
37
+ routes: [
38
+ {
39
+ method: "any",
40
+ pattern: "/web",
41
+ handler: (res, req) => new Web(res, req, webOptions).request()
42
+ },
43
+ {
44
+ method: "get",
45
+ pattern: "/*",
46
+ handler: (res, req) => new Ssr(res, req, ssrOptions, entry).request()
47
+ }
48
+ ]
49
+ })
50
+ .app()
51
+ .listen();
@@ -0,0 +1,21 @@
1
+ import {Schema} from "@jwn-js/common";
2
+
3
+ export const schema: Schema = {
4
+ actions: [
5
+ {
6
+ name: "view"
7
+ }
8
+ ],
9
+ controllers: [
10
+ {
11
+ id: 1,
12
+ name: "Index",
13
+ subactions: [
14
+ {
15
+ name: "index",
16
+ action: "view"
17
+ }
18
+ ]
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,9 @@
1
+ import {Route} from "@jwn-js/common";
2
+
3
+ export const webRoutes: Array<Route> = [
4
+ {
5
+ method: "any",
6
+ name: "Index",
7
+ component: () => import("@/backend/views/Index/IndexController")
8
+ },
9
+ ];
@@ -0,0 +1,16 @@
1
+ import {Controller} from "@jwn-js/common";
2
+ import {http} from "@jwn-js/common";
3
+
4
+ export default class IndexController extends Controller {
5
+
6
+ @http()
7
+ async index() {
8
+
9
+ return {
10
+ page: {
11
+ title: "Index Page",
12
+ h1: "Index page h1"
13
+ }
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <div class="app">
3
+ <RouterView />
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts">
8
+ import {defineComponent, computed} from "vue";
9
+ import {useStore} from "vuex";
10
+ import {useHead} from "@vueuse/head";
11
+
12
+
13
+ /**
14
+ * @emits
15
+ * web-notification - open notification
16
+ * confirm - open confirm dialog
17
+ */
18
+ export default defineComponent({
19
+ name: "App",
20
+ setup() {
21
+ const store = useStore();
22
+ useHead(computed(() => store.state.page));
23
+ }
24
+ })
25
+ </script>
26
+
27
+ <style lang="postcss">
28
+ @import "~primevue/resources/themes/bootstrap4-light-blue/theme.css";
29
+ @import "~primevue/resources/primevue.min.css";
30
+ </style>
@@ -0,0 +1,2 @@
1
+ import entry from "./main";
2
+ export default entry;
@@ -0,0 +1,4 @@
1
+ import entry from "./main";
2
+ import "@/backend/server";
3
+
4
+ export default entry;
@@ -0,0 +1,46 @@
1
+ import type {Store} from "vuex";
2
+ import {NavigationGuardFetchWithThis} from "@vuemod/prefetch";
3
+ import {RouteLocationNormalized} from "vue-router";
4
+
5
+ interface Options {
6
+ store: Store<any>,
7
+ isFetch: boolean,
8
+ }
9
+ declare type Callback = (
10
+ store: Store<any>,
11
+ body: Record<string, any>,
12
+ to:RouteLocationNormalized,
13
+ from:RouteLocationNormalized
14
+ ) => Promise<void>
15
+
16
+ /**
17
+ * Admin prefetch helper
18
+ * @param options
19
+ * @param fn
20
+ */
21
+ export const customerPrefetch = (options: {
22
+ controller?: string,
23
+ subaction?: string,
24
+ memcache?: number,
25
+ }, fn?:Callback): NavigationGuardFetchWithThis<any> => {
26
+
27
+ return async ({store, isFetch}: Options, to, from) => {
28
+ if(isFetch) {
29
+ const {body} = await store.dispatch("fetch", [{
30
+ lang: store.state.toLang,
31
+ route: to.fullPath,
32
+ ...(to.query || {}),
33
+ ...(options || {})
34
+ }, {
35
+ ...(store.state?.Customer?.jwt ? {mergeHeaders: {"authorization": `Bearer ${store.state.Customer.jwt}`}} : {})
36
+ }]);
37
+ store.commit("SET_PAGE", body.data?.page || {});
38
+ store.commit("MERGE_CONTEXT", {memcache: options.memcache});
39
+
40
+ if(fn) {
41
+ await fn(store, body, to, from);
42
+ }
43
+ }
44
+
45
+ }
46
+ }
@@ -0,0 +1,68 @@
1
+ import ssr, {Context} from "vite-ssr-vue";
2
+ import App from "./App.vue";
3
+ import createRouter from "./routes";
4
+ import createStore from "./store";
5
+ import {createHead} from "@vueuse/head";
6
+ import {createPrefetch} from "@vuemod/prefetch";
7
+ import {amitt} from "amitt";
8
+ import {sync} from "vuex-router-sync";
9
+
10
+ // Multilang
11
+ import Multilang from "@jwn-js/plugins/Multilang";
12
+ import {parseLang} from "@/helpers/parseLang";
13
+
14
+ // Primevue
15
+ import PrimeVue from 'primevue/config';
16
+ import ConfirmationService from 'primevue/confirmationservice';
17
+
18
+ const defaultLang = "ru";
19
+
20
+ export default ssr(App, {
21
+ created({app, context, req, res, isClient}) {
22
+ const emitter = amitt();
23
+ const head = createHead();
24
+ const router = createRouter({isClient});
25
+ const store = createStore({
26
+ redirect: async function(url: string, statusCode: number = 307) {
27
+ console.log("Redirecting: " + url);
28
+ if(isClient) {
29
+ await router.push(url);
30
+ } else {
31
+ res.redirect(url, statusCode);
32
+ }
33
+ }
34
+ });
35
+ app.use(router);
36
+ app.use(store);
37
+ app.use(head);
38
+ app.use(Multilang, {
39
+ default: defaultLang,
40
+ getLang() {
41
+
42
+ return store.state.lang;
43
+ }
44
+ });
45
+ sync(store, router);
46
+
47
+ const prefetch = createPrefetch();
48
+ app.use(prefetch, router, store);
49
+ app.use(PrimeVue);
50
+ app.use(ConfirmationService);
51
+ app.config.globalProperties.$emitter = emitter;
52
+
53
+ if(!isClient) {
54
+ store.state.context = context as Context;
55
+ }
56
+
57
+ // Routers hooks
58
+ router.beforeEach(async (to) => {
59
+ store.commit('SET_TO_LANG', parseLang(to.fullPath, defaultLang));
60
+ });
61
+
62
+ router.afterEach(async (to, from) => {
63
+ store.commit('SET_LANG', parseLang(to.fullPath, defaultLang));
64
+ });
65
+
66
+ return {head, router, store}
67
+ }
68
+ });