bfg-common 1.5.596 → 1.5.597

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.
@@ -1,332 +1,313 @@
1
- <template>
2
- <common-vm-actions-register-new
3
- v-if="isNewView"
4
- v-model="vmForm"
5
- v-model:location="location"
6
- :project="props.project"
7
- :ready-complete-table-info="props.readyCompleteTableInfo"
8
- :name-request-url="props.nameRequestUrl"
9
- :wizard="wizard"
10
- :selected-scheme="selectedScheme"
11
- :dynamic-steps="dynamicSteps"
12
- :name-form-submit="nameFormSubmit"
13
- :name-test-ids="nameTestIds"
14
- :allowed-location-kinds="allowedLocationKinds"
15
- :location-description="locationDescription"
16
- :is-sphere="isSphere"
17
- :compute-resource-tree-local="computeResourceTreeLocal"
18
- :compatibility-text="compatibilityText"
19
- :is-loading-compute-tree="isLoadingComputeTree"
20
- :compute-resource-alert="computeResourceAlert"
21
- :location-nodes="props.locationNodes"
22
- @finish="emits('finish')"
23
- @hide="emits('hide')"
24
- @change-steps="onChangeSteps"
25
- @change-name="onChangeName(...$event)"
26
- />
27
- <common-vm-actions-register-old
28
- v-else
29
- v-model="vmForm"
30
- v-model:location="location"
31
- :project="props.project"
32
- :ready-complete-table-info="props.readyCompleteTableInfo"
33
- :name-request-url="props.nameRequestUrl"
34
- :wizard="wizard"
35
- :selected-scheme="selectedScheme"
36
- :dynamic-steps="dynamicSteps"
37
- :name-form-submit="nameFormSubmit"
38
- :name-test-ids="nameTestIds"
39
- :allowed-location-kinds="allowedLocationKinds"
40
- :location-description="locationDescription"
41
- :is-sphere="isSphere"
42
- :compute-resource-tree-local="computeResourceTreeLocal"
43
- :compatibility-text="compatibilityText"
44
- :is-loading-compute-tree="isLoadingComputeTree"
45
- :compute-resource-alert="computeResourceAlert"
46
- :location-nodes="props.locationNodes"
47
- @finish="emits('finish')"
48
- @hide="emits('hide')"
49
- @change-steps="onChangeSteps"
50
- @change-name="onChangeName(...$event)"
51
- />
52
- </template>
53
-
54
- <script setup lang="ts">
55
- import type { UI_I_WizardStep } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
56
- import type { UI_I_ValidationReturn } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
57
- import Wizard from '~/node_modules/bfg-uikit/components/ui/wizard/lib/utils/utils'
58
- import type { UI_I_Localization } from '~/lib/models/interfaces'
59
- import type { UI_T_Project } from '~/lib/models/types'
60
- import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
61
- import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
62
- import type { UI_I_NameTestIds } from '~/components/common/wizards/common/steps/name/lib/models/interfaces'
63
- import type { UI_T_CompatibilityStatus } from '~/components/common/wizards/common/compatibility/lib/models/types'
64
- import {
65
- dynamicSteps,
66
- stepsFunc,
67
- stepsSchemeInitial,
68
- } from '~/components/common/vm/actions/register/lib/config/steps'
69
- import { allowedLocationKinds } from '~/components/common/vm/actions/register/lib/config'
70
-
71
- const vmForm = defineModel<any>({ required: true })
72
-
73
- const props = withDefaults(
74
- defineProps<{
75
- project: UI_T_Project
76
- readyCompleteTableInfo: UI_I_TableInfoItem[]
77
- nameRequestUrl: string
78
- isLoadingComputeTree?: boolean // для сферы
79
- computeResourceAlert?: string[] // для сферы
80
- dataCenter?: UI_I_TreeNode | null // для сферы
81
- computeResourceTree?: UI_I_TreeNode[] // для сферы
82
- locationNodes?: UI_I_TreeNode[] // для сферы
83
- }>(),
84
- {
85
- isLoadingComputeTree: false,
86
- computeResourceAlert: () => [],
87
- dataCenter: null,
88
- computeResourceTree: undefined,
89
- locationNodes: () => [],
90
- }
91
- )
92
-
93
- const emits = defineEmits<{
94
- (event: 'finish'): void
95
- (event: 'hide'): void
96
- (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
97
- (
98
- event: 'get-compute-resource-tree',
99
- value: { id: string | number; cb: () => void }
100
- ): void // для сферы
101
- }>()
102
-
103
- const { $store, $recursion }: any = useNuxtApp()
104
-
105
- const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
106
-
107
- const localization = computed<UI_I_Localization>(() => useLocal())
108
- const isSphere = computed<boolean>(() => props.project === 'sphere')
109
-
110
- const location = ref<UI_I_TreeNode | null>(props.dataCenter) // для сферы
111
-
112
- const wizard: Wizard = new Wizard(
113
- stepsFunc(localization.value),
114
- stepsSchemeInitial
115
- )
116
- if (isSphere.value) {
117
- wizard.changeScheme(1)
118
- wizard.selectStepHard(1)
119
- }
120
-
121
- const locationDescription = computed<string>(
122
- () => localization.value.common.selectLocationVirtualMachine
123
- )
124
-
125
- const nameTestIds: UI_I_NameTestIds = {
126
- name: 'virtual-machine-name',
127
- helpIcon: 'show-vm-name-help-icon',
128
- }
129
-
130
- const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
131
- const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
132
- wizard.changeSteps(value, validationFunc)
133
- }
134
- const validationFunc = async (
135
- value: UI_I_WizardStep[],
136
- currentStep: UI_I_WizardStep,
137
- nextStep: UI_I_WizardStep
138
- ): Promise<UI_I_ValidationReturn> => {
139
- let stepHasError = false
140
- let stepShouldStop = {
141
- ifOnCurrentStep: false,
142
- ifFromAnyStep: false,
143
- stoppageStepId: -1,
144
- }
145
-
146
- wizard.setLoader(true)
147
- if (
148
- wizard.isValidateForStep(
149
- isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
150
- currentStep.id,
151
- nextStep.id
152
- )
153
- ) {
154
- const nameValidation = await onCheckName(value)
155
-
156
- value = nameValidation.newValue
157
- stepHasError = stepHasError || nameValidation.stepHasError
158
- } else if (
159
- isSphere.value &&
160
- wizard.isValidateForStep(
161
- dynamicSteps.selectComputeResource,
162
- currentStep.id,
163
- nextStep.id
164
- )
165
- ) {
166
- const computeResourceValidation = await checkComputeResource(value)
167
-
168
- value = computeResourceValidation.newValue
169
- stepHasError = stepHasError || computeResourceValidation.stepHasError
170
- }
171
- wizard.setLoader(false)
172
-
173
- return {
174
- newValue: value,
175
- stepHasError,
176
- stepShouldStop,
177
- }
178
- }
179
-
180
- const nameFormSubmit = ref<null | Function>(null)
181
- const onCheckName = async (
182
- value: UI_I_WizardStep[]
183
- ): Promise<UI_I_ValidationReturn> => {
184
- let stepHasError = false
185
-
186
- return new Promise((resolve) => {
187
- const step = isSphere.value
188
- ? dynamicSteps.selectNameFolder
189
- : dynamicSteps.selectName
190
- nameFormSubmit.value = (isValid: boolean) => {
191
- if (!isValid) {
192
- stepHasError = wizard.setValidation(step, 'name', {
193
- fieldMessage: 'aaa',
194
- alertMessage: 'aaa',
195
- })
196
- } else if (wizard.hasMessage(step, 'name')) {
197
- value = wizard.removeValidation(step, 'name', value)
198
- }
199
-
200
- resolve({
201
- stepHasError,
202
- newValue: value,
203
- })
204
- nameFormSubmit.value = null
205
- }
206
- })
207
- }
208
- const compatibilityText = computed<[UI_T_CompatibilityStatus, string]>(() => {
209
- const { computeResource } = vmForm.value
210
-
211
- if (!computeResource)
212
- return [
213
- 'none',
214
- localization.value.vmWizard.noDestinationComputeResourceSelected,
215
- ]
216
-
217
- let res: [UI_T_CompatibilityStatus, string] = [
218
- 'success',
219
- localization.value.common.compatibilityChecksSucceeded,
220
- ]
221
-
222
- if (!['cluster', 'host', 'resource_pool'].includes(computeResource?.type)) {
223
- res = [
224
- 'error',
225
- localization.value.common.selectValidClusterOrHostDestination,
226
- ]
227
- }
228
- if (computeResource?.type === 'cluster') {
229
- const hasHost = !!computeResource.nodes.length
230
- if (!hasHost) {
231
- res = ['error', localization.value.common.clusterNotContainAnyHosts]
232
- }
233
- }
234
-
235
- if (computeResource?.type === 'host') {
236
- if (computeResource.state === 'Error') {
237
- // TODO check Maintenance Mode
238
- res = [
239
- 'error',
240
- localization.value.common.selectedHostDisconnectedMaintenanceMode,
241
- ]
242
- }
243
- }
244
-
245
- return res
246
- })
247
- const computeResourceAlert = ref<string[]>([])
248
- const checkComputeResource = (
249
- value: UI_I_WizardStep[]
250
- ): UI_I_ValidationReturn => {
251
- let stepHasError = false
252
-
253
- const { computeResource } = vmForm.value
254
-
255
- if (
256
- !computeResource ||
257
- // compatibilityText.value[0] !== 1 ||
258
- computeResource.type === 'datacenter' ||
259
- computeResource.type === 'folder' ||
260
- (computeResource.type === 'cluster' && !computeResource.nodes.length)
261
- ) {
262
- computeResourceAlert.value = [
263
- localization.value.common.specifyValidClusterOrHostDestination,
264
- ]
265
- stepHasError = wizard.setValidation(
266
- dynamicSteps.selectComputeResource,
267
- 'computeResource',
268
- {
269
- fieldMessage: 'aaa',
270
- alertMessage: 'aaa',
271
- }
272
- )
273
- } else {
274
- computeResourceAlert.value = []
275
- if (
276
- wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
277
- ) {
278
- value = wizard.removeValidation(
279
- dynamicSteps.selectComputeResource,
280
- 'computeResource',
281
- value
282
- )
283
- }
284
- }
285
-
286
- return {
287
- stepHasError,
288
- newValue: value,
289
- }
290
- }
291
-
292
- const isLoadingComputeTree = ref<boolean>(false)
293
- const onChangeName = (name: string, node: UI_I_TreeNode | null): void => {
294
- vmForm.value.name = name
295
- if (isSphere.value) {
296
- vmForm.value.locationPath = node.id
297
- vmForm.value.dataCenter = $recursion.findParentByValue(
298
- node,
299
- 'datacenter',
300
- 'type',
301
- 'parent'
302
- )
303
- isLoadingComputeTree.value = true
304
- emits('get-compute-resource-tree', {
305
- id: node.id,
306
- cb: () => {
307
- isLoadingComputeTree.value = false
308
- },
309
- })
310
- }
311
- }
312
-
313
- watch(
314
- () => vmForm.value.computeResource,
315
- (newValue, oldValue) => {
316
- if (newValue && newValue.id !== oldValue?.id) {
317
- onSelectComputeResourceTree(newValue)
318
- }
319
- },
320
- { deep: true }
321
- )
322
- const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
323
- emits('select-compute-resource-tree', node)
324
- }
325
-
326
- const computeResourceTreeLocal = computed<UI_I_TreeNode | null>(() => {
327
- // для сферы
328
- return props.computeResourceTree?.[0] || null
329
- })
330
- </script>
331
-
332
- <style scoped lang="scss"></style>
1
+ <template>
2
+ <component
3
+ :is="currentComponent"
4
+ v-model="vmForm"
5
+ v-model:location="location"
6
+ :project="props.project"
7
+ :ready-complete-table-info="props.readyCompleteTableInfo"
8
+ :name-request-url="props.nameRequestUrl"
9
+ :wizard="wizard"
10
+ :selected-scheme="selectedScheme"
11
+ :dynamic-steps="dynamicSteps"
12
+ :name-form-submit="nameFormSubmit"
13
+ :name-test-ids="nameTestIds"
14
+ :allowed-location-kinds="allowedLocationKinds"
15
+ :location-description="locationDescription"
16
+ :is-sphere="isSphere"
17
+ :compute-resource-tree-local="computeResourceTreeLocal"
18
+ :compatibility-text="compatibilityText"
19
+ :is-loading-compute-tree="isLoadingComputeTree"
20
+ :compute-resource-alert="computeResourceAlert"
21
+ :location-nodes="props.locationNodes"
22
+ @finish="emits('finish')"
23
+ @hide="emits('hide')"
24
+ @change-steps="onChangeSteps"
25
+ @change-name="onChangeName(...$event)"
26
+ />
27
+ </template>
28
+
29
+ <script setup lang="ts">
30
+ import type { UI_I_WizardStep } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
31
+ import type { UI_I_ValidationReturn } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
32
+ import Wizard from '~/node_modules/bfg-uikit/components/ui/wizard/lib/utils/utils'
33
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
34
+ import type { UI_T_Project } from '~/lib/models/types'
35
+ import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
36
+ import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
37
+ import type { UI_I_NameTestIds } from '~/components/common/wizards/common/steps/name/lib/models/interfaces'
38
+ import type { UI_T_CompatibilityStatus } from '~/components/common/wizards/common/compatibility/lib/models/types'
39
+ import {
40
+ dynamicSteps,
41
+ stepsFunc,
42
+ stepsSchemeInitial,
43
+ } from '~/components/common/vm/actions/register/lib/config/steps'
44
+ import { allowedLocationKinds } from '~/components/common/vm/actions/register/lib/config'
45
+
46
+ const vmForm = defineModel<any>({ required: true })
47
+
48
+ const props = withDefaults(
49
+ defineProps<{
50
+ project: UI_T_Project
51
+ readyCompleteTableInfo: UI_I_TableInfoItem[]
52
+ nameRequestUrl: string
53
+ isLoadingComputeTree?: boolean // для сферы
54
+ computeResourceAlert?: string[] // для сферы
55
+ dataCenter?: UI_I_TreeNode | null // для сферы
56
+ computeResourceTree?: UI_I_TreeNode[] // для сферы
57
+ locationNodes?: UI_I_TreeNode[] // для сферы
58
+ }>(),
59
+ {
60
+ isLoadingComputeTree: false,
61
+ computeResourceAlert: () => [],
62
+ dataCenter: null,
63
+ computeResourceTree: undefined,
64
+ locationNodes: () => [],
65
+ }
66
+ )
67
+
68
+ const emits = defineEmits<{
69
+ (event: 'finish'): void
70
+ (event: 'hide'): void
71
+ (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
72
+ (
73
+ event: 'get-compute-resource-tree',
74
+ value: { id: string | number; cb: () => void }
75
+ ): void // для сферы
76
+ }>()
77
+
78
+ const { $store, $recursion }: any = useNuxtApp()
79
+
80
+ const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
81
+
82
+ const currentComponent = computed(() =>
83
+ isNewView.value
84
+ ? defineAsyncComponent(() => import('./New.vue'))
85
+ : defineAsyncComponent(() => import('./Old.vue'))
86
+ )
87
+
88
+ const localization = computed<UI_I_Localization>(() => useLocal())
89
+ const isSphere = computed<boolean>(() => props.project === 'sphere')
90
+
91
+ const location = ref<UI_I_TreeNode | null>(props.dataCenter) // для сферы
92
+
93
+ const wizard: Wizard = new Wizard(
94
+ stepsFunc(localization.value),
95
+ stepsSchemeInitial
96
+ )
97
+ if (isSphere.value) {
98
+ wizard.changeScheme(1)
99
+ wizard.selectStepHard(1)
100
+ }
101
+
102
+ const locationDescription = computed<string>(
103
+ () => localization.value.common.selectLocationVirtualMachine
104
+ )
105
+
106
+ const nameTestIds: UI_I_NameTestIds = {
107
+ name: 'virtual-machine-name',
108
+ helpIcon: 'show-vm-name-help-icon',
109
+ }
110
+
111
+ const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
112
+ const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
113
+ wizard.changeSteps(value, validationFunc)
114
+ }
115
+ const validationFunc = async (
116
+ value: UI_I_WizardStep[],
117
+ currentStep: UI_I_WizardStep,
118
+ nextStep: UI_I_WizardStep
119
+ ): Promise<UI_I_ValidationReturn> => {
120
+ let stepHasError = false
121
+ let stepShouldStop = {
122
+ ifOnCurrentStep: false,
123
+ ifFromAnyStep: false,
124
+ stoppageStepId: -1,
125
+ }
126
+
127
+ wizard.setLoader(true)
128
+ if (
129
+ wizard.isValidateForStep(
130
+ isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
131
+ currentStep.id,
132
+ nextStep.id
133
+ )
134
+ ) {
135
+ const nameValidation = await onCheckName(value)
136
+
137
+ value = nameValidation.newValue
138
+ stepHasError = stepHasError || nameValidation.stepHasError
139
+ } else if (
140
+ isSphere.value &&
141
+ wizard.isValidateForStep(
142
+ dynamicSteps.selectComputeResource,
143
+ currentStep.id,
144
+ nextStep.id
145
+ )
146
+ ) {
147
+ const computeResourceValidation = await checkComputeResource(value)
148
+
149
+ value = computeResourceValidation.newValue
150
+ stepHasError = stepHasError || computeResourceValidation.stepHasError
151
+ }
152
+ wizard.setLoader(false)
153
+
154
+ return {
155
+ newValue: value,
156
+ stepHasError,
157
+ stepShouldStop,
158
+ }
159
+ }
160
+
161
+ const nameFormSubmit = ref<null | Function>(null)
162
+ const onCheckName = async (
163
+ value: UI_I_WizardStep[]
164
+ ): Promise<UI_I_ValidationReturn> => {
165
+ let stepHasError = false
166
+
167
+ return new Promise((resolve) => {
168
+ const step = isSphere.value
169
+ ? dynamicSteps.selectNameFolder
170
+ : dynamicSteps.selectName
171
+ nameFormSubmit.value = (isValid: boolean) => {
172
+ if (!isValid) {
173
+ stepHasError = wizard.setValidation(step, 'name', {
174
+ fieldMessage: 'aaa',
175
+ alertMessage: 'aaa',
176
+ })
177
+ } else if (wizard.hasMessage(step, 'name')) {
178
+ value = wizard.removeValidation(step, 'name', value)
179
+ }
180
+
181
+ resolve({
182
+ stepHasError,
183
+ newValue: value,
184
+ })
185
+ nameFormSubmit.value = null
186
+ }
187
+ })
188
+ }
189
+ const compatibilityText = computed<[UI_T_CompatibilityStatus, string]>(() => {
190
+ const { computeResource } = vmForm.value
191
+
192
+ if (!computeResource)
193
+ return [
194
+ 'none',
195
+ localization.value.vmWizard.noDestinationComputeResourceSelected,
196
+ ]
197
+
198
+ let res: [UI_T_CompatibilityStatus, string] = [
199
+ 'success',
200
+ localization.value.common.compatibilityChecksSucceeded,
201
+ ]
202
+
203
+ if (!['cluster', 'host', 'resource_pool'].includes(computeResource?.type)) {
204
+ res = [
205
+ 'error',
206
+ localization.value.common.selectValidClusterOrHostDestination,
207
+ ]
208
+ }
209
+ if (computeResource?.type === 'cluster') {
210
+ const hasHost = !!computeResource.nodes.length
211
+ if (!hasHost) {
212
+ res = ['error', localization.value.common.clusterNotContainAnyHosts]
213
+ }
214
+ }
215
+
216
+ if (computeResource?.type === 'host') {
217
+ if (computeResource.state === 'Error') {
218
+ // TODO check Maintenance Mode
219
+ res = [
220
+ 'error',
221
+ localization.value.common.selectedHostDisconnectedMaintenanceMode,
222
+ ]
223
+ }
224
+ }
225
+
226
+ return res
227
+ })
228
+ const computeResourceAlert = ref<string[]>([])
229
+ const checkComputeResource = (
230
+ value: UI_I_WizardStep[]
231
+ ): UI_I_ValidationReturn => {
232
+ let stepHasError = false
233
+
234
+ const { computeResource } = vmForm.value
235
+
236
+ if (
237
+ !computeResource ||
238
+ // compatibilityText.value[0] !== 1 ||
239
+ computeResource.type === 'datacenter' ||
240
+ computeResource.type === 'folder' ||
241
+ (computeResource.type === 'cluster' && !computeResource.nodes.length)
242
+ ) {
243
+ computeResourceAlert.value = [
244
+ localization.value.common.specifyValidClusterOrHostDestination,
245
+ ]
246
+ stepHasError = wizard.setValidation(
247
+ dynamicSteps.selectComputeResource,
248
+ 'computeResource',
249
+ {
250
+ fieldMessage: 'aaa',
251
+ alertMessage: 'aaa',
252
+ }
253
+ )
254
+ } else {
255
+ computeResourceAlert.value = []
256
+ if (
257
+ wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
258
+ ) {
259
+ value = wizard.removeValidation(
260
+ dynamicSteps.selectComputeResource,
261
+ 'computeResource',
262
+ value
263
+ )
264
+ }
265
+ }
266
+
267
+ return {
268
+ stepHasError,
269
+ newValue: value,
270
+ }
271
+ }
272
+
273
+ const isLoadingComputeTree = ref<boolean>(false)
274
+ const onChangeName = (name: string, node: UI_I_TreeNode | null): void => {
275
+ vmForm.value.name = name
276
+ if (isSphere.value) {
277
+ vmForm.value.locationPath = node.id
278
+ vmForm.value.dataCenter = $recursion.findParentByValue(
279
+ node,
280
+ 'datacenter',
281
+ 'type',
282
+ 'parent'
283
+ )
284
+ isLoadingComputeTree.value = true
285
+ emits('get-compute-resource-tree', {
286
+ id: node.id,
287
+ cb: () => {
288
+ isLoadingComputeTree.value = false
289
+ },
290
+ })
291
+ }
292
+ }
293
+
294
+ watch(
295
+ () => vmForm.value.computeResource,
296
+ (newValue, oldValue) => {
297
+ if (newValue && newValue.id !== oldValue?.id) {
298
+ onSelectComputeResourceTree(newValue)
299
+ }
300
+ },
301
+ { deep: true }
302
+ )
303
+ const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
304
+ emits('select-compute-resource-tree', node)
305
+ }
306
+
307
+ const computeResourceTreeLocal = computed<UI_I_TreeNode | null>(() => {
308
+ // для сферы
309
+ return props.computeResourceTree?.[0] || null
310
+ })
311
+ </script>
312
+
313
+ <style scoped lang="scss"></style>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bfg-common",
3
3
  "private": false,
4
- "version": "1.5.596",
4
+ "version": "1.5.597",
5
5
  "scripts": {
6
6
  "build": "nuxt build",
7
7
  "dev": "nuxt dev --port=3002",