@stonecrop/stonecrop 0.11.0 → 0.11.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.
Files changed (49) hide show
  1. package/package.json +4 -4
  2. package/dist/composable.js +0 -1
  3. package/dist/composables/use-lazy-link-state.js +0 -125
  4. package/dist/composables/use-stonecrop.js +0 -476
  5. package/dist/operation-log-DB-dGNT9.js +0 -593
  6. package/dist/operation-log-DB-dGNT9.js.map +0 -1
  7. package/dist/src/composable.d.ts +0 -11
  8. package/dist/src/composable.d.ts.map +0 -1
  9. package/dist/src/composable.js +0 -477
  10. package/dist/src/composables/operation-log.js +0 -224
  11. package/dist/src/composables/stonecrop.js +0 -574
  12. package/dist/src/composables/use-lazy-link-state.d.ts +0 -25
  13. package/dist/src/composables/use-lazy-link-state.d.ts.map +0 -1
  14. package/dist/src/composables/use-stonecrop.d.ts +0 -93
  15. package/dist/src/composables/use-stonecrop.d.ts.map +0 -1
  16. package/dist/src/composables/useNestedSchema.d.ts +0 -110
  17. package/dist/src/composables/useNestedSchema.d.ts.map +0 -1
  18. package/dist/src/composables/useNestedSchema.js +0 -155
  19. package/dist/src/doctype.js +0 -234
  20. package/dist/src/exceptions.js +0 -16
  21. package/dist/src/field-triggers.js +0 -567
  22. package/dist/src/index.js +0 -23
  23. package/dist/src/plugins/index.js +0 -96
  24. package/dist/src/registry.js +0 -246
  25. package/dist/src/schema-validator.js +0 -315
  26. package/dist/src/stonecrop.js +0 -339
  27. package/dist/src/stores/data.d.ts +0 -11
  28. package/dist/src/stores/data.d.ts.map +0 -1
  29. package/dist/src/stores/hst.js +0 -495
  30. package/dist/src/stores/index.js +0 -12
  31. package/dist/src/stores/operation-log.js +0 -568
  32. package/dist/src/stores/xstate.d.ts +0 -31
  33. package/dist/src/stores/xstate.d.ts.map +0 -1
  34. package/dist/src/tsdoc-metadata.json +0 -11
  35. package/dist/src/types/field-triggers.js +0 -4
  36. package/dist/src/types/index.js +0 -4
  37. package/dist/src/types/operation-log.js +0 -0
  38. package/dist/src/types/registry.js +0 -0
  39. package/dist/src/utils.d.ts +0 -24
  40. package/dist/src/utils.d.ts.map +0 -1
  41. package/dist/stonecrop.css +0 -1
  42. package/dist/stonecrop.umd.cjs +0 -6
  43. package/dist/stonecrop.umd.cjs.map +0 -1
  44. package/dist/stores/data.js +0 -7
  45. package/dist/stores/xstate.js +0 -29
  46. package/dist/tests/setup.d.ts +0 -5
  47. package/dist/tests/setup.d.ts.map +0 -1
  48. package/dist/tests/setup.js +0 -15
  49. package/dist/utils.js +0 -46
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-stonecrop.d.ts","sourceRoot":"","sources":["../../../src/composables/use-stonecrop.ts"],"names":[],"mappings":"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"}
@@ -1,110 +0,0 @@
1
- import { type Ref } from 'vue';
2
- import type { SchemaTypes } from '@stonecrop/aform/types';
3
- /**
4
- * Registry interface for schema lookup
5
- * Compatible with Stonecrop Registry but doesn't require it as a dependency
6
- * @public
7
- */
8
- export interface SchemaRegistry {
9
- /**
10
- * Map of doctype slugs to their metadata including schema, slug, and doctype name
11
- */
12
- registry: Record<string, {
13
- doctype: string;
14
- slug: string;
15
- schema?: SchemaTypes[] | Iterable<SchemaTypes>;
16
- }>;
17
- }
18
- /**
19
- * Options for useNestedSchema composable
20
- * @public
21
- */
22
- export interface UseNestedSchemaOptions {
23
- /**
24
- * The target doctype slug to load schema for
25
- */
26
- doctype: string;
27
- /**
28
- * Registry instance for schema lookup (optional)
29
- * If not provided, you must supply schema directly via setSchema
30
- */
31
- registry?: SchemaRegistry;
32
- /**
33
- * Direct schema array to use instead of loading from registry
34
- */
35
- schema?: SchemaTypes[];
36
- /**
37
- * Initial data for the nested form
38
- */
39
- initialData?: any;
40
- }
41
- /**
42
- * Return type for useNestedSchema composable
43
- * @public
44
- */
45
- export interface UseNestedSchemaReturn {
46
- /**
47
- * The loaded/provided nested schema
48
- */
49
- schema: Ref<SchemaTypes[] | undefined>;
50
- /**
51
- * Error message if schema loading fails
52
- */
53
- error: Ref<string | undefined>;
54
- /**
55
- * Loading state
56
- */
57
- loading: Ref<boolean>;
58
- /**
59
- * Initialize empty record data based on schema
60
- */
61
- initializeRecord: () => Record<string, any>;
62
- /**
63
- * Initialize array of records
64
- */
65
- initializeArray: (count: number) => Record<string, any>[];
66
- /**
67
- * Manually set schema (useful if not using registry)
68
- */
69
- setSchema: (newSchema: SchemaTypes[]) => void;
70
- /**
71
- * Load schema from registry
72
- */
73
- loadSchema: () => Promise<void>;
74
- /**
75
- * Get the doctype name (display name)
76
- */
77
- doctypeName: Ref<string>;
78
- }
79
- /**
80
- * Composable for managing nested schema loading and initialization
81
- *
82
- * This composable provides utilities for working with nested doctypes in forms
83
- * without being tightly coupled to Stonecrop or any specific state management solution.
84
- *
85
- * **Note:** This composable supports 1:1 nested schemas only. For 1:many relationships,
86
- * use nested table schemas which provide proper doctype mapping.
87
- *
88
- * @example
89
- * ```typescript
90
- * // With Stonecrop registry
91
- * const { schema, initializeRecord, loadSchema } = useNestedSchema({
92
- * doctype: 'address',
93
- * registry: stonecrop.registry,
94
- * })
95
- * await loadSchema()
96
- *
97
- * // With direct schema
98
- * const { schema, initializeRecord } = useNestedSchema({
99
- * doctype: 'address',
100
- * schema: addressSchema,
101
- * })
102
- *
103
- * // Initialize data
104
- * const emptyAddress = initializeRecord()
105
- * ```
106
- *
107
- * @internal
108
- */
109
- export declare function useNestedSchema(options: UseNestedSchemaOptions): UseNestedSchemaReturn;
110
- //# sourceMappingURL=useNestedSchema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useNestedSchema.d.ts","sourceRoot":"","sources":["../../../src/composables/useNestedSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAEnC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEzD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,CACf,MAAM,EACN;QACC,OAAO,EAAE,MAAM,CAAA;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;KAC9C,CACD,CAAA;CACD;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAA;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,EAAE,CAAA;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,GAAG,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,CAAA;IAEtC;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAE9B;;OAEG;IACH,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAErB;;OAEG;IACH,gBAAgB,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE3C;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAA;IAEzD;;OAEG;IACH,SAAS,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,IAAI,CAAA;IAE7C;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAE/B;;OAEG;IACH,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CAwItF"}
@@ -1,155 +0,0 @@
1
- import { ref } from 'vue';
2
- /**
3
- * Composable for managing nested schema loading and initialization
4
- *
5
- * This composable provides utilities for working with nested doctypes in forms
6
- * without being tightly coupled to Stonecrop or any specific state management solution.
7
- *
8
- * **Note:** This composable supports 1:1 nested schemas only. For 1:many relationships,
9
- * use nested table schemas which provide proper doctype mapping.
10
- *
11
- * @example
12
- * ```typescript
13
- * // With Stonecrop registry
14
- * const { schema, initializeRecord, loadSchema } = useNestedSchema({
15
- * doctype: 'address',
16
- * registry: stonecrop.registry,
17
- * })
18
- * await loadSchema()
19
- *
20
- * // With direct schema
21
- * const { schema, initializeRecord } = useNestedSchema({
22
- * doctype: 'address',
23
- * schema: addressSchema,
24
- * })
25
- *
26
- * // Initialize data
27
- * const emptyAddress = initializeRecord()
28
- * ```
29
- *
30
- * @internal
31
- */
32
- export function useNestedSchema(options) {
33
- const schema = ref();
34
- const error = ref();
35
- const loading = ref(false);
36
- const doctypeName = ref(options.doctype);
37
- // Initialize with provided schema if available
38
- if (options.schema) {
39
- schema.value = options.schema;
40
- }
41
- // Initialize with provided data if available
42
- if (options.initialData) {
43
- // Data is provided externally, composable just manages schema
44
- }
45
- /**
46
- * Load schema from registry
47
- */
48
- const loadSchema = async () => {
49
- if (!options.registry) {
50
- error.value = 'No registry provided and no schema set directly';
51
- return;
52
- }
53
- loading.value = true;
54
- error.value = undefined;
55
- try {
56
- // Get doctype from registry
57
- const doctype = options.registry.registry[options.doctype];
58
- if (!doctype) {
59
- error.value = `Doctype '${options.doctype}' not found in registry`;
60
- return;
61
- }
62
- doctypeName.value = doctype.doctype;
63
- // Convert schema to array (handles both arrays and Immutable Lists)
64
- if (Array.isArray(doctype.schema)) {
65
- schema.value = doctype.schema;
66
- }
67
- else if (doctype.schema && typeof doctype.schema[Symbol.iterator] === 'function') {
68
- schema.value = Array.from(doctype.schema);
69
- }
70
- else {
71
- error.value = 'Invalid schema format';
72
- }
73
- }
74
- catch (err) {
75
- error.value = `Failed to load schema: ${err instanceof Error ? err.message : String(err)}`;
76
- }
77
- finally {
78
- loading.value = false;
79
- }
80
- };
81
- /**
82
- * Manually set schema
83
- */
84
- const setSchema = (newSchema) => {
85
- schema.value = newSchema;
86
- error.value = undefined;
87
- };
88
- /**
89
- * Initialize empty record based on schema
90
- */
91
- const initializeRecord = () => {
92
- const initialData = {};
93
- if (!schema.value) {
94
- return initialData;
95
- }
96
- schema.value.forEach(field => {
97
- const fieldtype = 'fieldtype' in field ? field.fieldtype : 'Data';
98
- const fieldname = field.fieldname;
99
- // Provide sensible defaults based on field type
100
- switch (fieldtype) {
101
- case 'Data':
102
- case 'Text':
103
- initialData[fieldname] = '';
104
- break;
105
- case 'Check':
106
- initialData[fieldname] = false;
107
- break;
108
- case 'Int':
109
- case 'Float':
110
- case 'Decimal':
111
- initialData[fieldname] = 0;
112
- break;
113
- case 'Doctype':
114
- // Initialize nested Doctype fields as empty objects (1:1 only)
115
- initialData[fieldname] = {};
116
- break;
117
- case 'JSON':
118
- initialData[fieldname] = {};
119
- break;
120
- case 'Date':
121
- case 'Time':
122
- case 'Datetime':
123
- initialData[fieldname] = null;
124
- break;
125
- default:
126
- initialData[fieldname] = null;
127
- }
128
- // Use default value if specified in schema
129
- if ('default' in field && field.default !== undefined) {
130
- initialData[fieldname] = field.default;
131
- }
132
- });
133
- return initialData;
134
- };
135
- /**
136
- * Initialize array of records
137
- */
138
- const initializeArray = (count) => {
139
- return Array.from({ length: count }, () => initializeRecord());
140
- };
141
- // Auto-load if registry is provided
142
- if (options.registry && !options.schema) {
143
- void loadSchema();
144
- }
145
- return {
146
- schema,
147
- error,
148
- loading,
149
- doctypeName,
150
- initializeRecord,
151
- initializeArray,
152
- setSchema,
153
- loadSchema,
154
- };
155
- }
@@ -1,234 +0,0 @@
1
- import { List, Map } from 'immutable';
2
- /**
3
- * Doctype runtime class with Immutable.js collections for HST change tracking.
4
- * @public
5
- */
6
- export default class Doctype {
7
- /**
8
- * The doctype name
9
- * @public
10
- * @readonly
11
- */
12
- doctype;
13
- /**
14
- * Alias for doctype (for DoctypeLike interface compatibility)
15
- * @public
16
- * @readonly
17
- */
18
- get name() {
19
- return this.doctype;
20
- }
21
- /**
22
- * The doctype schema
23
- * @public
24
- * @readonly
25
- */
26
- schema;
27
- /**
28
- * The doctype workflow
29
- * @public
30
- * @readonly
31
- */
32
- workflow;
33
- /**
34
- * The doctype actions and field triggers
35
- * @public
36
- * @readonly
37
- */
38
- actions;
39
- /**
40
- * The doctype component
41
- * @public
42
- * @readonly
43
- */
44
- component;
45
- /**
46
- * Creates a new Doctype instance
47
- * @param doctype - The doctype name
48
- * @param schema - The doctype schema definition
49
- * @param workflow - The doctype workflow configuration (XState machine)
50
- * @param actions - The doctype actions and field triggers
51
- * @param component - Optional Vue component for rendering the doctype
52
- */
53
- constructor(doctype, schema, workflow, actions, component) {
54
- this.doctype = doctype;
55
- this.schema = schema;
56
- this.workflow = workflow;
57
- this.actions = actions;
58
- this.component = component;
59
- }
60
- /**
61
- * Creates a Doctype instance from a plain configuration object.
62
- * Handles conversion of arrays to Immutable.js collections internally.
63
- *
64
- * This is the recommended way to create a Doctype from API responses
65
- * or configuration files, as it encapsulates the Immutable.js construction
66
- * that the framework uses internally.
67
- *
68
- * @param config - Plain object with doctype configuration (typically from API response)
69
- * @returns A new Doctype instance with Immutable.js collections
70
- *
71
- * @example
72
- * ```ts
73
- * // From an API response
74
- * const response = await client.getMeta({ doctype: 'plan' })
75
- * const doctype = Doctype.fromObject(response)
76
- * registry.addDoctype(doctype)
77
- * ```
78
- *
79
- * @example
80
- * ```ts
81
- * // From a configuration object
82
- * const planDoctype = Doctype.fromObject({
83
- * name: 'Plan',
84
- * fields: [
85
- * { fieldname: 'title', label: 'Title', fieldtype: 'Data' },
86
- * { fieldname: 'status', label: 'Status', fieldtype: 'Data' },
87
- * ],
88
- * workflow: {
89
- * id: 'plan',
90
- * initial: 'draft',
91
- * states: { draft: {}, submitted: {} }
92
- * }
93
- * })
94
- * ```
95
- *
96
- * @public
97
- */
98
- static fromObject(config) {
99
- const schema = config.fields ? List(config.fields) : List();
100
- const actions = config.actions ? Map(config.actions) : Map();
101
- return new Doctype(config.name, schema, config.workflow, actions);
102
- }
103
- /**
104
- * Returns the schema as a plain array for use with components that expect
105
- * plain JavaScript arrays (e.g., AForm, ATable).
106
- *
107
- * @returns Array of schema fields
108
- *
109
- * @example
110
- * ```ts
111
- * const schemaArray = doctype.getSchemaArray()
112
- * // Use with AForm
113
- * <AForm :schema="schemaArray" v-model:data="formData" />
114
- * ```
115
- *
116
- * @public
117
- */
118
- getSchemaArray() {
119
- if (!this.schema)
120
- return [];
121
- return this.schema.toArray();
122
- }
123
- /**
124
- * Returns the actions as a plain object for use with components that expect
125
- * plain JavaScript objects.
126
- *
127
- * @returns Object mapping action names to field trigger arrays
128
- *
129
- * @public
130
- */
131
- getActionsObject() {
132
- if (!this.actions)
133
- return {};
134
- return this.actions.toObject();
135
- }
136
- /**
137
- * Returns the transitions available from a given workflow state, derived from the
138
- * doctype's workflow configuration. Supports both XState format and WorkflowMeta format.
139
- *
140
- * @param currentState - The state name to read transitions from
141
- * @returns Array of transition descriptors with `name` and `targetState`
142
- *
143
- * @example
144
- * ```ts
145
- * const transitions = doctype.getAvailableTransitions('draft')
146
- * // [{ name: 'SUBMIT', targetState: 'submitted' }]
147
- * ```
148
- *
149
- * @public
150
- */
151
- getAvailableTransitions(currentState) {
152
- const workflow = this.workflow;
153
- if (!workflow)
154
- return [];
155
- // Check if this is WorkflowMeta format (states is an array) or XState format (states is an object)
156
- if (Array.isArray(workflow.states)) {
157
- // WorkflowMeta format: validate state exists and filter actions by allowedStates
158
- const states = workflow.states;
159
- if (!states.includes(currentState))
160
- return [];
161
- const actions = workflow.actions;
162
- if (!actions)
163
- return [];
164
- return Object.entries(actions)
165
- .filter(([, actionDef]) => {
166
- const allowedStates = actionDef.allowedStates;
167
- // If no allowedStates specified, action is available in all valid states
168
- if (!allowedStates || allowedStates.length === 0)
169
- return true;
170
- return allowedStates.includes(currentState);
171
- })
172
- .map(([name]) => ({
173
- name,
174
- // WorkflowMeta doesn't define target states - transitions are handled server-side
175
- targetState: currentState,
176
- }));
177
- }
178
- // XState format: use the on property of the state
179
- const states = workflow.states;
180
- if (!states)
181
- return [];
182
- const stateConfig = states[currentState];
183
- if (!stateConfig?.on)
184
- return [];
185
- return Object.entries(stateConfig.on).map(([name, target]) => ({
186
- name,
187
- targetState: typeof target === 'string' ? target : 'unknown',
188
- }));
189
- }
190
- /**
191
- * Returns metadata for a specific action, if available.
192
- * Only works with WorkflowMeta format; returns undefined for XState format.
193
- *
194
- * @param actionName - The action name to get metadata for
195
- * @returns Action metadata or undefined
196
- *
197
- * @example
198
- * ```ts
199
- * const actionMeta = doctype.getActionMeta('submit')
200
- * // { label: 'Submit', handler: 'plan:submit', allowedStates: ['draft'] }
201
- * ```
202
- *
203
- * @public
204
- */
205
- getActionMeta(actionName) {
206
- const workflow = this.workflow;
207
- if (!workflow || !Array.isArray(workflow.states))
208
- return undefined;
209
- const actions = workflow.actions;
210
- return actions?.[actionName];
211
- }
212
- /**
213
- * Converts the registered doctype string to a slug (kebab-case). The following conversions are made:
214
- * - It replaces camelCase and PascalCase with kebab-case strings
215
- * - It replaces spaces and underscores with hyphens
216
- * - It converts the string to lowercase
217
- *
218
- * @returns The slugified doctype string
219
- *
220
- * @example
221
- * ```ts
222
- * const doctype = new Doctype('TaskItem', schema, workflow, actions)
223
- * console.log(doctype.slug) // 'task-item'
224
- * ```
225
- *
226
- * @public
227
- */
228
- get slug() {
229
- return this.doctype
230
- .replace(/([a-z])([A-Z])/g, '$1-$2')
231
- .replace(/[\s_]+/g, '-')
232
- .toLowerCase();
233
- }
234
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * NotImplementedError
3
- * @param message {string} - The error message
4
- * @class
5
- * @description This error is thrown when a method has not been implemented
6
- * @example
7
- * throw new NotImplementedError('Method not implemented')
8
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error|Error}
9
- * @public
10
- */
11
- export class NotImplementedError extends Error {
12
- constructor(message = '') {
13
- super(message);
14
- this.name = 'NotImplemented';
15
- }
16
- }