@questwork/q-inventory 0.1.0

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 (67) hide show
  1. package/.storybook/main.js +23 -0
  2. package/.storybook/preview.js +17 -0
  3. package/README.md +16 -0
  4. package/app/qInventory/App.vue +164 -0
  5. package/app/qInventory/index.html +12 -0
  6. package/app/qInventory/main.ts +4 -0
  7. package/app/qInventory/styles.scss +59 -0
  8. package/dist/components/InventoryAssetDetail.vue.d.ts +8 -0
  9. package/dist/components/InventoryAssetDetail.vue.d.ts.map +1 -0
  10. package/dist/components/InventoryLocationAdmin.vue.d.ts +10 -0
  11. package/dist/components/InventoryLocationAdmin.vue.d.ts.map +1 -0
  12. package/dist/components/InventoryLocationDetail.vue.d.ts +8 -0
  13. package/dist/components/InventoryLocationDetail.vue.d.ts.map +1 -0
  14. package/dist/components/InventoryOverview.vue.d.ts +15 -0
  15. package/dist/components/InventoryOverview.vue.d.ts.map +1 -0
  16. package/dist/components/InventoryScanner.vue.d.ts +21 -0
  17. package/dist/components/InventoryScanner.vue.d.ts.map +1 -0
  18. package/dist/components/QInventory.vue.d.ts +24 -0
  19. package/dist/components/QInventory.vue.d.ts.map +1 -0
  20. package/dist/index.d.ts +16 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/mixins/CSSMixin.d.ts +7 -0
  23. package/dist/mixins/CSSMixin.d.ts.map +1 -0
  24. package/dist/models/index.d.ts +62 -0
  25. package/dist/models/index.d.ts.map +1 -0
  26. package/dist/models/inventoryAssetRepoAxios.d.ts +18 -0
  27. package/dist/models/inventoryAssetRepoAxios.d.ts.map +1 -0
  28. package/dist/models/inventoryAuthRepoAxios.d.ts +26 -0
  29. package/dist/models/inventoryAuthRepoAxios.d.ts.map +1 -0
  30. package/dist/models/inventoryAxiosBase.d.ts +41 -0
  31. package/dist/models/inventoryAxiosBase.d.ts.map +1 -0
  32. package/dist/models/inventoryLocationRepoAxios.d.ts +13 -0
  33. package/dist/models/inventoryLocationRepoAxios.d.ts.map +1 -0
  34. package/dist/models/inventoryMovementRepoAxios.d.ts +13 -0
  35. package/dist/models/inventoryMovementRepoAxios.d.ts.map +1 -0
  36. package/dist/q-inventory.esm.js +961 -0
  37. package/dist/q-inventory.esm.js.map +1 -0
  38. package/dist/q-inventory.min.cjs +2 -0
  39. package/dist/q-inventory.min.cjs.map +1 -0
  40. package/dist/q-inventory.min.css +1 -0
  41. package/dist/q-inventory.min.js +2 -0
  42. package/dist/q-inventory.min.js.map +1 -0
  43. package/dist-app/qInventory/assets/q-inventory-app.css +1 -0
  44. package/dist-app/qInventory/assets/q-inventory-app.js +18 -0
  45. package/dist-app/qInventory/index.html +13 -0
  46. package/package.json +58 -0
  47. package/src/components/InventoryAssetDetail.vue +55 -0
  48. package/src/components/InventoryLocationAdmin.vue +56 -0
  49. package/src/components/InventoryLocationDetail.vue +51 -0
  50. package/src/components/InventoryOverview.vue +81 -0
  51. package/src/components/InventoryScanner.vue +315 -0
  52. package/src/components/QInventory.vue +117 -0
  53. package/src/index.ts +36 -0
  54. package/src/mixins/CSSMixin.ts +14 -0
  55. package/src/models/index.ts +114 -0
  56. package/src/models/inventoryAssetRepoAxios.ts +38 -0
  57. package/src/models/inventoryAuthRepoAxios.ts +48 -0
  58. package/src/models/inventoryAxiosBase.ts +149 -0
  59. package/src/models/inventoryLocationRepoAxios.ts +25 -0
  60. package/src/models/inventoryMovementRepoAxios.ts +24 -0
  61. package/src/styles/index.scss +148 -0
  62. package/stories/stories.scss +9 -0
  63. package/stories/stories.ts +362 -0
  64. package/tsconfig.json +29 -0
  65. package/vite.app.config.js +37 -0
  66. package/vite.config.js +68 -0
  67. package/vitest.config.js +11 -0
@@ -0,0 +1,148 @@
1
+ .q-inventory,
2
+ .inventory-scanner,
3
+ .inventory-overview,
4
+ .inventory-asset-detail,
5
+ .inventory-location-detail,
6
+ .inventory-location-admin {
7
+ box-sizing: border-box;
8
+ color: #202124;
9
+ font-family: Arial, sans-serif;
10
+ }
11
+
12
+ .q-inventory {
13
+ min-height: 100%;
14
+ background: #f6f7f9;
15
+ }
16
+
17
+ .q-inventory__toolbar,
18
+ .inventory-scanner__mode,
19
+ .inventory-scanner__manual,
20
+ .inventory-overview__header,
21
+ .inventory-location-detail__header,
22
+ .inventory-location-admin__form {
23
+ display: flex;
24
+ gap: 8px;
25
+ padding: 12px;
26
+ }
27
+
28
+ .q-inventory__tab,
29
+ .inventory-scanner__mode-button,
30
+ button {
31
+ min-height: 36px;
32
+ border: 1px solid #ccd1d8;
33
+ border-radius: 4px;
34
+ background: #fff;
35
+ color: #202124;
36
+ cursor: pointer;
37
+ padding: 0 12px;
38
+ }
39
+
40
+ .q-inventory__tab--active,
41
+ .inventory-scanner__mode-button--active {
42
+ border-color: #1769aa;
43
+ background: #1769aa;
44
+ color: #fff;
45
+ }
46
+
47
+ .inventory-scanner__state,
48
+ .inventory-scanner__basket-header,
49
+ .inventory-scanner__basket,
50
+ .inventory-scanner__log,
51
+ .inventory-scanner__log-empty,
52
+ .inventory-overview__rows,
53
+ .inventory-asset-detail__body,
54
+ .inventory-asset-detail__empty,
55
+ .inventory-location-detail__asset,
56
+ .inventory-location-admin__row {
57
+ padding: 12px;
58
+ }
59
+
60
+ .inventory-scanner__basket-header {
61
+ align-items: center;
62
+ display: flex;
63
+ justify-content: space-between;
64
+ gap: 8px;
65
+ border-top: 1px solid #e0e3e7;
66
+ border-bottom: 1px solid #e0e3e7;
67
+ background: #fff;
68
+ font-size: 13px;
69
+ }
70
+
71
+ .inventory-scanner__basket-header div {
72
+ display: grid;
73
+ gap: 2px;
74
+ }
75
+
76
+ .inventory-scanner__basket-header span,
77
+ .inventory-scanner__empty,
78
+ .inventory-scanner__log-empty {
79
+ color: #5f6368;
80
+ }
81
+
82
+ .inventory-scanner__basket,
83
+ .inventory-scanner__log {
84
+ display: grid;
85
+ gap: 8px;
86
+ }
87
+
88
+ .inventory-scanner__basket-item,
89
+ .inventory-scanner__log-item {
90
+ display: grid;
91
+ gap: 4px;
92
+ border: 1px solid #d7dde5;
93
+ border-radius: 4px;
94
+ background: #fff;
95
+ padding: 10px;
96
+ }
97
+
98
+ .inventory-scanner__basket-item {
99
+ border-left: 4px solid #1769aa;
100
+ }
101
+
102
+ .inventory-scanner__log-item {
103
+ border-left: 4px solid #188038;
104
+ }
105
+
106
+ .inventory-scanner__log-item--failed {
107
+ border-left-color: #d93025;
108
+ }
109
+
110
+ .inventory-scanner__log-item--warning {
111
+ border-left-color: #f9ab00;
112
+ }
113
+
114
+ .inventory-scanner__log-item div {
115
+ align-items: center;
116
+ display: flex;
117
+ justify-content: space-between;
118
+ gap: 8px;
119
+ }
120
+
121
+ .inventory-scanner__basket-item small,
122
+ .inventory-scanner__log-item span,
123
+ .inventory-scanner__log-item small {
124
+ color: #5f6368;
125
+ }
126
+
127
+ .inventory-scanner__input,
128
+ .inventory-location-admin__form input {
129
+ min-height: 36px;
130
+ min-width: 0;
131
+ border: 1px solid #ccd1d8;
132
+ border-radius: 4px;
133
+ flex: 1;
134
+ padding: 0 8px;
135
+ }
136
+
137
+ .inventory-overview__row {
138
+ align-items: center;
139
+ display: grid;
140
+ grid-template-columns: minmax(90px, 1fr) minmax(120px, 2fr) minmax(120px, 2fr);
141
+ width: 100%;
142
+ margin-bottom: 6px;
143
+ text-align: left;
144
+ }
145
+
146
+ .inventory-overview__location {
147
+ color: #1769aa;
148
+ }
@@ -0,0 +1,9 @@
1
+ body {
2
+ margin: 0;
3
+ }
4
+
5
+ .q-inventory-story {
6
+ max-width: 430px;
7
+ min-height: 720px;
8
+ background: #f6f7f9;
9
+ }
@@ -0,0 +1,362 @@
1
+ import { setup } from '@storybook/vue3'
2
+ import { onMounted, ref } from 'vue'
3
+ import { name, version } from '../package.json'
4
+ import type { InventoryMovePayload } from '../src'
5
+ import {
6
+ INVENTORY_LOCATION_KIND,
7
+ INVENTORY_LOCATION_TYPE,
8
+ InventoryAssetDetail,
9
+ InventoryAssetRepoAxios,
10
+ InventoryLocationAdmin,
11
+ InventoryLocationDetail,
12
+ InventoryLocationRepoAxios,
13
+ InventoryMovementRepoAxios,
14
+ InventoryOverview,
15
+ InventoryScanner,
16
+ QInventory,
17
+ } from '../src'
18
+ import '../src/styles/index.scss'
19
+ import './stories.scss'
20
+
21
+ const BACKEND_HOST = getBackendHost()
22
+ const TENANT_CODE = 'tenantCode'
23
+ const MOCKUP_REPO = 'mockup'
24
+
25
+ const baseAssets = [
26
+ {
27
+ assetTag: 'QR-0001',
28
+ currentLocationCode: 'RACK-A12',
29
+ currentLocationKind: INVENTORY_LOCATION_KIND.REGISTERED,
30
+ name: 'Barcode scanner',
31
+ },
32
+ {
33
+ assetTag: 'QR-0002',
34
+ currentLocationCode: 'USER:peter',
35
+ currentLocationKind: INVENTORY_LOCATION_KIND.VIRTUAL,
36
+ name: 'Receipt printer',
37
+ },
38
+ {
39
+ assetTag: 'QR-0003',
40
+ currentLocationCode: 'HKCEC-HALL3',
41
+ currentLocationKind: INVENTORY_LOCATION_KIND.REGISTERED,
42
+ name: 'iPad kiosk',
43
+ },
44
+ ]
45
+
46
+ const locations = [
47
+ {
48
+ locationCode: 'RACK-A12',
49
+ locationType: INVENTORY_LOCATION_TYPE.RACK,
50
+ name: 'Rack A12',
51
+ },
52
+ {
53
+ locationCode: 'HKCEC-HALL3',
54
+ locationType: INVENTORY_LOCATION_TYPE.VENUE,
55
+ name: 'HKCEC Hall 3',
56
+ },
57
+ ]
58
+
59
+ const history = [
60
+ {
61
+ assetTag: 'QR-0002',
62
+ fromLocationCode: 'RACK-A12',
63
+ movedAt: Date.now() - 60000,
64
+ toLocationCode: 'USER:peter',
65
+ },
66
+ ]
67
+
68
+ function cloneAssets() {
69
+ return baseAssets.map((asset) => ({ ...asset }))
70
+ }
71
+
72
+ function makeMockAssetApiClient(assetsRef: { value: Record<string, unknown>[] }) {
73
+ return {
74
+ async findAll() {
75
+ return assetsRef.value
76
+ },
77
+ async findOne(assetTag: string) {
78
+ return [assetsRef.value.find((a) => a.assetTag === assetTag)].filter(Boolean)
79
+ },
80
+ async saveOne(doc: Record<string, unknown>) {
81
+ assetsRef.value.push(doc)
82
+ return doc
83
+ },
84
+ async move(payload: Record<string, unknown>) {
85
+ console.log('move', payload)
86
+ const asset = assetsRef.value.find((item) => item.assetTag === payload.assetTag)
87
+ if (asset) {
88
+ asset.currentLocationCode = payload.toLocationCode
89
+ asset.currentLocationKind = payload.toLocationKind
90
+ asset.lastMovedAt = Date.now()
91
+ asset.lastMovedBy = 'peter'
92
+ }
93
+ return payload
94
+ },
95
+ }
96
+ }
97
+
98
+ function makeMockMovementApiClient() {
99
+ return {
100
+ async findAll(query: Record<string, unknown> = {}) {
101
+ if (query.assetTag === 'QR-0002') {
102
+ return history
103
+ }
104
+ return []
105
+ },
106
+ }
107
+ }
108
+
109
+ function makeBackendMockupApiClient(options: { assetsRef?: { value: Record<string, unknown>[] }, locationsRef?: { value: Record<string, unknown>[] } } = {}) {
110
+ const { assetsRef, locationsRef } = options
111
+ const assetRepo = new InventoryAssetRepoAxios({
112
+ baseURL: BACKEND_HOST,
113
+ movedBy: 'peter',
114
+ qRepo: MOCKUP_REPO,
115
+ tenantCode: TENANT_CODE,
116
+ })
117
+ const locationRepo = new InventoryLocationRepoAxios({
118
+ baseURL: BACKEND_HOST,
119
+ movedBy: 'peter',
120
+ qRepo: MOCKUP_REPO,
121
+ tenantCode: TENANT_CODE,
122
+ })
123
+ const movementRepo = new InventoryMovementRepoAxios({
124
+ baseURL: BACKEND_HOST,
125
+ movedBy: 'peter',
126
+ qRepo: MOCKUP_REPO,
127
+ tenantCode: TENANT_CODE,
128
+ })
129
+
130
+ const assetClient = {
131
+ async findAll(query: Record<string, unknown> = {}) {
132
+ const data = await assetRepo.findAll(query)
133
+ if (assetsRef) assetsRef.value = data
134
+ return data
135
+ },
136
+ async move(payload: InventoryMovePayload) {
137
+ const result = await assetRepo.move(payload)
138
+ await assetClient.findAll()
139
+ return result
140
+ },
141
+ }
142
+
143
+ const locationClient = {
144
+ async findAll(query: Record<string, unknown> = {}) {
145
+ const data = await locationRepo.findAll(query)
146
+ if (locationsRef) locationsRef.value = data
147
+ return data
148
+ },
149
+ }
150
+
151
+ const movementClient = {
152
+ async findAll(query: Record<string, unknown> = {}) {
153
+ return movementRepo.findAll(query)
154
+ },
155
+ }
156
+
157
+ return {
158
+ assetClient,
159
+ locationClient,
160
+ movementClient,
161
+ }
162
+ }
163
+
164
+ function getBackendHost() {
165
+ if (typeof window !== 'undefined') {
166
+ return window.localStorage.getItem('qInventoryBackendHost') || 'http://127.0.0.1:8033'
167
+ }
168
+ return 'http://127.0.0.1:8033'
169
+ }
170
+
171
+ setup((app) => {
172
+ app.use(QInventory)
173
+ })
174
+
175
+ export default {
176
+ title: 'QInventory',
177
+ }
178
+
179
+ export const story01 = () => ({
180
+ template: `
181
+ <div class="q-inventory-story">
182
+ <q-inventory
183
+ :asset-api-client="assetApiClient"
184
+ :location-api-client="locationApiClient"
185
+ :movement-api-client="movementApiClient"
186
+ :assets="assets"
187
+ current-user-code="peter"
188
+ :locations="locations"
189
+ />
190
+ </div>
191
+ `,
192
+ setup() {
193
+ const assets = ref(cloneAssets())
194
+ const assetApiClient = makeMockAssetApiClient(assets)
195
+ const locationApiClient = {
196
+ async findAll() {
197
+ return locations
198
+ },
199
+ }
200
+ const movementApiClient = makeMockMovementApiClient()
201
+ return {
202
+ assetApiClient,
203
+ locationApiClient,
204
+ movementApiClient,
205
+ assets,
206
+ locations,
207
+ }
208
+ },
209
+ })
210
+ story01.storyName = `${name} ${version}`
211
+
212
+ export const backendMockup = () => ({
213
+ template: `
214
+ <div class="q-inventory-story">
215
+ <div class="q-inventory-story__backend">
216
+ Backend: {{ backendHost }}
217
+ <button type="button" @click="reload">Reload</button>
218
+ </div>
219
+ <q-inventory
220
+ :asset-api-client="assetApiClient"
221
+ :location-api-client="locationApiClient"
222
+ :movement-api-client="movementApiClient"
223
+ :assets="assets"
224
+ current-user-code="peter"
225
+ :locations="locations"
226
+ @moved="reload"
227
+ @save-location="reload"
228
+ />
229
+ </div>
230
+ `,
231
+ setup() {
232
+ const assets = ref<Record<string, unknown>[]>([])
233
+ const locations = ref<Record<string, unknown>[]>([])
234
+ const { assetClient, locationClient, movementClient } = makeBackendMockupApiClient({ assetsRef: assets, locationsRef: locations })
235
+
236
+ async function reload() {
237
+ await Promise.all([
238
+ assetClient.findAll(),
239
+ locationClient.findAll(),
240
+ ])
241
+ }
242
+
243
+ onMounted(reload)
244
+
245
+ return {
246
+ assetApiClient: assetClient,
247
+ locationApiClient: locationClient,
248
+ movementApiClient: movementClient,
249
+ assets,
250
+ backendHost: BACKEND_HOST,
251
+ locations,
252
+ reload,
253
+ }
254
+ },
255
+ })
256
+ backendMockup.storyName = 'backend mockup endpoint'
257
+
258
+ export const scanner = () => ({
259
+ components: { InventoryScanner },
260
+ template: `
261
+ <div class="q-inventory-story">
262
+ <inventory-scanner
263
+ :asset-api-client="assetApiClient"
264
+ current-user-code="peter"
265
+ @moved="onMoved"
266
+ />
267
+ </div>
268
+ `,
269
+ setup() {
270
+ const assets = ref(cloneAssets())
271
+ const assetApiClient = makeMockAssetApiClient(assets)
272
+ return {
273
+ assetApiClient,
274
+ onMoved(payload: unknown) {
275
+ console.log('moved', payload)
276
+ },
277
+ }
278
+ },
279
+ })
280
+ scanner.storyName = 'scanner workflow'
281
+
282
+ export const overview = () => ({
283
+ components: { InventoryOverview },
284
+ template: `
285
+ <div class="q-inventory-story">
286
+ <inventory-overview
287
+ :assets="assets"
288
+ :locations="locations"
289
+ />
290
+ </div>
291
+ `,
292
+ setup() {
293
+ const assets = ref(cloneAssets())
294
+ return {
295
+ assets,
296
+ locations,
297
+ }
298
+ },
299
+ })
300
+ overview.storyName = 'overview with in-transit item'
301
+
302
+ export const assetDetail = () => ({
303
+ components: { InventoryAssetDetail },
304
+ template: `
305
+ <div class="q-inventory-story">
306
+ <inventory-asset-detail
307
+ :movement-api-client="movementApiClient"
308
+ :asset="asset"
309
+ />
310
+ </div>
311
+ `,
312
+ setup() {
313
+ const assets = cloneAssets()
314
+ return {
315
+ movementApiClient: makeMockMovementApiClient(),
316
+ asset: assets[1],
317
+ }
318
+ },
319
+ })
320
+ assetDetail.storyName = 'asset detail'
321
+
322
+ export const locationDetail = () => ({
323
+ components: { InventoryLocationDetail },
324
+ template: `
325
+ <div class="q-inventory-story">
326
+ <inventory-location-detail
327
+ :asset-api-client="assetApiClient"
328
+ :location="location"
329
+ />
330
+ </div>
331
+ `,
332
+ setup() {
333
+ const assets = ref(cloneAssets())
334
+ const assetApiClient = makeMockAssetApiClient(assets)
335
+ return {
336
+ assetApiClient,
337
+ location: locations[0],
338
+ }
339
+ },
340
+ })
341
+ locationDetail.storyName = 'location detail'
342
+
343
+ export const locationAdmin = () => ({
344
+ components: { InventoryLocationAdmin },
345
+ template: `
346
+ <div class="q-inventory-story">
347
+ <inventory-location-admin
348
+ :locations="locations"
349
+ @save-location="onSaveLocation"
350
+ />
351
+ </div>
352
+ `,
353
+ setup() {
354
+ return {
355
+ locations,
356
+ onSaveLocation(payload: unknown) {
357
+ console.log('saveLocation', payload)
358
+ },
359
+ }
360
+ },
361
+ })
362
+ locationAdmin.storyName = 'location admin'
package/tsconfig.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "allowJs": true,
7
+ "checkJs": false,
8
+ "jsx": "preserve",
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "sourceMap": true,
12
+ "outDir": "./dist",
13
+ "rootDir": "./src",
14
+ "strict": false,
15
+ "moduleResolution": "node",
16
+ "allowSyntheticDefaultImports": true,
17
+ "esModuleInterop": true,
18
+ "skipLibCheck": true,
19
+ "forceConsistentCasingInFileNames": true
20
+ },
21
+ "include": [
22
+ "src/**/*",
23
+ "src/**/*.vue"
24
+ ],
25
+ "exclude": [
26
+ "node_modules",
27
+ "dist"
28
+ ]
29
+ }
@@ -0,0 +1,37 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+ import commonjs from 'vite-plugin-commonjs'
4
+
5
+ export default defineConfig({
6
+ base: '/qInventory/',
7
+ root: 'app/qInventory',
8
+ build: {
9
+ assetsDir: 'assets',
10
+ cssCodeSplit: false,
11
+ emptyOutDir: true,
12
+ outDir: '../../dist-app/qInventory',
13
+ rollupOptions: {
14
+ output: {
15
+ assetFileNames: (assetInfo) => {
16
+ if (assetInfo.name && assetInfo.name.endsWith('.css')) {
17
+ return 'assets/q-inventory-app.css'
18
+ }
19
+ return 'assets/[name][extname]'
20
+ },
21
+ chunkFileNames: 'assets/q-inventory-app.js',
22
+ entryFileNames: 'assets/q-inventory-app.js',
23
+ inlineDynamicImports: true,
24
+ manualChunks: undefined,
25
+ },
26
+ },
27
+ sourcemap: false,
28
+ target: ['chrome100', 'safari15', 'firefox91'],
29
+ },
30
+ esbuild: {
31
+ legalComments: 'none',
32
+ },
33
+ plugins: [
34
+ vue(),
35
+ commonjs(),
36
+ ],
37
+ })
package/vite.config.js ADDED
@@ -0,0 +1,68 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+ import commonjs from 'vite-plugin-commonjs'
4
+ import dts from 'vite-plugin-dts'
5
+
6
+ const libName = 'QInventory'
7
+ const fileName = 'q-inventory'
8
+
9
+ export default defineConfig({
10
+ build: {
11
+ lib: {
12
+ entry: './src/index.ts',
13
+ name: libName,
14
+ fileName: (format) => {
15
+ if (format === 'es') return `${fileName}.esm.js`
16
+ if (format === 'cjs') return `${fileName}.min.cjs`
17
+ return `${fileName}.min.js`
18
+ },
19
+ formats: ['es', 'cjs', 'umd'],
20
+ },
21
+ rollupOptions: {
22
+ external: [
23
+ 'vue',
24
+ '@questwork/q-inventory-model',
25
+ '@questwork/q-utilities',
26
+ ],
27
+ output: {
28
+ assetFileNames: `${fileName}.min.[ext]`,
29
+ globals: {
30
+ vue: 'Vue',
31
+ '@questwork/q-inventory-model': 'qInventoryModel',
32
+ '@questwork/q-utilities': 'qUtilities',
33
+ },
34
+ exports: 'named',
35
+ },
36
+ },
37
+ sourcemap: true,
38
+ target: ['chrome100', 'safari15', 'firefox91'],
39
+ terserOptions: {
40
+ compress: false,
41
+ mangle: false,
42
+ },
43
+ },
44
+ esbuild: {
45
+ legalComments: 'none',
46
+ },
47
+ plugins: [
48
+ vue(),
49
+ commonjs(),
50
+ dts({
51
+ include: ['src/**/*.ts', 'src/**/*.vue'],
52
+ exclude: ['**/*.spec.ts'],
53
+ outDir: 'dist',
54
+ }),
55
+ ],
56
+ css: {
57
+ preprocessorOptions: {
58
+ scss: {
59
+ api: 'modern-compiler',
60
+ },
61
+ },
62
+ },
63
+ test: {
64
+ environment: 'happy-dom',
65
+ globals: true,
66
+ include: ['src/**/*.spec.ts'],
67
+ },
68
+ })
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'vitest/config'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ export default defineConfig({
5
+ plugins: [vue()],
6
+ test: {
7
+ environment: 'happy-dom',
8
+ globals: true,
9
+ include: ['src/**/*.spec.ts'],
10
+ },
11
+ })