@rancher/shell 0.3.3 → 0.3.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/assets/styles/app.scss +1 -1
- package/assets/styles/fonts/_fontstack.scss +11 -11
- package/assets/styles/vendor/vue-js-modal.scss +3 -3
- package/assets/translations/en-us.yaml +92 -22
- package/assets/translations/zh-hans.yaml +84 -15
- package/babel.config.js +13 -0
- package/chart/gatekeeper.vue +77 -0
- package/chart/istio.vue +108 -111
- package/chart/logging/index.vue +13 -4
- package/chart/monitoring/index.vue +15 -5
- package/chart/monitoring/steps/uninstall-v1.vue +2 -2
- package/chart/rancher-backup/index.vue +10 -3
- package/cloud-credential/aws.vue +1 -1
- package/cloud-credential/digitalocean.vue +1 -1
- package/cloud-credential/gcp.vue +1 -1
- package/cloud-credential/generic.vue +2 -2
- package/cloud-credential/linode.vue +1 -1
- package/cloud-credential/pnap.vue +1 -1
- package/components/ActionMenu.vue +3 -4
- package/components/AssignTo.vue +1 -1
- package/components/AsyncButton.vue +1 -1
- package/components/BannerGraphic.vue +1 -1
- package/components/ButtonDropdown.vue +2 -3
- package/components/ChartPsp.vue +76 -0
- package/components/CruResource.vue +6 -2
- package/components/DashboardMetrics.vue +12 -10
- package/components/DetailText.vue +1 -1
- package/components/DisableAuthProviderModal.vue +1 -1
- package/components/EmberPage.vue +1 -1
- package/components/EtcdInfoBanner.vue +5 -4
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +15 -2
- package/components/FileDiff.vue +6 -7
- package/components/GrafanaDashboard.vue +18 -21
- package/components/LazyImage.vue +10 -12
- package/components/LogItem.vue +1 -1
- package/components/Markdown.vue +1 -1
- package/components/PromptRemove.vue +2 -2
- package/components/PromptRestore.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +16 -0
- package/components/ResourceDetail/index.vue +21 -4
- package/components/ResourceList/index.vue +1 -1
- package/components/ResourceTable.vue +4 -1
- package/components/SingleClusterInfo.vue +2 -2
- package/components/SortableTable/THead.vue +1 -1
- package/components/SortableTable/index.vue +5 -2
- package/components/__tests__/AsyncButton.test.ts +3 -1
- package/components/__tests__/ChartPsp.test.ts +75 -0
- package/components/__tests__/CruResource.test.ts +3 -1
- package/components/auth/Principal.vue +1 -1
- package/components/fleet/FleetBundles.vue +3 -1
- package/components/fleet/FleetClusters.vue +1 -2
- package/components/fleet/FleetIntro.vue +9 -1
- package/components/fleet/FleetNoWorkspaces.vue +62 -0
- package/components/fleet/FleetSummary.vue +7 -1
- package/components/form/LabeledSelect.vue +14 -11
- package/components/form/MatchExpressions.vue +17 -2
- package/components/form/NameNsDescription.vue +31 -45
- package/components/form/ResourceSelector.vue +1 -1
- package/components/form/SecretSelector.vue +5 -1
- package/components/form/ServiceNameSelect.vue +1 -1
- package/components/form/SimpleSecretSelector.vue +9 -9
- package/components/form/__tests__/LabeledSelect.test.ts +138 -0
- package/components/form/__tests__/NameNsDescription.ts +32 -0
- package/components/formatter/InternalExternalIP.vue +6 -0
- package/components/formatter/InvolvedObjectLink.vue +54 -0
- package/components/formatter/Link.vue +20 -4
- package/components/formatter/LinkName.vue +6 -1
- package/components/formatter/ServiceTargets.vue +1 -1
- package/components/nav/Group.vue +2 -2
- package/components/nav/NamespaceFilter.vue +15 -11
- package/components/nav/TopLevelMenu.vue +2 -4
- package/components/nav/Type.vue +1 -1
- package/components/nav/WorkspaceSwitcher.vue +46 -5
- package/config/labels-annotations.js +17 -0
- package/config/product/auth.js +3 -2
- package/config/product/explorer.js +11 -4
- package/config/product/fleet.js +2 -0
- package/config/router.js +414 -0
- package/config/table-headers.js +10 -2
- package/config/types.js +11 -8
- package/config/uiplugins.js +30 -0
- package/content/docs/en-us/whats-new.md +10 -0
- package/content/docs/zh-hans/whats-new.md +11 -1
- package/core/plugin-helpers.js +64 -61
- package/core/plugin-routes.ts +23 -0
- package/creators/app/app.package.json +2 -1
- package/creators/app/files/.eslintrc.js +1 -1
- package/creators/app/files/babel.config.js +1 -18
- package/creators/app/files/vue.config.js +7 -0
- package/creators/app/init +5 -5
- package/creators/pkg/files/.github/workflows/build-extension.yml +111 -0
- package/creators/pkg/init +35 -4
- package/creators/update/init +1 -1
- package/detail/constraints.gatekeeper.sh.constraint.vue +20 -10
- package/detail/fleet.cattle.io.gitrepo.vue +19 -11
- package/detail/harvesterhci.io.management.cluster.vue +3 -3
- package/detail/provisioning.cattle.io.cluster.vue +54 -12
- package/detail/workload/index.vue +3 -3
- package/dialog/AddClusterMemberDialog.vue +1 -1
- package/dialog/AddProjectMemberDialog.vue +2 -2
- package/dialog/AddonConfigConfirmationDialog.vue +27 -15
- package/dialog/DiagnosticTimingsDialog.vue +1 -1
- package/dialog/ForceMachineRemoveDialog.vue +1 -1
- package/dialog/GenericPrompt.vue +18 -6
- package/dialog/RotateEncryptionKeyDialog.vue +1 -1
- package/dialog/SaveAsRKETemplateDialog.vue +1 -1
- package/dialog/ScaleMachineDownDialog.vue +1 -1
- package/edit/auth/github.vue +8 -8
- package/edit/auth/googleoauth.vue +5 -5
- package/edit/auth/ldap/index.vue +1 -1
- package/edit/auth/oidc.vue +1 -1
- package/edit/auth/saml.vue +1 -1
- package/edit/cis.cattle.io.clusterscan.vue +1 -1
- package/edit/fleet.cattle.io.clustergroup.vue +6 -4
- package/edit/fleet.cattle.io.gitrepo.vue +16 -3
- package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
- package/edit/management.cattle.io.fleetworkspace.vue +141 -6
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
- package/edit/management.cattle.io.setting.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
- package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
- package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
- package/edit/namespace.vue +2 -2
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +10 -0
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
- package/edit/provisioning.cattle.io.cluster/rke2.vue +248 -84
- package/edit/resources.cattle.io.backup.vue +1 -1
- package/edit/service.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
- package/edit/workload/__tests__/Job.test.ts +3 -1
- package/edit/workload/index.vue +8 -3
- package/edit/workload/mixins/workload.js +16 -0
- package/layouts/default.vue +7 -3
- package/list/fleet.cattle.io.bundle.vue +6 -3
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
- package/list/fleet.cattle.io.gitrepo.vue +44 -5
- package/list/management.cattle.io.fleetworkspace.vue +45 -0
- package/list/node.vue +69 -16
- package/list/provisioning.cattle.io.cluster.vue +30 -1
- package/machine-config/azure.vue +97 -38
- package/middleware/authenticated.js +34 -0
- package/mixins/chart.js +73 -2
- package/mixins/resource-fetch.js +2 -2
- package/models/apps.statefulset.js +28 -0
- package/models/cluster/node.js +23 -2
- package/models/cluster.x-k8s.io.machine.js +4 -2
- package/models/clusterroletemplatebinding.js +7 -0
- package/models/constraints.gatekeeper.sh.constraint.js +9 -0
- package/models/fleet.cattle.io.cluster.js +19 -10
- package/models/fleet.cattle.io.gitrepo.js +7 -2
- package/models/management.cattle.io.cluster.js +1 -1
- package/models/management.cattle.io.fleetworkspace.js +12 -0
- package/models/management.cattle.io.gitreporestriction.js +5 -0
- package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
- package/models/namespace.js +5 -5
- package/models/provisioning.cattle.io.cluster.js +7 -5
- package/nuxt/App.js +210 -0
- package/nuxt/axios.js +186 -0
- package/nuxt/client.js +817 -0
- package/nuxt/components/nuxt-build-indicator.vue +143 -0
- package/nuxt/components/nuxt-child.js +122 -0
- package/nuxt/components/nuxt-error.vue +98 -0
- package/nuxt/components/nuxt-link.client.js +98 -0
- package/nuxt/components/nuxt-link.server.js +16 -0
- package/nuxt/components/nuxt-loading.vue +154 -0
- package/nuxt/components/nuxt.js +101 -0
- package/nuxt/cookie-universal-nuxt.js +9 -0
- package/nuxt/empty.js +1 -0
- package/nuxt/index.js +365 -0
- package/nuxt/jsonp.js +82 -0
- package/nuxt/loading.html +39 -0
- package/nuxt/middleware.js +12 -0
- package/nuxt/mixins/fetch.client.js +90 -0
- package/nuxt/mixins/fetch.server.js +69 -0
- package/nuxt/portal-vue.js +4 -0
- package/nuxt/server.js +312 -0
- package/nuxt/store.js +178 -0
- package/nuxt/utils.js +630 -0
- package/nuxt/views/app.template.html +9 -0
- package/nuxt/views/error.html +23 -0
- package/package.json +5 -9
- package/pages/auth/setup.vue +2 -2
- package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
- package/pages/c/_cluster/apps/charts/chart.vue +4 -4
- package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
- package/pages/c/_cluster/apps/charts/install.vue +40 -66
- package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
- package/pages/c/_cluster/explorer/index.vue +29 -25
- package/pages/c/_cluster/explorer/tools/index.vue +8 -8
- package/pages/c/_cluster/fleet/index.vue +95 -34
- package/pages/c/_cluster/gatekeeper/index.vue +1 -1
- package/pages/c/_cluster/istio/index.vue +5 -5
- package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +7 -0
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
- package/pages/c/_cluster/uiplugins/index.vue +49 -17
- package/pages/home.vue +9 -4
- package/pages/index.vue +10 -1
- package/plugins/clean-html-directive.js +31 -0
- package/plugins/dashboard-store/actions.js +32 -9
- package/plugins/dashboard-store/mutations.js +5 -2
- package/plugins/dashboard-store/resource-class.js +8 -1
- package/plugins/steve/mutations.js +3 -2
- package/plugins/steve/steve-description-class.js +5 -1
- package/plugins/steve/subscribe.js +63 -54
- package/plugins/steve-create-worker.js +14 -0
- package/promptRemove/management.cattle.io.globalrole.vue +2 -2
- package/promptRemove/management.cattle.io.project.vue +2 -2
- package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
- package/promptRemove/pod.vue +1 -1
- package/public/index.html +65 -0
- package/rancher-components/components/Banner/Banner.test.ts +9 -1
- package/rancher-components/components/Banner/Banner.vue +1 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
- package/rancher-components/components/Form/Radio/RadioButton.vue +1 -1
- package/scripts/build-pkg.sh +1 -0
- package/scripts/clean +6 -0
- package/scripts/extension/bundle +58 -0
- package/scripts/extension/helmpatch +89 -0
- package/scripts/extension/publish +314 -0
- package/scripts/test-plugins-build.sh +4 -0
- package/store/__tests__/index.test.ts +110 -0
- package/store/index.js +145 -58
- package/store/type-map.js +26 -19
- package/tsconfig.default.json +36 -0
- package/tsconfig.json +24 -0
- package/types/shell/index.d.ts +420 -343
- package/utils/__tests__/string.test.ts +12 -0
- package/utils/auth.js +65 -0
- package/utils/monitoring.js +2 -1
- package/utils/position.js +5 -8
- package/utils/router.scrollBehavior.js +80 -0
- package/utils/select.js +1 -3
- package/utils/socket.js +1 -0
- package/utils/string.js +13 -0
- package/utils/time.js +9 -0
- package/vue.config.js +679 -0
- package/yarn-error.log +196 -0
- package/chart/rancher-alerting-drivers.vue +0 -53
- package/chart/rancher-gatekeeper.vue +0 -37
- package/creators/app/files/nuxt.config.js +0 -6
- package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
- package/nuxt.config.js +0 -798
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Vue from 'vue'
|
|
2
|
+
import { hasFetch, normalizeError, addLifecycleHook, purifyData, createGetCounter } from '../utils'
|
|
3
|
+
|
|
4
|
+
async function serverPrefetch() {
|
|
5
|
+
if (!this._fetchOnServer) {
|
|
6
|
+
return
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Call and await on $fetch
|
|
10
|
+
try {
|
|
11
|
+
await this.$options.fetch.call(this)
|
|
12
|
+
} catch (err) {
|
|
13
|
+
if (process.dev) {
|
|
14
|
+
console.error('Error in fetch():', err)
|
|
15
|
+
}
|
|
16
|
+
this.$fetchState.error = normalizeError(err)
|
|
17
|
+
}
|
|
18
|
+
this.$fetchState.pending = false
|
|
19
|
+
|
|
20
|
+
// Define an ssrKey for hydration
|
|
21
|
+
this._fetchKey = this._fetchKey || this.$ssrContext.fetchCounters['']++
|
|
22
|
+
|
|
23
|
+
// Add data-fetch-key on parent element of Component
|
|
24
|
+
const attrs = this.$vnode.data.attrs = this.$vnode.data.attrs || {}
|
|
25
|
+
attrs['data-fetch-key'] = this._fetchKey
|
|
26
|
+
|
|
27
|
+
// Add to ssrContext for window.__NUXT__.fetch
|
|
28
|
+
|
|
29
|
+
if (this.$ssrContext.nuxt.fetch[this._fetchKey] !== undefined) {
|
|
30
|
+
console.warn(`Duplicate fetch key detected (${this._fetchKey}). This may lead to unexpected results.`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.$ssrContext.nuxt.fetch[this._fetchKey] =
|
|
34
|
+
this.$fetchState.error ? { _error: this.$fetchState.error } : purifyData(this._data)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default {
|
|
38
|
+
created() {
|
|
39
|
+
if (!hasFetch(this)) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof this.$options.fetchOnServer === 'function') {
|
|
44
|
+
this._fetchOnServer = this.$options.fetchOnServer.call(this) !== false
|
|
45
|
+
} else {
|
|
46
|
+
this._fetchOnServer = this.$options.fetchOnServer !== false
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const defaultKey = this.$options._scopeId || this.$options.name || ''
|
|
50
|
+
const getCounter = createGetCounter(this.$ssrContext.fetchCounters, defaultKey)
|
|
51
|
+
|
|
52
|
+
if (typeof this.$options.fetchKey === 'function') {
|
|
53
|
+
this._fetchKey = this.$options.fetchKey.call(this, getCounter)
|
|
54
|
+
} else {
|
|
55
|
+
const key = 'string' === typeof this.$options.fetchKey ? this.$options.fetchKey : defaultKey
|
|
56
|
+
this._fetchKey = key ? key + ':' + getCounter(key) : String(getCounter(key))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Added for remove vue undefined warning while ssr
|
|
60
|
+
this.$fetch = () => {} // issue #8043
|
|
61
|
+
Vue.util.defineReactive(this, '$fetchState', {
|
|
62
|
+
pending: true,
|
|
63
|
+
error: null,
|
|
64
|
+
timestamp: Date.now()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
addLifecycleHook(this, 'serverPrefetch', serverPrefetch)
|
|
68
|
+
}
|
|
69
|
+
}
|
package/nuxt/server.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import Vue from 'vue'
|
|
2
|
+
import { joinURL, normalizeURL, withQuery } from 'ufo'
|
|
3
|
+
import fetch from 'node-fetch'
|
|
4
|
+
import middleware from './middleware.js'
|
|
5
|
+
import {
|
|
6
|
+
applyAsyncData,
|
|
7
|
+
middlewareSeries,
|
|
8
|
+
sanitizeComponent,
|
|
9
|
+
getMatchedComponents,
|
|
10
|
+
promisify
|
|
11
|
+
} from './utils.js'
|
|
12
|
+
import fetchMixin from './mixins/fetch.server'
|
|
13
|
+
import { createApp, NuxtError } from './index.js'
|
|
14
|
+
import NuxtLink from './components/nuxt-link.server.js' // should be included after ./index.js
|
|
15
|
+
|
|
16
|
+
// Update serverPrefetch strategy
|
|
17
|
+
Vue.config.optionMergeStrategies.serverPrefetch = Vue.config.optionMergeStrategies.created
|
|
18
|
+
|
|
19
|
+
// Fetch mixin
|
|
20
|
+
if (!Vue.__nuxt__fetch__mixin__) {
|
|
21
|
+
Vue.mixin(fetchMixin)
|
|
22
|
+
Vue.__nuxt__fetch__mixin__ = true
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!Vue.__original_use__) {
|
|
26
|
+
Vue.__original_use__ = Vue.use
|
|
27
|
+
Vue.__install_times__ = 0
|
|
28
|
+
Vue.use = function (plugin, ...args) {
|
|
29
|
+
plugin.__nuxt_external_installed__ = Vue._installedPlugins.includes(plugin)
|
|
30
|
+
return Vue.__original_use__(plugin, ...args)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (Vue.__install_times__ === 2) {
|
|
34
|
+
Vue.__install_times__ = 0
|
|
35
|
+
Vue._installedPlugins = Vue._installedPlugins.filter(plugin => {
|
|
36
|
+
return plugin.__nuxt_external_installed__ === true
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
Vue.__install_times__++
|
|
40
|
+
|
|
41
|
+
// Component: <NuxtLink>
|
|
42
|
+
Vue.component(NuxtLink.name, NuxtLink)
|
|
43
|
+
Vue.component('NLink', NuxtLink)
|
|
44
|
+
|
|
45
|
+
if (!global.fetch) { global.fetch = fetch }
|
|
46
|
+
|
|
47
|
+
const noopApp = () => new Vue({ render: h => h('div', { domProps: { id: '__nuxt' } }) })
|
|
48
|
+
|
|
49
|
+
const createNext = ssrContext => (opts) => {
|
|
50
|
+
// If static target, render on client-side
|
|
51
|
+
ssrContext.redirected = opts
|
|
52
|
+
if (ssrContext.target === 'static' || !ssrContext.res) {
|
|
53
|
+
ssrContext.nuxt.serverRendered = false
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
let fullPath = withQuery(opts.path, opts.query)
|
|
57
|
+
const $config = ssrContext.runtimeConfig || {}
|
|
58
|
+
const routerBase = ($config._app && $config._app.basePath) || '/'
|
|
59
|
+
if (!fullPath.startsWith('http') && (routerBase !== '/' && !fullPath.startsWith(routerBase))) {
|
|
60
|
+
fullPath = joinURL(routerBase, fullPath)
|
|
61
|
+
}
|
|
62
|
+
// Avoid loop redirect
|
|
63
|
+
if (decodeURI(fullPath) === decodeURI(ssrContext.url)) {
|
|
64
|
+
ssrContext.redirected = false
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
ssrContext.res.writeHead(opts.status, {
|
|
68
|
+
Location: normalizeURL(fullPath)
|
|
69
|
+
})
|
|
70
|
+
ssrContext.res.end()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// This exported function will be called by `bundleRenderer`.
|
|
74
|
+
// This is where we perform data-prefetching to determine the
|
|
75
|
+
// state of our application before actually rendering it.
|
|
76
|
+
// Since data fetching is async, this function is expected to
|
|
77
|
+
// return a Promise that resolves to the app instance.
|
|
78
|
+
export default async (ssrContext) => {
|
|
79
|
+
// Create ssrContext.next for simulate next() of beforeEach() when wanted to redirect
|
|
80
|
+
ssrContext.redirected = false
|
|
81
|
+
ssrContext.next = createNext(ssrContext)
|
|
82
|
+
// Used for beforeNuxtRender({ Components, nuxtState })
|
|
83
|
+
ssrContext.beforeRenderFns = []
|
|
84
|
+
// Nuxt object (window.{{globals.context}}, defaults to window.__NUXT__)
|
|
85
|
+
ssrContext.nuxt = { layout: 'default', data: [], fetch: {}, error: null, state: null, serverRendered: true, routePath: '' }
|
|
86
|
+
|
|
87
|
+
ssrContext.fetchCounters = {}
|
|
88
|
+
|
|
89
|
+
// Remove query from url is static target
|
|
90
|
+
|
|
91
|
+
// Public runtime config
|
|
92
|
+
ssrContext.nuxt.config = ssrContext.runtimeConfig.public
|
|
93
|
+
if (ssrContext.nuxt.config._app) {
|
|
94
|
+
__webpack_public_path__ = joinURL(ssrContext.nuxt.config._app.cdnURL, ssrContext.nuxt.config._app.assetsPath)
|
|
95
|
+
}
|
|
96
|
+
// Create the app definition and the instance (created for each request)
|
|
97
|
+
const { app, router, store } = await createApp(ssrContext, ssrContext.runtimeConfig.private)
|
|
98
|
+
const _app = new Vue(app)
|
|
99
|
+
// Add ssr route path to nuxt context so we can account for page navigation between ssr and csr
|
|
100
|
+
ssrContext.nuxt.routePath = app.context.route.path
|
|
101
|
+
|
|
102
|
+
// Add meta infos (used in renderer.js)
|
|
103
|
+
ssrContext.meta = _app.$meta()
|
|
104
|
+
|
|
105
|
+
// Keep asyncData for each matched component in ssrContext (used in app/utils.js via this.$ssrContext)
|
|
106
|
+
ssrContext.asyncData = {}
|
|
107
|
+
|
|
108
|
+
const beforeRender = async () => {
|
|
109
|
+
// Call beforeNuxtRender() methods
|
|
110
|
+
await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt })))
|
|
111
|
+
|
|
112
|
+
ssrContext.rendered = () => {
|
|
113
|
+
// Add the state from the vuex store
|
|
114
|
+
ssrContext.nuxt.state = store.state
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const renderErrorPage = async () => {
|
|
119
|
+
// Don't server-render the page in static target
|
|
120
|
+
if (ssrContext.target === 'static') {
|
|
121
|
+
ssrContext.nuxt.serverRendered = false
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Load layout for error page
|
|
125
|
+
const layout = (NuxtError.options || NuxtError).layout
|
|
126
|
+
const errLayout = typeof layout === 'function' ? layout.call(NuxtError, app.context) : layout
|
|
127
|
+
ssrContext.nuxt.layout = errLayout || 'default'
|
|
128
|
+
await _app.loadLayout(errLayout)
|
|
129
|
+
_app.setLayout(errLayout)
|
|
130
|
+
|
|
131
|
+
await beforeRender()
|
|
132
|
+
return _app
|
|
133
|
+
}
|
|
134
|
+
const render404Page = () => {
|
|
135
|
+
app.context.error({ statusCode: 404, path: ssrContext.url, message: 'This page could not be found' })
|
|
136
|
+
return renderErrorPage()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const s = Date.now()
|
|
140
|
+
|
|
141
|
+
// Components are already resolved by setContext -> getRouteData (app/utils.js)
|
|
142
|
+
const Components = getMatchedComponents(app.context.route)
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
** Dispatch store nuxtServerInit
|
|
146
|
+
*/
|
|
147
|
+
if (store._actions && store._actions.nuxtServerInit) {
|
|
148
|
+
try {
|
|
149
|
+
await store.dispatch('nuxtServerInit', app.context)
|
|
150
|
+
} catch (err) {
|
|
151
|
+
console.debug('Error occurred when calling nuxtServerInit: ', err.message)
|
|
152
|
+
throw err
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// ...If there is a redirect or an error, stop the process
|
|
156
|
+
if (ssrContext.redirected) {
|
|
157
|
+
return noopApp()
|
|
158
|
+
}
|
|
159
|
+
if (ssrContext.nuxt.error) {
|
|
160
|
+
return renderErrorPage()
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/*
|
|
164
|
+
** Call global middleware (nuxt.config.js)
|
|
165
|
+
*/
|
|
166
|
+
let midd = ["i18n"]
|
|
167
|
+
midd = midd.map((name) => {
|
|
168
|
+
if (typeof name === 'function') {
|
|
169
|
+
return name
|
|
170
|
+
}
|
|
171
|
+
if (typeof middleware[name] !== 'function') {
|
|
172
|
+
app.context.error({ statusCode: 500, message: 'Unknown middleware ' + name })
|
|
173
|
+
}
|
|
174
|
+
return middleware[name]
|
|
175
|
+
})
|
|
176
|
+
await middlewareSeries(midd, app.context)
|
|
177
|
+
// ...If there is a redirect or an error, stop the process
|
|
178
|
+
if (ssrContext.redirected) {
|
|
179
|
+
return noopApp()
|
|
180
|
+
}
|
|
181
|
+
if (ssrContext.nuxt.error) {
|
|
182
|
+
return renderErrorPage()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
** Set layout
|
|
187
|
+
*/
|
|
188
|
+
let layout = Components.length ? Components[0].options.layout : NuxtError.layout
|
|
189
|
+
if (typeof layout === 'function') {
|
|
190
|
+
layout = layout(app.context)
|
|
191
|
+
}
|
|
192
|
+
await _app.loadLayout(layout)
|
|
193
|
+
if (ssrContext.nuxt.error) {
|
|
194
|
+
return renderErrorPage()
|
|
195
|
+
}
|
|
196
|
+
layout = _app.setLayout(layout)
|
|
197
|
+
ssrContext.nuxt.layout = _app.layoutName
|
|
198
|
+
|
|
199
|
+
/*
|
|
200
|
+
** Call middleware (layout + pages)
|
|
201
|
+
*/
|
|
202
|
+
midd = []
|
|
203
|
+
|
|
204
|
+
layout = sanitizeComponent(layout)
|
|
205
|
+
if (layout.options.middleware) {
|
|
206
|
+
midd = midd.concat(layout.options.middleware)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
Components.forEach((Component) => {
|
|
210
|
+
if (Component.options.middleware) {
|
|
211
|
+
midd = midd.concat(Component.options.middleware)
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
midd = midd.map((name) => {
|
|
215
|
+
if (typeof name === 'function') {
|
|
216
|
+
return name
|
|
217
|
+
}
|
|
218
|
+
if (typeof middleware[name] !== 'function') {
|
|
219
|
+
app.context.error({ statusCode: 500, message: 'Unknown middleware ' + name })
|
|
220
|
+
}
|
|
221
|
+
return middleware[name]
|
|
222
|
+
})
|
|
223
|
+
await middlewareSeries(midd, app.context)
|
|
224
|
+
// ...If there is a redirect or an error, stop the process
|
|
225
|
+
if (ssrContext.redirected) {
|
|
226
|
+
return noopApp()
|
|
227
|
+
}
|
|
228
|
+
if (ssrContext.nuxt.error) {
|
|
229
|
+
return renderErrorPage()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/*
|
|
233
|
+
** Call .validate()
|
|
234
|
+
*/
|
|
235
|
+
let isValid = true
|
|
236
|
+
try {
|
|
237
|
+
for (const Component of Components) {
|
|
238
|
+
if (typeof Component.options.validate !== 'function') {
|
|
239
|
+
continue
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
isValid = await Component.options.validate(app.context)
|
|
243
|
+
|
|
244
|
+
if (!isValid) {
|
|
245
|
+
break
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} catch (validationError) {
|
|
249
|
+
// ...If .validate() threw an error
|
|
250
|
+
app.context.error({
|
|
251
|
+
statusCode: validationError.statusCode || '500',
|
|
252
|
+
message: validationError.message
|
|
253
|
+
})
|
|
254
|
+
return renderErrorPage()
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ...If .validate() returned false
|
|
258
|
+
if (!isValid) {
|
|
259
|
+
// Render a 404 error page
|
|
260
|
+
return render404Page()
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// If no Components found, returns 404
|
|
264
|
+
if (!Components.length) {
|
|
265
|
+
return render404Page()
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Call asyncData & fetch hooks on components matched by the route.
|
|
269
|
+
const asyncDatas = await Promise.all(Components.map((Component) => {
|
|
270
|
+
const promises = []
|
|
271
|
+
|
|
272
|
+
// Call asyncData(context)
|
|
273
|
+
if (Component.options.asyncData && typeof Component.options.asyncData === 'function') {
|
|
274
|
+
const promise = promisify(Component.options.asyncData, app.context)
|
|
275
|
+
promise.then((asyncDataResult) => {
|
|
276
|
+
ssrContext.asyncData[Component.cid] = asyncDataResult
|
|
277
|
+
applyAsyncData(Component)
|
|
278
|
+
return asyncDataResult
|
|
279
|
+
})
|
|
280
|
+
promises.push(promise)
|
|
281
|
+
} else {
|
|
282
|
+
promises.push(null)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Call fetch(context)
|
|
286
|
+
if (Component.options.fetch && Component.options.fetch.length) {
|
|
287
|
+
promises.push(Component.options.fetch(app.context))
|
|
288
|
+
} else {
|
|
289
|
+
promises.push(null)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return Promise.all(promises)
|
|
293
|
+
}))
|
|
294
|
+
|
|
295
|
+
if (process.env.DEBUG && asyncDatas.length) console.debug('Data fetching ' + ssrContext.url + ': ' + (Date.now() - s) + 'ms')
|
|
296
|
+
|
|
297
|
+
// datas are the first row of each
|
|
298
|
+
ssrContext.nuxt.data = asyncDatas.map(r => r[0] || {})
|
|
299
|
+
|
|
300
|
+
// ...If there is a redirect or an error, stop the process
|
|
301
|
+
if (ssrContext.redirected) {
|
|
302
|
+
return noopApp()
|
|
303
|
+
}
|
|
304
|
+
if (ssrContext.nuxt.error) {
|
|
305
|
+
return renderErrorPage()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Call beforeNuxtRender methods & add store state
|
|
309
|
+
await beforeRender()
|
|
310
|
+
|
|
311
|
+
return _app
|
|
312
|
+
}
|
package/nuxt/store.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import Vue from 'vue'
|
|
2
|
+
import Vuex from 'vuex'
|
|
3
|
+
|
|
4
|
+
Vue.use(Vuex)
|
|
5
|
+
|
|
6
|
+
const VUEX_PROPERTIES = ['state', 'getters', 'actions', 'mutations']
|
|
7
|
+
|
|
8
|
+
let store = {};
|
|
9
|
+
|
|
10
|
+
(function updateModules () {
|
|
11
|
+
store = normalizeRoot(require('../store/index.js'), 'store/index.js')
|
|
12
|
+
|
|
13
|
+
// If store is an exported method = classic mode (deprecated)
|
|
14
|
+
|
|
15
|
+
if (typeof store === 'function') {
|
|
16
|
+
return console.warn('Classic mode for store/ is deprecated and will be removed in Nuxt 3.')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Enforce store modules
|
|
20
|
+
store.modules = store.modules || {}
|
|
21
|
+
|
|
22
|
+
resolveStoreModules(require('../store/action-menu.js'), 'action-menu.js')
|
|
23
|
+
resolveStoreModules(require('../store/auth.js'), 'auth.js')
|
|
24
|
+
resolveStoreModules(require('../store/aws.js'), 'aws.js')
|
|
25
|
+
resolveStoreModules(require('../store/catalog.js'), 'catalog.js')
|
|
26
|
+
resolveStoreModules(require('../store/digitalocean.js'), 'digitalocean.js')
|
|
27
|
+
resolveStoreModules(require('../store/features.js'), 'features.js')
|
|
28
|
+
resolveStoreModules(require('../store/github.js'), 'github.js')
|
|
29
|
+
resolveStoreModules(require('../store/growl.js'), 'growl.js')
|
|
30
|
+
resolveStoreModules(require('../store/i18n.js'), 'i18n.js')
|
|
31
|
+
resolveStoreModules(require('../store/linode.js'), 'linode.js')
|
|
32
|
+
resolveStoreModules(require('../store/plugins.js'), 'plugins.js')
|
|
33
|
+
resolveStoreModules(require('../store/pnap.js'), 'pnap.js')
|
|
34
|
+
resolveStoreModules(require('../store/prefs.js'), 'prefs.js')
|
|
35
|
+
resolveStoreModules(require('../store/resource-fetch.js'), 'resource-fetch.js')
|
|
36
|
+
resolveStoreModules(require('../store/type-map.js'), 'type-map.js')
|
|
37
|
+
resolveStoreModules(require('../store/uiplugins.ts'), 'uiplugins.ts')
|
|
38
|
+
resolveStoreModules(require('../store/wm.js'), 'wm.js')
|
|
39
|
+
|
|
40
|
+
// If the environment supports hot reloading...
|
|
41
|
+
|
|
42
|
+
if (process.client && module.hot) {
|
|
43
|
+
// Whenever any Vuex module is updated...
|
|
44
|
+
module.hot.accept([
|
|
45
|
+
'../store/action-menu.js',
|
|
46
|
+
'../store/auth.js',
|
|
47
|
+
'../store/aws.js',
|
|
48
|
+
'../store/catalog.js',
|
|
49
|
+
'../store/digitalocean.js',
|
|
50
|
+
'../store/features.js',
|
|
51
|
+
'../store/github.js',
|
|
52
|
+
'../store/growl.js',
|
|
53
|
+
'../store/i18n.js',
|
|
54
|
+
'../store/index.js',
|
|
55
|
+
'../store/linode.js',
|
|
56
|
+
'../store/plugins.js',
|
|
57
|
+
'../store/pnap.js',
|
|
58
|
+
'../store/prefs.js',
|
|
59
|
+
'../store/resource-fetch.js',
|
|
60
|
+
'../store/type-map.js',
|
|
61
|
+
'../store/uiplugins.ts',
|
|
62
|
+
'../store/wm.js',
|
|
63
|
+
], () => {
|
|
64
|
+
// Update `root.modules` with the latest definitions.
|
|
65
|
+
updateModules()
|
|
66
|
+
// Trigger a hot update in the store.
|
|
67
|
+
window.$nuxt.$store.hotUpdate(store)
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
})()
|
|
71
|
+
|
|
72
|
+
// createStore
|
|
73
|
+
export const createStore = store instanceof Function ? store : () => {
|
|
74
|
+
return new Vuex.Store(Object.assign({
|
|
75
|
+
strict: (process.env.NODE_ENV !== 'production')
|
|
76
|
+
}, store))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function normalizeRoot (moduleData, filePath) {
|
|
80
|
+
moduleData = moduleData.default || moduleData
|
|
81
|
+
|
|
82
|
+
if (moduleData.commit) {
|
|
83
|
+
throw new Error(`[nuxt] ${filePath} should export a method that returns a Vuex instance.`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (typeof moduleData !== 'function') {
|
|
87
|
+
// Avoid TypeError: setting a property that has only a getter when overwriting top level keys
|
|
88
|
+
moduleData = Object.assign({}, moduleData)
|
|
89
|
+
}
|
|
90
|
+
return normalizeModule(moduleData, filePath)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function normalizeModule (moduleData, filePath) {
|
|
94
|
+
if (moduleData.state && typeof moduleData.state !== 'function') {
|
|
95
|
+
console.warn(`'state' should be a method that returns an object in ${filePath}`)
|
|
96
|
+
|
|
97
|
+
const state = Object.assign({}, moduleData.state)
|
|
98
|
+
// Avoid TypeError: setting a property that has only a getter when overwriting top level keys
|
|
99
|
+
moduleData = Object.assign({}, moduleData, { state: () => state })
|
|
100
|
+
}
|
|
101
|
+
return moduleData
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function resolveStoreModules (moduleData, filename) {
|
|
105
|
+
moduleData = moduleData.default || moduleData
|
|
106
|
+
// Remove store src + extension (./foo/index.js -> foo/index)
|
|
107
|
+
const namespace = filename.replace(/\.(js|mjs|ts)$/, '')
|
|
108
|
+
const namespaces = namespace.split('/')
|
|
109
|
+
let moduleName = namespaces[namespaces.length - 1]
|
|
110
|
+
const filePath = `store/${filename}`
|
|
111
|
+
|
|
112
|
+
moduleData = moduleName === 'state'
|
|
113
|
+
? normalizeState(moduleData, filePath)
|
|
114
|
+
: normalizeModule(moduleData, filePath)
|
|
115
|
+
|
|
116
|
+
// If src is a known Vuex property
|
|
117
|
+
if (VUEX_PROPERTIES.includes(moduleName)) {
|
|
118
|
+
const property = moduleName
|
|
119
|
+
const propertyStoreModule = getStoreModule(store, namespaces, { isProperty: true })
|
|
120
|
+
|
|
121
|
+
// Replace state since it's a function
|
|
122
|
+
mergeProperty(propertyStoreModule, moduleData, property)
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// If file is foo/index.js, it should be saved as foo
|
|
127
|
+
const isIndexModule = (moduleName === 'index')
|
|
128
|
+
if (isIndexModule) {
|
|
129
|
+
namespaces.pop()
|
|
130
|
+
moduleName = namespaces[namespaces.length - 1]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const storeModule = getStoreModule(store, namespaces)
|
|
134
|
+
|
|
135
|
+
for (const property of VUEX_PROPERTIES) {
|
|
136
|
+
mergeProperty(storeModule, moduleData[property], property)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (moduleData.namespaced === false) {
|
|
140
|
+
delete storeModule.namespaced
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function normalizeState (moduleData, filePath) {
|
|
145
|
+
if (typeof moduleData !== 'function') {
|
|
146
|
+
console.warn(`${filePath} should export a method that returns an object`)
|
|
147
|
+
const state = Object.assign({}, moduleData)
|
|
148
|
+
return () => state
|
|
149
|
+
}
|
|
150
|
+
return normalizeModule(moduleData, filePath)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function getStoreModule (storeModule, namespaces, { isProperty = false } = {}) {
|
|
154
|
+
// If ./mutations.js
|
|
155
|
+
if (!namespaces.length || (isProperty && namespaces.length === 1)) {
|
|
156
|
+
return storeModule
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const namespace = namespaces.shift()
|
|
160
|
+
|
|
161
|
+
storeModule.modules[namespace] = storeModule.modules[namespace] || {}
|
|
162
|
+
storeModule.modules[namespace].namespaced = true
|
|
163
|
+
storeModule.modules[namespace].modules = storeModule.modules[namespace].modules || {}
|
|
164
|
+
|
|
165
|
+
return getStoreModule(storeModule.modules[namespace], namespaces, { isProperty })
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function mergeProperty (storeModule, moduleData, property) {
|
|
169
|
+
if (!moduleData) {
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (property === 'state') {
|
|
174
|
+
storeModule.state = moduleData || storeModule.state
|
|
175
|
+
} else {
|
|
176
|
+
storeModule[property] = Object.assign({}, storeModule[property], moduleData)
|
|
177
|
+
}
|
|
178
|
+
}
|