bt-core-app 0.0.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 (53) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/README.md +45 -0
  3. package/index.html +13 -0
  4. package/package.json +39 -0
  5. package/public/vite.svg +1 -0
  6. package/src/assets/vue.svg +1 -0
  7. package/src/components/BT-Btn.vue +40 -0
  8. package/src/components/BT-Col.vue +36 -0
  9. package/src/components/BT-Span.vue +21 -0
  10. package/src/components/Dialog-Confirm.vue +47 -0
  11. package/src/components/Dialog-Select-Date.vue +89 -0
  12. package/src/components/Dialog-Select.vue +140 -0
  13. package/src/components/Dialog-Text.vue +59 -0
  14. package/src/composables/actions-tracker.ts +99 -0
  15. package/src/composables/actions.ts +354 -0
  16. package/src/composables/api.ts +471 -0
  17. package/src/composables/auth.ts +382 -0
  18. package/src/composables/cosmetics.ts +178 -0
  19. package/src/composables/csv.ts +198 -0
  20. package/src/composables/dates.ts +79 -0
  21. package/src/composables/demo.ts +25 -0
  22. package/src/composables/dialogs.ts +115 -0
  23. package/src/composables/document-meta.ts +40 -0
  24. package/src/composables/draggable.ts +189 -0
  25. package/src/composables/filters.ts +256 -0
  26. package/src/composables/forage.ts +49 -0
  27. package/src/composables/helpers.ts +694 -0
  28. package/src/composables/id.ts +20 -0
  29. package/src/composables/list.ts +601 -0
  30. package/src/composables/navigation.ts +214 -0
  31. package/src/composables/presets.ts +20 -0
  32. package/src/composables/pwa.ts +89 -0
  33. package/src/composables/resizable.ts +382 -0
  34. package/src/composables/rules.ts +40 -0
  35. package/src/composables/stores.ts +797 -0
  36. package/src/composables/track.ts +55 -0
  37. package/src/composables/urls.ts +11 -0
  38. package/src/core.ts +92 -0
  39. package/src/index.ts +16 -0
  40. package/src/types.ts +13 -0
  41. package/src/useApi.ts +68 -0
  42. package/src/vite-env.d.ts +1 -0
  43. package/test/api.test.ts +84 -0
  44. package/test/forage.test.ts +31 -0
  45. package/test/helpers.test.ts +231 -0
  46. package/test/navigation.test.ts +99 -0
  47. package/test/stores-last-update.test.ts +138 -0
  48. package/test/stores-session.test.ts +118 -0
  49. package/test/track.test.ts +29 -0
  50. package/test/utils.ts +15 -0
  51. package/tsconfig.json +33 -0
  52. package/tsconfig.node.json +11 -0
  53. package/vite.config.ts +19 -0
@@ -0,0 +1,471 @@
1
+ import { toValue } from 'vue'
2
+ import { appendUrl } from '@/composables/helpers'
3
+ import { type BTAuth } from './auth'
4
+
5
+ export interface QueryParams {
6
+ filterBy?: string,
7
+ includeCount?: boolean,
8
+ includeDetails?: boolean,
9
+ includeInactive?: boolean,
10
+ lastUpdate?: string,
11
+ other?: any //for other random params
12
+ properties?: string[] | string,
13
+ query?: string,
14
+ searchString?: string,
15
+ sortOrder?: string,
16
+ sortBy?: string,
17
+ takeFrom?: number,
18
+ takeAmount?: number
19
+ }
20
+
21
+ export interface PathOptions {
22
+ /**always added to end before query {url}/{additionalUrl}?{query} */
23
+ additionalUrl?: string
24
+ /**application/json or other options */
25
+ contentType?: string
26
+ /**that data to send in the body for POST, PATCH, and DELETE requests */
27
+ data?: any
28
+ /** resulting url after building {nav | url}/{additionalUrl}?{params} */
29
+ finalUrl?: string,
30
+ /**override default headers */
31
+ headers?: HeadersInit
32
+ /**id will be added as a url paramter (/{id}?) rather than as a query parameter */
33
+ id?: string
34
+ /**where to find the url */
35
+ nav?: string
36
+ /**headers will not be calculated. Only the given headers in these options will be used */
37
+ overrideHeaders?: boolean
38
+ /**query parameters */
39
+ params?: QueryParams
40
+ /**attaches a proxyID to the request */
41
+ proxyID?: string
42
+ /**whether to refresh the store data and go straight to the server */
43
+ refresh?: boolean
44
+ /**returns result as a json object. Defaults to true. */
45
+ returnJson?: boolean
46
+ /**returns result as a string */
47
+ returnText?: boolean
48
+ /**If false, returns response no matter the status code */
49
+ throwError?: boolean
50
+ /**if exists then overrides default nav */
51
+ url?: string
52
+ /**whether to preference using the local cache */
53
+ useLocalCache?: boolean
54
+ }
55
+
56
+ type FindPath = (navName?: string) => string | undefined
57
+ // type BuildHeaders = (path: PathOptions) => HeadersInit
58
+ // type BuildQuery = (params: any) => string
59
+ // type BuildUrl = (path: PathOptions) => string
60
+
61
+ interface UseApiOptions {
62
+ auth?: BTAuth
63
+ /**overrides the default */
64
+ buildHeaders?: (path: PathOptions) => HeadersInit
65
+ /**build a query. Overrides the default */
66
+ buildQuery?: (params: any) => string
67
+ /**overrides the default */
68
+ buildUrl?: (path: PathOptions) => string
69
+ /**defaults to 'application/json' */
70
+ defaultContentType?: string
71
+ /**returns result as a json object. Defaults to true. */
72
+ defaultReturnJson?: boolean
73
+ /**returns result as a string */
74
+ defaultReturnText?: boolean
75
+ /**defaults to true. Will throw an error on fail */
76
+ defaultThrowError?: boolean
77
+ /**defaults to a function that returns '' */
78
+ findPath?: FindPath
79
+ /**if true and logged in then will set an authorization header with 'bearer [token]' */
80
+ useBearerToken?: boolean
81
+ }
82
+
83
+ export interface BTApi {
84
+ buildHeaders: (options: PathOptions) => HeadersInit
85
+ buildQuery: (params: any) => string
86
+ buildUrl: (path: PathOptions) => string
87
+ deleteItem: (pathOptions: PathOptions) => Promise<string | undefined>
88
+ get: <T>(pathOptions: PathOptions) => Promise<T>
89
+ getAll: <T>(pathOptions: PathOptions) => Promise<T>
90
+ post: <T>(pathOptions: PathOptions) => Promise<T | undefined>
91
+ patch: <T>(pathOptions: PathOptions) => Promise<T | undefined>
92
+ }
93
+
94
+ export function createApi(options?: UseApiOptions): BTApi {
95
+ const buildHeaders = options?.buildHeaders ?? defaultBuildHeaders
96
+ const buildQuery = options?.buildQuery ?? defaultBuildQuery
97
+ const buildUrl = options?.buildUrl ?? defaultBuildUrl
98
+
99
+ function defaultBuildQuery(params: QueryParams): string {
100
+ let query = new URLSearchParams()
101
+
102
+ Object.entries(params).forEach(x => {
103
+ if (x[1] != undefined) {
104
+ query.append(x[0], x[1])
105
+ }
106
+ })
107
+
108
+ if (params.filterBy) {
109
+ query.set('filterBy', params.filterBy)
110
+ }
111
+
112
+ if (params.includeCount)
113
+ query.set('includeCount', params.includeCount.toString())
114
+
115
+ if (params.includeDetails != undefined)
116
+ query.set('includeDetails', params.includeDetails.toString())
117
+
118
+ if (params.includeInactive)
119
+ query.set('includeInactive', params.includeInactive.toString())
120
+
121
+ if (params.properties)
122
+ query.set('properties', params.properties.toString())
123
+
124
+ if (params.query)
125
+ query.set('query', params.query.toString())
126
+
127
+ if (params.searchString)
128
+ query.set('searchString', params.searchString)
129
+
130
+ if (params.sortOrder)
131
+ query.set('sortOrder', params.sortOrder)
132
+
133
+ if (params.sortBy)
134
+ query.set('sortBy', params.sortBy)
135
+
136
+ if (params.takeFrom)
137
+ query.set('takeFrom', params.takeFrom.toString())
138
+
139
+ if (params.takeAmount)
140
+ query.set('takeAmount', params.takeAmount.toString())
141
+
142
+ if (params.other) {
143
+ Object.entries(params.other).forEach(x => {
144
+ if (x[1] != undefined) {
145
+ query.append(x[0], x[1].toString())
146
+ }
147
+ })
148
+ }
149
+
150
+ return query.toString()
151
+ }
152
+
153
+ /**returns path and sets final url */
154
+ function defaultBuildUrl(path: PathOptions) {
155
+ let url: string | undefined = toValue(path.url) ?? undefined
156
+ let id = toValue(path.id)
157
+
158
+ if (url == null && path.nav != null && options?.findPath != null)
159
+ url = options.findPath(path.nav)
160
+
161
+ if (path.additionalUrl != null) {
162
+ if (url == null)
163
+ url = path.additionalUrl
164
+ else
165
+ url = appendUrl(url, path.additionalUrl)
166
+ }
167
+
168
+ if (id != null) {
169
+ if (url?.includes('{id}'))
170
+ url = url.replaceAll('{id}', id)
171
+ else
172
+ url = appendUrl(url, id)
173
+ }
174
+
175
+ if (path.params != null)
176
+ url = `${url}?${buildQuery(path.params)}`
177
+
178
+ path.finalUrl = url
179
+
180
+ return path.finalUrl ?? ''
181
+ }
182
+
183
+ function defaultBuildHeaders(path: PathOptions): HeadersInit {
184
+ let fetchOptions:any = { ...path.headers }
185
+ const auth = options?.auth?.credentials
186
+
187
+ if (path.proxyID)
188
+ fetchOptions.ManagedCompanyAccountID ??= path.proxyID
189
+
190
+ if (options?.useBearerToken != false && auth?.isLoggedIn == true)
191
+ fetchOptions.authorization ??= `bearer ${auth.token}`
192
+
193
+ fetchOptions['Content-Type'] ??= (path.contentType ?? options?.defaultContentType ?? 'application/json')
194
+
195
+ return fetchOptions
196
+ }
197
+
198
+ async function get<T>(pathOptions: PathOptions): Promise<T> {
199
+ const throwError = pathOptions.throwError ?? options?.defaultThrowError ?? true
200
+ const returnJson = pathOptions.returnJson ?? options?.defaultReturnJson ?? true
201
+ const returnText = pathOptions.returnText ?? options?.defaultReturnText ?? false
202
+
203
+ let url = pathOptions.finalUrl
204
+ let headers = pathOptions.headers
205
+
206
+ if (url == null)
207
+ url = buildUrl(pathOptions)
208
+
209
+ if (pathOptions.overrideHeaders !== true)
210
+ headers = buildHeaders(pathOptions)
211
+
212
+ console.log(`Get from ${url}`)
213
+
214
+ let res: any = undefined
215
+
216
+ try {
217
+ res = await fetch(url, {
218
+ method: 'GET',
219
+ mode: 'cors',
220
+ cache: 'no-cache',
221
+ headers
222
+ });
223
+
224
+ // if (!throwError) {
225
+ // return res
226
+ // }
227
+
228
+ if (!res.ok) {
229
+ let errorContent = await res.text()
230
+ throw new Error(errorContent ?? res.statusText ?? 'Get error')
231
+ }
232
+
233
+ if (returnText)
234
+ return await res.text()
235
+ if (returnJson)
236
+ return await res.json()
237
+
238
+ return res
239
+ }
240
+ catch (err) {
241
+ if (!throwError) {
242
+ return res
243
+ }
244
+
245
+ throw new Error(err as string)
246
+ }
247
+ }
248
+
249
+ async function getAll<T>(pathOptions: PathOptions): Promise<T> {
250
+ const throwError = pathOptions.throwError ?? options?.defaultThrowError ?? true
251
+ const returnJson = pathOptions.returnJson ?? options?.defaultReturnJson ?? true
252
+ const returnText = pathOptions.returnText ?? options?.defaultReturnText ?? false
253
+
254
+ let url = pathOptions.finalUrl
255
+ let headers = pathOptions.headers
256
+
257
+ if (url == null)
258
+ url = buildUrl(pathOptions)
259
+
260
+ if (pathOptions.overrideHeaders !== true)
261
+ headers = buildHeaders(pathOptions)
262
+
263
+ console.log(`Get all from ${url}`)
264
+
265
+ let res: any = undefined
266
+
267
+ try {
268
+ res = await fetch(url, {
269
+ method: 'GET',
270
+ mode: 'cors',
271
+ cache: 'no-cache',
272
+ headers
273
+ });
274
+
275
+ // if (!throwError) {
276
+ // return res
277
+ // }
278
+
279
+ if (!res.ok) {
280
+ let errorContent = await res.text()
281
+ throw new Error(errorContent ?? res.statusText ?? 'Get all error')
282
+ }
283
+
284
+ if (returnText)
285
+ return await res.text()
286
+ if (returnJson)
287
+ return await res.json()
288
+
289
+ return res
290
+ }
291
+ catch (err) {
292
+ if (!throwError) {
293
+ return res
294
+ }
295
+
296
+ throw new Error(err as string)
297
+ }
298
+
299
+ }
300
+
301
+ async function post<T>(pathOptions: PathOptions): Promise<T | undefined> {
302
+ const throwError = pathOptions.throwError ?? options?.defaultThrowError ?? true
303
+ const returnJson = pathOptions.returnJson ?? options?.defaultReturnJson ?? true
304
+ const returnText = pathOptions.returnText ?? options?.defaultReturnText ?? false
305
+
306
+ let url = pathOptions.finalUrl
307
+ let headers = pathOptions.headers
308
+
309
+ if (url == null)
310
+ url = buildUrl(pathOptions)
311
+
312
+ if (pathOptions.overrideHeaders !== true)
313
+ headers = buildHeaders(pathOptions)
314
+
315
+ console.log(`Post to ${url}`)
316
+
317
+ let res: any = undefined
318
+
319
+ try {
320
+ res = await fetch(url, {
321
+ method: 'POST',
322
+ mode: 'cors',
323
+ cache: 'no-cache',
324
+ headers,
325
+ body: JSON.stringify(pathOptions.data)
326
+ })
327
+
328
+ // if (!throwError) {
329
+ // return res
330
+ // }
331
+
332
+ if (!res.ok) {
333
+ let errorContent = await res.text()
334
+ throw new Error(errorContent ?? res.statusText ?? 'Post error!')
335
+ }
336
+
337
+ if (returnText)
338
+ return await res.text()
339
+ if (returnJson)
340
+ return await res.json()
341
+
342
+ return res
343
+ }
344
+ catch (err) {
345
+ if (!throwError) {
346
+ return res
347
+ }
348
+
349
+ if (res.status == 200)
350
+ return undefined
351
+
352
+ throw new Error(err as string)
353
+ }
354
+ }
355
+
356
+ async function patch<T>(pathOptions: PathOptions): Promise<T | undefined> {
357
+ const throwError = pathOptions.throwError ?? options?.defaultThrowError ?? true
358
+ const returnJson = pathOptions.returnJson ?? options?.defaultReturnJson ?? true
359
+ const returnText = pathOptions.returnText ?? options?.defaultReturnText ?? false
360
+
361
+ let url = pathOptions.finalUrl
362
+ let headers = pathOptions.headers
363
+
364
+ if (url == null)
365
+ url = buildUrl(pathOptions)
366
+
367
+ if (pathOptions.overrideHeaders !== true)
368
+ headers = buildHeaders(pathOptions)
369
+
370
+ console.log(`Patch to ${url}`)
371
+
372
+ let res: any = undefined
373
+
374
+ try {
375
+ res = await fetch(url, {
376
+ method: 'PATCH',
377
+ mode: 'cors',
378
+ cache: 'no-cache',
379
+ headers,
380
+ body: JSON.stringify(pathOptions.data)
381
+ })
382
+
383
+ // if (!throwError) {
384
+ // return res
385
+ // }
386
+
387
+ if (!res.ok) {
388
+ let errorContent = await res.text()
389
+ throw new Error(errorContent ?? res.statusText ?? 'Patch error!')
390
+ }
391
+
392
+ if (returnText)
393
+ return await res.text()
394
+ if (returnJson)
395
+ return await res.json()
396
+
397
+ return res
398
+ }
399
+ catch (err) {
400
+ if (!throwError) {
401
+ return res
402
+ }
403
+
404
+ if (res.status == 200)
405
+ return undefined
406
+
407
+ throw new Error(err as string)
408
+ }
409
+ }
410
+
411
+ /**
412
+ *
413
+ * @param options
414
+ * returns an error msg if failed
415
+ */
416
+ async function deleteItem(pathOptions: PathOptions): Promise<string | undefined> {
417
+ const throwError = pathOptions.throwError ?? options?.defaultThrowError ?? true
418
+
419
+ let url = pathOptions.finalUrl
420
+ let headers = pathOptions.headers
421
+
422
+ if (url == null)
423
+ url = buildUrl(pathOptions)
424
+
425
+ if (pathOptions.overrideHeaders !== true)
426
+ headers = buildHeaders(pathOptions)
427
+
428
+ console.log(`Delete ${url}`)
429
+
430
+ let res: any = undefined
431
+
432
+ try {
433
+ res = await fetch(url, {
434
+ method: 'DELETE',
435
+ mode: 'cors',
436
+ cache: 'no-cache',
437
+ headers,
438
+ body: JSON.stringify(pathOptions.data)
439
+ })
440
+
441
+ // if (!throwError) {
442
+ // return res
443
+ // }
444
+
445
+ if (res.status == 200) {
446
+ return undefined
447
+ }
448
+ else {
449
+ return res.statusText
450
+ }
451
+ }
452
+ catch (err) {
453
+ if (!throwError) {
454
+ return res
455
+ }
456
+
457
+ throw new Error(err as string)
458
+ }
459
+ }
460
+
461
+ return {
462
+ buildHeaders,
463
+ buildQuery,
464
+ buildUrl,
465
+ deleteItem,
466
+ get,
467
+ getAll,
468
+ patch,
469
+ post
470
+ }
471
+ }