@owdproject/core 3.1.3 → 3.1.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 (50) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +6 -7
  3. package/bin/owd.js +14 -14
  4. package/index.ts +5 -2
  5. package/module.ts +78 -61
  6. package/package.json +19 -17
  7. package/project.json +4 -0
  8. package/runtime/components/Core/Application/CoreApplicationRender.vue +6 -5
  9. package/runtime/components/Core/Application/CoreApplicationWindowsRender.vue +8 -8
  10. package/runtime/components/Core/Background/CoreBackground.vue +1 -1
  11. package/runtime/components/Core/Desktop/CoreDesktop.vue +31 -24
  12. package/runtime/components/Core/Explorer/CoreExplorerFile.vue +47 -38
  13. package/runtime/components/Core/Explorer/CoreExplorerFolder.vue +0 -1
  14. package/runtime/components/Core/Time/CoreTime.vue +10 -7
  15. package/runtime/components/Core/Window/CoreWindow.vue +49 -35
  16. package/runtime/components/Core/Window/CoreWindowContent.vue +3 -5
  17. package/runtime/components/Core/Window/CoreWindowNav.vue +12 -7
  18. package/runtime/composables/useApplicationEntries.ts +51 -0
  19. package/runtime/composables/useApplicationManager.ts +278 -5
  20. package/runtime/composables/useDesktopManager.ts +22 -4
  21. package/runtime/composables/useTerminalManager.ts +63 -4
  22. package/runtime/core/controllers/ApplicationController.ts +203 -192
  23. package/runtime/core/controllers/WindowController.ts +342 -334
  24. package/runtime/plugins/resize.client.ts +4 -4
  25. package/runtime/stores/storeApplication.ts +236 -0
  26. package/runtime/stores/storeApplicationMeta.ts +12 -8
  27. package/runtime/stores/storeApplicationWindows.ts +16 -12
  28. package/runtime/stores/storeDesktop.ts +35 -29
  29. package/runtime/stores/storeDesktopDefaultApps.ts +53 -0
  30. package/runtime/stores/storeDesktopVolume.ts +12 -12
  31. package/runtime/stores/storeDesktopWindow.ts +13 -13
  32. package/runtime/stores/storeDesktopWorkspace.ts +35 -31
  33. package/runtime/utils/utilApp.ts +27 -22
  34. package/runtime/utils/utilCommon.ts +43 -43
  35. package/runtime/utils/utilDebug.ts +17 -17
  36. package/runtime/utils/utilDesktop.ts +4 -4
  37. package/runtime/utils/utilTerminal.ts +6 -5
  38. package/runtime/utils/utilWindow.ts +11 -11
  39. package/test/fixtures/basic/app.vue +1 -2
  40. package/test/fixtures/basic/nuxt.config.ts +1 -3
  41. package/tsconfig.app.json +1 -1
  42. package/tsconfig.json +1 -1
  43. package/types/index.d.ts +235 -207
  44. package/vitest.config.ts +3 -3
  45. package/eslint.config.mjs +0 -30
  46. package/runtime/composables/useAppEntries.ts +0 -36
  47. package/runtime/composables/useClipboardFs.ts +0 -25
  48. package/runtime/core/managers/ApplicationManager.ts +0 -237
  49. package/runtime/core/managers/DesktopManager.ts +0 -37
  50. package/runtime/core/managers/TerminalManager.ts +0 -44
package/types/index.d.ts CHANGED
@@ -1,283 +1,307 @@
1
- import type { Nuxt } from '@nuxt/schema';
2
- import { useApplicationManager } from '../runtime/composables/useApplicationManager';
1
+ import type { Nuxt } from '@nuxt/schema'
2
+ import { useApplicationManager } from '../runtime/composables/useApplicationManager'
3
3
 
4
4
  declare module 'nuxt/schema' {
5
5
  interface PublicRuntimeConfig {
6
6
  owd: {
7
7
  tailwindPaths: []
8
- };
8
+ }
9
9
  }
10
10
  }
11
11
 
12
12
  interface IApplicationManager {
13
- apps: Map<string, IApplicationController>
13
+ apps: Map<string, IApplicationController>
14
14
 
15
- get appsEntries(): Reactive<ApplicationEntry[]>
15
+ get appsEntries(): Reactive<ApplicationEntry[]>
16
16
 
17
- get appsRunning(): Reactive<IApplicationController[]>
17
+ get appsRunning(): Reactive<IApplicationController[]>
18
18
 
19
- get windowsOpened(): Reactive<IWindowController[]>
19
+ get windowsOpened(): Reactive<IWindowController[]>
20
20
 
21
- get appCategories(): string[]
21
+ get appCategories(): string[]
22
22
 
23
- get appsByCategory(): { [category: string]: IApplicationController[] }
23
+ get appsByCategory(): { [category: string]: IApplicationController[] }
24
24
 
25
- defineApp(id: string, config: ApplicationConfig): Promise<IApplicationController>
25
+ defineApp(
26
+ id: string,
27
+ config: ApplicationConfig,
28
+ ): Promise<IApplicationController>
26
29
 
27
- closeApp(id: string): void
30
+ closeApp(id: string): void
28
31
 
29
- launchAppEntry(id: string, entry: string): Promise<IApplicationController | undefined | void>
30
- execAppCommand(id: string, command: string, meta: undefined | any): Promise<CommandOutput | void>
32
+ launchAppEntry(
33
+ id: string,
34
+ entry: string,
35
+ ): Promise<IApplicationController | undefined | void>
36
+ execAppCommand(
37
+ id: string,
38
+ command: string,
39
+ meta: undefined | any,
40
+ ): Promise<CommandOutput | void>
31
41
 
32
- isAppDefined(id: string): boolean
42
+ isAppDefined(id: string): boolean
33
43
 
34
- isAppRunning(id: string): boolean
44
+ isAppRunning(id: string): boolean
35
45
  }
36
46
 
37
- type ApplicationCommand = (app: IApplicationController, args: any) => void;
47
+ type ApplicationCommand = (app: IApplicationController, args: any) => void
38
48
 
39
49
  interface ApplicationConfig {
40
- id: string
41
- title: string
42
- icon?: string
43
- category?: string
44
- version?: string
45
- description?: string
46
- provides?: ApplicationConfigProvide
47
- singleton?: boolean
48
- meta?: IApplicationMeta
49
- permissions?: ApplicationPermission[];
50
- windows?: { [key: string]: WindowConfig }
51
- entries: { [key: string]: ApplicationEntry }
52
- commands?: { [key: string]: ApplicationCommand }
53
-
54
- onReady?(app: IApplicationController): void | Promise<void>
55
-
56
- onLaunch?(app: IApplicationController): void | Promise<void>
57
-
58
- onRestore?(app: IApplicationController): void | Promise<void>
59
-
60
- onClose?(app: IApplicationController): void | Promise<void>
50
+ id: string
51
+ title: string
52
+ icon?: string
53
+ category?: string
54
+ version?: string
55
+ description?: string
56
+ provides?: ApplicationConfigProvide
57
+ singleton?: boolean
58
+ meta?: IApplicationMeta
59
+ permissions?: ApplicationPermission[]
60
+ windows?: { [key: string]: WindowConfig }
61
+ entries: { [key: string]: ApplicationEntry }
62
+ commands?: { [key: string]: ApplicationCommand }
63
+
64
+ onReady?(app: IApplicationController): void | Promise<void>
65
+
66
+ onLaunch?(app: IApplicationController): void | Promise<void>
67
+
68
+ onRestore?(app: IApplicationController): void | Promise<void>
69
+
70
+ onClose?(app: IApplicationController): void | Promise<void>
61
71
  }
62
72
 
63
73
  interface ApplicationConfigProvide {
64
- name: string
65
- entry: string
74
+ name: string
75
+ command: string
66
76
  }
67
77
 
68
78
  type IApplicationMeta = { [key: string]: any }
69
79
 
70
80
  interface IApplicationController {
71
- id: string
72
- config: ApplicationConfig
81
+ id: string
82
+ config: ApplicationConfig
73
83
 
74
- get meta(): { [key: string]: any }
84
+ get meta(): { [key: string]: any }
75
85
 
76
- store: Pinia
77
- windows: Reactive<Map<string, IWindowController>>
86
+ store: Pinia
87
+ windows: Reactive<Map<string, IWindowController>>
78
88
 
79
- isRunning: boolean
89
+ isRunning: boolean
80
90
 
81
- setRunning(value: boolean): void
91
+ setRunning(value: boolean): void
82
92
 
83
- initApplication(): Promise<void>
93
+ initApplication(): Promise<void>
84
94
 
85
- restoreApplication(): Promise<boolean>
95
+ restoreApplication(): Promise<boolean>
86
96
 
87
- getWindowsByModel(model: string): IWindowController[]
97
+ getWindowsByModel(model: string): IWindowController[]
88
98
 
89
- getFirstWindowByModel(model: string): IWindowController | undefined
99
+ getFirstWindowByModel(model: string): IWindowController | undefined
90
100
 
91
- openWindow(model: string, windowStoredState?: WindowStoredState, options?: {
92
- isRestoring?: boolean
93
- })
101
+ openWindow(
102
+ model: string,
103
+ windowStoredState?: WindowStoredState,
104
+ options?: {
105
+ isRestoring?: boolean
106
+ },
107
+ )
94
108
 
95
- closeWindow(windowId: string): void
109
+ closeWindow(windowId: string): void
96
110
 
97
- closeAllWindows(): void
111
+ closeAllWindows(): void
98
112
 
99
- execCommand(command: string): Promise<CommandOutput | void>
113
+ execCommand(command: string): Promise<CommandOutput | void>
100
114
 
101
- // deprecated
102
- get windowsOpened(): Reactive<Map<string, IWindowController>>
115
+ // deprecated
116
+ get windowsOpened(): Reactive<Map<string, IWindowController>>
103
117
  }
104
118
 
105
119
  interface IWindowController {
106
- application: IApplicationController
107
- instanced: boolean
108
- model: string
120
+ application: IApplicationController
121
+ instanced: boolean
122
+ model: string
109
123
 
110
- config: WindowConfig
111
- override: WindowOverride
124
+ config: WindowConfig
125
+ override: WindowOverride
112
126
 
113
- get state(): WindowState
127
+ get state(): WindowState
114
128
 
115
- // common
116
- get title(): string
129
+ // common
130
+ get title(): string
117
131
 
118
- get icon(): string | undefined
132
+ get icon(): string | undefined
119
133
 
120
- // sizes
121
- get size(): WindowSize
134
+ // sizes
135
+ get size(): WindowSize
122
136
 
123
- // minimize
124
- get isMinimizable(): boolean
137
+ // minimize
138
+ get isMinimizable(): boolean
125
139
 
126
- // maximize
127
- get isMaximizable(): boolean
140
+ // maximize
141
+ get isMaximizable(): boolean
128
142
 
129
- get isMaximized(): boolean
143
+ get isMaximized(): boolean
130
144
 
131
- // destroy
132
- get isDestroyable(): boolean
145
+ // destroy
146
+ get isDestroyable(): boolean
133
147
 
134
- // draggable
135
- get isDraggable(): boolean
148
+ // draggable
149
+ get isDraggable(): boolean
136
150
 
137
- // resizable
138
- get isResizable(): boolean
151
+ // resizable
152
+ get isResizable(): boolean
139
153
 
140
- get actions(): {
141
- // position
142
- setActive(value: boolean)
143
- setFocus(value: boolean)
144
- bringToFront()
145
- setPosition(data: WindowPosition)
154
+ get actions(): {
155
+ // position
156
+ setActive(value: boolean)
157
+ setFocus(value: boolean)
158
+ bringToFront()
159
+ setPosition(data: WindowPosition)
146
160
 
147
- // size
148
- setSize(data: WindowSize)
161
+ // size
162
+ setSize(data: WindowSize)
149
163
 
150
- // minimize
151
- minimize(): boolean
164
+ // minimize
165
+ minimize(): boolean
152
166
 
153
- // maximize
154
- toggleMaximize(): boolean
155
- maximize(): boolean
156
- unmaximize(): boolean
167
+ // maximize
168
+ toggleMaximize(): boolean
169
+ maximize(): boolean
170
+ unmaximize(): boolean
157
171
 
158
- // destroy
159
- destroy(): boolean
172
+ // destroy
173
+ destroy(): boolean
160
174
 
161
- // workspace
162
- setWorkspace(workspaceId: string)
175
+ // workspace
176
+ setWorkspace(workspaceId: string)
163
177
 
164
- // override
165
- setTitleOverride(title: string | undefined): void
166
- resetTitleOverride(): void
167
- }
178
+ // override
179
+ setTitleOverride(title: string | undefined): void
180
+ resetTitleOverride(): void
181
+ }
168
182
  }
169
183
 
170
184
  interface WindowContent {
171
- padded?: boolean
172
- centered?: boolean
185
+ padded?: boolean
186
+ centered?: boolean
173
187
  }
174
188
 
175
189
  interface WindowConfig {
176
- title?: string
177
- category?: string
178
- icon?: string
179
-
180
- component?: Raw<Component>
181
-
182
- // position
183
- position?: WindowPosition
184
-
185
- // sizes
186
- size: WindowSize
187
-
188
- // minimize
189
- minimizable?: boolean
190
-
191
- // maximize
192
- maximized?: boolean
193
- maximizable?: boolean
194
-
195
- // destroy
196
- destroyable?: boolean
197
-
198
- // draggable
199
- draggable?: boolean
200
-
201
- // draggable
202
- resizable?: boolean
203
-
204
- overridable?: Partial<Record<'position' | 'size' | 'maximized' | 'draggable' | 'resizable' | 'destroyable' | 'minimizable', boolean>>
190
+ title?: string
191
+ category?: string
192
+ icon?: string
193
+
194
+ component?: Raw<Component>
195
+
196
+ // position
197
+ position?: WindowPosition
198
+
199
+ // sizes
200
+ size: WindowSize
201
+
202
+ // minimize
203
+ minimizable?: boolean
204
+
205
+ // maximize
206
+ maximized?: boolean
207
+ maximizable?: boolean
208
+
209
+ // destroy
210
+ destroyable?: boolean
211
+
212
+ // draggable
213
+ draggable?: boolean
214
+
215
+ // draggable
216
+ resizable?: boolean
217
+
218
+ overridable?: Partial<
219
+ Record<
220
+ | 'position'
221
+ | 'size'
222
+ | 'maximized'
223
+ | 'draggable'
224
+ | 'resizable'
225
+ | 'destroyable'
226
+ | 'minimizable',
227
+ boolean
228
+ >
229
+ >
205
230
  }
206
231
 
207
232
  interface WindowStoredState {
208
- model: string,
209
- state: WindowState
210
- meta: any
233
+ model: string
234
+ state: WindowState
235
+ meta: any
211
236
  }
212
237
 
213
238
  interface WindowOverride {
214
- title?: undefined | string
215
- icon?: undefined | string
239
+ title?: undefined | string
240
+ icon?: undefined | string
216
241
  }
217
242
 
218
243
  interface WindowState {
219
- id: string
220
- createdAt: number
244
+ id: string
245
+ createdAt: number
221
246
 
222
- category?: string
223
- workspace: string
247
+ category?: string
248
+ workspace: string
224
249
 
225
- // position
226
- position?: WindowPosition
250
+ // position
251
+ position?: WindowPosition
227
252
 
228
- // sizes
229
- size?: WindowSize
253
+ // sizes
254
+ size?: WindowSize
230
255
 
231
- // focused
232
- focused: boolean
256
+ // focused
257
+ focused: boolean
233
258
 
234
- // minimize
235
- active?: boolean
236
- minimizable?: boolean
259
+ // minimize
260
+ active?: boolean
261
+ minimizable?: boolean
237
262
 
238
- // maximize
239
- maximized?: boolean
240
- maximizable?: boolean
263
+ // maximize
264
+ maximized?: boolean
265
+ maximizable?: boolean
241
266
 
242
- // destroy
243
- destroyable?: boolean
267
+ // destroy
268
+ destroyable?: boolean
244
269
 
245
- // draggable
246
- draggable?: boolean
270
+ // draggable
271
+ draggable?: boolean
247
272
 
248
- // draggable
249
- resizable?: boolean
273
+ // draggable
274
+ resizable?: boolean
250
275
  }
251
276
 
252
277
  interface WindowSize {
253
- width?: WindowSizeValue
254
- height?: WindowSizeValue
255
- minWidth?: WindowSizeValue
256
- minHeight?: WindowSizeValue
257
- maxWidth?: WindowSizeValue
258
- maxHeight?: WindowSizeValue
278
+ width?: WindowSizeValue
279
+ height?: WindowSizeValue
280
+ minWidth?: WindowSizeValue
281
+ minHeight?: WindowSizeValue
282
+ maxWidth?: WindowSizeValue
283
+ maxHeight?: WindowSizeValue
259
284
  }
260
285
 
261
286
  interface WindowPosition {
262
- x?: number
263
- y?: number
264
- z?: number
287
+ x?: number
288
+ y?: number
289
+ z?: number
265
290
  }
266
291
 
267
292
  type WindowSizeValue = number | string | undefined
268
293
 
269
294
  interface ApplicationEntry {
270
- title?: string
271
- icon?: string
272
- category?: string
273
- visibility?: ApplicationEntryVisibility
274
- command: string | any
295
+ title?: string
296
+ icon?: string
297
+ category?: string
298
+ visibility?: ApplicationEntryVisibility
299
+ command: string | any
275
300
  }
276
301
 
277
-
278
302
  interface ApplicationEntryWithInherited extends ApplicationEntry {
279
- application: IApplicationController
280
- visibility: ApplicationEntryVisibility
303
+ application: IApplicationController
304
+ visibility: ApplicationEntryVisibility
281
305
  }
282
306
 
283
307
  type ApplicationEntryVisibility = 'primary' | 'secondary' | 'hidden'
@@ -285,75 +309,79 @@ type ApplicationEntryVisibility = 'primary' | 'secondary' | 'hidden'
285
309
  // DESKTOP
286
310
 
287
311
  interface IDesktopManager {
288
- defaultApps: DefaultAppsConfig
312
+ defaultApps: DefaultAppsConfig
289
313
 
290
- getDefaultApp(feature: string)
314
+ getDefaultApp(feature: string)
291
315
 
292
- setDefaultApp(feature: string, application: IApplicationController, entry: ApplicationEntry)
316
+ setDefaultApp(
317
+ feature: string,
318
+ application: IApplicationController,
319
+ command: ApplicationCommand,
320
+ )
293
321
  }
294
322
 
295
323
  interface DesktopConfig {
296
- theme?: string
297
- modules?: string[]
298
- apps?: string[]
324
+ theme?: string
325
+ modules?: string[]
326
+ apps?: string[]
299
327
 
300
- name?: string
301
- defaultApps?: DefaultAppsConfig
302
- features?: string[]
328
+ name?: stringThis
329
+ defaultApps?: DefaultAppsConfig
330
+ features?: string[]
303
331
 
304
- systemBar?: DesktopSystemBarConfig
305
- dockBar?: DesktopDockBarConfig
306
- workspaces?: DesktopWorkspacesConfig
332
+ systemBar?: DesktopSystemBarConfig
333
+ dockBar?: DesktopDockBarConfig
334
+ workspaces?: DesktopWorkspacesConfig
307
335
  }
308
336
 
309
337
  interface DesktopWindowsConfig {
310
- position: 'relative' | 'absolute' | 'fixed'
338
+ position: 'relative' | 'absolute' | 'fixed'
311
339
  }
312
340
 
313
341
  interface DesktopDockBarConfig {
314
- enabled?: boolean
315
- position?: 'top' | 'bottom'
342
+ enabled?: boolean
343
+ position?: 'top' | 'bottom'
316
344
  }
317
345
 
318
346
  interface DesktopSystemBarConfig {
319
- enabled?: boolean
320
- position?: 'top' | 'bottom'
321
- startButton?: boolean
347
+ enabled?: boolean
348
+ position?: 'top' | 'bottom'
349
+ startButton?: boolean
322
350
  }
323
351
 
324
352
  interface DesktopWorkspacesConfig {
325
- enabled?: boolean
353
+ enabled?: boolean
326
354
  }
327
355
 
328
356
  // TERMINAL
329
357
 
330
358
  type TerminalCommand = {
331
- name: string
332
- applicationId: string
359
+ name: string
360
+ applicationId: string
333
361
  }
334
362
 
335
363
  interface CommandOutput {
336
- text: string
337
- isError?: boolean
364
+ text: string
365
+ isError?: boolean
338
366
  }
339
367
 
340
368
  // DEFAULT APP
341
369
 
342
370
  interface DefaultAppsConfig {
343
- terminal?: DefaultAppConfig
344
- browser?: DefaultAppConfig
345
- editor?: DefaultAppConfig
371
+ terminal?: DefaultAppConfig
372
+ browser?: DefaultAppConfig
373
+ editor?: DefaultAppConfig
346
374
 
347
- [key: string]: DefaultAppConfig
375
+ [key: string]: DefaultAppConfig
348
376
  }
349
377
 
350
378
  interface DefaultAppConfig {
351
- application: IApplicationController
352
- entry: ApplicationEntry
379
+ application: IApplicationController
380
+ entry: ApplicationEntry
353
381
  }
354
382
 
355
383
  export function defineDesktopApp(config: ApplicationConfig)
356
384
  export function defineDesktopConfig(config: DesktopConfig)
357
- export function registerTailwindPath(nuxt: Nuxt, path: string): void;
385
+ export function registerTailwindPath(nuxt: Nuxt, path: string): void
358
386
 
359
387
  export {}
package/vitest.config.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types='vitest' />
2
- import { defineConfig } from 'vite';
3
- import vue from '@vitejs/plugin-vue';
2
+ import { defineConfig } from 'vite'
3
+ import vue from '@vitejs/plugin-vue'
4
4
 
5
5
  export default defineConfig(() => ({
6
6
  root: __dirname,
@@ -21,4 +21,4 @@ export default defineConfig(() => ({
21
21
  provider: 'v8' as const,
22
22
  },
23
23
  },
24
- }));
24
+ }))
package/eslint.config.mjs DELETED
@@ -1,30 +0,0 @@
1
- import { FlatCompat } from '@eslint/eslintrc';
2
- import { dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import js from '@eslint/js';
5
- import baseConfig from '../../eslint.config.mjs';
6
- const compat = new FlatCompat({
7
- baseDirectory: dirname(fileURLToPath(import.meta.url)),
8
- recommendedConfig: js.configs.recommended,
9
- });
10
-
11
- export default [
12
- ...baseConfig,
13
- {
14
- files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx', '**/*.vue'],
15
- // Override or add rules here
16
- rules: {},
17
- },
18
- //...compat.extends('@nuxt/eslint-config'),
19
- {
20
- files: ['**/*.vue'],
21
- languageOptions: {
22
- parserOptions: {
23
- parser: await import('@typescript-eslint/parser'),
24
- },
25
- },
26
- },
27
- {
28
- ignores: ['.nuxt/**', '.output/**', 'node_modules'],
29
- },
30
- ];
@@ -1,36 +0,0 @@
1
- import {useApplicationManager} from './useApplicationManager'
2
- import {computed} from "@vue/reactivity"
3
-
4
- type SortBy = 'title' | 'category' | ((a: ApplicationEntryWithInherited, b: ApplicationEntryWithInherited) => number)
5
- type Visibility = 'primary' | 'all' | ((entry: ApplicationEntryWithInherited) => boolean)
6
-
7
- export function useAppEntries() {
8
- const applicationManager = useApplicationManager()
9
-
10
- const sortedAppEntries = function(
11
- sortBy: SortBy = 'title',
12
- visibility: Visibility = 'primary'
13
- ): Ref<ApplicationEntryWithInherited[]> {
14
- return computed(() => {
15
- const currentEntries = [...applicationManager.appsEntries]
16
-
17
- // filtering
18
- const filtered = typeof visibility === 'function'
19
- ? currentEntries.filter(visibility)
20
- : visibility === 'primary'
21
- ? currentEntries.filter(e => e.visibility !== 'secondary')
22
- : currentEntries
23
-
24
- // sorting
25
- const sorted = typeof sortBy === 'function'
26
- ? filtered.sort(sortBy)
27
- : sortBy === 'title'
28
- ? filtered.sort((a, b) => (a.title || '').localeCompare(b.title || ''))
29
- : filtered.sort((a, b) => (a.category || '').localeCompare(b.category || ''))
30
-
31
- return sorted
32
- })
33
- }
34
-
35
- return { sortedAppEntries }
36
- }