@rancher/shell 0.3.4 → 0.3.6

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 (289) hide show
  1. package/assets/images/providers/outscale.svg +19 -0
  2. package/assets/styles/app.scss +1 -1
  3. package/assets/styles/base/_basic.scss +18 -0
  4. package/assets/styles/base/_mixins.scss +0 -11
  5. package/assets/styles/base/_variables.scss +2 -4
  6. package/assets/styles/fonts/_fontstack.scss +11 -11
  7. package/assets/styles/global/_button.scss +12 -2
  8. package/assets/styles/vendor/vue-js-modal.scss +3 -3
  9. package/assets/translations/en-us.yaml +113 -22
  10. package/assets/translations/zh-hans.yaml +113 -24
  11. package/babel.config.js +13 -0
  12. package/chart/gatekeeper.vue +78 -0
  13. package/chart/istio.vue +135 -112
  14. package/chart/logging/index.vue +13 -4
  15. package/chart/monitoring/index.vue +15 -5
  16. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  17. package/chart/rancher-backup/index.vue +10 -3
  18. package/cloud-credential/aws.vue +1 -1
  19. package/cloud-credential/digitalocean.vue +1 -1
  20. package/cloud-credential/gcp.vue +1 -1
  21. package/cloud-credential/generic.vue +2 -2
  22. package/cloud-credential/linode.vue +1 -1
  23. package/cloud-credential/pnap.vue +1 -1
  24. package/components/ActionMenu.vue +3 -4
  25. package/components/AssignTo.vue +1 -1
  26. package/components/AsyncButton.vue +1 -1
  27. package/components/BannerGraphic.vue +1 -1
  28. package/components/BrandImage.vue +1 -4
  29. package/components/ButtonDropdown.vue +2 -3
  30. package/components/Carousel.vue +85 -37
  31. package/components/ChartPsp.vue +76 -0
  32. package/components/CruResource.vue +6 -2
  33. package/components/DashboardMetrics.vue +12 -10
  34. package/components/DetailText.vue +1 -1
  35. package/components/DisableAuthProviderModal.vue +1 -1
  36. package/components/EmberPage.vue +1 -1
  37. package/components/EtcdInfoBanner.vue +12 -7
  38. package/components/ExplorerMembers.vue +101 -6
  39. package/components/ExplorerProjectsNamespaces.vue +46 -3
  40. package/components/FileDiff.vue +6 -7
  41. package/components/GrafanaDashboard.vue +27 -23
  42. package/components/LazyImage.vue +10 -12
  43. package/components/LogItem.vue +1 -1
  44. package/components/Markdown.vue +1 -1
  45. package/components/PromptRemove.vue +2 -2
  46. package/components/PromptRestore.vue +1 -1
  47. package/components/ResourceDetail/Masthead.vue +16 -0
  48. package/components/ResourceDetail/index.vue +21 -4
  49. package/components/ResourceList/index.vue +1 -1
  50. package/components/ResourceTable.vue +4 -1
  51. package/components/SingleClusterInfo.vue +2 -2
  52. package/components/SortableTable/THead.vue +1 -1
  53. package/components/SortableTable/index.vue +28 -13
  54. package/components/SortableTable/selection.js +58 -50
  55. package/components/Wizard.vue +4 -2
  56. package/components/__tests__/AsyncButton.test.ts +3 -1
  57. package/components/__tests__/ChartPsp.test.ts +75 -0
  58. package/components/__tests__/CruResource.test.ts +3 -1
  59. package/components/auth/Principal.vue +1 -1
  60. package/components/auth/RoleDetailEdit.vue +2 -2
  61. package/components/fleet/FleetBundles.vue +3 -1
  62. package/components/fleet/FleetClusters.vue +1 -2
  63. package/components/fleet/FleetIntro.vue +9 -1
  64. package/components/fleet/FleetNoWorkspaces.vue +62 -0
  65. package/components/fleet/FleetSummary.vue +7 -1
  66. package/components/form/HookOption.vue +14 -10
  67. package/components/form/LabeledSelect.vue +14 -11
  68. package/components/form/Labels.vue +32 -27
  69. package/components/form/MatchExpressions.vue +19 -4
  70. package/components/form/Members/ClusterPermissionsEditor.vue +32 -7
  71. package/components/form/NameNsDescription.vue +32 -46
  72. package/components/form/ProjectMemberEditor.vue +46 -21
  73. package/components/form/ResourceSelector.vue +1 -1
  74. package/components/form/SecretSelector.vue +5 -1
  75. package/components/form/ServiceNameSelect.vue +1 -1
  76. package/components/form/SimpleSecretSelector.vue +9 -9
  77. package/components/form/Tolerations.vue +4 -1
  78. package/components/form/ValueFromResource.vue +14 -9
  79. package/components/form/WorkloadPorts.vue +2 -2
  80. package/components/form/__tests__/LabeledSelect.test.ts +138 -0
  81. package/components/form/__tests__/NameNsDescription.ts +59 -0
  82. package/components/formatter/InternalExternalIP.vue +6 -0
  83. package/components/formatter/InvolvedObjectLink.vue +54 -0
  84. package/components/formatter/Link.vue +20 -4
  85. package/components/formatter/LinkName.vue +6 -1
  86. package/components/formatter/ServiceTargets.vue +1 -1
  87. package/components/formatter/WorkloadHealthScale.vue +8 -2
  88. package/components/nav/Group.vue +2 -2
  89. package/components/nav/NamespaceFilter.vue +23 -11
  90. package/components/nav/TopLevelMenu.vue +2 -4
  91. package/components/nav/Type.vue +1 -1
  92. package/components/nav/WorkspaceSwitcher.vue +46 -5
  93. package/components/nuxt/nuxt-build-indicator.vue +143 -0
  94. package/components/nuxt/nuxt-child.js +122 -0
  95. package/components/nuxt/nuxt-error.vue +98 -0
  96. package/components/nuxt/nuxt-link.client.js +98 -0
  97. package/components/nuxt/nuxt-link.server.js +16 -0
  98. package/components/nuxt/nuxt-loading.vue +154 -0
  99. package/components/nuxt/nuxt.js +101 -0
  100. package/config/labels-annotations.js +17 -0
  101. package/config/middleware.js +12 -0
  102. package/config/product/auth.js +3 -2
  103. package/config/product/explorer.js +34 -6
  104. package/config/product/fleet.js +2 -0
  105. package/config/query-params.js +1 -0
  106. package/config/router.js +414 -0
  107. package/config/store.js +181 -0
  108. package/config/table-headers.js +54 -12
  109. package/config/types.js +18 -8
  110. package/config/uiplugins.js +30 -0
  111. package/content/docs/en-us/whats-new.md +10 -0
  112. package/content/docs/zh-hans/whats-new.md +11 -1
  113. package/core/plugin-routes.ts +23 -0
  114. package/core/plugin.ts +4 -2
  115. package/core/types.ts +258 -1
  116. package/creators/app/app.package.json +2 -1
  117. package/creators/app/files/.eslintrc.js +1 -1
  118. package/creators/app/files/babel.config.js +1 -18
  119. package/creators/app/files/tsconfig.json +0 -1
  120. package/creators/app/files/vue.config.js +6 -0
  121. package/creators/app/init +5 -5
  122. package/creators/pkg/files/.github/workflows/build-extension.yml +110 -0
  123. package/creators/pkg/files/tsconfig.json +0 -1
  124. package/creators/pkg/init +35 -4
  125. package/creators/pkg/pkg.package.json +3 -3
  126. package/creators/update/init +1 -1
  127. package/detail/constraints.gatekeeper.sh.constraint.vue +34 -17
  128. package/detail/fleet.cattle.io.clustergroup.vue +7 -1
  129. package/detail/fleet.cattle.io.gitrepo.vue +19 -11
  130. package/detail/harvesterhci.io.management.cluster.vue +3 -3
  131. package/detail/provisioning.cattle.io.cluster.vue +54 -12
  132. package/detail/workload/index.vue +3 -3
  133. package/dialog/AddClusterMemberDialog.vue +1 -1
  134. package/dialog/AddProjectMemberDialog.vue +2 -2
  135. package/dialog/AddonConfigConfirmationDialog.vue +27 -15
  136. package/dialog/DiagnosticTimingsDialog.vue +1 -1
  137. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  138. package/dialog/GenericPrompt.vue +18 -6
  139. package/dialog/RotateEncryptionKeyDialog.vue +1 -1
  140. package/dialog/SaveAsRKETemplateDialog.vue +1 -1
  141. package/dialog/ScaleMachineDownDialog.vue +1 -1
  142. package/edit/auth/github.vue +8 -8
  143. package/edit/auth/googleoauth.vue +5 -5
  144. package/edit/auth/ldap/index.vue +1 -1
  145. package/edit/auth/oidc.vue +1 -1
  146. package/edit/auth/saml.vue +1 -1
  147. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  148. package/edit/fleet.cattle.io.clustergroup.vue +6 -4
  149. package/edit/fleet.cattle.io.gitrepo.vue +32 -4
  150. package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
  151. package/edit/logging.banzaicloud.io.output/index.vue +18 -5
  152. package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -0
  153. package/edit/management.cattle.io.fleetworkspace.vue +141 -6
  154. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
  155. package/edit/management.cattle.io.setting.vue +1 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
  157. package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
  158. package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
  159. package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
  160. package/edit/namespace.vue +14 -10
  161. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
  162. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  163. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +21 -4
  164. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
  165. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
  166. package/edit/provisioning.cattle.io.cluster/import.vue +23 -25
  167. package/edit/provisioning.cattle.io.cluster/rke2.vue +344 -102
  168. package/edit/resources.cattle.io.backup.vue +1 -1
  169. package/edit/service.vue +1 -1
  170. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
  171. package/edit/workload/__tests__/Job.test.ts +3 -1
  172. package/edit/workload/index.vue +8 -3
  173. package/edit/workload/mixins/workload.js +22 -7
  174. package/edit/workload/storage/Mount.vue +3 -3
  175. package/initialize/App.js +206 -0
  176. package/initialize/client.js +863 -0
  177. package/initialize/index.js +364 -0
  178. package/layouts/default.vue +7 -3
  179. package/layouts/standalone.vue +13 -0
  180. package/list/catalog.cattle.io.clusterrepo.vue +1 -0
  181. package/list/fleet.cattle.io.bundle.vue +6 -3
  182. package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
  183. package/list/fleet.cattle.io.gitrepo.vue +44 -5
  184. package/list/management.cattle.io.fleetworkspace.vue +45 -0
  185. package/list/node.vue +69 -16
  186. package/list/provisioning.cattle.io.cluster.vue +30 -1
  187. package/list/rbac.authorization.k8s.io.clusterrolebinding.vue +48 -0
  188. package/list/workload.vue +6 -4
  189. package/machine-config/azure.vue +97 -38
  190. package/middleware/authenticated.js +34 -0
  191. package/mixins/chart.js +101 -2
  192. package/mixins/fetch.client.js +95 -0
  193. package/mixins/fetch.server.js +73 -0
  194. package/mixins/labeled-form-element.ts +2 -2
  195. package/mixins/resource-fetch.js +2 -2
  196. package/models/apps.statefulset.js +28 -0
  197. package/models/cluster/node.js +23 -2
  198. package/models/cluster.x-k8s.io.machine.js +4 -2
  199. package/models/clusterroletemplatebinding.js +7 -0
  200. package/models/constraints.gatekeeper.sh.constraint.js +46 -0
  201. package/models/fleet.cattle.io.cluster.js +19 -10
  202. package/models/fleet.cattle.io.gitrepo.js +7 -2
  203. package/models/management.cattle.io.cluster.js +1 -1
  204. package/models/management.cattle.io.fleetworkspace.js +12 -0
  205. package/models/management.cattle.io.gitreporestriction.js +5 -0
  206. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
  207. package/models/pod.js +4 -0
  208. package/models/provisioning.cattle.io.cluster.js +7 -5
  209. package/models/rbac.authorization.k8s.io.clusterrolebinding.js +16 -0
  210. package/models/rbac.authorization.k8s.io.rolebinding.js +16 -0
  211. package/package.json +13 -21
  212. package/pages/auth/setup.vue +2 -2
  213. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
  214. package/pages/c/_cluster/apps/charts/chart.vue +4 -4
  215. package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
  216. package/pages/c/_cluster/apps/charts/install.vue +98 -102
  217. package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
  218. package/pages/c/_cluster/explorer/index.vue +29 -25
  219. package/pages/c/_cluster/explorer/tools/index.vue +8 -8
  220. package/pages/c/_cluster/fleet/index.vue +95 -34
  221. package/pages/c/_cluster/gatekeeper/index.vue +1 -1
  222. package/pages/c/_cluster/istio/index.vue +5 -5
  223. package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
  224. package/pages/c/_cluster/monitoring/index.vue +7 -0
  225. package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
  226. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
  227. package/pages/c/_cluster/uiplugins/index.vue +49 -17
  228. package/pages/diagnostic.vue +32 -25
  229. package/pages/home.vue +9 -4
  230. package/pages/index.vue +10 -1
  231. package/pages/rio/mesh.vue +1 -2
  232. package/pkg/tsconfig.json +0 -1
  233. package/plugins/clean-html-directive.js +34 -0
  234. package/plugins/dashboard-store/actions.js +32 -9
  235. package/plugins/dashboard-store/index.js +1 -1
  236. package/plugins/dashboard-store/mutations.js +5 -2
  237. package/plugins/dashboard-store/resource-class.js +8 -1
  238. package/plugins/plugin.js +0 -14
  239. package/plugins/portal-vue.js +4 -0
  240. package/plugins/steve/mutations.js +3 -2
  241. package/plugins/steve/steve-description-class.js +5 -1
  242. package/plugins/steve/subscribe.js +63 -54
  243. package/plugins/steve-create-worker.js +14 -0
  244. package/promptRemove/management.cattle.io.globalrole.vue +2 -2
  245. package/promptRemove/management.cattle.io.project.vue +2 -2
  246. package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
  247. package/promptRemove/pod.vue +1 -1
  248. package/public/index.html +65 -0
  249. package/rancher-components/components/Banner/Banner.test.ts +7 -1
  250. package/rancher-components/components/Banner/Banner.vue +2 -1
  251. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
  252. package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
  253. package/rancher-components/components/Form/Radio/RadioButton.vue +14 -3
  254. package/scripts/build-pkg.sh +1 -0
  255. package/scripts/clean +6 -0
  256. package/scripts/extension/bundle +58 -0
  257. package/scripts/extension/helmpatch +89 -0
  258. package/scripts/extension/publish +333 -0
  259. package/scripts/serve-pkgs +6 -2
  260. package/scripts/test-plugins-build.sh +4 -0
  261. package/store/__tests__/index.test.ts +110 -0
  262. package/store/index.js +145 -58
  263. package/store/type-map.js +6 -2
  264. package/tsconfig.default.json +36 -0
  265. package/tsconfig.json +23 -0
  266. package/types/rancher/index.d.ts +2 -0
  267. package/types/shell/index.d.ts +466 -320
  268. package/utils/__tests__/grafana.test.ts +44 -0
  269. package/utils/__tests__/string.test.ts +12 -0
  270. package/utils/auth.js +65 -0
  271. package/utils/axios.js +190 -0
  272. package/utils/cookie-universal-nuxt.js +10 -0
  273. package/utils/dom.js +15 -0
  274. package/utils/grafana.js +35 -16
  275. package/utils/monitoring.js +2 -1
  276. package/utils/nuxt.js +659 -0
  277. package/utils/position.js +5 -8
  278. package/utils/router.scrollBehavior.js +80 -0
  279. package/utils/select.js +1 -3
  280. package/utils/socket.js +1 -0
  281. package/utils/string.js +13 -0
  282. package/utils/time.js +9 -0
  283. package/vue.config.js +690 -0
  284. package/chart/rancher-alerting-drivers.vue +0 -53
  285. package/chart/rancher-gatekeeper.vue +0 -37
  286. package/creators/app/files/nuxt.config.js +0 -6
  287. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
  288. package/nuxt.config.js +0 -798
  289. package/plugins/dashboard-store/extensions.js +0 -22
@@ -0,0 +1,863 @@
1
+ import Vue from 'vue';
2
+ import fetch from 'unfetch';
3
+ import middleware from '../config/middleware.js';
4
+ import {
5
+ applyAsyncData,
6
+ promisify,
7
+ middlewareSeries,
8
+ sanitizeComponent,
9
+ resolveRouteComponents,
10
+ getMatchedComponents,
11
+ getMatchedComponentsInstances,
12
+ flatMapComponents,
13
+ setContext,
14
+ compile,
15
+ getQueryDiff,
16
+ globalHandleError,
17
+ isSamePath,
18
+ urlJoin
19
+ } from '../utils/nuxt.js';
20
+ import { createApp, NuxtError } from './index.js';
21
+ import fetchMixin from '../mixins/fetch.client';
22
+ import NuxtLink from '../components/nuxt/nuxt-link.client.js'; // should be included after ./index.js
23
+
24
+ // Fetch mixin
25
+ if (!Vue.__nuxt__fetch__mixin__) {
26
+ Vue.mixin(fetchMixin);
27
+ Vue.__nuxt__fetch__mixin__ = true;
28
+ }
29
+
30
+ // Component: <NuxtLink>
31
+ Vue.component(NuxtLink.name, NuxtLink);
32
+ Vue.component('NLink', NuxtLink);
33
+
34
+ if (!global.fetch) {
35
+ global.fetch = fetch;
36
+ }
37
+
38
+ // Global shared references
39
+ let _lastPaths = [];
40
+ let app;
41
+ let router;
42
+
43
+ // Try to rehydrate SSR data from window
44
+ const NUXT = window.__NUXT__ || {};
45
+
46
+ const $config = nuxt.publicRuntimeConfig || {}; // eslint-disable-line no-undef
47
+
48
+ if ($config._app) {
49
+ __webpack_public_path__ = urlJoin($config._app.cdnURL, $config._app.assetsPath); // eslint-disable-line camelcase, no-undef
50
+ }
51
+
52
+ Object.assign(Vue.config, { silent: false, performance: true });
53
+
54
+ const logs = NUXT.logs || [];
55
+
56
+ if (logs.length > 0) {
57
+ const ssrLogStyle = 'background: #2E495E;border-radius: 0.5em;color: white;font-weight: bold;padding: 2px 0.5em;';
58
+
59
+ console.group && console.group('%cNuxt SSR', ssrLogStyle); // eslint-disable-line no-console
60
+ logs.forEach(logObj => (console[logObj.type] || console.log)(...logObj.args)); // eslint-disable-line no-console
61
+ delete NUXT.logs;
62
+ console.groupEnd && console.groupEnd(); // eslint-disable-line no-console
63
+ }
64
+
65
+ // Setup global Vue error handler
66
+ if (!Vue.config.$nuxt) {
67
+ const defaultErrorHandler = Vue.config.errorHandler;
68
+
69
+ Vue.config.errorHandler = async(err, vm, info, ...rest) => {
70
+ // Call other handler if exist
71
+ let handled = null;
72
+
73
+ if (typeof defaultErrorHandler === 'function') {
74
+ handled = defaultErrorHandler(err, vm, info, ...rest);
75
+ }
76
+ if (handled === true) {
77
+ return handled;
78
+ }
79
+
80
+ if (vm && vm.$root) {
81
+ const nuxtApp = Object.keys(Vue.config.$nuxt)
82
+ .find(nuxtInstance => vm.$root[nuxtInstance]);
83
+
84
+ // Show Nuxt Error Page
85
+ if (nuxtApp && vm.$root[nuxtApp].error && info !== 'render function') {
86
+ const currentApp = vm.$root[nuxtApp];
87
+
88
+ // Load error layout
89
+ let layout = (NuxtError.options || NuxtError).layout;
90
+
91
+ if (typeof layout === 'function') {
92
+ layout = layout(currentApp.context);
93
+ }
94
+ if (layout) {
95
+ await currentApp.loadLayout(layout).catch(() => {});
96
+ }
97
+ currentApp.setLayout(layout);
98
+
99
+ currentApp.error(err);
100
+ }
101
+ }
102
+
103
+ if (typeof defaultErrorHandler === 'function') {
104
+ return handled;
105
+ }
106
+
107
+ // Log to console
108
+ if (process.env.NODE_ENV !== 'production') {
109
+ console.error(err); // eslint-disable-line no-console
110
+ } else {
111
+ console.error(err.message || err); // eslint-disable-line no-console
112
+ }
113
+ };
114
+ Vue.config.$nuxt = {};
115
+ }
116
+ Vue.config.$nuxt.$nuxt = true;
117
+
118
+ const errorHandler = Vue.config.errorHandler || console.error; // eslint-disable-line no-console
119
+
120
+ // Create and mount App
121
+ createApp(null, nuxt.publicRuntimeConfig).then(mountApp).catch(errorHandler); // eslint-disable-line no-undef
122
+
123
+ function componentOption(component, key, ...args) {
124
+ if (!component || !component.options || !component.options[key]) {
125
+ return {};
126
+ }
127
+ const option = component.options[key];
128
+
129
+ if (typeof option === 'function') {
130
+ return option(...args);
131
+ }
132
+
133
+ return option;
134
+ }
135
+
136
+ function mapTransitions(toComponents, to, from) {
137
+ const componentTransitions = (component) => {
138
+ const transition = componentOption(component, 'transition', to, from) || {};
139
+
140
+ return (typeof transition === 'string' ? { name: transition } : transition);
141
+ };
142
+
143
+ const fromComponents = from ? getMatchedComponents(from) : [];
144
+ const maxDepth = Math.max(toComponents.length, fromComponents.length);
145
+
146
+ const mergedTransitions = [];
147
+
148
+ for (let i = 0; i < maxDepth; i++) {
149
+ // Clone original objects to prevent overrides
150
+ const toTransitions = Object.assign({}, componentTransitions(toComponents[i]));
151
+ const transitions = Object.assign({}, componentTransitions(fromComponents[i]));
152
+
153
+ // Combine transitions & prefer `leave` properties of "from" route
154
+ Object.keys(toTransitions)
155
+ .filter(key => typeof toTransitions[key] !== 'undefined' && !key.toLowerCase().includes('leave'))
156
+ .forEach((key) => {
157
+ transitions[key] = toTransitions[key];
158
+ });
159
+
160
+ mergedTransitions.push(transitions);
161
+ }
162
+
163
+ return mergedTransitions;
164
+ }
165
+
166
+ async function loadAsyncComponents(to, from, next) {
167
+ // Check if route changed (this._routeChanged), only if the page is not an error (for validate())
168
+ this._routeChanged = Boolean(app.nuxt.err) || from.name !== to.name;
169
+ this._paramChanged = !this._routeChanged && from.path !== to.path;
170
+ this._queryChanged = !this._paramChanged && from.fullPath !== to.fullPath;
171
+ this._diffQuery = (this._queryChanged ? getQueryDiff(to.query, from.query) : []);
172
+
173
+ if ((this._routeChanged || this._paramChanged) && this.$loading.start && !this.$loading.manual) {
174
+ this.$loading.start();
175
+ }
176
+
177
+ try {
178
+ if (this._queryChanged) {
179
+ const Components = await resolveRouteComponents(
180
+ to,
181
+ (Component, instance) => ({ Component, instance })
182
+ );
183
+ // Add a marker on each component that it needs to refresh or not
184
+ const startLoader = Components.some(({ Component, instance }) => {
185
+ const watchQuery = Component.options.watchQuery;
186
+
187
+ if (watchQuery === true) {
188
+ return true;
189
+ }
190
+ if (Array.isArray(watchQuery)) {
191
+ return watchQuery.some(key => this._diffQuery[key]);
192
+ }
193
+ if (typeof watchQuery === 'function') {
194
+ return watchQuery.apply(instance, [to.query, from.query]);
195
+ }
196
+
197
+ return false;
198
+ });
199
+
200
+ if (startLoader && this.$loading.start && !this.$loading.manual) {
201
+ this.$loading.start();
202
+ }
203
+ }
204
+ // Call next()
205
+ next();
206
+ } catch (error) {
207
+ const err = error || {};
208
+ const statusCode = err.statusCode || err.status || (err.response && err.response.status) || 500;
209
+ const message = err.message || '';
210
+
211
+ // Handle chunk loading errors
212
+ // This may be due to a new deployment or a network problem
213
+ if (/^Loading( CSS)? chunk (\d)+ failed\./.test(message)) {
214
+ window.location.reload(true /* skip cache */);
215
+
216
+ return; // prevent error page blinking for user
217
+ }
218
+
219
+ this.error({ statusCode, message });
220
+ this.$nuxt.$emit('routeChanged', to, from, err);
221
+ next();
222
+ }
223
+ }
224
+
225
+ function applySSRData(Component, ssrData) {
226
+ if (NUXT.serverRendered && ssrData) {
227
+ applyAsyncData(Component, ssrData);
228
+ }
229
+
230
+ Component._Ctor = Component;
231
+
232
+ return Component;
233
+ }
234
+
235
+ // Get matched components
236
+ function resolveComponents(route) {
237
+ return flatMapComponents(route, async(Component, _, match, key, index) => {
238
+ // If component is not resolved yet, resolve it
239
+ if (typeof Component === 'function' && !Component.options) {
240
+ Component = await Component();
241
+ }
242
+ // Sanitize it and save it
243
+ const _Component = applySSRData(sanitizeComponent(Component), NUXT.data ? NUXT.data[index] : null);
244
+
245
+ match.components[key] = _Component;
246
+
247
+ return _Component;
248
+ });
249
+ }
250
+
251
+ function callMiddleware(Components, context, layout) {
252
+ let midd = ['i18n'];
253
+ let unknownMiddleware = false;
254
+
255
+ // If layout is undefined, only call global middleware
256
+ if (typeof layout !== 'undefined') {
257
+ midd = []; // Exclude global middleware if layout defined (already called before)
258
+ layout = sanitizeComponent(layout);
259
+ if (layout.options.middleware) {
260
+ midd = midd.concat(layout.options.middleware);
261
+ }
262
+ Components.forEach((Component) => {
263
+ if (Component.options.middleware) {
264
+ midd = midd.concat(Component.options.middleware);
265
+ }
266
+ });
267
+ }
268
+
269
+ midd = midd.map((name) => {
270
+ if (typeof name === 'function') {
271
+ return name;
272
+ }
273
+ if (typeof middleware[name] !== 'function') {
274
+ unknownMiddleware = true;
275
+ this.error({ statusCode: 500, message: `Unknown middleware ${ name }` });
276
+ }
277
+
278
+ return middleware[name];
279
+ });
280
+
281
+ if (unknownMiddleware) {
282
+ return;
283
+ }
284
+
285
+ return middlewareSeries(midd, context);
286
+ }
287
+
288
+ async function render(to, from, next) {
289
+ if (this._routeChanged === false && this._paramChanged === false && this._queryChanged === false) {
290
+ return next();
291
+ }
292
+
293
+ if (to === from) {
294
+ _lastPaths = [];
295
+ } else {
296
+ const fromMatches = [];
297
+
298
+ _lastPaths = getMatchedComponents(from, fromMatches).map((Component, i) => {
299
+ return compile(from.matched[fromMatches[i]].path)(from.params);
300
+ });
301
+ }
302
+
303
+ // nextCalled is true when redirected
304
+ let nextCalled = false;
305
+ const _next = (path) => {
306
+ if (from.path === path.path && this.$loading.finish) {
307
+ this.$loading.finish();
308
+ }
309
+
310
+ if (from.path !== path.path && this.$loading.pause) {
311
+ this.$loading.pause();
312
+ }
313
+
314
+ if (nextCalled) {
315
+ return;
316
+ }
317
+
318
+ nextCalled = true;
319
+ next(path);
320
+ };
321
+
322
+ // Update context
323
+ await setContext(app, {
324
+ route: to,
325
+ from,
326
+ next: _next.bind(this)
327
+ });
328
+ this._dateLastError = app.nuxt.dateErr;
329
+ this._hadError = Boolean(app.nuxt.err);
330
+
331
+ // Get route's matched components
332
+ const matches = [];
333
+ const Components = getMatchedComponents(to, matches);
334
+
335
+ // If no Components matched, generate 404
336
+ if (!Components.length) {
337
+ // Default layout
338
+ await callMiddleware.call(this, Components, app.context);
339
+ if (nextCalled) {
340
+ return;
341
+ }
342
+
343
+ // Load layout for error page
344
+ const errorLayout = (NuxtError.options || NuxtError).layout;
345
+ const layout = await this.loadLayout(
346
+ typeof errorLayout === 'function' ? errorLayout.call(NuxtError, app.context) : errorLayout
347
+ );
348
+
349
+ await callMiddleware.call(this, Components, app.context, layout);
350
+ if (nextCalled) {
351
+ return;
352
+ }
353
+
354
+ // Show error page
355
+ app.context.error({ statusCode: 404, message: 'This page could not be found' });
356
+
357
+ return next();
358
+ }
359
+
360
+ // Update ._data and other properties if hot reloaded
361
+ Components.forEach((Component) => {
362
+ if (Component._Ctor && Component._Ctor.options) {
363
+ Component.options.asyncData = Component._Ctor.options.asyncData;
364
+ Component.options.fetch = Component._Ctor.options.fetch;
365
+ }
366
+ });
367
+
368
+ // Apply transitions
369
+ this.setTransitions(mapTransitions(Components, to, from));
370
+
371
+ try {
372
+ // Call middleware
373
+ await callMiddleware.call(this, Components, app.context);
374
+ if (nextCalled) {
375
+ return;
376
+ }
377
+ if (app.context._errored) {
378
+ return next();
379
+ }
380
+
381
+ // Set layout
382
+ let layout = Components[0].options.layout;
383
+
384
+ if (typeof layout === 'function') {
385
+ layout = layout(app.context);
386
+ }
387
+ layout = await this.loadLayout(layout);
388
+
389
+ // Call middleware for layout
390
+ await callMiddleware.call(this, Components, app.context, layout);
391
+ if (nextCalled) {
392
+ return;
393
+ }
394
+ if (app.context._errored) {
395
+ return next();
396
+ }
397
+
398
+ // Call .validate()
399
+ let isValid = true;
400
+
401
+ try {
402
+ for (const Component of Components) {
403
+ if (typeof Component.options.validate !== 'function') {
404
+ continue;
405
+ }
406
+
407
+ isValid = await Component.options.validate(app.context);
408
+
409
+ if (!isValid) {
410
+ break;
411
+ }
412
+ }
413
+ } catch (validationError) {
414
+ // ...If .validate() threw an error
415
+ this.error({
416
+ statusCode: validationError.statusCode || '500',
417
+ message: validationError.message
418
+ });
419
+
420
+ return next();
421
+ }
422
+
423
+ // ...If .validate() returned false
424
+ if (!isValid) {
425
+ this.error({ statusCode: 404, message: 'This page could not be found' });
426
+
427
+ return next();
428
+ }
429
+
430
+ let instances;
431
+
432
+ // Call asyncData & fetch hooks on components matched by the route.
433
+ await Promise.all(Components.map((Component, i) => {
434
+ // Check if only children route changed
435
+ Component._path = compile(to.matched[matches[i]].path)(to.params);
436
+ Component._dataRefresh = false;
437
+ const childPathChanged = Component._path !== _lastPaths[i];
438
+
439
+ // Refresh component (call asyncData & fetch) when:
440
+ // Route path changed part includes current component
441
+ // Or route param changed part includes current component and watchParam is not `false`
442
+ // Or route query is changed and watchQuery returns `true`
443
+ if (this._routeChanged && childPathChanged) {
444
+ Component._dataRefresh = true;
445
+ } else if (this._paramChanged && childPathChanged) {
446
+ const watchParam = Component.options.watchParam;
447
+
448
+ Component._dataRefresh = watchParam !== false;
449
+ } else if (this._queryChanged) {
450
+ const watchQuery = Component.options.watchQuery;
451
+
452
+ if (watchQuery === true) {
453
+ Component._dataRefresh = true;
454
+ } else if (Array.isArray(watchQuery)) {
455
+ Component._dataRefresh = watchQuery.some(key => this._diffQuery[key]);
456
+ } else if (typeof watchQuery === 'function') {
457
+ if (!instances) {
458
+ instances = getMatchedComponentsInstances(to);
459
+ }
460
+ Component._dataRefresh = watchQuery.apply(instances[i], [to.query, from.query]);
461
+ }
462
+ }
463
+ if (!this._hadError && this._isMounted && !Component._dataRefresh) {
464
+ return;
465
+ }
466
+
467
+ const promises = [];
468
+
469
+ const hasAsyncData = (
470
+ Component.options.asyncData &&
471
+ typeof Component.options.asyncData === 'function'
472
+ );
473
+
474
+ const hasFetch = Boolean(Component.options.fetch) && Component.options.fetch.length;
475
+
476
+ const loadingIncrease = (hasAsyncData && hasFetch) ? 30 : 45;
477
+
478
+ // Call asyncData(context)
479
+ if (hasAsyncData) {
480
+ const promise = promisify(Component.options.asyncData, app.context);
481
+
482
+ promise.then((asyncDataResult) => {
483
+ applyAsyncData(Component, asyncDataResult);
484
+
485
+ if (this.$loading.increase) {
486
+ this.$loading.increase(loadingIncrease);
487
+ }
488
+ });
489
+ promises.push(promise);
490
+ }
491
+
492
+ // Check disabled page loading
493
+ this.$loading.manual = Component.options.loading === false;
494
+
495
+ // Call fetch(context)
496
+ if (hasFetch) {
497
+ let p = Component.options.fetch(app.context);
498
+
499
+ if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) {
500
+ p = Promise.resolve(p);
501
+ }
502
+ p.then((fetchResult) => {
503
+ if (this.$loading.increase) {
504
+ this.$loading.increase(loadingIncrease);
505
+ }
506
+ });
507
+ promises.push(p);
508
+ }
509
+
510
+ return Promise.all(promises);
511
+ }));
512
+
513
+ // If not redirected
514
+ if (!nextCalled) {
515
+ if (this.$loading.finish && !this.$loading.manual) {
516
+ this.$loading.finish();
517
+ }
518
+
519
+ next();
520
+ }
521
+ } catch (err) {
522
+ const error = err || {};
523
+
524
+ if (error.message === 'ERR_REDIRECT') {
525
+ return this.$nuxt.$emit('routeChanged', to, from, error);
526
+ }
527
+ _lastPaths = [];
528
+
529
+ globalHandleError(error);
530
+
531
+ // Load error layout
532
+ let layout = (NuxtError.options || NuxtError).layout;
533
+
534
+ if (typeof layout === 'function') {
535
+ layout = layout(app.context);
536
+ }
537
+ await this.loadLayout(layout);
538
+
539
+ this.error(error);
540
+ this.$nuxt.$emit('routeChanged', to, from, error);
541
+ next();
542
+ }
543
+ }
544
+
545
+ // Fix components format in matched, it's due to code-splitting of vue-router
546
+ function normalizeComponents(to, ___) {
547
+ flatMapComponents(to, (Component, _, match, key) => {
548
+ if (typeof Component === 'object' && !Component.options) {
549
+ // Updated via vue-router resolveAsyncComponents()
550
+ Component = Vue.extend(Component);
551
+ Component._Ctor = Component;
552
+ match.components[key] = Component;
553
+ }
554
+
555
+ return Component;
556
+ });
557
+ }
558
+
559
+ function setLayoutForNextPage(to) {
560
+ // Set layout
561
+ let hasError = Boolean(this.$options.nuxt.err);
562
+
563
+ if (this._hadError && this._dateLastError === this.$options.nuxt.dateErr) {
564
+ hasError = false;
565
+ }
566
+ let layout = hasError ? (NuxtError.options || NuxtError).layout : to.matched[0].components.default.options.layout;
567
+
568
+ if (typeof layout === 'function') {
569
+ layout = layout(app.context);
570
+ }
571
+
572
+ this.setLayout(layout);
573
+ }
574
+
575
+ function checkForErrors(app) {
576
+ // Hide error component if no error
577
+ if (app._hadError && app._dateLastError === app.$options.nuxt.dateErr) {
578
+ app.error();
579
+ }
580
+ }
581
+
582
+ // When navigating on a different route but the same component is used, Vue.js
583
+ // Will not update the instance data, so we have to update $data ourselves
584
+ function fixPrepatch(to, ___) {
585
+ if (this._routeChanged === false && this._paramChanged === false && this._queryChanged === false) {
586
+ return;
587
+ }
588
+
589
+ const instances = getMatchedComponentsInstances(to);
590
+ const Components = getMatchedComponents(to);
591
+
592
+ let triggerScroll = false;
593
+
594
+ Vue.nextTick(() => {
595
+ instances.forEach((instance, i) => {
596
+ if (!instance || instance._isDestroyed) {
597
+ return;
598
+ }
599
+
600
+ if (
601
+ instance.constructor._dataRefresh &&
602
+ Components[i] === instance.constructor &&
603
+ instance.$vnode.data.keepAlive !== true &&
604
+ typeof instance.constructor.options.data === 'function'
605
+ ) {
606
+ const newData = instance.constructor.options.data.call(instance);
607
+
608
+ for (const key in newData) {
609
+ Vue.set(instance.$data, key, newData[key]);
610
+ }
611
+
612
+ triggerScroll = true;
613
+ }
614
+ });
615
+
616
+ if (triggerScroll) {
617
+ // Ensure to trigger scroll event after calling scrollBehavior
618
+ window.$nuxt.$nextTick(() => {
619
+ window.$nuxt.$emit('triggerScroll');
620
+ });
621
+ }
622
+
623
+ checkForErrors(this);
624
+
625
+ // Hot reloading
626
+ setTimeout(() => hotReloadAPI(this), 100);
627
+ });
628
+ }
629
+
630
+ function nuxtReady(_app) {
631
+ window.onNuxtReadyCbs.forEach((cb) => {
632
+ if (typeof cb === 'function') {
633
+ cb(_app);
634
+ }
635
+ });
636
+ // Special JSDOM
637
+ if (typeof window._onNuxtLoaded === 'function') {
638
+ window._onNuxtLoaded(_app);
639
+ }
640
+ // Add router hooks
641
+ router.afterEach((to, from) => {
642
+ // Wait for fixPrepatch + $data updates
643
+ Vue.nextTick(() => _app.$nuxt.$emit('routeChanged', to, from));
644
+ });
645
+ }
646
+
647
+ const noopData = () => {
648
+ return {};
649
+ };
650
+ const noopFetch = () => {};
651
+
652
+ // Special hot reload with asyncData(context)
653
+ function getNuxtChildComponents($parent, $components = []) {
654
+ $parent.$children.forEach(($child) => {
655
+ if ($child.$vnode && $child.$vnode.data.nuxtChild && !$components.find(c => (c.$options.__file === $child.$options.__file))) {
656
+ $components.push($child);
657
+ }
658
+ if ($child.$children && $child.$children.length) {
659
+ getNuxtChildComponents($child, $components);
660
+ }
661
+ });
662
+
663
+ return $components;
664
+ }
665
+
666
+ function hotReloadAPI(_app) {
667
+ if (!module.hot) {
668
+ return;
669
+ }
670
+
671
+ const $components = getNuxtChildComponents(_app.$nuxt, []);
672
+
673
+ $components.forEach(addHotReload.bind(_app));
674
+ }
675
+
676
+ function addHotReload($component, depth) {
677
+ if ($component.$vnode.data._hasHotReload) {
678
+ return;
679
+ }
680
+ $component.$vnode.data._hasHotReload = true;
681
+
682
+ const _forceUpdate = $component.$forceUpdate.bind($component.$parent);
683
+
684
+ $component.$vnode.context.$forceUpdate = async() => {
685
+ const Components = getMatchedComponents(router.currentRoute);
686
+ let Component = Components[depth];
687
+
688
+ if (!Component) {
689
+ return _forceUpdate();
690
+ }
691
+ if (typeof Component === 'object' && !Component.options) {
692
+ // Updated via vue-router resolveAsyncComponents()
693
+ Component = Vue.extend(Component);
694
+ Component._Ctor = Component;
695
+ }
696
+ this.error();
697
+ const promises = [];
698
+ const next = function(path) {
699
+ this.$loading.finish && this.$loading.finish();
700
+ router.push(path);
701
+ };
702
+
703
+ await setContext(app, {
704
+ route: router.currentRoute,
705
+ isHMR: true,
706
+ next: next.bind(this)
707
+ });
708
+ const context = app.context;
709
+
710
+ if (this.$loading.start && !this.$loading.manual) {
711
+ this.$loading.start();
712
+ }
713
+
714
+ callMiddleware.call(this, Components, context)
715
+ .then(() => {
716
+ // If layout changed
717
+ if (depth !== 0) {
718
+ return;
719
+ }
720
+
721
+ let layout = Component.options.layout || 'default';
722
+
723
+ if (typeof layout === 'function') {
724
+ layout = layout(context);
725
+ }
726
+ if (this.layoutName === layout) {
727
+ return;
728
+ }
729
+ const promise = this.loadLayout(layout);
730
+
731
+ promise.then(() => {
732
+ this.setLayout(layout);
733
+ Vue.nextTick(() => hotReloadAPI(this));
734
+ });
735
+
736
+ return promise;
737
+ })
738
+
739
+ .then(() => {
740
+ return callMiddleware.call(this, Components, context, this.layout);
741
+ })
742
+
743
+ .then(() => {
744
+ // Call asyncData(context)
745
+ const pAsyncData = promisify(Component.options.asyncData || noopData, context);
746
+
747
+ pAsyncData.then((asyncDataResult) => {
748
+ applyAsyncData(Component, asyncDataResult);
749
+ this.$loading.increase && this.$loading.increase(30);
750
+ });
751
+ promises.push(pAsyncData);
752
+
753
+ // Call fetch()
754
+ Component.options.fetch = Component.options.fetch || noopFetch;
755
+ let pFetch = Component.options.fetch.length && Component.options.fetch(context);
756
+
757
+ if (!pFetch || (!(pFetch instanceof Promise) && (typeof pFetch.then !== 'function'))) {
758
+ pFetch = Promise.resolve(pFetch);
759
+ }
760
+ pFetch.then(() => this.$loading.increase && this.$loading.increase(30));
761
+ promises.push(pFetch);
762
+
763
+ return Promise.all(promises);
764
+ })
765
+ .then(() => {
766
+ this.$loading.finish && this.$loading.finish();
767
+ _forceUpdate();
768
+ setTimeout(() => hotReloadAPI(this), 100);
769
+ });
770
+ };
771
+ }
772
+
773
+ async function mountApp(__app) {
774
+ // Set global variables
775
+ app = __app.app;
776
+ router = __app.router;
777
+
778
+ // Create Vue instance
779
+ const _app = new Vue(app);
780
+
781
+ // Mounts Vue app to DOM element
782
+ const mount = () => {
783
+ _app.$mount('#app');
784
+
785
+ // Add afterEach router hooks
786
+ router.afterEach(normalizeComponents);
787
+
788
+ router.afterEach(setLayoutForNextPage.bind(_app));
789
+
790
+ router.afterEach(fixPrepatch.bind(_app));
791
+
792
+ // Listen for first Vue update
793
+ Vue.nextTick(() => {
794
+ // Call window.{{globals.readyCallback}} callbacks
795
+ nuxtReady(_app);
796
+
797
+ // Enable hot reloading
798
+ hotReloadAPI(_app);
799
+ });
800
+ };
801
+
802
+ // Resolve route components
803
+ const Components = await Promise.all(resolveComponents(app.context.route));
804
+
805
+ // Enable transitions
806
+ _app.setTransitions = _app.$options.nuxt.setTransitions.bind(_app);
807
+ if (Components.length) {
808
+ _app.setTransitions(mapTransitions(Components, router.currentRoute));
809
+ _lastPaths = router.currentRoute.matched.map(route => compile(route.path)(router.currentRoute.params));
810
+ }
811
+
812
+ // Initialize error handler
813
+ _app.$loading = {}; // To avoid error while _app.$nuxt does not exist
814
+ if (NUXT.error) {
815
+ _app.error(NUXT.error);
816
+ }
817
+
818
+ // Add beforeEach router hooks
819
+ router.beforeEach(loadAsyncComponents.bind(_app));
820
+ router.beforeEach(render.bind(_app));
821
+
822
+ // Fix in static: remove trailing slash to force hydration
823
+ // Full static, if server-rendered: hydrate, to allow custom redirect to generated page
824
+
825
+ // Fix in static: remove trailing slash to force hydration
826
+ if (NUXT.serverRendered && isSamePath(NUXT.routePath, _app.context.route.path)) {
827
+ return mount();
828
+ }
829
+
830
+ // First render on client-side
831
+ const clientFirstMount = () => {
832
+ normalizeComponents(router.currentRoute, router.currentRoute);
833
+ setLayoutForNextPage.call(_app, router.currentRoute);
834
+ checkForErrors(_app);
835
+ // Don't call fixPrepatch.call(_app, router.currentRoute, router.currentRoute) since it's first render
836
+ mount();
837
+ };
838
+
839
+ // fix: force next tick to avoid having same timestamp when an error happen on spa fallback
840
+ await new Promise(resolve => setTimeout(resolve, 0));
841
+ render.call(_app, router.currentRoute, router.currentRoute, (path) => {
842
+ // If not redirected
843
+ if (!path) {
844
+ clientFirstMount();
845
+
846
+ return;
847
+ }
848
+
849
+ // Add a one-time afterEach hook to
850
+ // mount the app wait for redirect and route gets resolved
851
+ const unregisterHook = router.afterEach((to, from) => {
852
+ unregisterHook();
853
+ clientFirstMount();
854
+ });
855
+
856
+ // Push the path and let route to be resolved
857
+ router.push(path, undefined, (err) => {
858
+ if (err) {
859
+ errorHandler(err);
860
+ }
861
+ });
862
+ });
863
+ }