@symbo.ls/utils 3.14.2 → 3.14.4

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 (122) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/array.cjs +1 -0
  3. package/dist/cjs/assets.cjs +1 -0
  4. package/dist/cjs/browser.cjs +1 -0
  5. package/dist/cjs/cache.cjs +1 -0
  6. package/dist/cjs/cdn.cjs +3 -0
  7. package/dist/cjs/component.cjs +1 -0
  8. package/dist/cjs/cookie.cjs +1 -0
  9. package/dist/cjs/date.cjs +1 -0
  10. package/dist/cjs/detectHeight.cjs +1 -0
  11. package/dist/cjs/element.cjs +1 -0
  12. package/dist/cjs/env.cjs +2 -0
  13. package/dist/cjs/events.cjs +1 -0
  14. package/dist/cjs/extends.cjs +1 -0
  15. package/dist/cjs/fibonacci.cjs +1 -0
  16. package/dist/cjs/files.cjs +1 -0
  17. package/dist/cjs/function.cjs +1 -0
  18. package/dist/cjs/globals.cjs +1 -0
  19. package/dist/cjs/if.cjs +1 -0
  20. package/dist/cjs/index.cjs +1 -0
  21. package/dist/cjs/key.cjs +1 -0
  22. package/dist/cjs/keys.cjs +1 -0
  23. package/dist/cjs/load.cjs +1 -0
  24. package/dist/cjs/log.cjs +1 -0
  25. package/dist/cjs/metadata.cjs +2 -0
  26. package/dist/cjs/methods.cjs +10 -0
  27. package/dist/cjs/node.cjs +1 -0
  28. package/dist/cjs/object.cjs +12 -0
  29. package/dist/cjs/projectKeys.cjs +1 -0
  30. package/dist/cjs/props.cjs +1 -0
  31. package/dist/cjs/scaling.cjs +1 -0
  32. package/dist/cjs/scope.cjs +1 -0
  33. package/dist/cjs/sharedLibraries.cjs +1 -0
  34. package/dist/cjs/state.cjs +1 -0
  35. package/dist/cjs/string-extra.cjs +1 -0
  36. package/dist/cjs/string.cjs +3 -0
  37. package/dist/cjs/style.cjs +1 -0
  38. package/dist/cjs/tags.cjs +1 -0
  39. package/dist/cjs/triggerEvent.cjs +1 -0
  40. package/dist/cjs/types.cjs +1 -0
  41. package/dist/cjs/update.cjs +1 -0
  42. package/dist/esm/array.js +1 -0
  43. package/dist/esm/assets.js +1 -0
  44. package/dist/esm/browser.js +1 -0
  45. package/dist/esm/cache.js +1 -0
  46. package/dist/esm/cdn.js +3 -0
  47. package/dist/esm/component.js +1 -0
  48. package/dist/esm/cookie.js +1 -0
  49. package/dist/esm/date.js +1 -0
  50. package/dist/esm/detectHeight.js +1 -0
  51. package/dist/esm/element.js +1 -0
  52. package/dist/esm/env.js +2 -0
  53. package/dist/esm/events.js +1 -0
  54. package/dist/esm/extends.js +1 -0
  55. package/dist/esm/fibonacci.js +1 -0
  56. package/dist/esm/files.js +1 -0
  57. package/dist/esm/function.js +1 -0
  58. package/dist/esm/globals.js +1 -0
  59. package/dist/esm/if.js +1 -0
  60. package/dist/esm/index.js +1 -0
  61. package/dist/esm/key.js +1 -0
  62. package/dist/esm/keys.js +1 -0
  63. package/dist/esm/load.js +1 -0
  64. package/dist/esm/log.js +1 -0
  65. package/dist/esm/metadata.js +2 -0
  66. package/dist/esm/methods.js +10 -0
  67. package/dist/esm/node.js +1 -0
  68. package/dist/esm/object.js +12 -0
  69. package/dist/esm/projectKeys.js +1 -0
  70. package/dist/esm/props.js +1 -0
  71. package/dist/esm/scaling.js +1 -0
  72. package/dist/esm/scope.js +1 -0
  73. package/dist/esm/sharedLibraries.js +1 -0
  74. package/dist/esm/state.js +1 -0
  75. package/dist/esm/string-extra.js +1 -0
  76. package/dist/esm/string.js +3 -0
  77. package/dist/esm/style.js +1 -0
  78. package/dist/esm/tags.js +1 -0
  79. package/dist/esm/triggerEvent.js +1 -0
  80. package/dist/esm/types.js +1 -0
  81. package/dist/esm/update.js +1 -0
  82. package/package.json +35 -18
  83. package/array.js +0 -162
  84. package/assets.js +0 -117
  85. package/browser.js +0 -13
  86. package/cache.js +0 -7
  87. package/cdn.js +0 -83
  88. package/component.js +0 -25
  89. package/cookie.js +0 -78
  90. package/date.js +0 -10
  91. package/detectHeight.js +0 -42
  92. package/element.js +0 -148
  93. package/env.js +0 -15
  94. package/events.js +0 -19
  95. package/extends.js +0 -519
  96. package/fibonacci.js +0 -9
  97. package/files.js +0 -3
  98. package/function.js +0 -145
  99. package/globals.js +0 -8
  100. package/if.js +0 -30
  101. package/index.js +0 -42
  102. package/key.js +0 -20
  103. package/keys.js +0 -176
  104. package/load.js +0 -236
  105. package/log.js +0 -12
  106. package/metadata.js +0 -392
  107. package/methods.js +0 -684
  108. package/node.js +0 -37
  109. package/object.js +0 -837
  110. package/projectKeys.js +0 -30
  111. package/props.js +0 -327
  112. package/scaling.js +0 -15
  113. package/scope.js +0 -32
  114. package/sharedLibraries.js +0 -184
  115. package/state.js +0 -203
  116. package/string-extra.js +0 -69
  117. package/string.js +0 -206
  118. package/style.js +0 -23
  119. package/tags.js +0 -176
  120. package/triggerEvent.js +0 -102
  121. package/types.js +0 -55
  122. package/update.js +0 -27
package/methods.js DELETED
@@ -1,684 +0,0 @@
1
- 'use strict'
2
-
3
- import { triggerEventOn } from './triggerEvent.js'
4
- import { DOMQ_PROPERTIES, METHODS, PARSED_DOMQ_PROPERTIES } from './keys.js'
5
- import { isDefined, isFunction, isObject, isObjectLike } from './types.js'
6
- import { deepClone } from './object.js'
7
- import { isProduction } from './env.js'
8
- import { removeValueFromArray } from './array.js'
9
- import { OPTIONS } from './cache.js'
10
- const ENV = process.env.NODE_ENV
11
-
12
- // TODO: update these files
13
- export function spotByPath (path) {
14
- const element = this
15
- const { __ref: ref } = element
16
- const arr = [].concat(path)
17
- let foundelement = ref.root[arr[0]]
18
-
19
- if (!arr || !arr.length) {
20
- return console.log(arr, 'on', element.key, 'is undefined')
21
- }
22
-
23
- while (foundelement.key === arr[0]) {
24
- arr.shift()
25
- if (!arr.length) break
26
- foundelement = foundelement[arr[0]]
27
- if (!foundelement) return
28
- }
29
-
30
- return foundelement
31
- }
32
-
33
- // TODO: update these files
34
- export function lookup (param) {
35
- const el = this
36
- let { parent } = el
37
-
38
- if (isFunction(param)) {
39
- if (parent.state && param(parent, parent.state, parent.context)) {
40
- return parent
41
- } else if (parent.parent) return parent.lookup(param)
42
- else return
43
- }
44
-
45
- if (el[param]) return el[param]
46
-
47
- while (parent.param !== param) {
48
- if (parent[param]) return parent[param]
49
- parent = parent.parent
50
- if (!parent) return
51
- }
52
-
53
- return parent
54
- }
55
-
56
- export function lookdown (param) {
57
- const el = this
58
- const { __ref: ref } = el
59
- const children = ref?.__children
60
-
61
- if (!children) return
62
-
63
- for (let i = 0; i < children.length; i++) {
64
- const v = children[i]
65
- const childElem = el[v]
66
-
67
- if (v === param) return childElem
68
- else if (isFunction(param)) {
69
- const exec = param(childElem, childElem.state, childElem.context)
70
- if (childElem.state && exec) {
71
- return childElem
72
- }
73
- }
74
- const lookdown = childElem?.lookdown?.(param)
75
- if (lookdown) return lookdown
76
- }
77
- }
78
-
79
- export function lookdownAll (param, results = []) {
80
- const el = this
81
- const { __ref: ref } = el
82
- const children = ref?.__children
83
-
84
- if (!children) return
85
-
86
- for (let i = 0; i < children.length; i++) {
87
- const v = children[i]
88
- const childElem = el[v]
89
-
90
- if (v === param) results.push(childElem)
91
- else if (isFunction(param)) {
92
- const exec = param(childElem, childElem.state, childElem.context)
93
- if (childElem.state && exec) results.push(childElem)
94
- }
95
- childElem?.lookdownAll?.(param, results)
96
- }
97
-
98
- return results.length ? results : undefined
99
- }
100
-
101
- export function setNodeStyles (params = {}) {
102
- const el = this
103
- if (!el.node?.style) return
104
-
105
- for (const param in params) {
106
- const value = params[param]
107
- const childElem = el[param]
108
- if (isObject(value) && childElem) setNodeStyles.call(childElem, value)
109
- else if (value != null) {
110
- const cssProp = param.replace(/[A-Z]/g, m => '-' + m.toLowerCase())
111
- const str = String(value).replace(/\s*!important\s*$/, '')
112
- el.node.style.setProperty(cssProp, str, 'important')
113
- }
114
- }
115
-
116
- return el
117
- }
118
-
119
- export function remove (opts) {
120
- const element = this
121
- const beforeRemoveReturns = triggerEventOn('beforeRemove', element, opts)
122
- if (beforeRemoveReturns === false) return element
123
- if (isFunction(element.node.remove)) element.node.remove()
124
- else if (!isProduction()) {
125
- console.warn('This item cant be removed')
126
- element.log()
127
- }
128
- delete element.parent[element.key]
129
- if (element.parent.__ref) {
130
- element.parent.__ref.__children = removeValueFromArray(
131
- element.parent.__ref.__children,
132
- element.key
133
- )
134
- }
135
- triggerEventOn('remove', element, opts)
136
- }
137
-
138
- export function get (param) {
139
- const element = this
140
- return element[param]
141
- }
142
-
143
- export function setProps (param, options) {
144
- const element = this
145
- if (!param) return
146
- element.update(param, options)
147
- return element
148
- }
149
-
150
- export function getRef (key) {
151
- if (key) return this.__ref && this.__ref[key]
152
- return this.__ref
153
- }
154
-
155
- export function getChildren () {
156
- const __children = this.getRef('__children')
157
- return __children.map(k => this[k])
158
- }
159
-
160
- export function getPath () {
161
- return this.getRef().path
162
- }
163
-
164
- // Module-level registry for the active root state. Smbls.create's
165
- // prepareContext registers the root state here as soon as it's
166
- // constructed — early enough that any component rendering during the
167
- // rest of context preparation (and in createElement) can resolve via
168
- // `getRootState()` without needing `this`.
169
- //
170
- // Why this exists: `getRootState()` historically read from
171
- // `window.platformState || window.smblsApp?.state`. Projects had to
172
- // pre-set `window.smblsApp = { state: context.state }` in their
173
- // `index.js` BEFORE calling `create(...)` so the framework could find
174
- // the state during early render. The runner's boot script bypasses the
175
- // project's index.js, so projects depending on that pre-init silently
176
- // renderered blank under runner. A registry the framework owns
177
- // eliminates the project-side pre-init requirement.
178
- let _activeRootState = null
179
-
180
- /**
181
- * Register the active root state so `getRootState()` (called without a
182
- * `this` context) can find it during early render. Called by
183
- * `prepareContext` in `packages/smbls/src/createDomql.js` immediately
184
- * after `prepareState` resolves.
185
- *
186
- * Multi-app pages: this is a singleton — second app overwrites the
187
- * first. Same behaviour as `window.smblsApp.state` had before. Apps
188
- * that render concurrently on one page need the element-walk path
189
- * (`el.getRootState()`), not the free-function path.
190
- */
191
- export const setActiveRootState = (state) => {
192
- _activeRootState = state || null
193
- }
194
-
195
- const readFallbackState = () => {
196
- // The framework-managed registry (set by prepareContext during
197
- // create(...)) is the single source of truth for the active root
198
- // state when called without a `this` context. The previous version
199
- // of this fallback also consulted `window.platformState` and
200
- // `window.smblsApp?.state` — but per the FA409 rule the framework
201
- // must not depend on values written to the global object. Projects
202
- // that need free-function `getRootState()` rely on the registry being
203
- // populated by `prepareContext`, which happens before any user code
204
- // runs in `createDomqlElement`.
205
- return _activeRootState || null
206
- }
207
-
208
- export function getRootState (param) {
209
- let state = null
210
- const hasRootState = (obj) => obj.__element && obj.root?.isRootState
211
- if (!this) {
212
- state = readFallbackState()
213
- } else if (hasRootState(this)) {
214
- state = this.root
215
- } else if (this.__ref && this.__ref.path) {
216
- const hasPlatformState = this.state && hasRootState(this.state)
217
- const hasPlatformStateOnParent =
218
- isFunction(this.state) &&
219
- this.parent.state &&
220
- hasRootState(this.parent.state)
221
- if (hasPlatformState || hasPlatformStateOnParent) {
222
- state = this.state.root || this.parent.state.root
223
- }
224
- }
225
- if (!state) {
226
- state = readFallbackState()
227
- }
228
- return param ? state?.[param] : state
229
- }
230
-
231
- export function getRoot (key) {
232
- const rootElem = this.getRootState()?.__element
233
- return rootElem && Object.keys(rootElem).length > 0 && key
234
- ? rootElem[key]
235
- : rootElem
236
- }
237
-
238
- export function getRootData (key) {
239
- return this.getRoot('data') &&
240
- Object.keys(this.getRoot('data')).length > 0 &&
241
- key
242
- ? this.getRoot('data')[key]
243
- : this.getRoot('data')
244
- }
245
-
246
- export function getRootContext (key) {
247
- const ctx = this.getRoot()?.context
248
- return key ? ctx[key] : ctx
249
- }
250
-
251
- export function getContext (key) {
252
- const ctx = this.context
253
- return key ? ctx[key] : ctx
254
- }
255
-
256
- export const defineSetter = (element, key, get, set) =>
257
- Object.defineProperty(element, key, { get, set })
258
-
259
- export function keys () {
260
- const element = this
261
- const keys = []
262
- for (const param in element) {
263
- if (
264
- // (REGISTRY[param] && !DOMQ_PROPERTIES.has(param)) ||
265
- !Object.prototype.hasOwnProperty.call(element, param) ||
266
- (DOMQ_PROPERTIES.has(param) &&
267
- !PARSED_DOMQ_PROPERTIES.has(param))
268
- ) {
269
- continue
270
- }
271
- keys.push(param)
272
- }
273
- return keys
274
- }
275
-
276
- export function parse (excl = []) {
277
- const element = this
278
- const obj = {}
279
- const keyList = keys.call(element)
280
- const hasChildren = keyList.includes('children')
281
- const exclSet = excl.length ? new Set(excl) : null
282
- for (let i = 0; i < keyList.length; i++) {
283
- const v = keyList[i]
284
- if ((exclSet && exclSet.has(v)) || !Object.prototype.hasOwnProperty.call(element, v)) continue
285
- if (hasChildren && v === 'content') continue
286
- const val = element[v]
287
- if (v === 'state') {
288
- if (element.__ref && !element.__ref.__hasRootState) continue
289
- const parsedVal = isFunction(val && val.parse) ? val.parse() : val
290
- obj[v] = isFunction(parsedVal)
291
- ? parsedVal
292
- : JSON.parse(JSON.stringify(parsedVal || {}))
293
- } else if (v === 'scope') {
294
- if (element.__ref && !element.__ref.__hasRootScope) continue
295
- obj[v] = JSON.parse(JSON.stringify(val || {}))
296
- } else if (v === 'props') {
297
- const { __element, update, ...props } = element[v]
298
- obj[v] = props
299
- } else if (isDefined(val) && Object.prototype.hasOwnProperty.call(element, v)) {
300
- obj[v] = val
301
- }
302
- }
303
- return obj
304
- }
305
-
306
- export function parseDeep (excl = [], visited = new WeakSet()) {
307
- const element = this
308
- if (visited.has(element)) return undefined
309
- visited.add(element)
310
- const obj = parse.call(element, excl)
311
- const exclSet = excl.length ? new Set(excl) : null
312
- for (const v in obj) {
313
- if ((exclSet && exclSet.has(v)) || !Object.prototype.hasOwnProperty.call(element, v)) continue
314
- const val = obj[v]
315
- if (Array.isArray(val)) {
316
- obj[v] = val.map(item =>
317
- isObjectLike(item) ? parseDeep.call(item, excl, visited) : item
318
- )
319
- } else if (isObjectLike(val)) {
320
- obj[v] = parseDeep.call(val, excl, visited)
321
- }
322
- }
323
- return obj
324
- }
325
-
326
- export function verbose (...args) {
327
- if (ENV !== 'test' && ENV !== 'development') return
328
-
329
- const element = this
330
- const { __ref: ref } = element
331
- console.groupCollapsed(element.key)
332
- if (args.length) {
333
- args.forEach(v => console.log(`%c${v}:\n`, 'font-weight: bold', element[v]))
334
- } else {
335
- console.log(ref.path)
336
- const keys = element.keys()
337
- keys.forEach(v => console.log(`%c${v}:`, 'font-weight: bold', element[v]))
338
- }
339
- console.log(element)
340
- console.groupEnd(element.key)
341
- return element
342
- }
343
-
344
- export function log (...params) {
345
- if (ENV === 'test' || ENV === 'development') {
346
- console.log(...params)
347
- }
348
- }
349
-
350
- export function warn (...params) {
351
- if (ENV === 'test' || ENV === 'development') {
352
- console.warn(...params)
353
- }
354
- }
355
-
356
- export function error (...params) {
357
- if (ENV === 'test' || ENV === 'development') {
358
- if (params[params.length - 1]?.debugger) debugger // eslint-disable-line
359
- if (params[params.length - 1]?.verbose) verbose.call(this)
360
- throw new Error(...params)
361
- }
362
- }
363
-
364
- export function nextElement () {
365
- const element = this
366
- const { key, parent } = element
367
- const { __children } = parent.__ref
368
-
369
- const currentIndex = __children.indexOf(key)
370
- const nextChild = __children[currentIndex + 1]
371
-
372
- return parent[nextChild]
373
- }
374
-
375
- export function previousElement (el) {
376
- const element = el || this
377
- const { key, parent } = element
378
- const { __children } = parent.__ref
379
-
380
- if (!__children) return
381
-
382
- const currentIndex = __children.indexOf(key)
383
- return parent[__children[currentIndex - 1]]
384
- }
385
-
386
- export function variables (obj = {}) {
387
- const element = this
388
- if (!element.data) element.data = {}
389
- if (!element.data.varCaches) element.data.varCaches = {}
390
- const varCaches = element.data.varCaches
391
- const changes = {}
392
- let changed
393
- for (const key in obj) {
394
- if (obj[key] !== varCaches[key]) {
395
- changed = true
396
- changes[key] = obj[key]
397
- }
398
- }
399
- return {
400
- changed: cb => {
401
- if (!changed) return
402
- const returns = cb(changes, deepClone(varCaches))
403
- for (const key in changes) {
404
- varCaches[key] = changes[key]
405
- }
406
- return returns
407
- },
408
- timeout: (cb, timeout) => {
409
- if (!changed) return
410
- const t = setTimeout(() => {
411
- cb(changes)
412
- clearTimeout(t)
413
- }, timeout)
414
- }
415
- }
416
- }
417
-
418
- /**
419
- * A unified call function that detects the calling context and adapts accordingly.
420
- * - When called in an async context (with await), it fully resolves promises
421
- * - When called in a sync context, it returns sync results directly and handles promises appropriately
422
- *
423
- * @param {string} fnKey - The name of the function to call
424
- * @param {...any} args - Arguments to pass to the function
425
- * @returns {any|Promise} - The result or a Promise to the result
426
- */
427
- export function call (fnKey, ...args) {
428
- const context = this.context
429
- const fn = (
430
- context.utils?.[fnKey] ||
431
- context.functions?.[fnKey] ||
432
- context.methods?.[fnKey] ||
433
- context.snippets?.[fnKey]
434
- )
435
- if (!fn) return
436
- try {
437
- const result = fn.call(this, ...args)
438
- if (result && typeof result.then === 'function') {
439
- result.catch((err) => {
440
- error.call(this, err)
441
- })
442
- }
443
- return result
444
- } catch (err) {
445
- error.call(this, err)
446
- if (context?.strictMode) throw err
447
- }
448
- }
449
-
450
- export async function getDB () {
451
- const element = this
452
- const db = element.context?.fetch
453
- if (!db) return null
454
- if (typeof db.select === 'function') {
455
- if (!db.__authInitialized && db.getSession) {
456
- const { initAdapterAuth } = await import('@symbo.ls/fetch')
457
- await initAdapterAuth(db, element.context)
458
- }
459
- return db
460
- }
461
- if (db.__resolved) {
462
- if (!db.__resolved.__authInitialized && db.__resolved.getSession) {
463
- const { initAdapterAuth } = await import('@symbo.ls/fetch')
464
- await initAdapterAuth(db.__resolved, element.context)
465
- }
466
- return db.__resolved
467
- }
468
- if (db.__resolving) return db.__resolving
469
- // Set __resolving synchronously BEFORE the async import to prevent
470
- // resolveAdapter() from starting a parallel resolveDb() during the yield
471
- const resolvePromise = import('@symbo.ls/fetch').then(({ resolveDb }) => resolveDb(db))
472
- db.__resolving = resolvePromise
473
- const resolved = await resolvePromise
474
- db.__resolved = resolved
475
- element.context.fetch = resolved
476
- delete db.__resolving
477
- if (resolved.getSession) {
478
- const { initAdapterAuth } = await import('@symbo.ls/fetch')
479
- await initAdapterAuth(resolved, element.context)
480
- }
481
- return resolved
482
- }
483
-
484
- export function getQuery (format) {
485
- const element = this
486
- const useStateQuery = format || OPTIONS.useStateQuery || element.context?.useStateQuery
487
- if (!useStateQuery) return null
488
-
489
- const query = {}
490
- buildQueryFromElement(element, query)
491
-
492
- if (useStateQuery === true) return query
493
- const formatter = QUERY_FORMATTERS[useStateQuery]
494
- return formatter ? formatter(query) : query
495
- }
496
-
497
- const buildQueryFromElement = (element, query) => {
498
- const ref = element.__ref
499
- if (!ref) return
500
-
501
- const stateKey = ref.__state
502
- if (stateKey && typeof stateKey === 'string') {
503
- setQueryPath(query, stateKey)
504
- }
505
-
506
- const children = ref.__children
507
- if (children) {
508
- for (let i = 0; i < children.length; i++) {
509
- const child = element[children[i]]
510
- if (child && child.__ref) {
511
- buildQueryFromElement(child, query)
512
- }
513
- }
514
- }
515
-
516
- const contentKey = ref.contentElementKey || 'content'
517
- const content = element[contentKey]
518
- if (content && content.__ref) {
519
- buildQueryFromElement(content, query)
520
- }
521
- }
522
-
523
- const setQueryPath = (query, path) => {
524
- const clean = path.replaceAll('../', '').replaceAll('~/', '')
525
- const parts = clean.split('/')
526
- let current = query
527
- for (let i = 0; i < parts.length; i++) {
528
- const part = parts[i]
529
- if (i === parts.length - 1) {
530
- if (!current[part]) current[part] = true
531
- } else {
532
- if (current[part] === true) current[part] = {}
533
- if (!current[part]) current[part] = {}
534
- current = current[part]
535
- }
536
- }
537
- }
538
-
539
- // --- Query formatters ---
540
-
541
- const queryToGraphQL = (query, indent = 0) => {
542
- const pad = ' '.repeat(indent)
543
- const entries = Object.entries(query)
544
- if (!entries.length) return ''
545
- const fields = entries.map(([key, value]) => {
546
- if (value === true) return `${pad}${key}`
547
- return `${pad}${key} {\n${queryToGraphQL(value, indent + 1)}\n${pad}}`
548
- })
549
- return fields.join('\n')
550
- }
551
-
552
- const formatGraphQL = query => {
553
- return `{\n${queryToGraphQL(query, 1)}\n}`
554
- }
555
-
556
- const formatJsonApi = query => {
557
- const result = { fields: {}, include: [] }
558
- const walk = (obj, prefix) => {
559
- const fields = []
560
- for (const key in obj) {
561
- if (obj[key] === true) {
562
- fields.push(key)
563
- } else {
564
- const nested = prefix ? `${prefix}.${key}` : key
565
- result.include.push(nested)
566
- walk(obj[key], nested)
567
- }
568
- }
569
- if (fields.length) {
570
- result.fields[prefix || '_root'] = fields
571
- }
572
- }
573
- walk(query, '')
574
- return result
575
- }
576
-
577
- const formatOData = query => {
578
- const build = obj => {
579
- const select = []
580
- const expand = []
581
- for (const key in obj) {
582
- if (obj[key] === true) {
583
- select.push(key)
584
- } else {
585
- const nested = build(obj[key])
586
- const parts = []
587
- if (nested.select) parts.push(`$select=${nested.select}`)
588
- if (nested.expand) parts.push(`$expand=${nested.expand}`)
589
- expand.push(parts.length ? `${key}(${parts.join(';')})` : key)
590
- }
591
- }
592
- return {
593
- select: select.length ? select.join(',') : '',
594
- expand: expand.length ? expand.join(',') : ''
595
- }
596
- }
597
- const { select, expand } = build(query)
598
- const parts = []
599
- if (select) parts.push(`$select=${select}`)
600
- if (expand) parts.push(`$expand=${expand}`)
601
- return parts.join('&')
602
- }
603
-
604
- const formatSQL = (query, options) => {
605
- const columns = []
606
- const joins = []
607
- const tables = new Set()
608
-
609
- const walk = (obj, table, parentTable) => {
610
- tables.add(table)
611
- if (parentTable) {
612
- joins.push(
613
- `LEFT JOIN ${table} ON ${table}.${parentTable}_id = ${parentTable}.id`
614
- )
615
- }
616
- for (const key in obj) {
617
- if (obj[key] === true) {
618
- columns.push(`${table}.${key}`)
619
- } else {
620
- walk(obj[key], key, table)
621
- }
622
- }
623
- }
624
-
625
- const roots = Object.keys(query)
626
- if (roots.length === 1 && query[roots[0]] !== true) {
627
- walk(query[roots[0]], roots[0], null)
628
- } else {
629
- walk(query, '_root', null)
630
- }
631
-
632
- const from = [...tables][0] || '_root'
633
- const select = columns.length ? columns.join(', ') : '*'
634
- const joinStr = joins.length ? '\n' + joins.join('\n') : ''
635
- return `SELECT ${select}\nFROM ${from}${joinStr}`
636
- }
637
-
638
- const formatPaths = query => {
639
- const paths = []
640
- const walk = (obj, prefix) => {
641
- for (const key in obj) {
642
- const path = prefix ? `${prefix}/${key}` : key
643
- if (obj[key] === true) {
644
- paths.push(path)
645
- } else {
646
- walk(obj[key], path)
647
- }
648
- }
649
- }
650
- walk(query, '')
651
- return paths
652
- }
653
-
654
- const formatSupabase = query => {
655
- const build = obj => {
656
- const parts = []
657
- for (const key in obj) {
658
- if (obj[key] === true) {
659
- parts.push(key)
660
- } else {
661
- parts.push(`${key}(${build(obj[key])})`)
662
- }
663
- }
664
- return parts.join(', ')
665
- }
666
- const roots = Object.keys(query)
667
- if (roots.length === 1 && query[roots[0]] !== true) {
668
- return { from: roots[0], select: build(query[roots[0]]) }
669
- }
670
- return { from: null, select: build(query) }
671
- }
672
-
673
- const QUERY_FORMATTERS = {
674
- graphql: formatGraphQL,
675
- 'json-api': formatJsonApi,
676
- odata: formatOData,
677
- sql: formatSQL,
678
- supabase: formatSupabase,
679
- paths: formatPaths
680
- }
681
-
682
- export function isMethod (param, element) {
683
- return Boolean(METHODS.has(param) || element?.context?.methods?.[param])
684
- }
package/node.js DELETED
@@ -1,37 +0,0 @@
1
- 'use strict'
2
-
3
- import { window } from './globals.js'
4
-
5
- export const isNode = obj => {
6
- return (
7
- (typeof Node === 'object'
8
- ? obj instanceof window.Node
9
- : obj &&
10
- typeof obj === 'object' &&
11
- typeof obj.nodeType === 'number' &&
12
- typeof obj.nodeName === 'string') || false
13
- )
14
- }
15
-
16
- // Returns true if it is a DOM element
17
- export const isHtmlElement = obj => {
18
- return (
19
- (typeof HTMLElement === 'object'
20
- ? obj instanceof window.HTMLElement // DOM2
21
- : obj &&
22
- typeof obj === 'object' &&
23
- obj !== null &&
24
- obj.nodeType === 1 &&
25
- typeof obj.nodeName === 'string') || false
26
- )
27
- }
28
-
29
- export const isDOMNode = obj => {
30
- return (
31
- typeof window !== 'undefined' &&
32
- ((window.Node && obj instanceof window.Node) ||
33
- (window.Window && obj instanceof window.Window) ||
34
- obj === window ||
35
- obj === document)
36
- )
37
- }