@conduction/nextcloud-vue 0.1.0-beta.1
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.
- package/dist/nextcloud-vue.cjs.js +10710 -0
- package/dist/nextcloud-vue.cjs.js.map +1 -0
- package/dist/nextcloud-vue.css +803 -0
- package/dist/nextcloud-vue.esm.js +10665 -0
- package/dist/nextcloud-vue.esm.js.map +1 -0
- package/package.json +63 -0
- package/src/components/CnCardGrid/CnCardGrid.vue +152 -0
- package/src/components/CnCardGrid/index.js +1 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +132 -0
- package/src/components/CnCellRenderer/index.js +1 -0
- package/src/components/CnConfigurationCard/CnConfigurationCard.vue +77 -0
- package/src/components/CnConfigurationCard/index.js +1 -0
- package/src/components/CnDataTable/CnDataTable.vue +354 -0
- package/src/components/CnDataTable/index.js +1 -0
- package/src/components/CnDetailViewLayout/CnDetailViewLayout.vue +88 -0
- package/src/components/CnDetailViewLayout/index.js +1 -0
- package/src/components/CnEmptyState/CnEmptyState.vue +78 -0
- package/src/components/CnEmptyState/index.js +1 -0
- package/src/components/CnFacetSidebar/CnFacetSidebar.vue +223 -0
- package/src/components/CnFacetSidebar/index.js +1 -0
- package/src/components/CnFilterBar/CnFilterBar.vue +152 -0
- package/src/components/CnFilterBar/index.js +1 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +682 -0
- package/src/components/CnIndexPage/index.js +1 -0
- package/src/components/CnKpiGrid/CnKpiGrid.vue +89 -0
- package/src/components/CnKpiGrid/index.js +1 -0
- package/src/components/CnListViewLayout/CnListViewLayout.vue +80 -0
- package/src/components/CnListViewLayout/index.js +1 -0
- package/src/components/CnMassActionBar/CnMassActionBar.vue +160 -0
- package/src/components/CnMassActionBar/index.js +1 -0
- package/src/components/CnMassCopyDialog/CnMassCopyDialog.vue +320 -0
- package/src/components/CnMassCopyDialog/index.js +1 -0
- package/src/components/CnMassDeleteDialog/CnMassDeleteDialog.vue +238 -0
- package/src/components/CnMassDeleteDialog/index.js +1 -0
- package/src/components/CnMassExportDialog/CnMassExportDialog.vue +190 -0
- package/src/components/CnMassExportDialog/index.js +1 -0
- package/src/components/CnMassImportDialog/CnMassImportDialog.vue +491 -0
- package/src/components/CnMassImportDialog/index.js +1 -0
- package/src/components/CnObjectCard/CnObjectCard.vue +292 -0
- package/src/components/CnObjectCard/index.js +1 -0
- package/src/components/CnPagination/CnPagination.vue +252 -0
- package/src/components/CnPagination/index.js +1 -0
- package/src/components/CnRowActions/CnRowActions.vue +73 -0
- package/src/components/CnRowActions/index.js +1 -0
- package/src/components/CnSettingsCard/CnSettingsCard.vue +92 -0
- package/src/components/CnSettingsCard/index.js +1 -0
- package/src/components/CnSettingsSection/CnSettingsSection.vue +266 -0
- package/src/components/CnSettingsSection/index.js +1 -0
- package/src/components/CnStatsBlock/CnStatsBlock.vue +366 -0
- package/src/components/CnStatsBlock/index.js +1 -0
- package/src/components/CnStatusBadge/CnStatusBadge.vue +77 -0
- package/src/components/CnStatusBadge/index.js +1 -0
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +312 -0
- package/src/components/CnVersionInfoCard/index.js +1 -0
- package/src/components/CnViewModeToggle/CnViewModeToggle.vue +77 -0
- package/src/components/CnViewModeToggle/index.js +1 -0
- package/src/components/index.js +25 -0
- package/src/composables/index.js +3 -0
- package/src/composables/useDetailView.js +132 -0
- package/src/composables/useListView.js +153 -0
- package/src/composables/useSubResource.js +142 -0
- package/src/css/badge.css +51 -0
- package/src/css/card.css +128 -0
- package/src/css/detail.css +68 -0
- package/src/css/index.css +8 -0
- package/src/css/layout.css +90 -0
- package/src/css/pagination.css +72 -0
- package/src/css/table.css +143 -0
- package/src/css/utilities.css +46 -0
- package/src/index.js +50 -0
- package/src/store/createSubResourcePlugin.js +135 -0
- package/src/store/index.js +3 -0
- package/src/store/plugins/auditTrails.js +17 -0
- package/src/store/plugins/files.js +186 -0
- package/src/store/plugins/index.js +4 -0
- package/src/store/plugins/lifecycle.js +180 -0
- package/src/store/plugins/relations.js +68 -0
- package/src/store/useObjectStore.js +625 -0
- package/src/types/auditTrail.d.ts +32 -0
- package/src/types/file.d.ts +23 -0
- package/src/types/index.d.ts +35 -0
- package/src/types/notification.d.ts +36 -0
- package/src/types/object.d.ts +40 -0
- package/src/types/organisation.d.ts +41 -0
- package/src/types/register.d.ts +25 -0
- package/src/types/schema.d.ts +39 -0
- package/src/types/shared.d.ts +79 -0
- package/src/types/source.d.ts +14 -0
- package/src/types/task.d.ts +31 -0
- package/src/utils/errors.js +96 -0
- package/src/utils/headers.js +44 -0
- package/src/utils/index.js +3 -0
- package/src/utils/schema.js +287 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRegister Notification entity type.
|
|
3
|
+
*
|
|
4
|
+
* Represents a notification related to an object (e.g., status changes,
|
|
5
|
+
* assignments, deadline alerts). Typically delivered via Nextcloud's
|
|
6
|
+
* notification system.
|
|
7
|
+
*/
|
|
8
|
+
export interface TNotification {
|
|
9
|
+
id: string | number
|
|
10
|
+
uuid?: string
|
|
11
|
+
type: TNotificationType
|
|
12
|
+
title: string
|
|
13
|
+
message?: string
|
|
14
|
+
objectId?: string
|
|
15
|
+
objectUuid?: string
|
|
16
|
+
objectType?: string
|
|
17
|
+
userId?: string
|
|
18
|
+
priority?: TNotificationPriority
|
|
19
|
+
read?: boolean
|
|
20
|
+
actionUrl?: string | null
|
|
21
|
+
created: string
|
|
22
|
+
updated?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Notification type categories. */
|
|
26
|
+
export type TNotificationType =
|
|
27
|
+
| 'status-change'
|
|
28
|
+
| 'assignment'
|
|
29
|
+
| 'deadline'
|
|
30
|
+
| 'mention'
|
|
31
|
+
| 'comment'
|
|
32
|
+
| 'system'
|
|
33
|
+
| string
|
|
34
|
+
|
|
35
|
+
/** Notification priority levels. */
|
|
36
|
+
export type TNotificationPriority = 'urgent' | 'high' | 'normal' | 'low'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRegister Object entity type.
|
|
3
|
+
*
|
|
4
|
+
* An object is the core data entity stored in a register under a schema.
|
|
5
|
+
* The `@self` key contains system metadata, while other keys are schema properties.
|
|
6
|
+
*/
|
|
7
|
+
export interface TObject {
|
|
8
|
+
'@self': {
|
|
9
|
+
id: string
|
|
10
|
+
name: string | null
|
|
11
|
+
description: string | null
|
|
12
|
+
uuid: string
|
|
13
|
+
uri: string
|
|
14
|
+
version: string | null
|
|
15
|
+
register: string
|
|
16
|
+
schema: string
|
|
17
|
+
schemaVersion: string | null
|
|
18
|
+
relations: string | unknown[] | null
|
|
19
|
+
files: string | unknown[] | null
|
|
20
|
+
folder: string | null
|
|
21
|
+
textRepresentation: string | null
|
|
22
|
+
locked: unknown[] | null
|
|
23
|
+
owner: string | null
|
|
24
|
+
authorization: unknown[] | null
|
|
25
|
+
application: string | null
|
|
26
|
+
organisation: string | null
|
|
27
|
+
groups: unknown[] | null
|
|
28
|
+
validation: unknown[] | null
|
|
29
|
+
deleted: unknown[] | null
|
|
30
|
+
geo: unknown[] | null
|
|
31
|
+
retention: unknown[] | null
|
|
32
|
+
size: string | null
|
|
33
|
+
updated: string
|
|
34
|
+
created: string
|
|
35
|
+
published: string | null
|
|
36
|
+
depublished: string | null
|
|
37
|
+
}
|
|
38
|
+
/** Schema-defined properties (dynamic keys). */
|
|
39
|
+
[key: string]: unknown
|
|
40
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { TQuota, TUsage, TCrudAuthorization } from './shared'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenRegister Organisation entity type.
|
|
5
|
+
*
|
|
6
|
+
* Organisations group users and control access to registers, schemas, and objects.
|
|
7
|
+
*/
|
|
8
|
+
export interface TOrganisation {
|
|
9
|
+
id?: number
|
|
10
|
+
uuid?: string
|
|
11
|
+
name: string
|
|
12
|
+
slug?: string
|
|
13
|
+
description?: string
|
|
14
|
+
users?: string[]
|
|
15
|
+
groups?: string[]
|
|
16
|
+
isDefault?: boolean
|
|
17
|
+
active?: boolean
|
|
18
|
+
owner?: string
|
|
19
|
+
parent?: string | null
|
|
20
|
+
children?: string[]
|
|
21
|
+
quota?: TQuota
|
|
22
|
+
usage?: TUsage
|
|
23
|
+
authorization?: TOrganisationAuthorization
|
|
24
|
+
created?: string
|
|
25
|
+
updated?: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Organisation-level authorization with per-entity-type CRUD + special permissions. */
|
|
29
|
+
export interface TOrganisationAuthorization {
|
|
30
|
+
register?: TCrudAuthorization
|
|
31
|
+
schema?: TCrudAuthorization
|
|
32
|
+
object?: TCrudAuthorization
|
|
33
|
+
view?: TCrudAuthorization
|
|
34
|
+
agent?: TCrudAuthorization
|
|
35
|
+
configuration?: TCrudAuthorization
|
|
36
|
+
application?: TCrudAuthorization
|
|
37
|
+
object_publish?: string[]
|
|
38
|
+
agent_use?: string[]
|
|
39
|
+
dashboard_view?: string[]
|
|
40
|
+
llm_use?: string[]
|
|
41
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TQuota, TUsage, TEntityStats } from './shared'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenRegister Register entity type.
|
|
5
|
+
*
|
|
6
|
+
* A register is a collection of schemas and their objects, backed by a data source.
|
|
7
|
+
*/
|
|
8
|
+
export interface TRegister {
|
|
9
|
+
id?: string
|
|
10
|
+
title: string
|
|
11
|
+
description: string
|
|
12
|
+
schemas: string[]
|
|
13
|
+
source: string
|
|
14
|
+
databaseId: string
|
|
15
|
+
published?: string | null
|
|
16
|
+
depublished?: string | null
|
|
17
|
+
tablePrefix?: string
|
|
18
|
+
updated?: string
|
|
19
|
+
created: string
|
|
20
|
+
slug: string
|
|
21
|
+
groups?: string[]
|
|
22
|
+
quota?: TQuota
|
|
23
|
+
usage?: TUsage
|
|
24
|
+
stats?: TEntityStats
|
|
25
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { TEntityStats } from './shared'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenRegister Schema entity type.
|
|
5
|
+
*
|
|
6
|
+
* Defines the structure and validation rules for objects in a register.
|
|
7
|
+
*/
|
|
8
|
+
export interface TSchema {
|
|
9
|
+
id?: string
|
|
10
|
+
title: string
|
|
11
|
+
version: string
|
|
12
|
+
description: string
|
|
13
|
+
summary: string
|
|
14
|
+
required: string[]
|
|
15
|
+
properties: Record<string, unknown>
|
|
16
|
+
archive: Record<string, unknown>
|
|
17
|
+
updated: string
|
|
18
|
+
created: string
|
|
19
|
+
slug: string
|
|
20
|
+
configuration?: TSchemaConfiguration
|
|
21
|
+
hardValidation: boolean
|
|
22
|
+
maxDepth: number
|
|
23
|
+
authorization?: Record<string, string[]>
|
|
24
|
+
extend?: string
|
|
25
|
+
stats?: TEntityStats
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Schema configuration options. */
|
|
29
|
+
export interface TSchemaConfiguration {
|
|
30
|
+
objectNameField?: string
|
|
31
|
+
objectDescriptionField?: string
|
|
32
|
+
objectSummaryField?: string
|
|
33
|
+
objectImageField?: string
|
|
34
|
+
allowFiles?: boolean
|
|
35
|
+
allowedTags?: string[]
|
|
36
|
+
unique?: boolean
|
|
37
|
+
facetCacheTtl?: number
|
|
38
|
+
autoPublish?: boolean
|
|
39
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility types used across OpenRegister entities.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** Standard paginated API response shape. */
|
|
6
|
+
export interface TPaginated<T = unknown> {
|
|
7
|
+
results: T[]
|
|
8
|
+
total: number
|
|
9
|
+
page: number
|
|
10
|
+
pages: number
|
|
11
|
+
limit: number
|
|
12
|
+
offset: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Empty paginated response (used as initial state). */
|
|
16
|
+
export type TEmptyPaginated = TPaginated<never>
|
|
17
|
+
|
|
18
|
+
/** Resource quota limits. Used by registers, organisations, views, applications. */
|
|
19
|
+
export interface TQuota {
|
|
20
|
+
storage?: number | null
|
|
21
|
+
bandwidth?: number | null
|
|
22
|
+
requests?: number | null
|
|
23
|
+
users?: number | null
|
|
24
|
+
groups?: number | null
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Resource usage tracking. Mirrors TQuota but values are always numbers. */
|
|
28
|
+
export interface TUsage {
|
|
29
|
+
storage?: number
|
|
30
|
+
bandwidth?: number
|
|
31
|
+
requests?: number
|
|
32
|
+
users?: number
|
|
33
|
+
groups?: number
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Aggregate statistics for objects, logs, and files. Used by schemas and registers. */
|
|
37
|
+
export interface TEntityStats {
|
|
38
|
+
objects: {
|
|
39
|
+
total: number
|
|
40
|
+
size: number
|
|
41
|
+
invalid: number
|
|
42
|
+
deleted: number
|
|
43
|
+
locked: number
|
|
44
|
+
published: number
|
|
45
|
+
}
|
|
46
|
+
logs: {
|
|
47
|
+
total: number
|
|
48
|
+
size: number
|
|
49
|
+
}
|
|
50
|
+
files: {
|
|
51
|
+
total: number
|
|
52
|
+
size: number
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** CRUD authorization configuration per entity type. */
|
|
57
|
+
export interface TCrudAuthorization {
|
|
58
|
+
create?: string[]
|
|
59
|
+
read?: string[]
|
|
60
|
+
update?: string[]
|
|
61
|
+
delete?: string[]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Unified API error shape returned by all store actions. */
|
|
65
|
+
export interface TApiError {
|
|
66
|
+
status: number | null
|
|
67
|
+
message: string
|
|
68
|
+
details: unknown | null
|
|
69
|
+
isValidation: boolean
|
|
70
|
+
fields: Record<string, string> | null
|
|
71
|
+
toString(): string
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Object path reference for routing. */
|
|
75
|
+
export interface TObjectPath {
|
|
76
|
+
register: string
|
|
77
|
+
schema: string
|
|
78
|
+
objectId?: string
|
|
79
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRegister Source entity type.
|
|
3
|
+
*
|
|
4
|
+
* A data source backing a register (database connection).
|
|
5
|
+
*/
|
|
6
|
+
export interface TSource {
|
|
7
|
+
id?: string | number
|
|
8
|
+
title: string
|
|
9
|
+
description: string
|
|
10
|
+
databaseUrl: string
|
|
11
|
+
type: 'internal' | 'mongodb'
|
|
12
|
+
updated: string
|
|
13
|
+
created: string
|
|
14
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRegister Task entity type.
|
|
3
|
+
*
|
|
4
|
+
* Tasks are CalDAV-based (iCalendar VTODO) and linked to objects.
|
|
5
|
+
* Fetched via the /tasks sub-resource endpoint and normalized from
|
|
6
|
+
* iCal format to this frontend-friendly shape.
|
|
7
|
+
*/
|
|
8
|
+
export interface TTask {
|
|
9
|
+
id: string
|
|
10
|
+
uid?: string
|
|
11
|
+
calendarId?: string
|
|
12
|
+
taskUri?: string
|
|
13
|
+
title: string
|
|
14
|
+
description?: string
|
|
15
|
+
reference?: string
|
|
16
|
+
objectUuid?: string
|
|
17
|
+
deadline?: string | null
|
|
18
|
+
daysText?: string
|
|
19
|
+
isOverdue?: boolean
|
|
20
|
+
isCompleted?: boolean
|
|
21
|
+
priority: TTaskPriority
|
|
22
|
+
status: TTaskStatus
|
|
23
|
+
created?: string
|
|
24
|
+
updated?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** CalDAV task priority levels (mapped from iCal 0-9 range). */
|
|
28
|
+
export type TTaskPriority = 'urgent' | 'high' | 'normal' | 'low'
|
|
29
|
+
|
|
30
|
+
/** CalDAV task status values. */
|
|
31
|
+
export type TTaskStatus = 'needs-action' | 'in-process' | 'completed' | 'cancelled'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified error shape returned by all store actions.
|
|
3
|
+
*
|
|
4
|
+
* @typedef {object} ApiError
|
|
5
|
+
* @property {number} status HTTP status code (0 for network errors)
|
|
6
|
+
* @property {string} message Human-readable error message
|
|
7
|
+
* @property {object|null} details Validation errors or additional details
|
|
8
|
+
* @property {boolean} isValidation Whether this is a validation error (400/422)
|
|
9
|
+
* @property {object|null} fields Per-field validation errors
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Parse an HTTP error response into a unified ApiError shape.
|
|
14
|
+
*
|
|
15
|
+
* Merges the best of Pipelinq's _parseResponseError (field extraction)
|
|
16
|
+
* and Procest's _parseError (status-specific messages, isValidation flag).
|
|
17
|
+
*
|
|
18
|
+
* @param {Response} response The fetch Response object
|
|
19
|
+
* @param {string} type The object type slug (used in error messages)
|
|
20
|
+
* @return {Promise<ApiError>} Parsed error object
|
|
21
|
+
*/
|
|
22
|
+
export async function parseResponseError(response, type) {
|
|
23
|
+
const status = response.status
|
|
24
|
+
let details = null
|
|
25
|
+
let fields = null
|
|
26
|
+
let message = ''
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const body = await response.json()
|
|
30
|
+
details = body.errors || body.error || body.message || null
|
|
31
|
+
fields = body.validationErrors || body.errors || null
|
|
32
|
+
} catch {
|
|
33
|
+
// Response body is not JSON
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
switch (true) {
|
|
37
|
+
case status === 400 || status === 422:
|
|
38
|
+
message = details && typeof details === 'string'
|
|
39
|
+
? details
|
|
40
|
+
: `Validation failed for ${type}`
|
|
41
|
+
return { status, message, details, isValidation: true, fields, toString() { return this.message } }
|
|
42
|
+
case status === 401:
|
|
43
|
+
message = 'Session expired, please log in again'
|
|
44
|
+
break
|
|
45
|
+
case status === 403:
|
|
46
|
+
message = 'You do not have permission to perform this action'
|
|
47
|
+
break
|
|
48
|
+
case status === 404:
|
|
49
|
+
message = `The requested ${type} could not be found`
|
|
50
|
+
break
|
|
51
|
+
case status === 409:
|
|
52
|
+
message = `This ${type} was modified by another user. Please reload.`
|
|
53
|
+
break
|
|
54
|
+
case status >= 500:
|
|
55
|
+
message = 'An unexpected server error occurred. Please try again.'
|
|
56
|
+
break
|
|
57
|
+
default:
|
|
58
|
+
message = response.statusText || 'An unexpected error occurred'
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { status, message, details, isValidation: false, fields, toString() { return this.message } }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Create a network error object for fetch failures (no response).
|
|
66
|
+
*
|
|
67
|
+
* @param {Error} error The caught error
|
|
68
|
+
* @return {ApiError} Network error object
|
|
69
|
+
*/
|
|
70
|
+
export function networkError(error) {
|
|
71
|
+
return {
|
|
72
|
+
status: 0,
|
|
73
|
+
message: error.message || 'A network error occurred. Check your connection and try again.',
|
|
74
|
+
details: null,
|
|
75
|
+
isValidation: false,
|
|
76
|
+
fields: null,
|
|
77
|
+
toString() { return this.message },
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Create a generic error object from a caught exception.
|
|
83
|
+
*
|
|
84
|
+
* @param {Error} error The caught error
|
|
85
|
+
* @return {ApiError} Generic error object
|
|
86
|
+
*/
|
|
87
|
+
export function genericError(error) {
|
|
88
|
+
return {
|
|
89
|
+
status: null,
|
|
90
|
+
message: error.message,
|
|
91
|
+
details: null,
|
|
92
|
+
isValidation: false,
|
|
93
|
+
fields: null,
|
|
94
|
+
toString() { return this.message },
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build standard Nextcloud request headers for API calls.
|
|
3
|
+
*
|
|
4
|
+
* Includes the CSRF request token and OCS API request header
|
|
5
|
+
* required by Nextcloud's API layer.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} [contentType='application/json'] Content-Type header value
|
|
8
|
+
* @return {object} Headers object for use with fetch()
|
|
9
|
+
*/
|
|
10
|
+
export function buildHeaders(contentType = 'application/json') {
|
|
11
|
+
const headers = {
|
|
12
|
+
requesttoken: OC.requestToken,
|
|
13
|
+
'OCS-APIREQUEST': 'true',
|
|
14
|
+
}
|
|
15
|
+
if (contentType) {
|
|
16
|
+
headers['Content-Type'] = contentType
|
|
17
|
+
}
|
|
18
|
+
return headers
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Build a query string from a params object.
|
|
23
|
+
*
|
|
24
|
+
* Handles _order serialization (JSON.stringify for objects) and skips
|
|
25
|
+
* null/undefined/empty values.
|
|
26
|
+
*
|
|
27
|
+
* @param {object} params Key-value pairs for query parameters
|
|
28
|
+
* @return {string} Query string including leading '?' or empty string
|
|
29
|
+
*/
|
|
30
|
+
export function buildQueryString(params = {}) {
|
|
31
|
+
const queryParams = new URLSearchParams()
|
|
32
|
+
|
|
33
|
+
for (const [key, value] of Object.entries(params)) {
|
|
34
|
+
if (value === undefined || value === null || value === '') continue
|
|
35
|
+
if (key === '_order' && typeof value === 'object') {
|
|
36
|
+
queryParams.set(key, JSON.stringify(value))
|
|
37
|
+
} else {
|
|
38
|
+
queryParams.set(key, String(value))
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const str = queryParams.toString()
|
|
43
|
+
return str ? '?' + str : ''
|
|
44
|
+
}
|