@stonecrop/stonecrop 0.10.7 → 0.10.9
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/doctype.js +51 -2
- package/dist/src/doctype.d.ts +28 -4
- package/dist/src/doctype.d.ts.map +1 -1
- package/dist/src/stonecrop.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +3 -3
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/stonecrop.d.ts +29 -5
- package/dist/stonecrop.js +42 -8
- package/dist/stonecrop.js.map +1 -1
- package/package.json +4 -4
- package/src/doctype.ts +67 -6
- package/src/stonecrop.ts +15 -5
- package/src/types/index.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/stonecrop",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.9",
|
|
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.9"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"pinia": "^3.0.4",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"vue-router": "^5.0.2",
|
|
61
61
|
"vite": "^7.3.1",
|
|
62
62
|
"vitest": "^4.0.18",
|
|
63
|
-
"@stonecrop/
|
|
64
|
-
"@stonecrop/
|
|
63
|
+
"@stonecrop/aform": "0.10.9",
|
|
64
|
+
"@stonecrop/atable": "0.10.9",
|
|
65
65
|
"stonecrop-rig": "0.7.0"
|
|
66
66
|
},
|
|
67
67
|
"description": "Schema-driven framework with XState workflows and HST state management",
|
package/src/doctype.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import type { SchemaTypes } from '@stonecrop/aform'
|
|
2
|
+
import type { WorkflowMeta } from '@stonecrop/schema'
|
|
1
3
|
import { List, Map } from 'immutable'
|
|
2
4
|
import { Component } from 'vue'
|
|
3
|
-
|
|
4
|
-
import type { SchemaTypes } from '@stonecrop/aform'
|
|
5
5
|
import type { UnknownMachineConfig } from 'xstate'
|
|
6
6
|
|
|
7
7
|
import type { ImmutableDoctype } from './types'
|
|
@@ -20,8 +20,8 @@ export type DoctypeConfig = {
|
|
|
20
20
|
tableName?: string
|
|
21
21
|
/** Field definitions */
|
|
22
22
|
fields?: SchemaTypes[]
|
|
23
|
-
/** Workflow configuration */
|
|
24
|
-
workflow?: UnknownMachineConfig
|
|
23
|
+
/** Workflow configuration (XState format or simple WorkflowMeta) */
|
|
24
|
+
workflow?: UnknownMachineConfig | WorkflowMeta
|
|
25
25
|
/** Actions and their field triggers */
|
|
26
26
|
actions?: Record<string, string[]>
|
|
27
27
|
/** Parent doctype for inheritance */
|
|
@@ -183,7 +183,7 @@ export default class Doctype {
|
|
|
183
183
|
|
|
184
184
|
/**
|
|
185
185
|
* Returns the transitions available from a given workflow state, derived from the
|
|
186
|
-
* doctype's
|
|
186
|
+
* doctype's workflow configuration. Supports both XState format and WorkflowMeta format.
|
|
187
187
|
*
|
|
188
188
|
* @param currentState - The state name to read transitions from
|
|
189
189
|
* @returns Array of transition descriptors with `name` and `targetState`
|
|
@@ -197,7 +197,34 @@ export default class Doctype {
|
|
|
197
197
|
* @public
|
|
198
198
|
*/
|
|
199
199
|
getAvailableTransitions(currentState: string): Array<{ name: string; targetState: string }> {
|
|
200
|
-
const
|
|
200
|
+
const workflow = this.workflow
|
|
201
|
+
if (!workflow) return []
|
|
202
|
+
|
|
203
|
+
// Check if this is WorkflowMeta format (states is an array) or XState format (states is an object)
|
|
204
|
+
if (Array.isArray(workflow.states)) {
|
|
205
|
+
// WorkflowMeta format: validate state exists and filter actions by allowedStates
|
|
206
|
+
const states = workflow.states
|
|
207
|
+
if (!states.includes(currentState)) return []
|
|
208
|
+
|
|
209
|
+
const actions = (workflow as WorkflowMeta).actions
|
|
210
|
+
if (!actions) return []
|
|
211
|
+
|
|
212
|
+
return Object.entries(actions)
|
|
213
|
+
.filter(([, actionDef]) => {
|
|
214
|
+
const allowedStates = actionDef.allowedStates
|
|
215
|
+
// If no allowedStates specified, action is available in all valid states
|
|
216
|
+
if (!allowedStates || allowedStates.length === 0) return true
|
|
217
|
+
return allowedStates.includes(currentState)
|
|
218
|
+
})
|
|
219
|
+
.map(([name]) => ({
|
|
220
|
+
name,
|
|
221
|
+
// WorkflowMeta doesn't define target states - transitions are handled server-side
|
|
222
|
+
targetState: currentState,
|
|
223
|
+
}))
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// XState format: use the on property of the state
|
|
227
|
+
const states = workflow.states
|
|
201
228
|
if (!states) return []
|
|
202
229
|
const stateConfig = states[currentState]
|
|
203
230
|
if (!stateConfig?.on) return []
|
|
@@ -207,6 +234,40 @@ export default class Doctype {
|
|
|
207
234
|
}))
|
|
208
235
|
}
|
|
209
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Returns metadata for a specific action, if available.
|
|
239
|
+
* Only works with WorkflowMeta format; returns undefined for XState format.
|
|
240
|
+
*
|
|
241
|
+
* @param actionName - The action name to get metadata for
|
|
242
|
+
* @returns Action metadata or undefined
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* const actionMeta = doctype.getActionMeta('submit')
|
|
247
|
+
* // { label: 'Submit', handler: 'plan:submit', allowedStates: ['draft'] }
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
250
|
+
* @public
|
|
251
|
+
*/
|
|
252
|
+
getActionMeta(
|
|
253
|
+
actionName: string
|
|
254
|
+
):
|
|
255
|
+
| {
|
|
256
|
+
label: string
|
|
257
|
+
handler: string
|
|
258
|
+
requiredFields?: string[]
|
|
259
|
+
allowedStates?: string[]
|
|
260
|
+
confirm?: boolean
|
|
261
|
+
args?: Record<string, unknown>
|
|
262
|
+
}
|
|
263
|
+
| undefined {
|
|
264
|
+
const workflow = this.workflow
|
|
265
|
+
if (!workflow || !Array.isArray(workflow.states)) return undefined
|
|
266
|
+
|
|
267
|
+
const actions = (workflow as WorkflowMeta).actions
|
|
268
|
+
return actions?.[actionName]
|
|
269
|
+
}
|
|
270
|
+
|
|
210
271
|
/**
|
|
211
272
|
* Converts the registered doctype string to a slug (kebab-case). The following conversions are made:
|
|
212
273
|
* - It replaces camelCase and PascalCase with kebab-case strings
|
package/src/stonecrop.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataClient } from '@stonecrop/schema'
|
|
1
|
+
import type { DataClient, WorkflowMeta } from '@stonecrop/schema'
|
|
2
2
|
import { reactive } from 'vue'
|
|
3
3
|
|
|
4
4
|
import Doctype from './doctype'
|
|
@@ -400,10 +400,20 @@ export class Stonecrop {
|
|
|
400
400
|
const record = this.getRecordById(slug, recordId)
|
|
401
401
|
const status = record?.get('status') as string | undefined
|
|
402
402
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
403
|
+
// Handle both XState format and WorkflowMeta format
|
|
404
|
+
const workflow = meta.workflow
|
|
405
|
+
let initialState: string
|
|
406
|
+
|
|
407
|
+
if (Array.isArray(workflow.states)) {
|
|
408
|
+
// WorkflowMeta format: states is a string array
|
|
409
|
+
initialState = workflow.states[0] ?? ''
|
|
410
|
+
} else {
|
|
411
|
+
// XState format: states is an object, use initial or first key
|
|
412
|
+
initialState =
|
|
413
|
+
typeof (workflow as { initial?: unknown }).initial === 'string'
|
|
414
|
+
? (workflow as { initial: string }).initial
|
|
415
|
+
: Object.keys(workflow.states ?? {})[0] ?? ''
|
|
416
|
+
}
|
|
407
417
|
|
|
408
418
|
return status || initialState
|
|
409
419
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataClient } from '@stonecrop/schema'
|
|
1
|
+
import type { DataClient, WorkflowMeta } from '@stonecrop/schema'
|
|
2
2
|
import type { SchemaTypes } from '@stonecrop/aform'
|
|
3
3
|
import { List, Map } from 'immutable'
|
|
4
4
|
import type { Component } from 'vue'
|
|
@@ -16,7 +16,7 @@ import type { RouteContext } from './registry'
|
|
|
16
16
|
*/
|
|
17
17
|
export type ImmutableDoctype = {
|
|
18
18
|
readonly schema?: List<SchemaTypes> // TODO: allow schema to be a function
|
|
19
|
-
readonly workflow?: UnknownMachineConfig | AnyStateNodeConfig
|
|
19
|
+
readonly workflow?: UnknownMachineConfig | AnyStateNodeConfig | WorkflowMeta
|
|
20
20
|
readonly actions?: Map<string, string[]>
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -27,7 +27,7 @@ export type ImmutableDoctype = {
|
|
|
27
27
|
export type MutableDoctype = {
|
|
28
28
|
doctype?: string
|
|
29
29
|
schema?: SchemaTypes[] // TODO: allow schema to be a function
|
|
30
|
-
workflow?: UnknownMachineConfig | AnyStateNodeConfig
|
|
30
|
+
workflow?: UnknownMachineConfig | AnyStateNodeConfig | WorkflowMeta
|
|
31
31
|
actions?: Record<string, string[]>
|
|
32
32
|
}
|
|
33
33
|
|