@conduction/nextcloud-vue 0.1.0-beta.1 → 0.1.0-beta.11
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/README.md +226 -0
- package/css/index.css +5 -0
- package/dist/nextcloud-vue.cjs.js +79416 -7715
- package/dist/nextcloud-vue.cjs.js.map +1 -1
- package/dist/nextcloud-vue.css +3583 -504
- package/dist/nextcloud-vue.esm.js +79343 -7692
- package/dist/nextcloud-vue.esm.js.map +1 -1
- package/l10n/en.json +164 -0
- package/l10n/nl.json +164 -0
- package/package.json +104 -63
- package/src/components/CnActionsBar/CnActionsBar.vue +254 -0
- package/src/components/CnActionsBar/index.js +1 -0
- package/src/components/CnAdvancedFormDialog/CnAdvancedFormDialog.vue +570 -0
- package/src/components/CnAdvancedFormDialog/CnDataTab.vue +217 -0
- package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +121 -0
- package/src/components/CnAdvancedFormDialog/CnPropertiesTab.vue +422 -0
- package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +247 -0
- package/src/components/CnAdvancedFormDialog/index.js +1 -0
- package/src/components/CnCard/CnCard.vue +415 -0
- package/src/components/CnCard/index.js +1 -0
- package/src/components/CnCardGrid/CnCardGrid.vue +156 -152
- package/src/components/CnCardGrid/index.js +1 -1
- package/src/components/CnCellRenderer/CnCellRenderer.vue +132 -132
- package/src/components/CnCellRenderer/index.js +1 -1
- package/src/components/CnChartWidget/CnChartWidget.vue +346 -0
- package/src/components/CnChartWidget/index.js +1 -0
- package/src/components/CnConfigurationCard/CnConfigurationCard.vue +77 -77
- package/src/components/CnConfigurationCard/index.js +1 -1
- package/src/components/CnContextMenu/CnContextMenu.vue +142 -0
- package/src/components/CnContextMenu/index.js +1 -0
- package/src/components/CnCopyDialog/CnCopyDialog.vue +266 -0
- package/src/components/CnCopyDialog/index.js +1 -0
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +229 -0
- package/src/components/CnDashboardGrid/index.js +1 -0
- package/src/components/CnDashboardPage/CnDashboardPage.vue +397 -0
- package/src/components/CnDashboardPage/index.js +1 -0
- package/src/components/CnDataTable/CnDataTable.vue +362 -354
- package/src/components/CnDataTable/index.js +1 -1
- package/src/components/CnDeleteDialog/CnDeleteDialog.vue +177 -0
- package/src/components/CnDeleteDialog/index.js +1 -0
- package/src/components/CnDetailCard/CnDetailCard.vue +225 -0
- package/src/components/CnDetailCard/index.js +1 -0
- package/src/components/CnDetailGrid/CnDetailGrid.vue +256 -0
- package/src/components/CnDetailGrid/index.js +1 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +432 -0
- package/src/components/CnDetailPage/index.js +1 -0
- package/src/components/CnFacetSidebar/CnFacetSidebar.vue +234 -223
- package/src/components/CnFacetSidebar/index.js +1 -1
- package/src/components/CnFilterBar/CnFilterBar.vue +153 -152
- package/src/components/CnFilterBar/index.js +1 -1
- package/src/components/CnFormDialog/CnFormDialog.vue +1047 -0
- package/src/components/CnFormDialog/index.js +1 -0
- package/src/components/CnIcon/CnIcon.vue +89 -0
- package/src/components/CnIcon/index.js +1 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +980 -682
- package/src/components/CnIndexPage/index.js +1 -1
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +536 -0
- package/src/components/CnIndexSidebar/index.js +1 -0
- package/src/components/CnInfoWidget/CnInfoWidget.vue +219 -0
- package/src/components/CnInfoWidget/index.js +1 -0
- package/src/components/CnItemCard/CnItemCard.vue +134 -0
- package/src/components/CnItemCard/index.js +1 -0
- package/src/components/CnJsonViewer/CnJsonViewer.vue +312 -0
- package/src/components/CnJsonViewer/index.js +1 -0
- package/src/components/CnKpiGrid/CnKpiGrid.vue +93 -89
- package/src/components/CnKpiGrid/index.js +1 -1
- package/src/components/CnMassActionBar/CnMassActionBar.vue +161 -160
- package/src/components/CnMassActionBar/index.js +1 -1
- package/src/components/CnMassCopyDialog/CnMassCopyDialog.vue +327 -320
- package/src/components/CnMassCopyDialog/index.js +1 -1
- package/src/components/CnMassDeleteDialog/CnMassDeleteDialog.vue +245 -238
- package/src/components/CnMassDeleteDialog/index.js +1 -1
- package/src/components/CnMassExportDialog/CnMassExportDialog.vue +191 -190
- package/src/components/CnMassExportDialog/index.js +1 -1
- package/src/components/CnMassImportDialog/CnMassImportDialog.vue +494 -491
- package/src/components/CnMassImportDialog/index.js +1 -1
- package/src/components/CnNoteCard/CnNoteCard.vue +149 -0
- package/src/components/CnNoteCard/index.js +1 -0
- package/src/components/CnNotesCard/CnNotesCard.vue +416 -0
- package/src/components/CnNotesCard/index.js +1 -0
- package/src/components/CnObjectCard/CnObjectCard.vue +294 -292
- package/src/components/CnObjectCard/index.js +1 -1
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +854 -0
- package/src/components/CnObjectDataWidget/index.js +1 -0
- package/src/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue +289 -0
- package/src/components/CnObjectMetadataWidget/index.js +1 -0
- package/src/components/CnObjectSidebar/CnAuditTrailTab.vue +369 -0
- package/src/components/CnObjectSidebar/CnFilesTab.vue +287 -0
- package/src/components/CnObjectSidebar/CnNotesTab.vue +250 -0
- package/src/components/CnObjectSidebar/CnObjectSidebar.vue +255 -0
- package/src/components/CnObjectSidebar/CnTagsTab.vue +259 -0
- package/src/components/CnObjectSidebar/CnTasksTab.vue +483 -0
- package/src/components/CnObjectSidebar/index.js +6 -0
- package/src/components/CnPageHeader/CnPageHeader.vue +61 -0
- package/src/components/CnPageHeader/index.js +1 -0
- package/src/components/CnPagination/CnPagination.vue +253 -252
- package/src/components/CnPagination/index.js +1 -1
- package/src/components/CnProgressBar/CnProgressBar.vue +262 -0
- package/src/components/CnProgressBar/index.js +1 -0
- package/src/components/CnRegisterMapping/CnRegisterMapping.vue +793 -0
- package/src/components/CnRegisterMapping/index.js +1 -0
- package/src/components/CnRowActions/CnRowActions.vue +95 -73
- package/src/components/CnRowActions/index.js +1 -1
- package/src/components/CnSchemaFormDialog/CnSchemaConfigurationTab.vue +226 -0
- package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +788 -0
- package/src/components/CnSchemaFormDialog/CnSchemaPropertiesTab.vue +305 -0
- package/src/components/CnSchemaFormDialog/CnSchemaPropertyActions.vue +1398 -0
- package/src/components/CnSchemaFormDialog/CnSchemaSecurityTab.vue +236 -0
- package/src/components/CnSchemaFormDialog/index.js +1 -0
- package/src/components/CnSettingsCard/CnSettingsCard.vue +92 -92
- package/src/components/CnSettingsCard/index.js +1 -1
- package/src/components/CnSettingsSection/CnSettingsSection.vue +267 -266
- package/src/components/CnSettingsSection/index.js +1 -1
- package/src/components/CnStatsBlock/CnStatsBlock.vue +437 -366
- package/src/components/CnStatsBlock/index.js +1 -1
- package/src/components/CnStatsPanel/CnStatsPanel.vue +321 -0
- package/src/components/CnStatsPanel/index.js +1 -0
- package/src/components/CnStatusBadge/CnStatusBadge.vue +90 -77
- package/src/components/CnStatusBadge/index.js +1 -1
- package/src/components/CnTabbedFormDialog/CnTabbedFormDialog.vue +545 -0
- package/src/components/CnTabbedFormDialog/index.js +1 -0
- package/src/components/CnTableWidget/CnTableWidget.vue +333 -0
- package/src/components/CnTableWidget/index.js +1 -0
- package/src/components/CnTasksCard/CnTasksCard.vue +374 -0
- package/src/components/CnTasksCard/index.js +1 -0
- package/src/components/CnTileWidget/CnTileWidget.vue +159 -0
- package/src/components/CnTileWidget/index.js +1 -0
- package/src/components/CnTimelineStages/CnTimelineStages.vue +294 -0
- package/src/components/CnTimelineStages/index.js +1 -0
- package/src/components/CnUserActionMenu/CnUserActionMenu.vue +436 -0
- package/src/components/CnUserActionMenu/index.js +1 -0
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +313 -312
- package/src/components/CnVersionInfoCard/index.js +1 -1
- package/src/components/CnWidgetRenderer/CnWidgetRenderer.vue +180 -0
- package/src/components/CnWidgetRenderer/index.js +1 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +248 -0
- package/src/components/CnWidgetWrapper/index.js +1 -0
- package/src/components/index.js +57 -25
- package/src/composables/index.js +5 -3
- package/src/composables/useContextMenu.js +126 -0
- package/src/composables/useDashboardView.js +286 -0
- package/src/composables/useDetailView.js +290 -132
- package/src/composables/useListView.js +364 -153
- package/src/composables/useSubResource.js +142 -142
- package/src/constants/metadata.js +30 -0
- package/src/css/CnSchemaFormDialog.css +546 -0
- package/src/css/__sample_nextcloud_tokens.css +110 -0
- package/src/css/actions-bar.css +54 -0
- package/src/css/badge.css +83 -51
- package/src/css/card.css +129 -128
- package/src/css/context-menu.css +20 -0
- package/src/css/dashboard.css +70 -0
- package/src/css/detail-page.css +235 -0
- package/src/css/detail.css +68 -68
- package/src/css/index-page.css +44 -0
- package/src/css/index-sidebar.css +193 -0
- package/src/css/index.css +17 -8
- package/src/css/layout.css +90 -90
- package/src/css/page-header.css +35 -0
- package/src/css/pagination.css +72 -72
- package/src/css/table.css +142 -143
- package/src/css/timeline-stages.css +220 -0
- package/src/css/utilities.css +46 -46
- package/src/index.js +95 -50
- package/src/l10n/index.js +12 -0
- package/src/mixins/gridLayout.js +118 -0
- package/src/store/createCrudStore.d.ts +350 -0
- package/src/store/createCrudStore.js +413 -0
- package/src/store/createSubResourcePlugin.js +125 -135
- package/src/store/index.js +4 -3
- package/src/store/pluginMerge.js +55 -0
- package/src/store/plugins/auditTrails.js +357 -17
- package/src/store/plugins/files.js +250 -186
- package/src/store/plugins/index.js +8 -4
- package/src/store/plugins/lifecycle.js +180 -180
- package/src/store/plugins/logs.d.ts +22 -0
- package/src/store/plugins/logs.js +172 -0
- package/src/store/plugins/registerMapping.js +195 -0
- package/src/store/plugins/relations.js +68 -68
- package/src/store/plugins/search.js +385 -0
- package/src/store/plugins/selection.js +104 -0
- package/src/store/useObjectStore.js +793 -625
- package/src/types/auditTrail.d.ts +32 -32
- package/src/types/file.d.ts +23 -23
- package/src/types/index.d.ts +67 -35
- package/src/types/notification.d.ts +36 -36
- package/src/types/object.d.ts +40 -40
- package/src/types/organisation.d.ts +41 -41
- package/src/types/register.d.ts +25 -25
- package/src/types/schema.d.ts +39 -39
- package/src/types/shared.d.ts +79 -79
- package/src/types/source.d.ts +14 -14
- package/src/types/task.d.ts +31 -31
- package/src/utils/errors.js +96 -96
- package/src/utils/getTheme.js +9 -0
- package/src/utils/headers.js +80 -44
- package/src/utils/id.js +13 -0
- package/src/utils/index.js +4 -3
- package/src/utils/schema.js +423 -287
- package/src/utils/widgetVisibility.js +162 -0
- package/src/components/CnDetailViewLayout/CnDetailViewLayout.vue +0 -88
- package/src/components/CnDetailViewLayout/index.js +0 -1
- package/src/components/CnEmptyState/CnEmptyState.vue +0 -78
- package/src/components/CnEmptyState/index.js +0 -1
- package/src/components/CnListViewLayout/CnListViewLayout.vue +0 -80
- package/src/components/CnListViewLayout/index.js +0 -1
- package/src/components/CnViewModeToggle/CnViewModeToggle.vue +0 -77
- package/src/components/CnViewModeToggle/index.js +0 -1
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand-written type definitions for `createCrudStore` (implementation is in
|
|
3
|
+
* `createCrudStore.js`). The library ships as JavaScript, but this file gives
|
|
4
|
+
* TypeScript consumers full entity inference, feature-flag gating, and
|
|
5
|
+
* `extend` merging with correct `this` typing.
|
|
6
|
+
*
|
|
7
|
+
* Design notes:
|
|
8
|
+
* - `const Id extends string` / `const F extends Features` preserves literal
|
|
9
|
+
* types so `features: { loading: true }` flows `true` through the
|
|
10
|
+
* conditional types without requiring `as const` at the call site.
|
|
11
|
+
* Requires TypeScript 5.0+.
|
|
12
|
+
* - Entity inference: if `config.entity` is a class constructor, `T` is the
|
|
13
|
+
* instance type. Otherwise `T` falls back to `unknown` unless the caller
|
|
14
|
+
* passes it explicitly via the second overload.
|
|
15
|
+
* - `ThisType<...>` inside `extend.actions` / `extend.getters` makes `this`
|
|
16
|
+
* resolve to the fully-merged store (state + getters + base actions +
|
|
17
|
+
* extended actions), matching Pinia's own runtime semantics.
|
|
18
|
+
* - `Omit<BaseActions<T>, keyof ExtActions>` implements override precedence:
|
|
19
|
+
* an extend action with the same name as a base action replaces it.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { StoreDefinition, _GettersTree } from 'pinia'
|
|
23
|
+
|
|
24
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
25
|
+
// Utility types
|
|
26
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Forces TypeScript to eagerly evaluate an intersection of types into a
|
|
30
|
+
* single flat object shape. Purely a hover/tooltip ergonomics helper —
|
|
31
|
+
* semantically identical to the input.
|
|
32
|
+
*
|
|
33
|
+
* Without this, VSCode's quick-info tooltip shows `StoreDefinition<...,
|
|
34
|
+
* FullState<Source, ...> & ..., ..., MergedActions<...>>` with the aliases
|
|
35
|
+
* left unexpanded, making it hard to see which properties the store has.
|
|
36
|
+
* With this, hover shows `{ item: Source | null; list: Source[]; ... }`
|
|
37
|
+
* directly.
|
|
38
|
+
*/
|
|
39
|
+
export type Prettify<T> = { [K in keyof T]: T[K] } & {}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A class constructor accepting raw data (e.g. `new Source(data)`).
|
|
43
|
+
*/
|
|
44
|
+
export type EntityClass<T> = new (data: any) => T
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Extract the instance type from an entity-class config field.
|
|
48
|
+
* Falls back to `unknown` when no class is provided.
|
|
49
|
+
*/
|
|
50
|
+
export type InferEntity<E> =
|
|
51
|
+
E extends EntityClass<infer T> ? T :
|
|
52
|
+
E extends null | undefined ? unknown :
|
|
53
|
+
unknown
|
|
54
|
+
|
|
55
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
56
|
+
// Feature flags
|
|
57
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Optional behavioral toggles. When a flag is set, the factory adds the
|
|
61
|
+
* corresponding state fields, getters, and actions to the store.
|
|
62
|
+
*/
|
|
63
|
+
export interface Features {
|
|
64
|
+
/** Add `loading` / `error` state plus the `isLoading` / `getError` getters. */
|
|
65
|
+
loading?: boolean
|
|
66
|
+
/** Add `viewMode` state, the `getViewMode` getter, and a `setViewMode(mode)` action. */
|
|
67
|
+
viewMode?: boolean
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type LoadingState<F> = F extends { loading: true } ? { loading: boolean; error: string | null } : {}
|
|
71
|
+
export type ViewModeState<F> = F extends { viewMode: true } ? { viewMode: string } : {}
|
|
72
|
+
|
|
73
|
+
// Getter trees are declared as `(state) => value` and Pinia exposes them on
|
|
74
|
+
// the store as `.name: value`. We declare them as getter functions so the
|
|
75
|
+
// `StoreDefinition<..., Getters, ...>` return-type mapping kicks in.
|
|
76
|
+
export type LoadingGetters<F> = F extends { loading: true }
|
|
77
|
+
? {
|
|
78
|
+
isLoading: (state: { loading: boolean }) => boolean
|
|
79
|
+
getError: (state: { error: string | null }) => string | null
|
|
80
|
+
}
|
|
81
|
+
: {}
|
|
82
|
+
export type ViewModeGetters<F> = F extends { viewMode: true }
|
|
83
|
+
? { getViewMode: (state: { viewMode: string }) => string }
|
|
84
|
+
: {}
|
|
85
|
+
|
|
86
|
+
export type ViewModeActions<F> = F extends { viewMode: true } ? { setViewMode(mode: string): void } : {}
|
|
87
|
+
|
|
88
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
89
|
+
// Base state, getters and actions
|
|
90
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* State shape every store receives by default, independent of features and
|
|
94
|
+
* extensions. Feature-specific fields (`loading`, `error`, `viewMode`) and
|
|
95
|
+
* anything contributed by `extend.state` / plugins are added on top.
|
|
96
|
+
*/
|
|
97
|
+
export interface BaseState<T> {
|
|
98
|
+
/** The currently active/selected item, or `null` when nothing is selected. */
|
|
99
|
+
item: T | null
|
|
100
|
+
/** The full list of items as last returned by `refreshList`. */
|
|
101
|
+
list: T[]
|
|
102
|
+
/** Active filter criteria (merged via `setFilters`). */
|
|
103
|
+
filters: Record<string, unknown>
|
|
104
|
+
/** Current pagination position. `limit` defaults to 20. */
|
|
105
|
+
pagination: { page: number; limit: number }
|
|
106
|
+
/**
|
|
107
|
+
* Internal, runtime-resolved configuration exposed so extend actions and
|
|
108
|
+
* plugins can build URLs, clean fields, or instantiate the entity class
|
|
109
|
+
* without re-reading user config.
|
|
110
|
+
*/
|
|
111
|
+
_options: {
|
|
112
|
+
/** The raw endpoint segment supplied to the factory (e.g. `'sources'`). */
|
|
113
|
+
endpoint: string
|
|
114
|
+
/** Fields stripped by `cleanForSave` before POST/PUT. */
|
|
115
|
+
cleanFields: readonly string[]
|
|
116
|
+
/** Fully-qualified base URL for this store's REST endpoint, already `prefixUrl`-normalized. */
|
|
117
|
+
baseApiUrl: string
|
|
118
|
+
/** Entity class constructor, or `null` when the store returns raw data. */
|
|
119
|
+
entity: EntityClass<T> | null
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Actions available on every store regardless of configuration. Extend
|
|
125
|
+
* actions with the same name replace these (see `MergedActions`).
|
|
126
|
+
*/
|
|
127
|
+
export interface BaseActions<T> {
|
|
128
|
+
/** Set the active item. Wraps in the configured Entity class when present; pass `null` to clear. */
|
|
129
|
+
setItem(data: T | Partial<T> | null): void
|
|
130
|
+
/** Replace the item list. Maps each entry through the Entity class when configured. */
|
|
131
|
+
setList(data: Array<T | Partial<T>>): void
|
|
132
|
+
/** Set `pagination.page` and `pagination.limit`. `limit` defaults to 20. */
|
|
133
|
+
setPagination(page: number, limit?: number): void
|
|
134
|
+
/** Merge filter key/value pairs into the current `filters` object. */
|
|
135
|
+
setFilters(filters: Record<string, unknown>): void
|
|
136
|
+
/** GET the list endpoint. Optional `search` is appended as `?_search=`; `soft=true` skips the loading toggle. */
|
|
137
|
+
refreshList(search?: string | null, soft?: boolean): Promise<{ response: Response; data: T[] }>
|
|
138
|
+
/** GET `/:id`, set it as the active item, and return the raw response data. */
|
|
139
|
+
getOne(id: string | number): Promise<T>
|
|
140
|
+
/** DELETE `/:id`, refresh the list, and clear the active item. */
|
|
141
|
+
deleteOne(idOrItem: string | number | { id: string | number }): Promise<{ response: Response }>
|
|
142
|
+
/** POST or PUT the item depending on whether it has an `id`, then refresh the list. */
|
|
143
|
+
save(item: Partial<T>): Promise<{ response: Response; data: T }>
|
|
144
|
+
/** Return a copy of `item` with `cleanFields` stripped, suitable for POST/PUT bodies. */
|
|
145
|
+
cleanForSave(item: T | Partial<T>): Partial<T>
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Action merge rule:
|
|
150
|
+
* - Base actions not overridden by the extend block are preserved.
|
|
151
|
+
* - Actions declared in `extend.actions` replace base actions of the same name.
|
|
152
|
+
* - `viewMode` feature action is appended when the flag is set.
|
|
153
|
+
* - Plugin-contributed actions are reachable via the loose index signature
|
|
154
|
+
* on `PluginActionContribution` below (typed as `any`-returning callables).
|
|
155
|
+
*/
|
|
156
|
+
export type PluginActionContribution = { [key: string]: (...args: any[]) => any }
|
|
157
|
+
|
|
158
|
+
export type MergedActions<T, ExtActions, F> =
|
|
159
|
+
Omit<BaseActions<T>, keyof ExtActions> & ExtActions & ViewModeActions<F> & PluginActionContribution
|
|
160
|
+
|
|
161
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
162
|
+
// Full store shape (state + getters + actions) used inside ThisType<...>
|
|
163
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
// Plugins contribute arbitrary state, getters, and actions at runtime. We spread
|
|
166
|
+
// a loose index signature into the resolved store shape so plugin-contributed
|
|
167
|
+
// members are reachable via dot access without `as any`. The index signature
|
|
168
|
+
// returns `any` (not `unknown`) so callable plugin actions (`store.refreshLogs()`)
|
|
169
|
+
// type-check without an intermediate cast — trade-off is that typos on
|
|
170
|
+
// plugin-contributed members are not caught. Plugins needing strict typing
|
|
171
|
+
// should ship their own `.d.ts` augmenting the specific store.
|
|
172
|
+
export type PluginContribution = { [key: string]: any }
|
|
173
|
+
|
|
174
|
+
export type FullState<T, ExtState, F> =
|
|
175
|
+
BaseState<T> & ExtState & LoadingState<F> & ViewModeState<F> & PluginContribution
|
|
176
|
+
|
|
177
|
+
export type FullGetters<ExtGetters, F> =
|
|
178
|
+
ExtGetters & LoadingGetters<F> & ViewModeGetters<F>
|
|
179
|
+
|
|
180
|
+
export type StoreThis<T, ExtState, ExtGetters, ExtActions, F> =
|
|
181
|
+
FullState<T, ExtState, F> &
|
|
182
|
+
// Getters are callable-free on the Pinia store instance — accessed as properties.
|
|
183
|
+
// We narrow each getter declaration to its return type so `this.myGetter` is typed.
|
|
184
|
+
{ [K in keyof ExtGetters]: ExtGetters[K] extends (state: any) => infer R ? R : never } &
|
|
185
|
+
LoadingGetters<F> & ViewModeGetters<F> &
|
|
186
|
+
MergedActions<T, ExtActions, F>
|
|
187
|
+
|
|
188
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
189
|
+
// Plugins
|
|
190
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* A plugin definition. Merged into the store at creation time:
|
|
194
|
+
* state is spread into store state, getters into getters, actions into actions.
|
|
195
|
+
*
|
|
196
|
+
* Merge precedence: base actions → plugin actions → extend.actions.
|
|
197
|
+
*
|
|
198
|
+
* Plugin-contributed properties are loosely typed on the resulting store
|
|
199
|
+
* (they appear as unknown state / any-returning actions). Consumers needing
|
|
200
|
+
* strict types on plugin output should augment the store's types at the
|
|
201
|
+
* call site, or use a plugin that ships a dedicated `.d.ts` with the shape.
|
|
202
|
+
*
|
|
203
|
+
* If `setup` is provided, it is invoked once per store instance the first
|
|
204
|
+
* time `useStore()` resolves it. Use this to register
|
|
205
|
+
* `store.$onAction` / `store.$subscribe` observers that react to base or
|
|
206
|
+
* other plugin actions without having to override them.
|
|
207
|
+
*/
|
|
208
|
+
export interface CrudPlugin {
|
|
209
|
+
/** Unique plugin identifier; used by `clearAllSubResources` and for debugging. */
|
|
210
|
+
name: string
|
|
211
|
+
/** State factory returning the state fields this plugin contributes. */
|
|
212
|
+
state?: () => Record<string, unknown>
|
|
213
|
+
/** Getters this plugin contributes — each receives the store state. */
|
|
214
|
+
getters?: Record<string, (state: any) => unknown>
|
|
215
|
+
/** Actions this plugin contributes. May override a base action with the same name. */
|
|
216
|
+
actions?: Record<string, (...args: any[]) => any>
|
|
217
|
+
/**
|
|
218
|
+
* Optional lifecycle hook run once per store instance, the first time
|
|
219
|
+
* `useStore()` resolves it. Typically used to register
|
|
220
|
+
* `store.$onAction` / `store.$subscribe` subscribers so the plugin can
|
|
221
|
+
* react to base or other-plugin actions without overriding them.
|
|
222
|
+
*/
|
|
223
|
+
setup?: (store: any) => void
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export interface PluginContrib {
|
|
227
|
+
[key: string]: unknown
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
231
|
+
// Config & extend shapes
|
|
232
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Domain-specific additions layered on top of the base store. Merged last,
|
|
236
|
+
* so `extend` can still override anything a plugin contributed.
|
|
237
|
+
*/
|
|
238
|
+
export interface ExtendConfig<
|
|
239
|
+
T,
|
|
240
|
+
ExtState extends Record<string, unknown>,
|
|
241
|
+
ExtGetters extends _GettersTree<BaseState<T> & ExtState>,
|
|
242
|
+
ExtActions extends Record<string, (...args: any[]) => any>,
|
|
243
|
+
F extends Features,
|
|
244
|
+
> {
|
|
245
|
+
/** State factory returning extra state properties merged into the store. */
|
|
246
|
+
state?: () => ExtState
|
|
247
|
+
/** Extra getters, or overrides of base/plugin getters with the same name. */
|
|
248
|
+
getters?: ExtGetters & ThisType<StoreThis<T, ExtState, ExtGetters, ExtActions, F>>
|
|
249
|
+
/** Extra actions, or overrides of base/plugin actions with the same name. */
|
|
250
|
+
actions?: ExtActions & ThisType<StoreThis<T, ExtState, ExtGetters, ExtActions, F>>
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Full configuration object accepted by `createCrudStore`. Mirrors the
|
|
255
|
+
* runtime options documented in `createCrudStore.js`.
|
|
256
|
+
*/
|
|
257
|
+
export interface CrudConfig<
|
|
258
|
+
T,
|
|
259
|
+
ExtState extends Record<string, unknown>,
|
|
260
|
+
ExtGetters extends _GettersTree<BaseState<T> & ExtState>,
|
|
261
|
+
ExtActions extends Record<string, (...args: any[]) => any>,
|
|
262
|
+
F extends Features,
|
|
263
|
+
Entity = EntityClass<T> | null | undefined,
|
|
264
|
+
> {
|
|
265
|
+
/** API resource path segment appended to `baseUrl` (e.g. `'sources'`). Required. */
|
|
266
|
+
endpoint: string
|
|
267
|
+
/** API base URL before the endpoint. Defaults to `'/apps/openregister/api'`. */
|
|
268
|
+
baseUrl?: string
|
|
269
|
+
/** Entity class constructor used to wrap raw API data; pass `null` for raw data. */
|
|
270
|
+
entity?: Entity
|
|
271
|
+
/** Fields stripped from items before POST/PUT. Defaults to `['id','uuid','created','updated']`. */
|
|
272
|
+
cleanFields?: readonly string[]
|
|
273
|
+
/** Feature flags enabling optional state/getters/actions. See `Features`. */
|
|
274
|
+
features?: F
|
|
275
|
+
/**
|
|
276
|
+
* Custom parser for `refreshList`'s JSON response body. Called with the
|
|
277
|
+
* store as `this`, so it can also perform side-effects (e.g. storing
|
|
278
|
+
* pagination info). Must return an array of items. Default:
|
|
279
|
+
* `(json) => json.results`.
|
|
280
|
+
*/
|
|
281
|
+
parseListResponse?: (this: StoreThis<T, ExtState, ExtGetters, ExtActions, F>, json: unknown) => T[] | Array<Partial<T>>
|
|
282
|
+
/**
|
|
283
|
+
* Plugin definitions merged into the store. Same shape as object-store
|
|
284
|
+
* plugins (`{ name, state?, getters?, actions?, setup? }`). Merge order
|
|
285
|
+
* is base → plugins → extend.
|
|
286
|
+
*/
|
|
287
|
+
plugins?: readonly CrudPlugin[]
|
|
288
|
+
/** Extra state/getters/actions merged on top of base and plugin contributions. */
|
|
289
|
+
extend?: ExtendConfig<T, ExtState, ExtGetters, ExtActions, F>
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
293
|
+
// The factory — overloaded
|
|
294
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Overload 1 — entity inference.
|
|
298
|
+
*
|
|
299
|
+
* Provide `config.entity` as a class constructor; `T` is inferred as the
|
|
300
|
+
* instance type:
|
|
301
|
+
*
|
|
302
|
+
* ```ts
|
|
303
|
+
* const useSourceStore = createCrudStore('source', {
|
|
304
|
+
* endpoint: 'sources',
|
|
305
|
+
* entity: Source, // T = Source
|
|
306
|
+
* features: { loading: true },
|
|
307
|
+
* })
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
export function createCrudStore<
|
|
311
|
+
Entity extends EntityClass<any>,
|
|
312
|
+
const Id extends string = string,
|
|
313
|
+
const F extends Features = {},
|
|
314
|
+
ExtState extends Record<string, unknown> = {},
|
|
315
|
+
ExtGetters extends _GettersTree<BaseState<InferEntity<Entity>> & ExtState> = {},
|
|
316
|
+
ExtActions extends Record<string, (...args: any[]) => any> = {},
|
|
317
|
+
>(
|
|
318
|
+
name: Id,
|
|
319
|
+
config: CrudConfig<InferEntity<Entity>, ExtState, ExtGetters, ExtActions, F, Entity>,
|
|
320
|
+
): StoreDefinition<
|
|
321
|
+
Id,
|
|
322
|
+
Prettify<FullState<InferEntity<Entity>, ExtState, F>>,
|
|
323
|
+
Prettify<FullGetters<ExtGetters, F>>,
|
|
324
|
+
Prettify<MergedActions<InferEntity<Entity>, ExtActions, F>>
|
|
325
|
+
>
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Overload 2 — explicit `T` for raw-data stores (no entity class).
|
|
329
|
+
*
|
|
330
|
+
* ```ts
|
|
331
|
+
* interface LogShape { id: number; message: string }
|
|
332
|
+
* const useLogStore = createCrudStore<'log', LogShape>('log', { endpoint: 'logs' })
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
export function createCrudStore<
|
|
336
|
+
const Id extends string,
|
|
337
|
+
T,
|
|
338
|
+
const F extends Features = {},
|
|
339
|
+
ExtState extends Record<string, unknown> = {},
|
|
340
|
+
ExtGetters extends _GettersTree<BaseState<T> & ExtState> = {},
|
|
341
|
+
ExtActions extends Record<string, (...args: any[]) => any> = {},
|
|
342
|
+
>(
|
|
343
|
+
name: Id,
|
|
344
|
+
config: CrudConfig<T, ExtState, ExtGetters, ExtActions, F, null | undefined>,
|
|
345
|
+
): StoreDefinition<
|
|
346
|
+
Id,
|
|
347
|
+
FullState<T, ExtState, F>,
|
|
348
|
+
FullGetters<ExtGetters, F>,
|
|
349
|
+
MergedActions<T, ExtActions, F>
|
|
350
|
+
>
|