pimelon-ui 0.0.98

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 (93) hide show
  1. package/license.md +0 -0
  2. package/package.json +75 -0
  3. package/readme.md +0 -0
  4. package/src/components/Alert.vue +57 -0
  5. package/src/components/Autocomplete.vue +176 -0
  6. package/src/components/Avatar.vue +62 -0
  7. package/src/components/Badge.vue +42 -0
  8. package/src/components/Button.vue +155 -0
  9. package/src/components/Card.vue +37 -0
  10. package/src/components/DatePicker.vue +252 -0
  11. package/src/components/Dialog.vue +216 -0
  12. package/src/components/Dropdown.vue +145 -0
  13. package/src/components/ErrorMessage.vue +24 -0
  14. package/src/components/FeatherIcon.vue +59 -0
  15. package/src/components/FileUploader.vue +220 -0
  16. package/src/components/GreenCheckIcon.vue +16 -0
  17. package/src/components/Input.vue +214 -0
  18. package/src/components/Link.vue +28 -0
  19. package/src/components/ListItem.vue +28 -0
  20. package/src/components/LoadingIndicator.vue +27 -0
  21. package/src/components/LoadingText.vue +21 -0
  22. package/src/components/Popover.vue +253 -0
  23. package/src/components/Resource.vue +21 -0
  24. package/src/components/TextEditor/FontColor.vue +108 -0
  25. package/src/components/TextEditor/InsertImage.vue +74 -0
  26. package/src/components/TextEditor/InsertLink.vue +67 -0
  27. package/src/components/TextEditor/InsertVideo.vue +94 -0
  28. package/src/components/TextEditor/MentionList.vue +95 -0
  29. package/src/components/TextEditor/Menu.vue +99 -0
  30. package/src/components/TextEditor/TextEditor.vue +275 -0
  31. package/src/components/TextEditor/TextEditorBubbleMenu.vue +69 -0
  32. package/src/components/TextEditor/TextEditorFixedMenu.vue +72 -0
  33. package/src/components/TextEditor/TextEditorFloatingMenu.vue +55 -0
  34. package/src/components/TextEditor/commands.js +272 -0
  35. package/src/components/TextEditor/icons/align-center.vue +14 -0
  36. package/src/components/TextEditor/icons/align-justify.vue +14 -0
  37. package/src/components/TextEditor/icons/align-left.vue +14 -0
  38. package/src/components/TextEditor/icons/align-right.vue +14 -0
  39. package/src/components/TextEditor/icons/arrow-go-back-line.vue +14 -0
  40. package/src/components/TextEditor/icons/arrow-go-forward-line.vue +14 -0
  41. package/src/components/TextEditor/icons/bold.vue +14 -0
  42. package/src/components/TextEditor/icons/code-view.vue +14 -0
  43. package/src/components/TextEditor/icons/double-quotes-r.vue +14 -0
  44. package/src/components/TextEditor/icons/font-color.vue +14 -0
  45. package/src/components/TextEditor/icons/format-clear.vue +14 -0
  46. package/src/components/TextEditor/icons/h-1.vue +14 -0
  47. package/src/components/TextEditor/icons/h-2.vue +14 -0
  48. package/src/components/TextEditor/icons/h-3.vue +14 -0
  49. package/src/components/TextEditor/icons/h-4.vue +14 -0
  50. package/src/components/TextEditor/icons/h-5.vue +14 -0
  51. package/src/components/TextEditor/icons/h-6.vue +14 -0
  52. package/src/components/TextEditor/icons/image-add-line.vue +14 -0
  53. package/src/components/TextEditor/icons/italic.vue +14 -0
  54. package/src/components/TextEditor/icons/link.vue +14 -0
  55. package/src/components/TextEditor/icons/list-ordered.vue +14 -0
  56. package/src/components/TextEditor/icons/list-unordered.vue +14 -0
  57. package/src/components/TextEditor/icons/readme.md +1 -0
  58. package/src/components/TextEditor/icons/separator.vue +14 -0
  59. package/src/components/TextEditor/icons/strikethrough.vue +14 -0
  60. package/src/components/TextEditor/icons/table-2.vue +14 -0
  61. package/src/components/TextEditor/icons/text.vue +11 -0
  62. package/src/components/TextEditor/icons/underline.vue +14 -0
  63. package/src/components/TextEditor/icons/video-add-line.vue +14 -0
  64. package/src/components/TextEditor/image-extension.js +152 -0
  65. package/src/components/TextEditor/index.js +6 -0
  66. package/src/components/TextEditor/mention.js +72 -0
  67. package/src/components/TextEditor/utils.js +11 -0
  68. package/src/components/TextEditor/video-extension.js +60 -0
  69. package/src/components/Toast.vue +83 -0
  70. package/src/components/Tooltip.vue +36 -0
  71. package/src/components/toast.js +98 -0
  72. package/src/directives/onOutsideClick.js +34 -0
  73. package/src/directives/visibility.js +24 -0
  74. package/src/index.js +56 -0
  75. package/src/resources/documentResource.js +194 -0
  76. package/src/resources/index.js +4 -0
  77. package/src/resources/listResource.js +312 -0
  78. package/src/resources/local.js +16 -0
  79. package/src/resources/plugin.js +105 -0
  80. package/src/resources/resources.js +215 -0
  81. package/src/style.css +15 -0
  82. package/src/utils/call.js +98 -0
  83. package/src/utils/config.js +9 -0
  84. package/src/utils/debounce.js +15 -0
  85. package/src/utils/file-to-base64.js +9 -0
  86. package/src/utils/markdown.js +29 -0
  87. package/src/utils/melonRequest.js +105 -0
  88. package/src/utils/pageMeta.js +52 -0
  89. package/src/utils/plugin.js +24 -0
  90. package/src/utils/request.js +49 -0
  91. package/src/utils/socketio.js +11 -0
  92. package/src/utils/tailwind.config.js +117 -0
  93. package/src/utils/vite-dev-server.js +14 -0
@@ -0,0 +1,194 @@
1
+ import { reactive } from 'vue'
2
+ import { getCacheKey, createResource } from './resources'
3
+ import {
4
+ updateRowInListResource,
5
+ deleteRowInListResource,
6
+ revertRowInListResource,
7
+ } from './listResource'
8
+ import { getLocal, saveLocal } from './local'
9
+
10
+ let documentCache = reactive({})
11
+
12
+ export function createDocumentResource(options, vm) {
13
+ if (!(options.doctype && options.name)) return
14
+
15
+ let cacheKey = getCacheKey([options.doctype, options.name])
16
+ let cachedResource = documentCache[cacheKey]
17
+ if (cachedResource) {
18
+ if (cachedResource.auto) {
19
+ cachedResource.reload()
20
+ }
21
+ return cachedResource
22
+ }
23
+
24
+ let setValueOptions = {
25
+ url: 'melon.client.set_value',
26
+ makeParams(values) {
27
+ return {
28
+ doctype: out.doctype,
29
+ name: out.name,
30
+ fieldname: values,
31
+ }
32
+ },
33
+ beforeSubmit(params) {
34
+ out.previousDoc = JSON.stringify(out.doc)
35
+ Object.assign(out.doc, params.fieldname || {})
36
+ // update data in list resources
37
+ updateRowInListResource(out.doctype, out.doc)
38
+ },
39
+ onSuccess(data) {
40
+ out.doc = transform(data)
41
+ options.setValue?.onSuccess?.call(vm, data)
42
+ },
43
+ onError(error) {
44
+ out.doc = JSON.parse(out.previousDoc)
45
+ options.setValue?.onError?.call(vm, error)
46
+ // revert data in list resource
47
+ revertRowInListResource(out.doctype, out.doc)
48
+ },
49
+ }
50
+
51
+ let out = reactive({
52
+ doctype: options.doctype,
53
+ name: options.name,
54
+ doc: null,
55
+ auto: options.auto || true,
56
+ get: createResource(
57
+ {
58
+ url: 'melon.client.get',
59
+ makeParams() {
60
+ return {
61
+ doctype: out.doctype,
62
+ name: out.name,
63
+ }
64
+ },
65
+ onSuccess(data) {
66
+ saveLocal(cacheKey, data)
67
+ out.doc = transform(data)
68
+ options.onSuccess?.call(vm, out.doc)
69
+ },
70
+ onError: options.onError,
71
+ },
72
+ vm
73
+ ),
74
+ setValue: createResource(setValueOptions, vm),
75
+ setValueDebounced: createResource(
76
+ {
77
+ ...setValueOptions,
78
+ debounce: options.debounce || 500,
79
+ },
80
+ vm
81
+ ),
82
+ delete: createResource(
83
+ {
84
+ url: 'melon.client.delete',
85
+ makeParams() {
86
+ return {
87
+ doctype: out.doctype,
88
+ name: out.name,
89
+ }
90
+ },
91
+ onSuccess() {
92
+ out.doc = null
93
+ options.delete?.onSuccess?.call(vm)
94
+ // delete from list resources
95
+ deleteRowInListResource(out.doctype, out.name)
96
+ },
97
+ onError: options.delete?.onError,
98
+ },
99
+ vm
100
+ ),
101
+ reload,
102
+ setDoc,
103
+ })
104
+
105
+ for (let methodKey in options.whitelistedMethods) {
106
+ let methodOptions = options.whitelistedMethods[methodKey]
107
+ if (typeof methodOptions == 'string') {
108
+ methodOptions = {
109
+ method: methodOptions,
110
+ }
111
+ }
112
+ let { method, onSuccess, ...otherOptions } = methodOptions
113
+ out[methodKey] = createResource(
114
+ {
115
+ url: 'run_doc_method',
116
+ makeParams(values) {
117
+ return {
118
+ dt: out.doctype,
119
+ dn: out.name,
120
+ method: method,
121
+ args: JSON.stringify(values),
122
+ }
123
+ },
124
+ onSuccess(data) {
125
+ if (data.docs) {
126
+ for (let doc of data.docs) {
127
+ if (
128
+ doc.doctype === out.doctype &&
129
+ doc.name.toString() === out.name.toString()
130
+ ) {
131
+ out.doc = transform(doc)
132
+ // update data in list resources
133
+ updateRowInListResource(out.doctype, out.doc)
134
+ break
135
+ }
136
+ }
137
+ }
138
+ onSuccess?.call(vm, out.doc)
139
+ },
140
+ ...otherOptions,
141
+ },
142
+ vm
143
+ )
144
+ }
145
+
146
+ function reload() {
147
+ return out.get.fetch()
148
+ }
149
+
150
+ function setDoc(doc) {
151
+ if (typeof doc === 'function') {
152
+ doc = doc.call(vm, out.doc)
153
+ }
154
+ out.doc = transform(doc)
155
+ }
156
+
157
+ function transform(doc) {
158
+ if (options.transform) {
159
+ let returnValue = options.transform.call(vm, doc)
160
+ if (typeof returnValue === 'object') {
161
+ return returnValue
162
+ }
163
+ }
164
+ return doc
165
+ }
166
+
167
+ if (options.realtime && vm.$socket) {
168
+ vm.$socket.on('list_update', (data) => {
169
+ if (data.doctype == out.doctype && data.name == out.name) {
170
+ out.get.fetch()
171
+ }
172
+ })
173
+ }
174
+
175
+ // cache
176
+ documentCache[cacheKey] = out
177
+ // offline
178
+ getLocal(cacheKey).then((data) => {
179
+ if ((out.get.loading || !out.get.fetched) && data) {
180
+ out.doc = transform(data)
181
+ }
182
+ })
183
+
184
+ if (out.auto) {
185
+ out.get.fetch()
186
+ }
187
+
188
+ return out
189
+ }
190
+
191
+ export function getCachedDocumentResource(doctype, name) {
192
+ let cacheKey = getCacheKey([doctype, name])
193
+ return documentCache[cacheKey] || null
194
+ }
@@ -0,0 +1,4 @@
1
+ export { createResource } from './resources'
2
+ export { createDocumentResource } from './documentResource'
3
+ export { createListResource } from './listResource'
4
+ export { default as resourcesPlugin } from './plugin'
@@ -0,0 +1,312 @@
1
+ import { reactive } from 'vue'
2
+ import { getCacheKey, createResource } from './resources'
3
+ import { saveLocal, getLocal } from './local'
4
+
5
+ let listCache = reactive({})
6
+ let resourcesByDocType = {}
7
+
8
+ export function createListResource(options, vm) {
9
+ if (!options.doctype) {
10
+ throw new Error('List resource requires doctype')
11
+ }
12
+
13
+ let cacheKey = getCacheKey(options.cache)
14
+ if (cacheKey) {
15
+ let cachedResource = listCache[cacheKey]
16
+ if (cachedResource) {
17
+ if (cachedResource.auto) {
18
+ cachedResource.reload()
19
+ }
20
+ return cachedResource
21
+ }
22
+ }
23
+
24
+ let out = reactive({
25
+ doctype: options.doctype,
26
+ fields: options.fields,
27
+ filters: options.filters,
28
+ orderBy: options.orderBy,
29
+ start: options.start || 0,
30
+ pageLength: options.pageLength || 20,
31
+ parent: options.parent,
32
+ debug: options.debug || 0,
33
+ originalData: null,
34
+ data: null,
35
+ next,
36
+ hasNextPage: true,
37
+ auto: options.auto,
38
+ list: createResource(
39
+ {
40
+ url: options.url || 'melon.client.get_list',
41
+ makeParams() {
42
+ return {
43
+ doctype: out.doctype,
44
+ fields: out.fields,
45
+ filters: out.filters,
46
+ order_by: out.orderBy,
47
+ start: out.start,
48
+ limit: out.pageLength,
49
+ limit_start: out.start,
50
+ limit_page_length: out.pageLength,
51
+ parent: out.parent,
52
+ debug: out.debug,
53
+ }
54
+ },
55
+ onSuccess(data) {
56
+ if (data.length < out.pageLength) {
57
+ out.hasNextPage = false
58
+ }
59
+ let pagedData
60
+ if (!out.start || out.start == 0) {
61
+ pagedData = data
62
+ } else if (out.start > 0) {
63
+ pagedData = out.originalData.concat(data)
64
+ }
65
+ saveLocal(cacheKey, pagedData)
66
+ setData(pagedData)
67
+ options.onSuccess?.call(vm, out.data)
68
+ },
69
+ onError: options.onError,
70
+ },
71
+ vm
72
+ ),
73
+ fetchOne: createResource(
74
+ {
75
+ url: 'melon.client.get_list',
76
+ makeParams(name) {
77
+ return {
78
+ doctype: out.doctype,
79
+ fields: out.fields || '*',
80
+ filters: { name },
81
+ }
82
+ },
83
+ onSuccess(data) {
84
+ if (data.length > 0 && out.originalData) {
85
+ let doc = data[0]
86
+ updateRowInListResource(out.doctype, doc)
87
+ }
88
+
89
+ options.fetchOne?.onSuccess?.call(vm, out.data)
90
+ },
91
+ onError: options.fetchOne?.onError,
92
+ },
93
+ vm
94
+ ),
95
+ insert: createResource(
96
+ {
97
+ url: 'melon.client.insert',
98
+ makeParams(values) {
99
+ return {
100
+ doc: {
101
+ doctype: out.doctype,
102
+ ...values,
103
+ },
104
+ }
105
+ },
106
+ onSuccess(data) {
107
+ out.list.fetch()
108
+ options.insert?.onSuccess?.call(vm, data)
109
+ },
110
+ onError: options.insert?.onError,
111
+ },
112
+ vm
113
+ ),
114
+ setValue: createResource(
115
+ {
116
+ url: 'melon.client.set_value',
117
+ makeParams(options) {
118
+ let { name, ...values } = options
119
+ return {
120
+ doctype: out.doctype,
121
+ name: name,
122
+ fieldname: values,
123
+ }
124
+ },
125
+ onSuccess(doc) {
126
+ updateRowInListResource(out.doctype, doc)
127
+ options.setValue?.onSuccess?.call(vm, doc)
128
+ },
129
+ onError: options.setValue?.onError,
130
+ },
131
+ vm
132
+ ),
133
+ delete: createResource(
134
+ {
135
+ url: 'melon.client.delete',
136
+ makeParams(name) {
137
+ return {
138
+ doctype: out.doctype,
139
+ name,
140
+ }
141
+ },
142
+ onSuccess(data) {
143
+ out.list.fetch()
144
+ options.delete?.onSuccess?.call(vm, data)
145
+ },
146
+ onError: options.delete?.onError,
147
+ },
148
+ vm
149
+ ),
150
+ runDocMethod: createResource(
151
+ {
152
+ url: 'run_doc_method',
153
+ makeParams({ method, name, ...values }) {
154
+ return {
155
+ dt: out.doctype,
156
+ dn: name,
157
+ method: method,
158
+ args: JSON.stringify(values),
159
+ }
160
+ },
161
+ onSuccess(data) {
162
+ if (data.docs) {
163
+ for (let doc of data.docs) {
164
+ updateRowInListResource(doc.doctype, doc)
165
+ }
166
+ }
167
+ options.runDocMethod?.onSuccess?.call(vm, data)
168
+ },
169
+ onError: options.runDocMethod?.onError,
170
+ },
171
+ vm
172
+ ),
173
+ update,
174
+ reload,
175
+ setData,
176
+ transform,
177
+ })
178
+
179
+ function update(updatedOptions) {
180
+ out.doctype = updatedOptions.doctype
181
+ out.fields = updatedOptions.fields
182
+ out.filters = updatedOptions.filters
183
+ out.orderBy = updatedOptions.orderBy
184
+ out.start = updatedOptions.start
185
+ out.pageLength = updatedOptions.pageLength
186
+ out.parent = updatedOptions.parent
187
+ out.debug = updatedOptions.debug
188
+ }
189
+
190
+ function transform(data) {
191
+ if (options.transform) {
192
+ let returnValue = options.transform.call(vm, data)
193
+ if (returnValue != null) {
194
+ return returnValue
195
+ }
196
+ }
197
+ return data
198
+ }
199
+
200
+ function reload() {
201
+ let _start = out.start
202
+ let _pageLength = out.pageLength
203
+ if (out.start > 0) {
204
+ out.start = 0
205
+ out.pageLength = out.originalData.length
206
+ }
207
+ return out.list.fetch().finally(() => {
208
+ out.start = _start
209
+ out.pageLength = _pageLength
210
+ })
211
+ }
212
+
213
+ function setData(data) {
214
+ out.originalData = data
215
+ if (typeof data === 'function') {
216
+ data = data.call(vm, out.data)
217
+ }
218
+ out.data = transform(data)
219
+ }
220
+
221
+ function next() {
222
+ out.start = out.start + out.pageLength
223
+ out.list.fetch()
224
+ }
225
+
226
+ if (options.realtime && vm.$socket) {
227
+ vm.$socket.on('list_update', (data) => {
228
+ if (
229
+ data.doctype === out.doctype &&
230
+ out.originalData?.find((d) => d.name === data.name)
231
+ ) {
232
+ out.fetchOne.submit(data.name)
233
+ }
234
+ })
235
+ }
236
+
237
+ if (cacheKey) {
238
+ // cache
239
+ listCache[cacheKey] = out
240
+ // offline
241
+ getLocal(cacheKey).then((data) => {
242
+ if ((out.list.loading || !out.list.fetched) && data) {
243
+ setData(data)
244
+ }
245
+ })
246
+ }
247
+
248
+ if (options.auto) {
249
+ out.list.fetch()
250
+ }
251
+
252
+ resourcesByDocType[out.doctype] = resourcesByDocType[out.doctype] || []
253
+ resourcesByDocType[out.doctype].push(out)
254
+
255
+ return out
256
+ }
257
+
258
+ export function getCachedListResource(cacheKey) {
259
+ cacheKey = getCacheKey(cacheKey)
260
+ return listCache[cacheKey] || null
261
+ }
262
+
263
+ export function updateRowInListResource(doctype, doc) {
264
+ if (!doc.name) return
265
+ let resources = resourcesByDocType[doctype] || []
266
+ for (let resource of resources) {
267
+ if (resource.originalData) {
268
+ for (let row of resource.originalData) {
269
+ if (row.name && row.name == doc.name) {
270
+ let previousRowData = JSON.stringify(row)
271
+ for (let key in row) {
272
+ if (key in doc) {
273
+ row[key] = doc[key]
274
+ }
275
+ }
276
+ row._previousData = previousRowData
277
+ }
278
+ }
279
+ resource.data = resource.transform(resource.originalData)
280
+ }
281
+ }
282
+ }
283
+
284
+ export function deleteRowInListResource(doctype, docname) {
285
+ let resources = resourcesByDocType[doctype] || []
286
+ for (let resource of resources) {
287
+ if (resource.originalData) {
288
+ resource.originalData = resource.originalData.filter(
289
+ (row) => row.name.toString() !== docname
290
+ )
291
+ resource.data = resource.transform(resource.originalData)
292
+ }
293
+ }
294
+ }
295
+
296
+ export function revertRowInListResource(doctype, doc) {
297
+ let resources = resourcesByDocType[doctype] || []
298
+ for (let resource of resources) {
299
+ if (resource.originalData) {
300
+ for (let row of resource.originalData) {
301
+ if (row.name && row.name == doc.name) {
302
+ let previousRowData = JSON.parse(row._previousData)
303
+ for (let key in row) {
304
+ row[key] = previousRowData[key]
305
+ }
306
+ delete row._previousData
307
+ }
308
+ }
309
+ resource.data = resource.transform(resource.originalData)
310
+ }
311
+ }
312
+ }
@@ -0,0 +1,16 @@
1
+ import { get, set } from 'idb-keyval'
2
+
3
+ export function saveLocal(key, data) {
4
+ if (typeof indexedDB === 'undefined') {
5
+ return Promise.resolve(null)
6
+ }
7
+ if (!key) return Promise.resolve()
8
+ return set(key, JSON.stringify(data))
9
+ }
10
+
11
+ export function getLocal(key) {
12
+ if (typeof indexedDB === 'undefined') {
13
+ return Promise.resolve(null)
14
+ }
15
+ return get(key).then((val) => (val ? JSON.parse(val) : val))
16
+ }
@@ -0,0 +1,105 @@
1
+ import { reactive, watch } from 'vue'
2
+ import { createResource, getCachedResource } from './resources'
3
+ import {
4
+ createDocumentResource,
5
+ getCachedDocumentResource,
6
+ } from './documentResource'
7
+ import { createListResource, getCachedListResource } from './listResource'
8
+
9
+ let createMixin = (mixinOptions) => ({
10
+ created() {
11
+ if (this.$options.resources) {
12
+ this._resources = reactive({})
13
+ for (let key in this.$options.resources) {
14
+ let options = this.$options.resources[key]
15
+
16
+ if (typeof options == 'function') {
17
+ watch(
18
+ () => {
19
+ try {
20
+ return options.call(this)
21
+ } catch (error) {
22
+ console.warn('Failed to get resource options\n\n', error)
23
+ return null
24
+ }
25
+ },
26
+ (options, oldOptions) => {
27
+ if (!options) {
28
+ return
29
+ }
30
+
31
+ let changed =
32
+ !oldOptions ||
33
+ JSON.stringify(options) !== JSON.stringify(oldOptions)
34
+
35
+ if (!changed) return
36
+
37
+ if (options.type === 'document') {
38
+ let resource = createDocumentResource(options, this)
39
+ this._resources[key] = resource
40
+ } else {
41
+ let resource = this._resources[key]
42
+ if (!resource) {
43
+ resource = createResourceForOptions(options, this)
44
+ this._resources[key] = resource
45
+ } else {
46
+ resource.update(options)
47
+ if (resource.auto) {
48
+ resource.reload()
49
+ }
50
+ }
51
+ }
52
+ },
53
+ {
54
+ immediate: true,
55
+ }
56
+ )
57
+ } else {
58
+ let resource = createResourceForOptions(options, this)
59
+ this._resources[key] = resource
60
+ }
61
+ }
62
+ }
63
+ },
64
+ methods: {
65
+ $getResource(cacheKey) {
66
+ return getCachedResource(cacheKey)
67
+ },
68
+ $getDocumentResource(doctype, name) {
69
+ return getCachedDocumentResource(doctype, name)
70
+ },
71
+ $getDoc(doctype, name) {
72
+ let resource = this.$getDocumentResource(doctype, name)
73
+ return resource ? resource.doc : null
74
+ },
75
+ $getListResource(cacheKey) {
76
+ return getCachedListResource(cacheKey)
77
+ },
78
+ $refetchResource(cache) {
79
+ let resource = this.$getResource(cache)
80
+ resource && resource.fetch()
81
+ },
82
+ },
83
+ computed: {
84
+ $resources() {
85
+ return this._resources
86
+ },
87
+ },
88
+ })
89
+
90
+ function createResourceForOptions(options, vm) {
91
+ if (options.type === 'document') {
92
+ return createDocumentResource(options, vm)
93
+ }
94
+ if (options.type === 'list') {
95
+ return createListResource(options, vm)
96
+ }
97
+ return createResource(options, vm)
98
+ }
99
+
100
+ export default {
101
+ install(app, options) {
102
+ let resourceMixin = createMixin(options)
103
+ app.mixin(resourceMixin)
104
+ },
105
+ }