@stonecrop/stonecrop 0.10.4 → 0.10.6
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 +2 -2
- package/dist/doctype.js +81 -4
- package/dist/index.js +2 -2
- package/dist/registry.js +4 -4
- package/dist/src/composables/stonecrop.d.ts +5 -5
- package/dist/src/composables/stonecrop.d.ts.map +1 -1
- package/dist/src/doctype.d.ts +95 -4
- package/dist/src/doctype.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/registry.d.ts +10 -10
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/stonecrop.d.ts +14 -14
- package/dist/src/stonecrop.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +2 -2
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/stonecrop.d.ts +121 -31
- package/dist/stonecrop.js +4606 -1376
- package/dist/stonecrop.js.map +1 -1
- package/package.json +5 -5
- package/src/composables/stonecrop.ts +12 -16
- package/src/doctype.ts +112 -4
- package/src/index.ts +3 -2
- package/src/registry.ts +11 -11
- package/src/stonecrop.ts +15 -15
- package/src/types/index.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/stonecrop",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"pinia-shared-state": "^1.0.1",
|
|
35
35
|
"pinia-xstate": "^3.0.0",
|
|
36
36
|
"xstate": "^5.25.0",
|
|
37
|
-
"@stonecrop/schema": "0.10.
|
|
37
|
+
"@stonecrop/schema": "0.10.6"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"pinia": "^3.0.4",
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
"vue-router": "^5.0.2",
|
|
61
61
|
"vite": "^7.3.1",
|
|
62
62
|
"vitest": "^4.0.18",
|
|
63
|
-
"@stonecrop/aform": "0.10.
|
|
64
|
-
"stonecrop
|
|
65
|
-
"
|
|
63
|
+
"@stonecrop/aform": "0.10.6",
|
|
64
|
+
"@stonecrop/atable": "0.10.6",
|
|
65
|
+
"stonecrop-rig": "0.7.0"
|
|
66
66
|
},
|
|
67
67
|
"description": "Schema-driven framework with XState workflows and HST state management",
|
|
68
68
|
"publishConfig": {
|
|
@@ -2,7 +2,7 @@ import { inject, onMounted, Ref, ref, watch, provide, computed, ComputedRef } fr
|
|
|
2
2
|
|
|
3
3
|
import Registry from '../registry'
|
|
4
4
|
import { Stonecrop } from '../stonecrop'
|
|
5
|
-
import
|
|
5
|
+
import Doctype from '../doctype'
|
|
6
6
|
import type { HSTNode } from '../stores/hst'
|
|
7
7
|
import { RouteContext } from '../types/registry'
|
|
8
8
|
import { storeToRefs } from 'pinia'
|
|
@@ -65,11 +65,11 @@ export type HSTStonecropReturn = BaseStonecropReturn & {
|
|
|
65
65
|
hstStore: Ref<HSTNode | undefined>
|
|
66
66
|
formData: Ref<Record<string, any>>
|
|
67
67
|
resolvedSchema: Ref<SchemaTypes[]>
|
|
68
|
-
loadNestedData: (parentPath: string, childDoctype:
|
|
69
|
-
saveRecursive: (doctype:
|
|
68
|
+
loadNestedData: (parentPath: string, childDoctype: Doctype, recordId?: string) => Record<string, any>
|
|
69
|
+
saveRecursive: (doctype: Doctype, recordId: string) => Promise<Record<string, any>>
|
|
70
70
|
createNestedContext: (
|
|
71
71
|
basePath: string,
|
|
72
|
-
childDoctype:
|
|
72
|
+
childDoctype: Doctype
|
|
73
73
|
) => {
|
|
74
74
|
provideHSTPath: (fieldname: string) => string
|
|
75
75
|
handleHSTChange: (changeData: HSTChangeData) => void
|
|
@@ -102,17 +102,13 @@ export function useStonecrop(): BaseStonecropReturn | HSTStonecropReturn
|
|
|
102
102
|
* @returns Stonecrop instance with full HST integration utilities
|
|
103
103
|
* @public
|
|
104
104
|
*/
|
|
105
|
-
export function useStonecrop(options: {
|
|
106
|
-
registry?: Registry
|
|
107
|
-
doctype: DoctypeMeta
|
|
108
|
-
recordId?: string
|
|
109
|
-
}): HSTStonecropReturn
|
|
105
|
+
export function useStonecrop(options: { registry?: Registry; doctype: Doctype; recordId?: string }): HSTStonecropReturn
|
|
110
106
|
/**
|
|
111
107
|
* @public
|
|
112
108
|
*/
|
|
113
109
|
export function useStonecrop(options?: {
|
|
114
110
|
registry?: Registry
|
|
115
|
-
doctype?:
|
|
111
|
+
doctype?: Doctype
|
|
116
112
|
recordId?: string
|
|
117
113
|
}): BaseStonecropReturn | HSTStonecropReturn {
|
|
118
114
|
if (!options) options = {}
|
|
@@ -124,7 +120,7 @@ export function useStonecrop(options?: {
|
|
|
124
120
|
const formData = ref<Record<string, any>>({})
|
|
125
121
|
|
|
126
122
|
// Use refs for router-loaded doctype to maintain reactivity
|
|
127
|
-
const routerDoctype = ref<
|
|
123
|
+
const routerDoctype = ref<Doctype | undefined>()
|
|
128
124
|
const routerRecordId = ref<string | undefined>()
|
|
129
125
|
|
|
130
126
|
// Resolved schema with nested Doctype fields expanded
|
|
@@ -418,7 +414,7 @@ export function useStonecrop(options?: {
|
|
|
418
414
|
* @param recordId - Optional record ID to load
|
|
419
415
|
* @returns Promise resolving to the loaded or initialized data
|
|
420
416
|
*/
|
|
421
|
-
const loadNestedData = (parentPath: string, childDoctype:
|
|
417
|
+
const loadNestedData = (parentPath: string, childDoctype: Doctype, recordId?: string): Record<string, any> => {
|
|
422
418
|
if (!stonecrop.value) {
|
|
423
419
|
return initializeNewRecord(childDoctype)
|
|
424
420
|
}
|
|
@@ -450,7 +446,7 @@ export function useStonecrop(options?: {
|
|
|
450
446
|
* @param recordId - The record ID to save
|
|
451
447
|
* @returns The complete save payload
|
|
452
448
|
*/
|
|
453
|
-
const saveRecursive = (doctype:
|
|
449
|
+
const saveRecursive = (doctype: Doctype, recordId: string): Record<string, any> => {
|
|
454
450
|
if (!hstStore.value || !stonecrop.value) {
|
|
455
451
|
throw new Error('HST store not initialized')
|
|
456
452
|
}
|
|
@@ -487,7 +483,7 @@ export function useStonecrop(options?: {
|
|
|
487
483
|
* @param _childDoctype - The child doctype metadata (unused but kept for API consistency)
|
|
488
484
|
* @returns Object with scoped provideHSTPath and handleHSTChange
|
|
489
485
|
*/
|
|
490
|
-
const createNestedContext = (basePath: string, _childDoctype:
|
|
486
|
+
const createNestedContext = (basePath: string, _childDoctype: Doctype) => {
|
|
491
487
|
const nestedProvideHSTPath = (fieldname: string): string => {
|
|
492
488
|
return `${basePath}.${fieldname}`
|
|
493
489
|
}
|
|
@@ -570,7 +566,7 @@ export function useStonecrop(options?: {
|
|
|
570
566
|
/**
|
|
571
567
|
* Initialize new record structure based on doctype schema
|
|
572
568
|
*/
|
|
573
|
-
function initializeNewRecord(doctype:
|
|
569
|
+
function initializeNewRecord(doctype: Doctype): Record<string, any> {
|
|
574
570
|
const initialData: Record<string, any> = {}
|
|
575
571
|
|
|
576
572
|
if (!doctype.schema) {
|
|
@@ -610,7 +606,7 @@ function initializeNewRecord(doctype: DoctypeMeta): Record<string, any> {
|
|
|
610
606
|
* Setup deep reactivity between form data and HST store
|
|
611
607
|
*/
|
|
612
608
|
function setupDeepReactivity(
|
|
613
|
-
doctype:
|
|
609
|
+
doctype: Doctype,
|
|
614
610
|
recordId: string,
|
|
615
611
|
formData: Ref<Record<string, any>>,
|
|
616
612
|
hstStore: HSTNode
|
package/src/doctype.ts
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
|
+
import { List, Map } from 'immutable'
|
|
1
2
|
import { Component } from 'vue'
|
|
2
3
|
|
|
4
|
+
import type { SchemaTypes } from '@stonecrop/aform'
|
|
5
|
+
import type { UnknownMachineConfig } from 'xstate'
|
|
6
|
+
|
|
3
7
|
import type { ImmutableDoctype } from './types'
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
|
-
*
|
|
10
|
+
* Plain object representation of doctype configuration for serialization/API responses.
|
|
11
|
+
* Compatible with the DoctypeMeta type from \@stonecrop/schema.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export type DoctypeConfig = {
|
|
15
|
+
/** Display name of the doctype */
|
|
16
|
+
name: string
|
|
17
|
+
/** URL-friendly slug (kebab-case) */
|
|
18
|
+
slug?: string
|
|
19
|
+
/** Database table name */
|
|
20
|
+
tableName?: string
|
|
21
|
+
/** Field definitions */
|
|
22
|
+
fields?: SchemaTypes[]
|
|
23
|
+
/** Workflow configuration */
|
|
24
|
+
workflow?: UnknownMachineConfig
|
|
25
|
+
/** Actions and their field triggers */
|
|
26
|
+
actions?: Record<string, string[]>
|
|
27
|
+
/** Parent doctype for inheritance */
|
|
28
|
+
inherits?: string
|
|
29
|
+
/** Doctype to use for list views */
|
|
30
|
+
listDoctype?: string
|
|
31
|
+
/** Parent doctype for child tables */
|
|
32
|
+
parentDoctype?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Doctype runtime class with Immutable.js collections for HST change tracking.
|
|
7
37
|
* @public
|
|
8
38
|
*/
|
|
9
|
-
export default class
|
|
39
|
+
export default class Doctype {
|
|
10
40
|
/**
|
|
11
41
|
* The doctype name
|
|
12
42
|
* @public
|
|
@@ -52,7 +82,7 @@ export default class DoctypeMeta {
|
|
|
52
82
|
readonly component?: Component
|
|
53
83
|
|
|
54
84
|
/**
|
|
55
|
-
* Creates a new
|
|
85
|
+
* Creates a new Doctype instance
|
|
56
86
|
* @param doctype - The doctype name
|
|
57
87
|
* @param schema - The doctype schema definition
|
|
58
88
|
* @param workflow - The doctype workflow configuration (XState machine)
|
|
@@ -73,6 +103,84 @@ export default class DoctypeMeta {
|
|
|
73
103
|
this.component = component
|
|
74
104
|
}
|
|
75
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Creates a Doctype instance from a plain configuration object.
|
|
108
|
+
* Handles conversion of arrays to Immutable.js collections internally.
|
|
109
|
+
*
|
|
110
|
+
* This is the recommended way to create a Doctype from API responses
|
|
111
|
+
* or configuration files, as it encapsulates the Immutable.js construction
|
|
112
|
+
* that the framework uses internally.
|
|
113
|
+
*
|
|
114
|
+
* @param config - Plain object with doctype configuration (typically from API response)
|
|
115
|
+
* @returns A new Doctype instance with Immutable.js collections
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* // From an API response
|
|
120
|
+
* const response = await client.getMeta({ doctype: 'plan' })
|
|
121
|
+
* const doctype = Doctype.fromObject(response)
|
|
122
|
+
* registry.addDoctype(doctype)
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* // From a configuration object
|
|
128
|
+
* const planDoctype = Doctype.fromObject({
|
|
129
|
+
* name: 'Plan',
|
|
130
|
+
* fields: [
|
|
131
|
+
* { fieldname: 'title', label: 'Title', fieldtype: 'Data' },
|
|
132
|
+
* { fieldname: 'status', label: 'Status', fieldtype: 'Data' },
|
|
133
|
+
* ],
|
|
134
|
+
* workflow: {
|
|
135
|
+
* id: 'plan',
|
|
136
|
+
* initial: 'draft',
|
|
137
|
+
* states: { draft: {}, submitted: {} }
|
|
138
|
+
* }
|
|
139
|
+
* })
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @public
|
|
143
|
+
*/
|
|
144
|
+
static fromObject(config: DoctypeConfig): Doctype {
|
|
145
|
+
const schema = config.fields ? List(config.fields) : List<SchemaTypes>()
|
|
146
|
+
const actions = config.actions ? Map(config.actions) : Map<string, string[]>()
|
|
147
|
+
|
|
148
|
+
return new Doctype(config.name, schema, config.workflow, actions)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Returns the schema as a plain array for use with components that expect
|
|
153
|
+
* plain JavaScript arrays (e.g., AForm, ATable).
|
|
154
|
+
*
|
|
155
|
+
* @returns Array of schema fields
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* const schemaArray = doctype.getSchemaArray()
|
|
160
|
+
* // Use with AForm
|
|
161
|
+
* <AForm :schema="schemaArray" v-model:data="formData" />
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @public
|
|
165
|
+
*/
|
|
166
|
+
getSchemaArray(): SchemaTypes[] {
|
|
167
|
+
if (!this.schema) return []
|
|
168
|
+
return this.schema.toArray()
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Returns the actions as a plain object for use with components that expect
|
|
173
|
+
* plain JavaScript objects.
|
|
174
|
+
*
|
|
175
|
+
* @returns Object mapping action names to field trigger arrays
|
|
176
|
+
*
|
|
177
|
+
* @public
|
|
178
|
+
*/
|
|
179
|
+
getActionsObject(): Record<string, string[]> {
|
|
180
|
+
if (!this.actions) return {}
|
|
181
|
+
return this.actions.toObject()
|
|
182
|
+
}
|
|
183
|
+
|
|
76
184
|
/**
|
|
77
185
|
* Returns the transitions available from a given workflow state, derived from the
|
|
78
186
|
* doctype's XState workflow configuration.
|
|
@@ -109,7 +217,7 @@ export default class DoctypeMeta {
|
|
|
109
217
|
*
|
|
110
218
|
* @example
|
|
111
219
|
* ```ts
|
|
112
|
-
* const doctype = new
|
|
220
|
+
* const doctype = new Doctype('TaskItem', schema, workflow, actions)
|
|
113
221
|
* console.log(doctype.slug) // 'task-item'
|
|
114
222
|
* ```
|
|
115
223
|
*
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type * from '@stonecrop/atable/types'
|
|
|
3
3
|
|
|
4
4
|
import { useStonecrop } from './composables/stonecrop'
|
|
5
5
|
import { useOperationLog, useUndoRedoShortcuts, withBatch } from './composables/operation-log'
|
|
6
|
-
import
|
|
6
|
+
import Doctype, { type DoctypeConfig } from './doctype'
|
|
7
7
|
import {
|
|
8
8
|
getGlobalTriggerEngine,
|
|
9
9
|
markOperationIrreversible,
|
|
@@ -36,7 +36,8 @@ export type { ValidationIssue, ValidationResult, ValidatorOptions } from './sche
|
|
|
36
36
|
export { ValidationSeverity } from './schema-validator'
|
|
37
37
|
|
|
38
38
|
export {
|
|
39
|
-
|
|
39
|
+
Doctype,
|
|
40
|
+
DoctypeConfig,
|
|
40
41
|
Registry,
|
|
41
42
|
Stonecrop,
|
|
42
43
|
StonecropOptions,
|
package/src/registry.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SchemaTypes } from '@stonecrop/aform'
|
|
2
2
|
import { Router } from 'vue-router'
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import Doctype from './doctype'
|
|
5
5
|
import { getGlobalTriggerEngine } from './field-triggers'
|
|
6
6
|
import { RouteContext } from './types/registry'
|
|
7
7
|
|
|
@@ -24,9 +24,9 @@ export default class Registry {
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* The registry property contains a collection of doctypes
|
|
27
|
-
* @see {@link
|
|
27
|
+
* @see {@link Doctype}
|
|
28
28
|
*/
|
|
29
|
-
readonly registry: Record<string,
|
|
29
|
+
readonly registry: Record<string, Doctype>
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* The Vue router instance
|
|
@@ -39,7 +39,7 @@ export default class Registry {
|
|
|
39
39
|
* @param router - Optional Vue router instance for route management
|
|
40
40
|
* @param getMeta - Optional function to fetch doctype metadata from an API
|
|
41
41
|
*/
|
|
42
|
-
constructor(router?: Router, getMeta?: (routeContext: RouteContext) =>
|
|
42
|
+
constructor(router?: Router, getMeta?: (routeContext: RouteContext) => Doctype | Promise<Doctype>) {
|
|
43
43
|
if (Registry._root) {
|
|
44
44
|
return Registry._root
|
|
45
45
|
}
|
|
@@ -52,17 +52,17 @@ export default class Registry {
|
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* The getMeta function fetches doctype metadata from an API based on route context
|
|
55
|
-
* @see {@link
|
|
55
|
+
* @see {@link Doctype}
|
|
56
56
|
*/
|
|
57
|
-
getMeta?: (routeContext: RouteContext) =>
|
|
57
|
+
getMeta?: (routeContext: RouteContext) => Doctype | Promise<Doctype>
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* Get doctype metadata
|
|
61
61
|
* @param doctype - The doctype to fetch metadata for
|
|
62
62
|
* @returns The doctype metadata
|
|
63
|
-
* @see {@link
|
|
63
|
+
* @see {@link Doctype}
|
|
64
64
|
*/
|
|
65
|
-
addDoctype(doctype:
|
|
65
|
+
addDoctype(doctype: Doctype) {
|
|
66
66
|
if (!(doctype.slug in this.registry)) {
|
|
67
67
|
this.registry[doctype.slug] = doctype
|
|
68
68
|
}
|
|
@@ -153,7 +153,7 @@ export default class Registry {
|
|
|
153
153
|
'options' in field &&
|
|
154
154
|
typeof field.options === 'string'
|
|
155
155
|
) {
|
|
156
|
-
const doctypeSlug = field.options
|
|
156
|
+
const doctypeSlug = field.options
|
|
157
157
|
|
|
158
158
|
// Circular reference protection
|
|
159
159
|
if (seen.has(doctypeSlug)) {
|
|
@@ -275,10 +275,10 @@ export default class Registry {
|
|
|
275
275
|
/**
|
|
276
276
|
* Get a registered doctype by slug
|
|
277
277
|
* @param slug - The doctype slug to look up
|
|
278
|
-
* @returns The
|
|
278
|
+
* @returns The Doctype instance if found, or undefined
|
|
279
279
|
* @public
|
|
280
280
|
*/
|
|
281
|
-
getDoctype(slug: string):
|
|
281
|
+
getDoctype(slug: string): Doctype | undefined {
|
|
282
282
|
return this.registry[slug]
|
|
283
283
|
}
|
|
284
284
|
|
package/src/stonecrop.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DataClient } from '@stonecrop/schema'
|
|
2
2
|
import { reactive } from 'vue'
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import Doctype from './doctype'
|
|
5
5
|
import Registry from './registry'
|
|
6
6
|
import { createHST, type HSTNode } from './stores/hst'
|
|
7
7
|
import { useOperationLogStore } from './stores/operation-log'
|
|
@@ -119,7 +119,7 @@ export class Stonecrop {
|
|
|
119
119
|
// Extend Registry.addDoctype to auto-create HST store sections
|
|
120
120
|
const originalAddDoctype = this.registry.addDoctype.bind(this.registry)
|
|
121
121
|
|
|
122
|
-
this.registry.addDoctype = (doctype:
|
|
122
|
+
this.registry.addDoctype = (doctype: Doctype) => {
|
|
123
123
|
// Call original method
|
|
124
124
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
125
125
|
originalAddDoctype(doctype)
|
|
@@ -136,7 +136,7 @@ export class Stonecrop {
|
|
|
136
136
|
* @param doctype - The doctype to get records for
|
|
137
137
|
* @returns HST node containing records hash
|
|
138
138
|
*/
|
|
139
|
-
records(doctype: string |
|
|
139
|
+
records(doctype: string | Doctype): HSTNode {
|
|
140
140
|
const slug = typeof doctype === 'string' ? doctype : doctype.slug
|
|
141
141
|
this.ensureDoctypeExists(slug)
|
|
142
142
|
return this.hstStore.getNode(slug)
|
|
@@ -148,7 +148,7 @@ export class Stonecrop {
|
|
|
148
148
|
* @param recordId - The record ID
|
|
149
149
|
* @param recordData - The record data
|
|
150
150
|
*/
|
|
151
|
-
addRecord(doctype: string |
|
|
151
|
+
addRecord(doctype: string | Doctype, recordId: string, recordData: any): void {
|
|
152
152
|
const slug = typeof doctype === 'string' ? doctype : doctype.slug
|
|
153
153
|
|
|
154
154
|
this.ensureDoctypeExists(slug)
|
|
@@ -163,7 +163,7 @@ export class Stonecrop {
|
|
|
163
163
|
* @param recordId - The record ID
|
|
164
164
|
* @returns HST node for the record or undefined
|
|
165
165
|
*/
|
|
166
|
-
getRecordById(doctype: string |
|
|
166
|
+
getRecordById(doctype: string | Doctype, recordId: string): HSTNode | undefined {
|
|
167
167
|
const slug = typeof doctype === 'string' ? doctype : doctype.slug
|
|
168
168
|
this.ensureDoctypeExists(slug)
|
|
169
169
|
|
|
@@ -188,7 +188,7 @@ export class Stonecrop {
|
|
|
188
188
|
* @param doctype - The doctype
|
|
189
189
|
* @param recordId - The record ID
|
|
190
190
|
*/
|
|
191
|
-
removeRecord(doctype: string |
|
|
191
|
+
removeRecord(doctype: string | Doctype, recordId: string): void {
|
|
192
192
|
const slug = typeof doctype === 'string' ? doctype : doctype.slug
|
|
193
193
|
this.ensureDoctypeExists(slug)
|
|
194
194
|
|
|
@@ -203,7 +203,7 @@ export class Stonecrop {
|
|
|
203
203
|
* @param doctype - The doctype
|
|
204
204
|
* @returns Array of record IDs
|
|
205
205
|
*/
|
|
206
|
-
getRecordIds(doctype: string |
|
|
206
|
+
getRecordIds(doctype: string | Doctype): string[] {
|
|
207
207
|
const slug = typeof doctype === 'string' ? doctype : doctype.slug
|
|
208
208
|
this.ensureDoctypeExists(slug)
|
|
209
209
|
|
|
@@ -219,7 +219,7 @@ export class Stonecrop {
|
|
|
219
219
|
* Clear all records for a doctype
|
|
220
220
|
* @param doctype - The doctype
|
|
221
221
|
*/
|
|
222
|
-
clearRecords(doctype: string |
|
|
222
|
+
clearRecords(doctype: string | Doctype): void {
|
|
223
223
|
const slug = typeof doctype === 'string' ? doctype : doctype.slug
|
|
224
224
|
this.ensureDoctypeExists(slug)
|
|
225
225
|
|
|
@@ -234,7 +234,7 @@ export class Stonecrop {
|
|
|
234
234
|
* Setup method for doctype initialization
|
|
235
235
|
* @param doctype - The doctype to setup
|
|
236
236
|
*/
|
|
237
|
-
setup(doctype:
|
|
237
|
+
setup(doctype: Doctype): void {
|
|
238
238
|
// Ensure doctype exists in store
|
|
239
239
|
this.ensureDoctypeExists(doctype.slug)
|
|
240
240
|
}
|
|
@@ -246,7 +246,7 @@ export class Stonecrop {
|
|
|
246
246
|
* @param action - The action to run
|
|
247
247
|
* @param args - Action arguments (typically record IDs)
|
|
248
248
|
*/
|
|
249
|
-
runAction(doctype:
|
|
249
|
+
runAction(doctype: Doctype, action: string, args?: any[]): void {
|
|
250
250
|
const registry = this.registry.registry[doctype.slug]
|
|
251
251
|
const actions = registry?.actions?.get(action)
|
|
252
252
|
const recordIds = Array.isArray(args) ? args.filter((arg): arg is string => typeof arg === 'string') : undefined
|
|
@@ -285,7 +285,7 @@ export class Stonecrop {
|
|
|
285
285
|
* @param doctype - The doctype
|
|
286
286
|
* @throws Error if no data client has been configured
|
|
287
287
|
*/
|
|
288
|
-
async getRecords(doctype:
|
|
288
|
+
async getRecords(doctype: Doctype): Promise<void> {
|
|
289
289
|
if (!this._client) {
|
|
290
290
|
throw new Error(
|
|
291
291
|
'No data client configured. Call setClient() with a DataClient implementation ' +
|
|
@@ -309,7 +309,7 @@ export class Stonecrop {
|
|
|
309
309
|
* @param recordId - The record ID
|
|
310
310
|
* @throws Error if no data client has been configured
|
|
311
311
|
*/
|
|
312
|
-
async getRecord(doctype:
|
|
312
|
+
async getRecord(doctype: Doctype, recordId: string): Promise<void> {
|
|
313
313
|
if (!this._client) {
|
|
314
314
|
throw new Error(
|
|
315
315
|
'No data client configured. Call setClient() with a DataClient implementation ' +
|
|
@@ -335,7 +335,7 @@ export class Stonecrop {
|
|
|
335
335
|
* @throws Error if no data client has been configured
|
|
336
336
|
*/
|
|
337
337
|
async dispatchAction(
|
|
338
|
-
doctype:
|
|
338
|
+
doctype: Doctype,
|
|
339
339
|
action: string,
|
|
340
340
|
args?: unknown[]
|
|
341
341
|
): Promise<{ success: boolean; data: unknown; error: string | null }> {
|
|
@@ -386,13 +386,13 @@ export class Stonecrop {
|
|
|
386
386
|
* empty the doctype's declared `workflow.initial` state is used as the fallback,
|
|
387
387
|
* giving callers a reliable state name without having to duplicate that logic.
|
|
388
388
|
*
|
|
389
|
-
* @param doctype - The doctype slug or
|
|
389
|
+
* @param doctype - The doctype slug or Doctype instance
|
|
390
390
|
* @param recordId - The record identifier
|
|
391
391
|
* @returns The current state name, or an empty string if the doctype has no workflow
|
|
392
392
|
*
|
|
393
393
|
* @public
|
|
394
394
|
*/
|
|
395
|
-
getRecordState(doctype: string |
|
|
395
|
+
getRecordState(doctype: string | Doctype, recordId: string): string {
|
|
396
396
|
const slug = typeof doctype === 'string' ? doctype : doctype.slug
|
|
397
397
|
const meta = this.registry.getDoctype(slug)
|
|
398
398
|
if (!meta?.workflow) return ''
|
package/src/types/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Component } from 'vue'
|
|
|
5
5
|
import type { Router } from 'vue-router'
|
|
6
6
|
import type { AnyStateNodeConfig, UnknownMachineConfig } from 'xstate'
|
|
7
7
|
|
|
8
|
-
import type
|
|
8
|
+
import type Doctype from '../doctype'
|
|
9
9
|
import Registry from '../registry'
|
|
10
10
|
import { Stonecrop } from '../stonecrop'
|
|
11
11
|
import type { RouteContext } from './registry'
|
|
@@ -47,7 +47,7 @@ export type Schema = {
|
|
|
47
47
|
export type InstallOptions = {
|
|
48
48
|
router?: Router
|
|
49
49
|
components?: Record<string, Component>
|
|
50
|
-
getMeta?: (routeContext: RouteContext) =>
|
|
50
|
+
getMeta?: (routeContext: RouteContext) => Doctype | Promise<Doctype>
|
|
51
51
|
/**
|
|
52
52
|
* Data client for fetching doctype metadata and records.
|
|
53
53
|
* Use \@stonecrop/graphql-client's StonecropClient for GraphQL backends,
|