@edgedev/create-edge-app 1.1.25 → 1.1.27

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 (111) hide show
  1. package/README.md +55 -20
  2. package/{agent.md → agents.md} +2 -0
  3. package/bin/cli.js +6 -6
  4. package/edge/components/auth/login.vue +384 -0
  5. package/edge/components/auth/register.vue +396 -0
  6. package/edge/components/auth.vue +108 -0
  7. package/edge/components/autoFileUpload.vue +215 -0
  8. package/edge/components/billing.vue +8 -0
  9. package/edge/components/buttonDivider.vue +14 -0
  10. package/edge/components/chip.vue +34 -0
  11. package/edge/components/clipboardButton.vue +42 -0
  12. package/edge/components/cms/block.vue +529 -0
  13. package/edge/components/cms/blockApi.vue +212 -0
  14. package/edge/components/cms/blockEditor.vue +725 -0
  15. package/edge/components/cms/blockInput.vue +66 -0
  16. package/edge/components/cms/blockPicker.vue +486 -0
  17. package/edge/components/cms/blockRender.vue +78 -0
  18. package/edge/components/cms/blockSheetContent.vue +28 -0
  19. package/edge/components/cms/codeEditor.vue +466 -0
  20. package/edge/components/cms/fontUpload.vue +327 -0
  21. package/edge/components/cms/htmlContent.vue +807 -0
  22. package/edge/components/cms/init_blocks/api_with_subarrays.html +17 -0
  23. package/edge/components/cms/init_blocks/array_with_collection.html +7 -0
  24. package/edge/components/cms/init_blocks/array_with_objects.html +7 -0
  25. package/edge/components/cms/init_blocks/carousel.html +103 -0
  26. package/edge/components/cms/init_blocks/contact_us.html +69 -0
  27. package/edge/components/cms/init_blocks/content_with_left_image.html +27 -0
  28. package/edge/components/cms/init_blocks/footer.html +24 -0
  29. package/edge/components/cms/init_blocks/header_divider.html +7 -0
  30. package/edge/components/cms/init_blocks/hero.html +35 -0
  31. package/edge/components/cms/init_blocks/hero_carousel.html +52 -0
  32. package/edge/components/cms/init_blocks/newsletter.html +117 -0
  33. package/edge/components/cms/init_blocks/post_content.html +7 -0
  34. package/edge/components/cms/init_blocks/post_title_header.html +21 -0
  35. package/edge/components/cms/init_blocks/posts_list.html +20 -0
  36. package/edge/components/cms/init_blocks/properties_showcase.html +100 -0
  37. package/edge/components/cms/init_blocks/property_carousel.html +59 -0
  38. package/edge/components/cms/init_blocks/property_detail.html +112 -0
  39. package/edge/components/cms/init_blocks/property_detail_header.html +34 -0
  40. package/edge/components/cms/init_blocks/property_results.html +137 -0
  41. package/edge/components/cms/init_blocks/property_search.html +75 -0
  42. package/edge/components/cms/init_blocks/simple_array.html +7 -0
  43. package/edge/components/cms/mediaCard.vue +116 -0
  44. package/edge/components/cms/mediaManager.vue +386 -0
  45. package/edge/components/cms/menu.vue +1103 -0
  46. package/edge/components/cms/optionsSelect.vue +107 -0
  47. package/edge/components/cms/page.vue +1785 -0
  48. package/edge/components/cms/posts.vue +1083 -0
  49. package/edge/components/cms/site.vue +1475 -0
  50. package/edge/components/cms/themeDefaultMenu.vue +548 -0
  51. package/edge/components/cms/themeEditor.vue +429 -0
  52. package/edge/components/dashboard.vue +776 -0
  53. package/edge/components/editor.vue +671 -0
  54. package/edge/components/fileTree.vue +72 -0
  55. package/edge/components/files.vue +89 -0
  56. package/edge/components/formSubtypes/myOrgs.vue +214 -0
  57. package/edge/components/formSubtypes/users.vue +336 -0
  58. package/edge/components/functionChips.vue +57 -0
  59. package/edge/components/gError.vue +98 -0
  60. package/edge/components/gHelper.vue +67 -0
  61. package/edge/components/gInput.vue +1331 -0
  62. package/edge/components/loggingIn.vue +41 -0
  63. package/edge/components/menu.vue +137 -0
  64. package/edge/components/menuContent.vue +132 -0
  65. package/edge/components/myAccount.vue +317 -0
  66. package/edge/components/myOrganizations.vue +75 -0
  67. package/edge/components/myProfile.vue +122 -0
  68. package/edge/components/orgSwitcher.vue +25 -0
  69. package/edge/components/organizationMembers.vue +522 -0
  70. package/edge/components/organizationSettings.vue +271 -0
  71. package/edge/components/shad/breadcrumbs.vue +35 -0
  72. package/edge/components/shad/button.vue +43 -0
  73. package/edge/components/shad/checkbox.vue +73 -0
  74. package/edge/components/shad/combobox.vue +238 -0
  75. package/edge/components/shad/datepicker.vue +184 -0
  76. package/edge/components/shad/dialog.vue +32 -0
  77. package/edge/components/shad/dropdownMenu.vue +54 -0
  78. package/edge/components/shad/dropdownMenuItem.vue +21 -0
  79. package/edge/components/shad/form.vue +59 -0
  80. package/edge/components/shad/html.vue +877 -0
  81. package/edge/components/shad/input.vue +139 -0
  82. package/edge/components/shad/number.vue +109 -0
  83. package/edge/components/shad/select.vue +151 -0
  84. package/edge/components/shad/selectTags.vue +278 -0
  85. package/edge/components/shad/switch.vue +67 -0
  86. package/edge/components/shad/tags.vue +137 -0
  87. package/edge/components/shad/textarea.vue +102 -0
  88. package/edge/components/shad/typeMoney.vue +167 -0
  89. package/edge/components/sideBar.vue +288 -0
  90. package/edge/components/sideBarContent.vue +268 -0
  91. package/edge/components/sidebarProvider.vue +33 -0
  92. package/edge/components/tooltip.vue +16 -0
  93. package/edge/components/userMenu.vue +148 -0
  94. package/edge/components/v/alert.vue +59 -0
  95. package/edge/components/v/alertTitle.vue +18 -0
  96. package/edge/components/v/card.vue +53 -0
  97. package/edge/components/v/cardActions.vue +18 -0
  98. package/edge/components/v/cardText.vue +18 -0
  99. package/edge/components/v/cardTitle.vue +20 -0
  100. package/edge/components/v/col.vue +56 -0
  101. package/edge/components/v/list.vue +46 -0
  102. package/edge/components/v/listItem.vue +26 -0
  103. package/edge/components/v/listItemTitle.vue +18 -0
  104. package/edge/components/v/row.vue +42 -0
  105. package/edge/components/v/toolbar.vue +24 -0
  106. package/edge/composables/global.ts +519 -0
  107. package/edge-pull.sh +2 -0
  108. package/edge-push.sh +1 -0
  109. package/edge-status.sh +14 -0
  110. package/package.json +1 -1
  111. package/edge-components-install.sh +0 -1
@@ -0,0 +1,519 @@
1
+ // DO NOT EDIT
2
+
3
+ const route = useRoute()
4
+
5
+ const edgeState = reactive({
6
+ currentOrganization: '',
7
+ organizationDocPath: '',
8
+ organizations: [],
9
+ changeTracker: {},
10
+ user: null,
11
+ userRoles: [],
12
+ lastPaginatedDoc: null,
13
+ subscribedStatus: null,
14
+ showLeftPanel: {} as Record<string, boolean>,
15
+ menuItems: [],
16
+ isAdminCollections: [] as string[],
17
+ redirectRoute: '',
18
+ isEmulator: false,
19
+ blockEditorTheme: '',
20
+ blockEditorSite: '',
21
+ cmsPageWithUnsavedChanges: null,
22
+ devOverride: false,
23
+ })
24
+
25
+ const setOrganization = async (organization: string, edgeFirebase: any) => {
26
+ if (organization) {
27
+ edgeState.changeTracker = {}
28
+ localStorage.setItem('organizationID', organization)
29
+ edgeState.currentOrganization = organization
30
+ await edgeFirebase.startUsersSnapshot(`organizations/${organization}`)
31
+ edgeState.organizationDocPath = `organizations/${organization}`
32
+ if (import.meta.env.VITE_FIREBASE_EMULATOR_FIRESTORE) {
33
+ edgeState.isEmulator = true
34
+ }
35
+ }
36
+ }
37
+
38
+ const showLeftPanel = (show: boolean) => {
39
+ edgeState.showLeftPanel[route.path] = show
40
+ }
41
+
42
+ const getSubscribedStatus = (org: any) => {
43
+ let isSubscribed = true
44
+ let status = ''
45
+ let description = ''
46
+ let color = ''
47
+ let icon = ''
48
+
49
+ if (!org || !org.stripeSubscription) {
50
+ isSubscribed = false
51
+ status = 'Not Subscribed'
52
+ description = 'No subscription found.'
53
+ color = 'bg-red-900'
54
+ icon = 'AlertCircle'
55
+ }
56
+ else {
57
+ const subscription = org.stripeSubscription
58
+
59
+ if (!subscription || subscription === 'canceled') {
60
+ isSubscribed = false
61
+ status = 'Canceled'
62
+ description = 'The subscription has been canceled.'
63
+ color = 'bg-red-600'
64
+ icon = 'X'
65
+ }
66
+ else {
67
+ switch (subscription) {
68
+ case 'trialing':
69
+ status = 'Trial'
70
+ description = 'The subscription is currently in a trial period.'
71
+ color = 'bg-green-600'
72
+ icon = 'Check'
73
+ break
74
+ case 'active':
75
+ status = 'Active'
76
+ description = 'The subscription is in good standing.'
77
+ color = 'bg-green-600'
78
+ icon = 'Check'
79
+ break
80
+ case 'incomplete':
81
+ status = 'Incomplete'
82
+ description = 'A successful payment needs to be made within 23 hours to activate the subscription.'
83
+ color = 'bg-amber-500'
84
+ icon = 'Hourglass'
85
+ break
86
+ case 'incomplete_expired':
87
+ status = 'Incomplete Expired'
88
+ description = 'The initial payment on the subscription failed and no successful payment was made within 23 hours of creating the subscription.'
89
+ color = 'bg-red-600'
90
+ icon = 'AlertCircle'
91
+ break
92
+ case 'past_due':
93
+ status = 'Past Due'
94
+ description = 'Payment on the latest finalized invoice either failed or wasn’t attempted.'
95
+ color = 'bg-red-600'
96
+ icon = 'AlertCircle'
97
+ break
98
+ case 'unpaid':
99
+ status = 'Unpaid'
100
+ description = 'The latest invoice hasn’t been paid but the subscription remains in place.'
101
+ color = 'bg-red-600'
102
+ icon = 'AlertCircle'
103
+ break
104
+ case 'paused':
105
+ status = 'Paused'
106
+ description = 'The subscription has ended its trial period without a default payment method.'
107
+ color = 'bg-amber-500'
108
+ icon = 'PauseCircle'
109
+ break
110
+ default:
111
+ status = 'Unknown'
112
+ description = 'The subscription status is unknown.'
113
+ color = 'bg-red-600'
114
+ icon = 'AlertCircle'
115
+ break
116
+ }
117
+ }
118
+ }
119
+
120
+ return {
121
+ isSubscribed,
122
+ status,
123
+ description,
124
+ color,
125
+ icon,
126
+ }
127
+ }
128
+
129
+ const isDarkMode = () => {
130
+ if (window.matchMedia) {
131
+ const darkMode = window.matchMedia('(prefers-color-scheme: dark)')
132
+ return darkMode.matches
133
+ }
134
+ return false
135
+ }
136
+
137
+ const generateShortId = () => {
138
+ return Math.random().toString(36).substr(2, 6)
139
+ }
140
+
141
+ const objHas = (obj: any, key: string): boolean => {
142
+ if (obj === null || obj === undefined) {
143
+ return false
144
+ }
145
+ return Object.prototype.hasOwnProperty.call(obj, key)
146
+ }
147
+
148
+ const getOrganizations = async (edgeFirebase: any) => {
149
+ console.log('getOrganizations')
150
+ const orgs: any = []
151
+ if (edgeFirebase.user.loggedIn) {
152
+ for (const role of edgeFirebase.user.roles) {
153
+ const segments = role.collectionPath.split('-')
154
+ if (segments[0] === 'organizations') {
155
+ await edgeFirebase.startDocumentSnapshot('organizations', segments[1])
156
+ let org = await edgeFirebase.getDocData('organizations', segments[1])
157
+ if (!org?.name) {
158
+ org = { name: 'Organization', docId: segments[1] }
159
+ }
160
+ if (!orgs.some((o: { docId: string }) => o.docId === org.docId)) {
161
+ orgs.push(org)
162
+ }
163
+ }
164
+ }
165
+ }
166
+ edgeState.organizations = orgs
167
+ console.log('Organizations:', edgeState.organizations)
168
+ }
169
+
170
+ const dupObject = (obj: any): any => {
171
+ // console.log('Duplicating object:', obj)
172
+ return JSON.parse(JSON.stringify(obj))
173
+ }
174
+
175
+ const currentOrganizationObject = computed(() => {
176
+ const edgeFirebase: any = inject('edgeFirebase')
177
+ if (edgeState.organizations.length > 0) {
178
+ if (edgeState.currentOrganization && edgeFirebase?.data[`organizations/${edgeState.currentOrganization}`]) {
179
+ return edgeFirebase?.data[`organizations/${edgeState.currentOrganization}`]
180
+ }
181
+ }
182
+ return ''
183
+ })
184
+
185
+ const edgeRules = {
186
+ forms: (value: any) => {
187
+ if (!value.length) {
188
+ return 'You must setup at least one form.'
189
+ }
190
+ return true
191
+ },
192
+ submits: (value: any) => {
193
+ if (!value.length) {
194
+ return 'You must setup at least one submit.'
195
+ }
196
+ return true
197
+ },
198
+ gptFunctionName: (value: string) => {
199
+ const pattern = /^[a-zA-Z0-9_-]{1,64}$/
200
+ return pattern.test(value) || 'The function name must be 1-64 characters and can only contain letters, numbers, underscores, and dashes.'
201
+ },
202
+ endpoint: (value: string) => {
203
+ const urlPattern = /^https?:\/\/(?!:\/\/)([a-zA-Z0-9]+\.)?[a-zA-Z0-9][a-zA-Z0-9-]+(\.[a-zA-Z]{2,6})?(:\d{1,5})?(\/[^\s]*)?$/i
204
+ if (!urlPattern.test(value)) {
205
+ return `"${value}" is not a valid URL. The URL must include the protocol (http or https) and the path.`
206
+ }
207
+ return true
208
+ },
209
+ domains: (value: string) => {
210
+ const domainPattern = /^https?:\/\/(?!:\/\/)([a-zA-Z0-9]+\.)?[a-zA-Z0-9][a-zA-Z0-9-]+(\.[a-zA-Z]{2,6})?(:\d{1,5})?$/i
211
+ const localhostPattern = /^https?:\/\/localhost(:\d{1,5})?$/i
212
+ const ipAddressPattern = /^https?:\/\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d{1,5})?$/
213
+ const domains = value.split(',')
214
+ for (const domain of domains) {
215
+ if (
216
+ !domainPattern.test(domain)
217
+ && !localhostPattern.test(domain)
218
+ && !ipAddressPattern.test(domain)
219
+ ) {
220
+ return `"${domain}" is not a valid domain or IP address. The domain or IP address must include the protocol (http or https).`
221
+ }
222
+ }
223
+ return true
224
+ },
225
+ required: (value: any) => {
226
+ if (typeof value === 'string' && !value) {
227
+ return 'This field is required.'
228
+ }
229
+ else if (Array.isArray(value) && value.length === 0) {
230
+ return 'This field is required.'
231
+ }
232
+ else if (typeof value === 'object' && value !== null && Object.keys(value).length === 0) {
233
+ return 'This field is required.'
234
+ }
235
+ else if (typeof value === 'boolean' && !value) {
236
+ return 'This field is required.'
237
+ }
238
+ return true
239
+ },
240
+ email: (value: string) => {
241
+ const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
242
+ return pattern.test(value) || 'Invalid e-mail.'
243
+ },
244
+ emailOrField: (value: string) => {
245
+ const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
246
+ return pattern.test(value) || (value.startsWith('{{') && value.endsWith('}}')) || `Invalid e-mail or field. If you want to use a field, it must be wrapped in double curly braces, e.g. {{${value}}}`
247
+ },
248
+ toEmails: (value: string) => {
249
+ const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
250
+ const emails = value.split(',')
251
+ for (const email of emails) {
252
+ if (!pattern.test(email)) {
253
+ return `"${email}" is not a valid email address`
254
+ }
255
+ }
256
+ return true
257
+ },
258
+ emailsOrFields: (value: string) => {
259
+ const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
260
+ const emails = value.split(',')
261
+ for (const email of emails) {
262
+ if (!pattern.test(email) && !(email.startsWith('{{') && email.endsWith('}}'))) {
263
+ return `"${email}" is not a valid email address or field. If you want to use a field, it must be wrapped in double curly braces, e.g. {{${email}}}`
264
+ }
265
+ }
266
+ return true
267
+ },
268
+ password: (value: string) => {
269
+ const pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
270
+ return pattern.test(value) || 'Password must have at least 8 characters, including uppercase and lowercase letters, numbers, and a special character'
271
+ },
272
+ }
273
+
274
+ const edgeLogOut = async (edgeFirebase: any) => {
275
+ edgeState.currentOrganization = ''
276
+ edgeState.organizationDocPath = ''
277
+ edgeState.organizations = []
278
+ edgeState.changeTracker = {}
279
+ edgeState.user = null
280
+ nextTick(async () => {
281
+ await edgeFirebase.logOut()
282
+ window.location.reload()
283
+ })
284
+ }
285
+
286
+ const orgUserRoles = (orgId: string) => {
287
+ orgId = orgId.replaceAll('/', '-')
288
+ const orgPath = `organizations-${orgId}`
289
+ const newData = JSON.parse(JSON.stringify(edgeState.userRoles))
290
+
291
+ for (let i = 0; i < newData.length; i++) {
292
+ const roles = newData[i].roles
293
+ for (let j = 0; j < roles.length; j++) {
294
+ const role = roles[j]
295
+ role.collectionPath = role.collectionPath.replace(/organizationDocPath/g, orgPath)
296
+ }
297
+ }
298
+
299
+ return newData
300
+ }
301
+
302
+ interface UserRoleType {
303
+ name: string
304
+ roles: { collectionPath: string; role: string }[]
305
+ }
306
+
307
+ interface RoleType {
308
+ collectionPath: string
309
+ role: string
310
+ }
311
+
312
+ const getRoleName = (roles: RoleType[], orgId: string) => {
313
+ const userRoles: UserRoleType[] = orgUserRoles(orgId)
314
+ for (const user of userRoles) {
315
+ let match = true
316
+ for (const userRole of user.roles) {
317
+ if (!roles.some(role => role.collectionPath === userRole.collectionPath && role.role === userRole.role)) {
318
+ match = false
319
+ break
320
+ }
321
+ }
322
+ if (match) {
323
+ return user.name
324
+ }
325
+ }
326
+ return 'Unknown'
327
+ }
328
+
329
+ const isAdminGlobal = (edgeFirebase: any) => computed(() => {
330
+ const roleCompares = dupObject(edgeState.isAdminCollections)
331
+ roleCompares.push(`organizations-${edgeState.currentOrganization}`)
332
+ console.log('roles compare')
333
+ console.log(roleCompares)
334
+ for (const compare of roleCompares) {
335
+ const orgRole = edgeFirebase?.user?.roles.find((role: any) =>
336
+ role.collectionPath === compare.replaceAll('/', '-'),
337
+ )
338
+ if (orgRole && orgRole.role === 'admin') {
339
+ return true
340
+ }
341
+ }
342
+ return false
343
+ })
344
+
345
+ interface MenuItem {
346
+ to: string
347
+ icon?: string
348
+ submenu?: SubMenuItem[]
349
+ }
350
+
351
+ interface SubMenuItem {
352
+ to: string
353
+ icon?: string
354
+ }
355
+
356
+ interface BestMatch {
357
+ icon: string
358
+ len: number
359
+ }
360
+
361
+ const iconFromMenu = (route: { path: string }): string => {
362
+ const normalize = (p: string): string => {
363
+ if (!p)
364
+ return '/'
365
+ const cleaned = p.replace(/\/+$/, '')
366
+ return cleaned.length ? cleaned : '/'
367
+ }
368
+
369
+ const current = normalize(route.path)
370
+ let best: BestMatch = { icon: 'LayoutDashboard', len: -1 }
371
+
372
+ for (const item of (edgeState.menuItems || []) as MenuItem[]) {
373
+ const parentTo = normalize(item.to)
374
+
375
+ // 1) Exact submenu match first (wins even if sub.to === item.to)
376
+ if (Array.isArray(item.submenu)) {
377
+ for (const sub of item.submenu) {
378
+ const subTo = normalize(sub.to)
379
+ if (subTo === current) {
380
+ return sub.icon || item.icon || 'LayoutDashboard'
381
+ }
382
+ // Track most specific submenu prefix match
383
+ if (current.startsWith(subTo) && subTo.length > best.len) {
384
+ best = { icon: sub.icon || item.icon || 'LayoutDashboard', len: subTo.length }
385
+ }
386
+ }
387
+ }
388
+
389
+ // 2) Exact parent match (only if no exact submenu already returned)
390
+ if (parentTo === current) {
391
+ return item.icon || 'LayoutDashboard'
392
+ }
393
+
394
+ // 3) Track most specific parent prefix match
395
+ if (current.startsWith(parentTo) && parentTo.length > best.len) {
396
+ best = { icon: item.icon || 'LayoutDashboard', len: parentTo.length }
397
+ }
398
+ }
399
+
400
+ // 4) Fallback
401
+ return best.icon
402
+ }
403
+ const toBool = (v: any): boolean => v === true || v === 'true' || v === 1 || v === '1'
404
+ const DEV_OVERRIDE_KEY = 'edgeDevOverride'
405
+
406
+ const devOverrideEnabled = (): boolean => {
407
+ if (edgeState.devOverride)
408
+ return true
409
+ if (typeof window === 'undefined')
410
+ return edgeState.devOverride
411
+ try {
412
+ return localStorage.getItem(DEV_OVERRIDE_KEY) === '1'
413
+ }
414
+ catch (error) {
415
+ console.warn('dev override read failed', error)
416
+ return false
417
+ }
418
+ }
419
+
420
+ const syncDevOverride = () => {
421
+ if (typeof window === 'undefined')
422
+ return
423
+ edgeState.devOverride = devOverrideEnabled()
424
+ }
425
+
426
+ const allowMenuItem = (item: any, isAdmin: boolean) => {
427
+ // const config = useRuntimeConfig()
428
+ const isDev = process.dev || devOverrideEnabled()
429
+ const adminOnly = toBool(item.adminOnly)
430
+ const devOnly = toBool(item.devOnly)
431
+ console.log('allowMenuItem', { item, isAdmin, isDev, adminOnly, devOnly })
432
+ const override = toBool(item.override)
433
+ if (item.override !== undefined)
434
+ return override
435
+ if (adminOnly && !isAdmin)
436
+ return false
437
+ if (devOnly && !isDev)
438
+ return false
439
+ return true
440
+ }
441
+
442
+ const cmsCollectionData = async (edgeFirebase: any, value: any, meta: any, currentSite: any = '') => {
443
+ for (const key in meta) {
444
+ if (meta[key]?.collection) {
445
+ const staticSearch = new edgeFirebase.SearchStaticData()
446
+
447
+ const currentQuery = meta[key].collection.query || []
448
+ for (const queryKey in meta[key].queryItems || {}) {
449
+ console.log('key', queryKey)
450
+ if (meta[key].queryItems[queryKey]) {
451
+ const findIndex = currentQuery.findIndex((q: any) => q.field === queryKey)
452
+ const queryOption = meta[key]?.queryOptions?.find((o: any) => o.field === queryKey)
453
+ const operator = queryOption?.operator || '=='
454
+ const newQuery = { field: queryKey, operator, value: meta[key].queryItems[queryKey] }
455
+ if (findIndex > -1) {
456
+ currentQuery[findIndex] = newQuery
457
+ }
458
+ else {
459
+ currentQuery.push(newQuery)
460
+ }
461
+ }
462
+ else {
463
+ const findIndex = currentQuery.findIndex((q: any) => q.field === queryKey)
464
+ if (findIndex > -1) {
465
+ currentQuery.splice(findIndex, 1)
466
+ }
467
+ }
468
+ }
469
+ let collectionPath = `${edgeState.organizationDocPath}/${meta[key].collection.path}`
470
+ if (meta[key].collection.path === 'posts' || meta[key].collection.path === 'post') {
471
+ collectionPath = `${edgeState.organizationDocPath}/sites/${currentSite}/published_posts`
472
+ }
473
+ await staticSearch.getData(collectionPath, currentQuery, meta[key].collection.order, meta[key].limit)
474
+
475
+ value[key] = Object.values(staticSearch.results.data)
476
+ }
477
+ }
478
+ return value
479
+ }
480
+
481
+ const getImage = (file: any, type: string) => {
482
+ const variants = Array.isArray(file?.cloudflareImageVariants)
483
+ ? file.cloudflareImageVariants.filter((variant: any) => typeof variant === 'string' && variant.length)
484
+ : []
485
+ if (variants.length) {
486
+ const normalizedType = (type || '').trim().toLowerCase()
487
+ if (normalizedType) {
488
+ const match = variants.find((variant: string) => variant.toLowerCase().endsWith(`/${normalizedType}`))
489
+ if (match) {
490
+ return match
491
+ }
492
+ }
493
+ return variants[0]
494
+ }
495
+ return file?.r2Url || ''
496
+ }
497
+
498
+ export const edgeGlobal = {
499
+ edgeState,
500
+ setOrganization,
501
+ showLeftPanel,
502
+ getSubscribedStatus,
503
+ isDarkMode,
504
+ generateShortId,
505
+ objHas,
506
+ getOrganizations,
507
+ dupObject,
508
+ currentOrganizationObject,
509
+ edgeRules,
510
+ edgeLogOut,
511
+ orgUserRoles,
512
+ getRoleName,
513
+ isAdminGlobal,
514
+ iconFromMenu,
515
+ cmsCollectionData,
516
+ allowMenuItem,
517
+ syncDevOverride,
518
+ getImage,
519
+ }
package/edge-pull.sh ADDED
@@ -0,0 +1,2 @@
1
+ git fetch edge-vue-components
2
+ git subtree pull --prefix=edge edge-vue-components main --squash
package/edge-push.sh ADDED
@@ -0,0 +1 @@
1
+ git subtree push --prefix=edge edge-vue-components main
package/edge-status.sh ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ git fetch edge-vue-components >/dev/null 2>&1
5
+
6
+ UP_TREE="$(git rev-parse edge-vue-components/main^{tree})"
7
+ LOCAL_TREE="$(git rev-parse HEAD:edge)"
8
+
9
+ if [ "$UP_TREE" = "$LOCAL_TREE" ]
10
+ then
11
+ echo "edge is in sync with edge-vue-components/main"
12
+ else
13
+ echo "edge differs from edge-vue-components/main"
14
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/create-edge-app",
3
- "version": "1.1.25",
3
+ "version": "1.1.27",
4
4
  "description": "Create Edge Starter App",
5
5
  "bin": {
6
6
  "create-edge-app": "./bin/cli.js"
@@ -1 +0,0 @@
1
- git clone https://github.com/Edge-Marketing-and-Design/edge-vue-components.git edge